Skip to content
File

Blob: src/worker/db/d1/schema/repositories.ts

typescript45 lines
1import { sql, desc } from "drizzle-orm";
2import { check, index, integer, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
3 
4import { namespaces } from "./namespaces";
5import { users } from "./users";
6 
7export type RepositoryVisibility = "public" | "private";
8 
9// A repository row identifies a repo by `(namespace_id, slug)` and binds
10// it to a Durable Object via `do_name`. `do_name` is the value passed to
11// `env.REPO_DO.idFromName()`. Legacy/imported rows use the historical
12// `<namespace>/<repo>` form so that existing storage stays addressable;
13// new repos created post-migration use a `repo:<uuid>` form.
14export const repositories = sqliteTable(
15 "repositories",
16 {
17 id: text("id").primaryKey(),
18 namespaceId: text("namespace_id")
19 .notNull()
20 .references(() => namespaces.id, { onDelete: "cascade" }),
21 createdBy: text("created_by")
22 .notNull()
23 .references(() => users.id, { onDelete: "restrict" }),
24 slug: text("slug").notNull(),
25 doName: text("do_name").notNull(),
26 visibility: text("visibility").notNull().$type<RepositoryVisibility>(),
27 createdAt: integer("created_at").notNull(),
28 updatedAt: integer("updated_at").notNull(),
29 },
30 (table) => [
31 uniqueIndex("uq_repositories_namespace_slug").on(table.namespaceId, table.slug),
32 uniqueIndex("uq_repositories_do_name").on(table.doName),
33 // Owner page / namespace listing without scanning the namespace.
34 index("idx_repositories_namespace_updated").on(
35 table.namespaceId,
36 desc(table.updatedAt),
37 table.slug
38 ),
39 check("chk_repositories_visibility", sql`"visibility" IN ('public','private')`),
40 ]
41);
42 
43export type RepositoryRow = typeof repositories.$inferSelect;
44export type NewRepositoryRow = typeof repositories.$inferInsert;