@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
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.up = up;
|
|
4
|
+
exports.down = down;
|
|
5
|
+
// @TODO subject indexes, naming?
|
|
6
|
+
// @TODO drop indexes in down()?
|
|
7
|
+
async function up(db) {
|
|
8
|
+
// actor
|
|
9
|
+
await db.schema
|
|
10
|
+
.createTable('actor')
|
|
11
|
+
.addColumn('did', 'varchar', (col) => col.primaryKey())
|
|
12
|
+
.addColumn('handle', 'varchar', (col) => col.unique())
|
|
13
|
+
.addColumn('indexed_at', 'varchar', (col) => col.notNull())
|
|
14
|
+
.addColumn('takedown_ref', 'varchar')
|
|
15
|
+
.addColumn('upstream_status', 'varchar')
|
|
16
|
+
.execute();
|
|
17
|
+
// await db.schema // Supports user search
|
|
18
|
+
// .createIndex(`actor_handle_tgrm_idx`)
|
|
19
|
+
// .on('actor')
|
|
20
|
+
// .using('gist')
|
|
21
|
+
// .expression(sql`"handle" gist_trgm_ops`)
|
|
22
|
+
// .execute()
|
|
23
|
+
// actor_sync
|
|
24
|
+
await db.schema
|
|
25
|
+
.createTable('actor_sync')
|
|
26
|
+
.addColumn('did', 'varchar', (col) => col.primaryKey())
|
|
27
|
+
.addForeignKeyConstraint('fx_actor_sync_did_to_actor_did', ['did'], 'actor', ['did'], (cb) => cb.onDelete('cascade').onUpdate('cascade'))
|
|
28
|
+
.addColumn('commit_cid', 'varchar', (col) => col.notNull())
|
|
29
|
+
.addColumn('repo_rev', 'varchar', (col) => col.notNull())
|
|
30
|
+
.execute();
|
|
31
|
+
// artist
|
|
32
|
+
await db.schema
|
|
33
|
+
.createTable('artist')
|
|
34
|
+
.addColumn('id', 'integer', (col) => {
|
|
35
|
+
col.primaryKey();
|
|
36
|
+
col.generatedAlwaysAsIdentity();
|
|
37
|
+
return col;
|
|
38
|
+
})
|
|
39
|
+
.addColumn('name', 'varchar', (col) => col.notNull())
|
|
40
|
+
.addColumn('mb_id', 'varchar(36)', (col) => col.notNull())
|
|
41
|
+
.execute();
|
|
42
|
+
// song
|
|
43
|
+
await db.schema
|
|
44
|
+
.createTable('song')
|
|
45
|
+
.addColumn('id', 'integer', (col) => {
|
|
46
|
+
col.primaryKey();
|
|
47
|
+
col.generatedAlwaysAsIdentity();
|
|
48
|
+
return col;
|
|
49
|
+
})
|
|
50
|
+
.addColumn('track_name', 'varchar', (col) => col.notNull())
|
|
51
|
+
.addColumn('track_mb_id', 'varchar', (col) => col.notNull().unique())
|
|
52
|
+
.addColumn('album_artwork_ref', 'varchar')
|
|
53
|
+
.addColumn('indexed_at', 'varchar', (col) => col.notNull())
|
|
54
|
+
.execute();
|
|
55
|
+
// did_cache
|
|
56
|
+
await db.schema
|
|
57
|
+
.createTable('did_cache')
|
|
58
|
+
.addColumn('did', 'varchar', (col) => col.primaryKey())
|
|
59
|
+
.addColumn('doc', 'text', (col) => col.notNull())
|
|
60
|
+
.addColumn('updatedAt', 'bigint', (col) => col.notNull())
|
|
61
|
+
.execute();
|
|
62
|
+
// playlist_idea
|
|
63
|
+
await db.schema
|
|
64
|
+
.createTable('playlist_idea')
|
|
65
|
+
.addColumn('id', 'integer', (col) => {
|
|
66
|
+
col.primaryKey();
|
|
67
|
+
col.generatedAlwaysAsIdentity();
|
|
68
|
+
return col;
|
|
69
|
+
})
|
|
70
|
+
.addColumn('uri', 'varchar', (col) => {
|
|
71
|
+
col.notNull();
|
|
72
|
+
col.unique();
|
|
73
|
+
return col;
|
|
74
|
+
})
|
|
75
|
+
.addColumn('title', 'varchar', (col) => col.notNull())
|
|
76
|
+
.addColumn('description', 'varchar')
|
|
77
|
+
.addColumn('creator_did', 'varchar', (col) => col.notNull())
|
|
78
|
+
.addForeignKeyConstraint('fx_playlist_idea_creator_did_to_actor_did', ['creator_did'], 'actor', ['did'], (cb) => cb.onDelete('cascade').onUpdate('cascade'))
|
|
79
|
+
.addColumn('owner_did', 'varchar', (col) => col.notNull())
|
|
80
|
+
.addForeignKeyConstraint('fx_playlist_idea_owner_did_to_actor_did', ['owner_did'], 'actor', ['did'], (cb) => cb.onDelete('cascade').onUpdate('cascade'))
|
|
81
|
+
.addColumn('created_at', 'varchar', (col) => col.notNull())
|
|
82
|
+
.execute();
|
|
83
|
+
// playlist
|
|
84
|
+
await db.schema
|
|
85
|
+
.createTable('playlist')
|
|
86
|
+
.addColumn('id', 'integer', (col) => {
|
|
87
|
+
col.primaryKey();
|
|
88
|
+
col.generatedAlwaysAsIdentity();
|
|
89
|
+
return col;
|
|
90
|
+
})
|
|
91
|
+
.addColumn('playlist_idea_uri', 'varchar', (col) => col.notNull())
|
|
92
|
+
.addForeignKeyConstraint('fx_playlist_playlist_idea_uri_to_playlist_idea_uri', ['playlist_idea_uri'], 'playlist_idea', ['uri'], (cb) => cb.onDelete('cascade').onUpdate('cascade'))
|
|
93
|
+
.addColumn('type', 'varchar', (col) => col.notNull())
|
|
94
|
+
.addColumn('name', 'varchar', (col) => col.notNull())
|
|
95
|
+
.execute();
|
|
96
|
+
// playlist_item
|
|
97
|
+
await db.schema
|
|
98
|
+
.createTable('playlist_item')
|
|
99
|
+
.addColumn('id', 'integer', (col) => {
|
|
100
|
+
col.primaryKey();
|
|
101
|
+
col.generatedAlwaysAsIdentity();
|
|
102
|
+
return col;
|
|
103
|
+
})
|
|
104
|
+
.addColumn('playlist_id', 'integer', (col) => col.notNull())
|
|
105
|
+
.addForeignKeyConstraint('fx_playlist_item_playlist_id_to_playlist_id', ['playlist_id'], 'playlist', ['id'], (cb) => cb.onDelete('cascade').onUpdate('cascade'))
|
|
106
|
+
.addColumn('song_id', 'integer', (col) => col.notNull())
|
|
107
|
+
.addForeignKeyConstraint('fx_playlist_item_song_id_to_song_id', ['song_id'], 'song', ['id'], (cb) => cb.onDelete('cascade').onUpdate('cascade'))
|
|
108
|
+
.addColumn('position', 'integer', (col) => col.notNull())
|
|
109
|
+
.execute();
|
|
110
|
+
// artist_list_item
|
|
111
|
+
await db.schema
|
|
112
|
+
.createTable('artist_list_item')
|
|
113
|
+
.addColumn('id', 'integer', (col) => {
|
|
114
|
+
col.primaryKey();
|
|
115
|
+
col.generatedAlwaysAsIdentity();
|
|
116
|
+
return col;
|
|
117
|
+
})
|
|
118
|
+
.addColumn('artist_id', 'integer', (col) => col.notNull())
|
|
119
|
+
.addForeignKeyConstraint('fx_artist_list_item_artist_id_to_artist_id', ['artist_id'], 'artist', ['id'], (cb) => cb.onDelete('cascade').onUpdate('cascade'))
|
|
120
|
+
.addColumn('song_id', 'integer', (col) => col.notNull())
|
|
121
|
+
.addForeignKeyConstraint('fx_artist_list_item_song_id_to_song_id', ['song_id'], 'song', ['id'], (cb) => cb.onDelete('cascade').onUpdate('cascade'))
|
|
122
|
+
.addColumn('position', 'integer', (col) => col.notNull())
|
|
123
|
+
.execute();
|
|
124
|
+
// profile
|
|
125
|
+
await db.schema
|
|
126
|
+
.createTable('profile')
|
|
127
|
+
.addColumn('uri', 'varchar', (col) => col.primaryKey())
|
|
128
|
+
.addColumn('cid', 'varchar', (col) => col.notNull())
|
|
129
|
+
.addColumn('creator_did', 'varchar', (col) => col.notNull())
|
|
130
|
+
.addForeignKeyConstraint('fx_profile_creator_did_to_actor_did', ['creator_did'], 'actor', ['did'], (cb) => cb.onDelete('cascade').onUpdate('cascade'))
|
|
131
|
+
.addColumn('display_name', 'varchar')
|
|
132
|
+
.addColumn('description', 'varchar')
|
|
133
|
+
.addColumn('avatar_cid', 'varchar')
|
|
134
|
+
.addColumn('banner_cid', 'varchar')
|
|
135
|
+
.addColumn('created_at', 'varchar', (col) => col.notNull())
|
|
136
|
+
.addColumn('indexed_at', 'varchar', (col) => col.notNull())
|
|
137
|
+
.execute();
|
|
138
|
+
// record
|
|
139
|
+
await db.schema
|
|
140
|
+
.createTable('record')
|
|
141
|
+
.addColumn('uri', 'varchar', (col) => col.primaryKey())
|
|
142
|
+
.addColumn('cid', 'varchar', (col) => col.notNull())
|
|
143
|
+
.addColumn('did', 'varchar', (col) => col.notNull())
|
|
144
|
+
.addForeignKeyConstraint('fx_record_did_to_actor_did', ['did'], 'actor', ['did'], (cb) => cb.onDelete('cascade').onUpdate('cascade'))
|
|
145
|
+
.addColumn('json', 'text', (col) => col.notNull())
|
|
146
|
+
.addColumn('indexed_at', 'varchar', (col) => col.notNull())
|
|
147
|
+
.addColumn('takedown_ref', 'varchar')
|
|
148
|
+
.execute();
|
|
149
|
+
// subscription_cursor
|
|
150
|
+
await db.schema
|
|
151
|
+
.createTable('subscription_cursor')
|
|
152
|
+
.addColumn('service', 'varchar', (col) => col.primaryKey())
|
|
153
|
+
.addColumn('cursor', 'bigint', (col) => col.notNull())
|
|
154
|
+
.addColumn('updated_at', 'bigint', (col) => col.notNull())
|
|
155
|
+
.execute();
|
|
156
|
+
}
|
|
157
|
+
async function down(db) {
|
|
158
|
+
await db.schema.dropTable('subscription_cursor').execute();
|
|
159
|
+
await db.schema.dropTable('record').execute();
|
|
160
|
+
await db.schema.dropTable('profile').execute();
|
|
161
|
+
await db.schema.dropTable('artist_list_item').execute();
|
|
162
|
+
await db.schema.dropTable('playlist_item').execute();
|
|
163
|
+
await db.schema.dropTable('playlist').execute();
|
|
164
|
+
await db.schema.dropTable('playlist_idea').execute();
|
|
165
|
+
await db.schema.dropTable('did_cache').execute();
|
|
166
|
+
await db.schema.dropTable('song').execute();
|
|
167
|
+
await db.schema.dropTable('artist').execute();
|
|
168
|
+
await db.schema.dropTable('actor_sync').execute();
|
|
169
|
+
await db.schema.dropTable('actor').execute();
|
|
170
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.up = up;
|
|
4
|
+
exports.down = down;
|
|
5
|
+
async function up(db) {
|
|
6
|
+
await db.schema
|
|
7
|
+
.createTable('song_recommendation')
|
|
8
|
+
.addColumn('id', 'integer', (col) => {
|
|
9
|
+
col.primaryKey();
|
|
10
|
+
col.generatedAlwaysAsIdentity();
|
|
11
|
+
return col;
|
|
12
|
+
})
|
|
13
|
+
.addColumn('uri', 'varchar', (col) => col.notNull().unique())
|
|
14
|
+
.addColumn('cid', 'varchar', (col) => col.notNull())
|
|
15
|
+
.addColumn('recommender_did', 'varchar', (col) => col.notNull())
|
|
16
|
+
.addForeignKeyConstraint('fx_song_rec_recommender_did_to_actor_did', ['recommender_did'], 'actor', ['did'], (cb) => cb.onDelete('cascade').onUpdate('cascade'))
|
|
17
|
+
.addColumn('playlist_idea_uri', 'varchar', (col) => col.notNull())
|
|
18
|
+
.addForeignKeyConstraint('fx_song_rec_playlist_idea_uri_to_playlist_idea_uri', ['playlist_idea_uri'], 'playlist_idea', ['uri'], (cb) => cb.onDelete('cascade').onUpdate('cascade'))
|
|
19
|
+
.addColumn('playlist_idea_cid', 'varchar', (col) => col.notNull())
|
|
20
|
+
.addColumn('song_id', 'integer', (col) => col.notNull())
|
|
21
|
+
.addForeignKeyConstraint('fx_song_rec_song_id_to_song_id', ['song_id'], 'song', ['id'], (cb) => cb.onDelete('cascade').onUpdate('cascade'))
|
|
22
|
+
.addColumn('note', 'varchar')
|
|
23
|
+
.addColumn('created_at', 'varchar', (col) => col.notNull())
|
|
24
|
+
.addColumn('indexed_at', 'varchar', (col) => col.notNull())
|
|
25
|
+
.execute();
|
|
26
|
+
await db.schema
|
|
27
|
+
.createIndex('song_rec_dedup_idx')
|
|
28
|
+
.on('song_recommendation')
|
|
29
|
+
.columns(['recommender_did', 'playlist_idea_uri', 'song_id'])
|
|
30
|
+
.unique()
|
|
31
|
+
.execute();
|
|
32
|
+
}
|
|
33
|
+
async function down(db) {
|
|
34
|
+
await db.schema.dropIndex('song_rec_dedup_idx').execute();
|
|
35
|
+
await db.schema.dropTable('song_recommendation').execute();
|
|
36
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.up = up;
|
|
4
|
+
exports.down = down;
|
|
5
|
+
async function up(db) {
|
|
6
|
+
await db.schema
|
|
7
|
+
.createTable('oauth_state')
|
|
8
|
+
.addColumn('key', 'varchar', (col) => col.primaryKey())
|
|
9
|
+
.addColumn('value', 'jsonb', (col) => col.notNull())
|
|
10
|
+
.addColumn('created_at', 'bigint', (col) => col.notNull())
|
|
11
|
+
.addColumn('expires_at', 'bigint', (col) => col.notNull())
|
|
12
|
+
.execute();
|
|
13
|
+
await db.schema.createIndex('oauth_state_expires_at_idx').on('oauth_state').column('expires_at').execute();
|
|
14
|
+
await db.schema
|
|
15
|
+
.createTable('oauth_session')
|
|
16
|
+
.addColumn('key', 'varchar', (col) => col.primaryKey())
|
|
17
|
+
.addColumn('value', 'jsonb', (col) => col.notNull())
|
|
18
|
+
.addColumn('updated_at', 'bigint', (col) => col.notNull())
|
|
19
|
+
.execute();
|
|
20
|
+
}
|
|
21
|
+
async function down(db) {
|
|
22
|
+
await db.schema.dropTable('oauth_session').execute();
|
|
23
|
+
await db.schema.dropIndex('oauth_state_expires_at_idx').execute();
|
|
24
|
+
await db.schema.dropTable('oauth_state').execute();
|
|
25
|
+
}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export * as _20230309T045948368Z from './
|
|
2
|
-
export * as
|
|
1
|
+
export * as _20230309T045948368Z from './20250515T045948368Z-init';
|
|
2
|
+
export * as _20260119T210000000Z from './20260119T210000000Z-song-recommendation';
|
|
3
|
+
export * as _20260119T220000000Z from './20260119T220000000Z-oauth';
|
|
@@ -1,5 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
// NOTE this file can be edited by hand, but it is also appended to by the migration:create command.
|
|
2
3
|
// It's important that every migration is exported from here with the proper name. We'd simplify
|
|
3
4
|
// this with kysely's FileMigrationProvider, but it doesn't play nicely with the build process.
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports._20260119T220000000Z = exports._20260119T210000000Z = exports._20230309T045948368Z = void 0;
|
|
40
|
+
exports._20230309T045948368Z = __importStar(require("./20250515T045948368Z-init"));
|
|
41
|
+
exports._20260119T210000000Z = __importStar(require("./20260119T210000000Z-song-recommendation"));
|
|
42
|
+
exports._20260119T220000000Z = __importStar(require("./20260119T220000000Z-oauth"));
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CtxMigrationProvider = void 0;
|
|
1
4
|
// Passes a context argument to migrations. We use this to thread the dialect into migrations
|
|
2
|
-
|
|
5
|
+
class CtxMigrationProvider {
|
|
3
6
|
migrations;
|
|
4
7
|
ctx;
|
|
5
8
|
constructor(migrations, ctx) {
|
|
@@ -17,3 +20,4 @@ export class CtxMigrationProvider {
|
|
|
17
20
|
return ctxMigrations;
|
|
18
21
|
}
|
|
19
22
|
}
|
|
23
|
+
exports.CtxMigrationProvider = CtxMigrationProvider;
|
|
@@ -33,7 +33,7 @@ export declare abstract class GenericKeyset<R, LR extends LabeledResult> {
|
|
|
33
33
|
unpack(cursorStr?: string): LR | undefined;
|
|
34
34
|
packCursor(cursor?: Cursor): string | undefined;
|
|
35
35
|
unpackCursor(cursorStr?: string): Cursor | undefined;
|
|
36
|
-
getSql(labeled?: LR, direction?: 'asc' | 'desc', tryIndex?: boolean): import("kysely").RawBuilder<
|
|
36
|
+
getSql(labeled?: LR, direction?: 'asc' | 'desc', tryIndex?: boolean): import("kysely").RawBuilder<0 | 1> | undefined;
|
|
37
37
|
}
|
|
38
38
|
type SortAtCidResult = {
|
|
39
39
|
sortAt: string;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.paginate = exports.IndexedAtDidKeyset = exports.CreatedAtDidKeyset = exports.TimeCidKeyset = exports.GenericKeyset = void 0;
|
|
4
|
+
const xrpc_server_1 = require("@atproto/xrpc-server");
|
|
5
|
+
const kysely_1 = require("kysely");
|
|
3
6
|
/**
|
|
4
7
|
* The GenericKeyset is an abstract class that sets-up the interface and partial implementation
|
|
5
8
|
* of a keyset-paginated cursor with two parts. There are three types involved:
|
|
@@ -14,7 +17,7 @@ import { sql } from 'kysely';
|
|
|
14
17
|
* Result -*-> LabeledResult <-*-> Cursor <--> packed/string cursor
|
|
15
18
|
* ↳ SQL Condition
|
|
16
19
|
*/
|
|
17
|
-
|
|
20
|
+
class GenericKeyset {
|
|
18
21
|
primary;
|
|
19
22
|
secondary;
|
|
20
23
|
constructor(primary, secondary) {
|
|
@@ -50,7 +53,7 @@ export class GenericKeyset {
|
|
|
50
53
|
const result = cursorStr.split('__');
|
|
51
54
|
const [primary, secondary, ...others] = result;
|
|
52
55
|
if (!primary || !secondary || others.length > 0) {
|
|
53
|
-
throw new InvalidRequestError('Malformed cursor');
|
|
56
|
+
throw new xrpc_server_1.InvalidRequestError('Malformed cursor');
|
|
54
57
|
}
|
|
55
58
|
return {
|
|
56
59
|
primary,
|
|
@@ -63,24 +66,25 @@ export class GenericKeyset {
|
|
|
63
66
|
if (tryIndex) {
|
|
64
67
|
// The tryIndex param will likely disappear and become the default implementation: here for now for gradual rollout query-by-query.
|
|
65
68
|
if (direction === 'asc') {
|
|
66
|
-
return sql `((${this.primary}, ${this.secondary}) > (${labeled.primary}, ${labeled.secondary}))`;
|
|
69
|
+
return (0, kysely_1.sql) `((${this.primary}, ${this.secondary}) > (${labeled.primary}, ${labeled.secondary}))`;
|
|
67
70
|
}
|
|
68
71
|
else {
|
|
69
|
-
return sql `((${this.primary}, ${this.secondary}) < (${labeled.primary}, ${labeled.secondary}))`;
|
|
72
|
+
return (0, kysely_1.sql) `((${this.primary}, ${this.secondary}) < (${labeled.primary}, ${labeled.secondary}))`;
|
|
70
73
|
}
|
|
71
74
|
}
|
|
72
75
|
else {
|
|
73
76
|
// @NOTE this implementation can struggle to use an index on (primary, secondary) for pagination due to the "or" usage.
|
|
74
77
|
if (direction === 'asc') {
|
|
75
|
-
return sql `((${this.primary} > ${labeled.primary}) or (${this.primary} = ${labeled.primary} and ${this.secondary} > ${labeled.secondary}))`;
|
|
78
|
+
return (0, kysely_1.sql) `((${this.primary} > ${labeled.primary}) or (${this.primary} = ${labeled.primary} and ${this.secondary} > ${labeled.secondary}))`;
|
|
76
79
|
}
|
|
77
80
|
else {
|
|
78
|
-
return sql `((${this.primary} < ${labeled.primary}) or (${this.primary} = ${labeled.primary} and ${this.secondary} < ${labeled.secondary}))`;
|
|
81
|
+
return (0, kysely_1.sql) `((${this.primary} < ${labeled.primary}) or (${this.primary} = ${labeled.primary} and ${this.secondary} < ${labeled.secondary}))`;
|
|
79
82
|
}
|
|
80
83
|
}
|
|
81
84
|
}
|
|
82
85
|
}
|
|
83
|
-
|
|
86
|
+
exports.GenericKeyset = GenericKeyset;
|
|
87
|
+
class TimeCidKeyset extends GenericKeyset {
|
|
84
88
|
labelResult(result) {
|
|
85
89
|
return { primary: result.sortAt, secondary: result.cid };
|
|
86
90
|
}
|
|
@@ -93,7 +97,7 @@ export class TimeCidKeyset extends GenericKeyset {
|
|
|
93
97
|
cursorToLabeledResult(cursor) {
|
|
94
98
|
const primaryDate = new Date(parseInt(cursor.primary, 10));
|
|
95
99
|
if (isNaN(primaryDate.getTime())) {
|
|
96
|
-
throw new InvalidRequestError('Malformed cursor');
|
|
100
|
+
throw new xrpc_server_1.InvalidRequestError('Malformed cursor');
|
|
97
101
|
}
|
|
98
102
|
return {
|
|
99
103
|
primary: primaryDate.toISOString(),
|
|
@@ -101,28 +105,37 @@ export class TimeCidKeyset extends GenericKeyset {
|
|
|
101
105
|
};
|
|
102
106
|
}
|
|
103
107
|
}
|
|
104
|
-
|
|
108
|
+
exports.TimeCidKeyset = TimeCidKeyset;
|
|
109
|
+
class CreatedAtDidKeyset extends TimeCidKeyset {
|
|
105
110
|
labelResult(result) {
|
|
106
111
|
return { primary: result.createdAt, secondary: result.did };
|
|
107
112
|
}
|
|
108
113
|
}
|
|
109
|
-
|
|
114
|
+
exports.CreatedAtDidKeyset = CreatedAtDidKeyset;
|
|
115
|
+
class IndexedAtDidKeyset extends TimeCidKeyset {
|
|
110
116
|
labelResult(result) {
|
|
111
117
|
return { primary: result.indexedAt, secondary: result.did };
|
|
112
118
|
}
|
|
113
119
|
}
|
|
114
|
-
|
|
115
|
-
|
|
120
|
+
exports.IndexedAtDidKeyset = IndexedAtDidKeyset;
|
|
121
|
+
const paginate = (qb, opts) => {
|
|
122
|
+
const { limit, cursor, keyset, direction = 'desc', tryIndex, nullsLast } = opts;
|
|
116
123
|
const keysetSql = keyset.getSql(keyset.unpack(cursor), direction, tryIndex);
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
.
|
|
124
|
+
let q = qb;
|
|
125
|
+
if (typeof limit === 'number') {
|
|
126
|
+
q = q.limit(limit);
|
|
127
|
+
}
|
|
128
|
+
if (nullsLast) {
|
|
129
|
+
q = q
|
|
130
|
+
.orderBy(direction === 'asc' ? (0, kysely_1.sql) `${keyset.primary} asc nulls last` : (0, kysely_1.sql) `${keyset.primary} desc nulls last`)
|
|
131
|
+
.orderBy(direction === 'asc' ? (0, kysely_1.sql) `${keyset.secondary} asc nulls last` : (0, kysely_1.sql) `${keyset.secondary} desc nulls last`);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
q = q.orderBy(keyset.primary, direction).orderBy(keyset.secondary, direction);
|
|
135
|
+
}
|
|
136
|
+
if (keysetSql) {
|
|
137
|
+
q = q.where(keysetSql);
|
|
138
|
+
}
|
|
139
|
+
return q;
|
|
128
140
|
};
|
|
141
|
+
exports.paginate = paginate;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export declare const tableName = "actor";
|
|
2
2
|
export interface ActorTable {
|
|
3
3
|
did: string;
|
|
4
|
-
handle
|
|
4
|
+
handle: string | null;
|
|
5
5
|
indexed_at: string;
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
takedown_ref: string | null;
|
|
7
|
+
upstream_status: string | null;
|
|
8
8
|
}
|
|
9
9
|
export type PartialDB = {
|
|
10
10
|
[tableName]: ActorTable;
|
|
@@ -2,9 +2,9 @@ import { Generated } from 'kysely';
|
|
|
2
2
|
export declare const tableName = "artist_list_item";
|
|
3
3
|
export interface ArtistListItemTable {
|
|
4
4
|
id: Generated<number>;
|
|
5
|
-
song_id: number;
|
|
6
|
-
seq_num: number;
|
|
7
5
|
artist_id: number;
|
|
6
|
+
song_id: number;
|
|
7
|
+
position: number;
|
|
8
8
|
}
|
|
9
9
|
export type PartialDB = {
|
|
10
10
|
[tableName]: ArtistListItemTable;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import { Generated } from 'kysely';
|
|
1
2
|
export declare const tableName = "playlist_idea";
|
|
2
3
|
export interface PlaylistIdeaTable {
|
|
4
|
+
id: Generated<number>;
|
|
3
5
|
uri: string;
|
|
4
6
|
title: string;
|
|
5
|
-
description
|
|
7
|
+
description: string | null;
|
|
6
8
|
creator_did: string;
|
|
7
9
|
owner_did: string;
|
|
8
|
-
master_playlist_id?: number;
|
|
9
|
-
recommended_playlist_id?: number;
|
|
10
10
|
created_at: string;
|
|
11
11
|
}
|
|
12
12
|
export type PartialDB = {
|
|
@@ -2,11 +2,11 @@ export declare const tableName = "profile";
|
|
|
2
2
|
export interface ProfileTable {
|
|
3
3
|
uri: string;
|
|
4
4
|
cid: string;
|
|
5
|
-
|
|
6
|
-
display_name
|
|
7
|
-
description
|
|
8
|
-
avatar_cid
|
|
9
|
-
banner_cid
|
|
5
|
+
creator_did: string;
|
|
6
|
+
display_name: string | null;
|
|
7
|
+
description: string | null;
|
|
8
|
+
avatar_cid: string | null;
|
|
9
|
+
banner_cid: string | null;
|
|
10
10
|
created_at: string;
|
|
11
11
|
indexed_at: string;
|
|
12
12
|
}
|