diff --git a/src/controllers/api/accounts.ts b/src/controllers/api/accounts.ts index c946b697..f14b8b5d 100644 --- a/src/controllers/api/accounts.ts +++ b/src/controllers/api/accounts.ts @@ -6,7 +6,6 @@ import { type AppController } from '@/app.ts'; import { Conf } from '@/config.ts'; import { getAuthor, getFollowedPubkeys } from '@/queries.ts'; import { booleanParamSchema, fileSchema } from '@/schema.ts'; -import { getPubkeysBySearch } from '@/controllers/api/search.ts'; import { Storages } from '@/storages.ts'; import { uploadFile } from '@/utils/upload.ts'; import { nostrNow } from '@/utils.ts'; @@ -19,6 +18,7 @@ import { renderReblog, renderStatus } from '@/views/mastodon/statuses.ts'; import { hydrateEvents } from '@/storages/hydrate.ts'; import { bech32ToPubkey } from '@/utils.ts'; import { addTag, deleteTag, findReplyTag, getTagSet } from '@/utils/tags.ts'; +import { getPubkeysBySearch } from '@/utils/search.ts'; const usernameSchema = z .string().min(1).max(30) diff --git a/src/controllers/api/search.ts b/src/controllers/api/search.ts index 01fb6665..05d42044 100644 --- a/src/controllers/api/search.ts +++ b/src/controllers/api/search.ts @@ -1,10 +1,8 @@ import { NostrEvent, NostrFilter, NSchema as n } from '@nostrify/nostrify'; import { nip19 } from 'nostr-tools'; -import { Kysely, sql } from 'kysely'; import { z } from 'zod'; import { AppController } from '@/app.ts'; -import { DittoTables } from '@/db/DittoTables.ts'; import { booleanParamSchema } from '@/schema.ts'; import { Storages } from '@/storages.ts'; import { hydrateEvents } from '@/storages/hydrate.ts'; @@ -12,6 +10,7 @@ import { extractIdentifier, lookupPubkey } from '@/utils/lookup.ts'; import { nip05Cache } from '@/utils/nip05.ts'; import { accountFromPubkey, renderAccount } from '@/views/mastodon/accounts.ts'; import { renderStatus } from '@/views/mastodon/statuses.ts'; +import { getPubkeysBySearch } from '@/utils/search.ts'; const searchQuerySchema = z.object({ q: z.string().transform(decodeURIComponent), @@ -194,16 +193,4 @@ async function getLookupFilters({ q, type, resolve }: SearchQuery, signal: Abort return []; } -/** Get pubkeys whose name and NIP-05 is similar to 'q' */ -async function getPubkeysBySearch(kysely: Kysely, { q, limit }: Pick) { - const pubkeys = (await sql<{ pubkey: string }>` - SELECT *, word_similarity(${q}, search) AS sml - FROM author_search - WHERE ${q} % search - ORDER BY sml DESC, search LIMIT ${limit} - `.execute(kysely)).rows.map(({ pubkey }) => pubkey); - - return pubkeys; -} - -export { getPubkeysBySearch, searchController }; +export { searchController }; diff --git a/src/controllers/api/search.test.ts b/src/utils/search.test.ts similarity index 92% rename from src/controllers/api/search.test.ts rename to src/utils/search.test.ts index 2c5e91bd..a67c0662 100644 --- a/src/controllers/api/search.test.ts +++ b/src/utils/search.test.ts @@ -1,7 +1,7 @@ import { assertEquals } from '@std/assert'; import { createTestDB } from '@/test.ts'; -import { getPubkeysBySearch } from '@/controllers/api/search.ts'; +import { getPubkeysBySearch } from '@/utils/search.ts'; Deno.test('fuzzy search works', async () => { await using db = await createTestDB(); diff --git a/src/utils/search.ts b/src/utils/search.ts new file mode 100644 index 00000000..460c2525 --- /dev/null +++ b/src/utils/search.ts @@ -0,0 +1,16 @@ +import { Kysely, sql } from 'kysely'; + +import { DittoTables } from '@/db/DittoTables.ts'; + +/** Get pubkeys whose name and NIP-05 is similar to 'q' */ +export async function getPubkeysBySearch(kysely: Kysely, opts: { q: string; limit: number }) { + const { q, limit } = opts; + const pubkeys = (await sql<{ pubkey: string }>` + SELECT *, word_similarity(${q}, search) AS sml + FROM author_search + WHERE ${q} % search + ORDER BY sml DESC, search LIMIT ${limit} + `.execute(kysely)).rows.map(({ pubkey }) => pubkey); + + return pubkeys; +}