Skip to content

Commit 16c70d2

Browse files
committed
Small styling
1 parent cdbe5d5 commit 16c70d2

4 files changed

Lines changed: 407 additions & 120 deletions

File tree

src/api/collections.ts

Lines changed: 82 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createGzip } from 'node:zlib'
22

3-
import { and, eq, ilike, or, sql } from 'drizzle-orm'
3+
import { and, desc, eq, ilike, inArray, or, sql } from 'drizzle-orm'
44
import type { Context } from 'hono'
55
import { stream } from 'hono/streaming'
66
import { pack as tarPack } from 'tar-stream'
@@ -14,10 +14,10 @@ import { type AuthEnv } from './auth.server.js'
1414
// Browse public collections
1515
export async function list(c: Context<AuthEnv>) {
1616
const q = c.req.query('q')
17-
const limit = c.req.query('limit')
18-
const offset = c.req.query('offset')
19-
const take = Math.min(parseInt(limit ?? '50', 10), 100)
20-
const skip = parseInt(offset ?? '0', 10)
17+
const owner = c.req.query('owner')
18+
const sort = c.req.query('sort')
19+
const take = Math.min(parseInt(c.req.query('limit') ?? '50', 10), 100)
20+
const skip = parseInt(c.req.query('offset') ?? '0', 10)
2121

2222
const conditions = [eq(schema.collections.public, true)]
2323
if (q) {
@@ -28,6 +28,9 @@ export async function list(c: Context<AuthEnv>) {
2828
)!,
2929
)
3030
}
31+
if (owner) {
32+
conditions.push(eq(schema.accounts.slug, owner))
33+
}
3134

3235
const results = await db
3336
.select({
@@ -45,9 +48,81 @@ export async function list(c: Context<AuthEnv>) {
4548
.where(and(...conditions))
4649
.limit(take)
4750
.offset(skip)
48-
.orderBy(schema.collections.updatedAt)
51+
.orderBy(sort === 'name' ? schema.collections.name : desc(schema.collections.updatedAt))
52+
53+
const ids = results.map((r) => r.id)
54+
const statsMap = new Map<
55+
string,
56+
{
57+
collectionId: string
58+
number: number
59+
semver: string
60+
recordCount: number
61+
fileCount: number
62+
totalBytes: number
63+
lastPushAt: Date
64+
}
65+
>()
4966

50-
return c.json(results)
67+
if (ids.length > 0) {
68+
const allVersions = await db
69+
.select({
70+
collectionId: schema.versions.collectionId,
71+
number: schema.versions.number,
72+
semver: schema.versions.semver,
73+
recordCount: schema.versions.recordCount,
74+
fileCount: schema.versions.fileCount,
75+
totalBytes: schema.versions.totalBytes,
76+
lastPushAt: schema.versions.createdAt,
77+
})
78+
.from(schema.versions)
79+
.where(inArray(schema.versions.collectionId, ids))
80+
.orderBy(desc(schema.versions.number))
81+
82+
for (const v of allVersions) {
83+
if (!statsMap.has(v.collectionId)) {
84+
statsMap.set(v.collectionId, v)
85+
}
86+
}
87+
}
88+
89+
const facetConditions = [eq(schema.collections.public, true)]
90+
if (q) {
91+
facetConditions.push(
92+
or(
93+
ilike(schema.collections.name, `%${q}%`),
94+
ilike(schema.collections.description, `%${q}%`),
95+
)!,
96+
)
97+
}
98+
99+
const ownerFacets = await db
100+
.select({
101+
slug: schema.accounts.slug,
102+
name: schema.accounts.displayName,
103+
count: sql<number>`count(*)::int`,
104+
})
105+
.from(schema.collections)
106+
.innerJoin(schema.accounts, eq(schema.collections.accountId, schema.accounts.id))
107+
.where(and(...facetConditions))
108+
.groupBy(schema.accounts.slug, schema.accounts.displayName)
109+
.orderBy(sql`count(*) DESC`)
110+
111+
return c.json({
112+
collections: results.map((r) => {
113+
const stats = statsMap.get(r.id)
114+
return {
115+
...r,
116+
latestVersion: stats?.number ?? null,
117+
semver: stats?.semver ?? null,
118+
recordCount: stats?.recordCount ?? null,
119+
fileCount: stats?.fileCount ?? null,
120+
totalBytes: stats?.totalBytes ?? null,
121+
lastPushAt: stats?.lastPushAt ?? null,
122+
}
123+
}),
124+
facets: { owners: ownerFacets },
125+
})
51126
}
52127

53128
// Create collection

0 commit comments

Comments
 (0)