@better-openclaw/db 1.0.0
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/.github/ISSUE_TEMPLATE/service-proposal.yml +57 -0
- package/.github/ISSUE_TEMPLATE/stack-submission.yml +32 -0
- package/.github/dependabot.yml +32 -0
- package/.github/workflows/ci.yml +57 -0
- package/.github/workflows/publish-core.yml +37 -0
- package/dist/chunk-DQk6qfdC.mjs +18 -0
- package/dist/chunk-uaV2rQ02.cjs +53 -0
- package/dist/index.cjs +28 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +11 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +11 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +13 -0
- package/dist/index.mjs.map +1 -0
- package/dist/schema.cjs +86 -0
- package/dist/schema.cjs.map +1 -0
- package/dist/schema.d.cts +841 -0
- package/dist/schema.d.cts.map +1 -0
- package/dist/schema.d.mts +841 -0
- package/dist/schema.d.mts.map +1 -0
- package/dist/schema.mjs +74 -0
- package/dist/schema.mjs.map +1 -0
- package/drizzle.config.ts +10 -0
- package/oldtsconfig.json +13 -0
- package/package.json +54 -0
- package/src/index.ts +14 -0
- package/src/schema.ts +86 -0
- package/tsconfig.base.json +25 -0
- package/tsconfig.json +9 -0
- package/tsdown.config.ts +10 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.mts","names":[],"sources":["../src/schema.ts"],"mappings":";;;;;;cAIa,IAAA,uBAAI,kBAAA;;;;QAQf,oBAAA,CAAA,QAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEW,OAAA,uBAAO,kBAAA;;;;QAWlB,oBAAA,CAAA,QAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEW,OAAA,uBAAO,kBAAA;;;;QAgBlB,oBAAA,CAAA,QAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEW,YAAA,uBAAY,kBAAA;;;;QAOvB,oBAAA,CAAA,QAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAIW,UAAA,uBAAU,kBAAA;;;;QAarB,oBAAA,CAAA,QAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEW,QAAA,uBAAQ,kBAAA;;;;QASnB,oBAAA,CAAA,QAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAEU,IAAA,UAAc,IAAA,CAAK,YAAA;AAAA,KACnB,OAAA,UAAiB,OAAA,CAAQ,YAAA;AAAA,KACzB,UAAA,UAAoB,UAAA,CAAW,YAAA;AAAA,KAC/B,QAAA,UAAkB,QAAA,CAAS,YAAA"}
|
package/dist/schema.mjs
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { t as __exportAll } from "./chunk-DQk6qfdC.mjs";
|
|
2
|
+
import { boolean, jsonb, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
|
|
3
|
+
|
|
4
|
+
//#region src/schema.ts
|
|
5
|
+
var schema_exports = /* @__PURE__ */ __exportAll({
|
|
6
|
+
account: () => account,
|
|
7
|
+
favorite: () => favorite,
|
|
8
|
+
savedStack: () => savedStack,
|
|
9
|
+
session: () => session,
|
|
10
|
+
user: () => user,
|
|
11
|
+
verification: () => verification
|
|
12
|
+
});
|
|
13
|
+
const user = pgTable("user", {
|
|
14
|
+
id: text("id").primaryKey(),
|
|
15
|
+
name: text("name").notNull(),
|
|
16
|
+
email: text("email").notNull().unique(),
|
|
17
|
+
emailVerified: boolean("email_verified").notNull(),
|
|
18
|
+
image: text("image"),
|
|
19
|
+
createdAt: timestamp("created_at").notNull(),
|
|
20
|
+
updatedAt: timestamp("updated_at").notNull()
|
|
21
|
+
});
|
|
22
|
+
const session = pgTable("session", {
|
|
23
|
+
id: text("id").primaryKey(),
|
|
24
|
+
expiresAt: timestamp("expires_at").notNull(),
|
|
25
|
+
token: text("token").notNull().unique(),
|
|
26
|
+
createdAt: timestamp("created_at").notNull(),
|
|
27
|
+
updatedAt: timestamp("updated_at").notNull(),
|
|
28
|
+
ipAddress: text("ip_address"),
|
|
29
|
+
userAgent: text("user_agent"),
|
|
30
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" })
|
|
31
|
+
});
|
|
32
|
+
const account = pgTable("account", {
|
|
33
|
+
id: text("id").primaryKey(),
|
|
34
|
+
accountId: text("account_id").notNull(),
|
|
35
|
+
providerId: text("provider_id").notNull(),
|
|
36
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
37
|
+
accessToken: text("access_token"),
|
|
38
|
+
refreshToken: text("refresh_token"),
|
|
39
|
+
idToken: text("id_token"),
|
|
40
|
+
accessTokenExpiresAt: timestamp("access_token_expires_at"),
|
|
41
|
+
refreshTokenExpiresAt: timestamp("refresh_token_expires_at"),
|
|
42
|
+
scope: text("scope"),
|
|
43
|
+
password: text("password"),
|
|
44
|
+
createdAt: timestamp("created_at").notNull(),
|
|
45
|
+
updatedAt: timestamp("updated_at").notNull()
|
|
46
|
+
});
|
|
47
|
+
const verification = pgTable("verification", {
|
|
48
|
+
id: text("id").primaryKey(),
|
|
49
|
+
identifier: text("identifier").notNull(),
|
|
50
|
+
value: text("value").notNull(),
|
|
51
|
+
expiresAt: timestamp("expires_at").notNull(),
|
|
52
|
+
createdAt: timestamp("created_at"),
|
|
53
|
+
updatedAt: timestamp("updated_at")
|
|
54
|
+
});
|
|
55
|
+
const savedStack = pgTable("saved_stack", {
|
|
56
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
57
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
58
|
+
name: text("name").notNull(),
|
|
59
|
+
description: text("description"),
|
|
60
|
+
services: jsonb("services").notNull().$type().default([]),
|
|
61
|
+
config: jsonb("config").notNull().$type().default({}),
|
|
62
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
63
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow()
|
|
64
|
+
});
|
|
65
|
+
const favorite = pgTable("favorite", {
|
|
66
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
67
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
68
|
+
stackId: uuid("stack_id").notNull().references(() => savedStack.id, { onDelete: "cascade" }),
|
|
69
|
+
createdAt: timestamp("created_at").notNull().defaultNow()
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
//#endregion
|
|
73
|
+
export { account, favorite, savedStack, session, schema_exports as t, user, verification };
|
|
74
|
+
//# sourceMappingURL=schema.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.mjs","names":[],"sources":["../src/schema.ts"],"sourcesContent":["import { pgTable, text, timestamp, boolean, jsonb, uuid } from \"drizzle-orm/pg-core\";\n\n// ── better-auth required tables ────────────────────────────────────────────────\n\nexport const user = pgTable(\"user\", {\n\tid: text(\"id\").primaryKey(),\n\tname: text(\"name\").notNull(),\n\temail: text(\"email\").notNull().unique(),\n\temailVerified: boolean(\"email_verified\").notNull(),\n\timage: text(\"image\"),\n\tcreatedAt: timestamp(\"created_at\").notNull(),\n\tupdatedAt: timestamp(\"updated_at\").notNull(),\n});\n\nexport const session = pgTable(\"session\", {\n\tid: text(\"id\").primaryKey(),\n\texpiresAt: timestamp(\"expires_at\").notNull(),\n\ttoken: text(\"token\").notNull().unique(),\n\tcreatedAt: timestamp(\"created_at\").notNull(),\n\tupdatedAt: timestamp(\"updated_at\").notNull(),\n\tipAddress: text(\"ip_address\"),\n\tuserAgent: text(\"user_agent\"),\n\tuserId: text(\"user_id\")\n\t\t.notNull()\n\t\t.references(() => user.id, { onDelete: \"cascade\" }),\n});\n\nexport const account = pgTable(\"account\", {\n\tid: text(\"id\").primaryKey(),\n\taccountId: text(\"account_id\").notNull(),\n\tproviderId: text(\"provider_id\").notNull(),\n\tuserId: text(\"user_id\")\n\t\t.notNull()\n\t\t.references(() => user.id, { onDelete: \"cascade\" }),\n\taccessToken: text(\"access_token\"),\n\trefreshToken: text(\"refresh_token\"),\n\tidToken: text(\"id_token\"),\n\taccessTokenExpiresAt: timestamp(\"access_token_expires_at\"),\n\trefreshTokenExpiresAt: timestamp(\"refresh_token_expires_at\"),\n\tscope: text(\"scope\"),\n\tpassword: text(\"password\"),\n\tcreatedAt: timestamp(\"created_at\").notNull(),\n\tupdatedAt: timestamp(\"updated_at\").notNull(),\n});\n\nexport const verification = pgTable(\"verification\", {\n\tid: text(\"id\").primaryKey(),\n\tidentifier: text(\"identifier\").notNull(),\n\tvalue: text(\"value\").notNull(),\n\texpiresAt: timestamp(\"expires_at\").notNull(),\n\tcreatedAt: timestamp(\"created_at\"),\n\tupdatedAt: timestamp(\"updated_at\"),\n});\n\n// ── App-specific tables ─────────────────────────────────────────────────────────\n\nexport const savedStack = pgTable(\"saved_stack\", {\n\tid: uuid(\"id\").primaryKey().defaultRandom(),\n\tuserId: text(\"user_id\")\n\t\t.notNull()\n\t\t.references(() => user.id, { onDelete: \"cascade\" }),\n\tname: text(\"name\").notNull(),\n\tdescription: text(\"description\"),\n\t/** Array of selected service IDs */\n\tservices: jsonb(\"services\").notNull().$type<string[]>().default([]),\n\t/** The full GenerationInput config stored as JSON */\n\tconfig: jsonb(\"config\").notNull().$type<Record<string, unknown>>().default({}),\n\tcreatedAt: timestamp(\"created_at\").notNull().defaultNow(),\n\tupdatedAt: timestamp(\"updated_at\").notNull().defaultNow(),\n});\n\nexport const favorite = pgTable(\"favorite\", {\n\tid: uuid(\"id\").primaryKey().defaultRandom(),\n\tuserId: text(\"user_id\")\n\t\t.notNull()\n\t\t.references(() => user.id, { onDelete: \"cascade\" }),\n\tstackId: uuid(\"stack_id\")\n\t\t.notNull()\n\t\t.references(() => savedStack.id, { onDelete: \"cascade\" }),\n\tcreatedAt: timestamp(\"created_at\").notNull().defaultNow(),\n});\n\nexport type User = typeof user.$inferSelect;\nexport type Session = typeof session.$inferSelect;\nexport type SavedStack = typeof savedStack.$inferSelect;\nexport type Favorite = typeof favorite.$inferSelect;\n"],"mappings":";;;;;;;;;;;;AAIA,MAAa,OAAO,QAAQ,QAAQ;CACnC,IAAI,KAAK,KAAK,CAAC,YAAY;CAC3B,MAAM,KAAK,OAAO,CAAC,SAAS;CAC5B,OAAO,KAAK,QAAQ,CAAC,SAAS,CAAC,QAAQ;CACvC,eAAe,QAAQ,iBAAiB,CAAC,SAAS;CAClD,OAAO,KAAK,QAAQ;CACpB,WAAW,UAAU,aAAa,CAAC,SAAS;CAC5C,WAAW,UAAU,aAAa,CAAC,SAAS;CAC5C,CAAC;AAEF,MAAa,UAAU,QAAQ,WAAW;CACzC,IAAI,KAAK,KAAK,CAAC,YAAY;CAC3B,WAAW,UAAU,aAAa,CAAC,SAAS;CAC5C,OAAO,KAAK,QAAQ,CAAC,SAAS,CAAC,QAAQ;CACvC,WAAW,UAAU,aAAa,CAAC,SAAS;CAC5C,WAAW,UAAU,aAAa,CAAC,SAAS;CAC5C,WAAW,KAAK,aAAa;CAC7B,WAAW,KAAK,aAAa;CAC7B,QAAQ,KAAK,UAAU,CACrB,SAAS,CACT,iBAAiB,KAAK,IAAI,EAAE,UAAU,WAAW,CAAC;CACpD,CAAC;AAEF,MAAa,UAAU,QAAQ,WAAW;CACzC,IAAI,KAAK,KAAK,CAAC,YAAY;CAC3B,WAAW,KAAK,aAAa,CAAC,SAAS;CACvC,YAAY,KAAK,cAAc,CAAC,SAAS;CACzC,QAAQ,KAAK,UAAU,CACrB,SAAS,CACT,iBAAiB,KAAK,IAAI,EAAE,UAAU,WAAW,CAAC;CACpD,aAAa,KAAK,eAAe;CACjC,cAAc,KAAK,gBAAgB;CACnC,SAAS,KAAK,WAAW;CACzB,sBAAsB,UAAU,0BAA0B;CAC1D,uBAAuB,UAAU,2BAA2B;CAC5D,OAAO,KAAK,QAAQ;CACpB,UAAU,KAAK,WAAW;CAC1B,WAAW,UAAU,aAAa,CAAC,SAAS;CAC5C,WAAW,UAAU,aAAa,CAAC,SAAS;CAC5C,CAAC;AAEF,MAAa,eAAe,QAAQ,gBAAgB;CACnD,IAAI,KAAK,KAAK,CAAC,YAAY;CAC3B,YAAY,KAAK,aAAa,CAAC,SAAS;CACxC,OAAO,KAAK,QAAQ,CAAC,SAAS;CAC9B,WAAW,UAAU,aAAa,CAAC,SAAS;CAC5C,WAAW,UAAU,aAAa;CAClC,WAAW,UAAU,aAAa;CAClC,CAAC;AAIF,MAAa,aAAa,QAAQ,eAAe;CAChD,IAAI,KAAK,KAAK,CAAC,YAAY,CAAC,eAAe;CAC3C,QAAQ,KAAK,UAAU,CACrB,SAAS,CACT,iBAAiB,KAAK,IAAI,EAAE,UAAU,WAAW,CAAC;CACpD,MAAM,KAAK,OAAO,CAAC,SAAS;CAC5B,aAAa,KAAK,cAAc;CAEhC,UAAU,MAAM,WAAW,CAAC,SAAS,CAAC,OAAiB,CAAC,QAAQ,EAAE,CAAC;CAEnE,QAAQ,MAAM,SAAS,CAAC,SAAS,CAAC,OAAgC,CAAC,QAAQ,EAAE,CAAC;CAC9E,WAAW,UAAU,aAAa,CAAC,SAAS,CAAC,YAAY;CACzD,WAAW,UAAU,aAAa,CAAC,SAAS,CAAC,YAAY;CACzD,CAAC;AAEF,MAAa,WAAW,QAAQ,YAAY;CAC3C,IAAI,KAAK,KAAK,CAAC,YAAY,CAAC,eAAe;CAC3C,QAAQ,KAAK,UAAU,CACrB,SAAS,CACT,iBAAiB,KAAK,IAAI,EAAE,UAAU,WAAW,CAAC;CACpD,SAAS,KAAK,WAAW,CACvB,SAAS,CACT,iBAAiB,WAAW,IAAI,EAAE,UAAU,WAAW,CAAC;CAC1D,WAAW,UAAU,aAAa,CAAC,SAAS,CAAC,YAAY;CACzD,CAAC"}
|
package/oldtsconfig.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@better-openclaw/db",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Shared database client and schema for better-openclaw",
|
|
6
|
+
"author": "bidew.io <bachir@bidew.io>",
|
|
7
|
+
"license": "AGPL-3.0",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/bidewio/better-openclaw-db.git",
|
|
11
|
+
"directory": "packages/db"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://better-openclaw.dev",
|
|
14
|
+
"packageManager": "pnpm@10.30.3",
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"main": "dist/index.mjs",
|
|
17
|
+
"types": "dist/index.d.ts",
|
|
18
|
+
"type": "module",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.mjs",
|
|
23
|
+
"require": "./dist/index.cjs",
|
|
24
|
+
"default": "./dist/index.mjs"
|
|
25
|
+
},
|
|
26
|
+
"./*": {
|
|
27
|
+
"types": "./dist/*.d.ts",
|
|
28
|
+
"import": "./dist/*.mjs",
|
|
29
|
+
"require": "./dist/*.cjs",
|
|
30
|
+
"default": "./dist/*.mjs"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsdown",
|
|
35
|
+
"build:tsc": "tsc",
|
|
36
|
+
"db:generate": "drizzle-kit generate",
|
|
37
|
+
"db:migrate": "drizzle-kit migrate",
|
|
38
|
+
"db:push": "drizzle-kit push",
|
|
39
|
+
"db:studio": "drizzle-kit studio"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"better-auth": "^1.5.2",
|
|
43
|
+
"drizzle-orm": "^0.45.1",
|
|
44
|
+
"postgres": "^3.4.8"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "^25.3.3",
|
|
48
|
+
"drizzle-kit": "^0.31.0",
|
|
49
|
+
"@biomejs/biome": "^2.4.4",
|
|
50
|
+
"tsdown": "^0.20.3",
|
|
51
|
+
"typescript": "^5.9.3",
|
|
52
|
+
"vitest": "^4.0.18"
|
|
53
|
+
}
|
|
54
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { drizzle } from "drizzle-orm/postgres-js";
|
|
2
|
+
import postgres from "postgres";
|
|
3
|
+
import * as schema from "./schema.js";
|
|
4
|
+
|
|
5
|
+
const connectionString = process.env.DATABASE_URL;
|
|
6
|
+
if (!connectionString) {
|
|
7
|
+
throw new Error("DATABASE_URL environment variable is required");
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const client = postgres(connectionString, { max: 10 });
|
|
11
|
+
export const db = drizzle(client, { schema });
|
|
12
|
+
|
|
13
|
+
export * from "./schema.js";
|
|
14
|
+
export { schema };
|
package/src/schema.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { pgTable, text, timestamp, boolean, jsonb, uuid } from "drizzle-orm/pg-core";
|
|
2
|
+
|
|
3
|
+
// ── better-auth required tables ────────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
export const user = pgTable("user", {
|
|
6
|
+
id: text("id").primaryKey(),
|
|
7
|
+
name: text("name").notNull(),
|
|
8
|
+
email: text("email").notNull().unique(),
|
|
9
|
+
emailVerified: boolean("email_verified").notNull(),
|
|
10
|
+
image: text("image"),
|
|
11
|
+
createdAt: timestamp("created_at").notNull(),
|
|
12
|
+
updatedAt: timestamp("updated_at").notNull(),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export const session = pgTable("session", {
|
|
16
|
+
id: text("id").primaryKey(),
|
|
17
|
+
expiresAt: timestamp("expires_at").notNull(),
|
|
18
|
+
token: text("token").notNull().unique(),
|
|
19
|
+
createdAt: timestamp("created_at").notNull(),
|
|
20
|
+
updatedAt: timestamp("updated_at").notNull(),
|
|
21
|
+
ipAddress: text("ip_address"),
|
|
22
|
+
userAgent: text("user_agent"),
|
|
23
|
+
userId: text("user_id")
|
|
24
|
+
.notNull()
|
|
25
|
+
.references(() => user.id, { onDelete: "cascade" }),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export const account = pgTable("account", {
|
|
29
|
+
id: text("id").primaryKey(),
|
|
30
|
+
accountId: text("account_id").notNull(),
|
|
31
|
+
providerId: text("provider_id").notNull(),
|
|
32
|
+
userId: text("user_id")
|
|
33
|
+
.notNull()
|
|
34
|
+
.references(() => user.id, { onDelete: "cascade" }),
|
|
35
|
+
accessToken: text("access_token"),
|
|
36
|
+
refreshToken: text("refresh_token"),
|
|
37
|
+
idToken: text("id_token"),
|
|
38
|
+
accessTokenExpiresAt: timestamp("access_token_expires_at"),
|
|
39
|
+
refreshTokenExpiresAt: timestamp("refresh_token_expires_at"),
|
|
40
|
+
scope: text("scope"),
|
|
41
|
+
password: text("password"),
|
|
42
|
+
createdAt: timestamp("created_at").notNull(),
|
|
43
|
+
updatedAt: timestamp("updated_at").notNull(),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export const verification = pgTable("verification", {
|
|
47
|
+
id: text("id").primaryKey(),
|
|
48
|
+
identifier: text("identifier").notNull(),
|
|
49
|
+
value: text("value").notNull(),
|
|
50
|
+
expiresAt: timestamp("expires_at").notNull(),
|
|
51
|
+
createdAt: timestamp("created_at"),
|
|
52
|
+
updatedAt: timestamp("updated_at"),
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// ── App-specific tables ─────────────────────────────────────────────────────────
|
|
56
|
+
|
|
57
|
+
export const savedStack = pgTable("saved_stack", {
|
|
58
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
59
|
+
userId: text("user_id")
|
|
60
|
+
.notNull()
|
|
61
|
+
.references(() => user.id, { onDelete: "cascade" }),
|
|
62
|
+
name: text("name").notNull(),
|
|
63
|
+
description: text("description"),
|
|
64
|
+
/** Array of selected service IDs */
|
|
65
|
+
services: jsonb("services").notNull().$type<string[]>().default([]),
|
|
66
|
+
/** The full GenerationInput config stored as JSON */
|
|
67
|
+
config: jsonb("config").notNull().$type<Record<string, unknown>>().default({}),
|
|
68
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
69
|
+
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
export const favorite = pgTable("favorite", {
|
|
73
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
74
|
+
userId: text("user_id")
|
|
75
|
+
.notNull()
|
|
76
|
+
.references(() => user.id, { onDelete: "cascade" }),
|
|
77
|
+
stackId: uuid("stack_id")
|
|
78
|
+
.notNull()
|
|
79
|
+
.references(() => savedStack.id, { onDelete: "cascade" }),
|
|
80
|
+
createdAt: timestamp("created_at").notNull().defaultNow(),
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
export type User = typeof user.$inferSelect;
|
|
84
|
+
export type Session = typeof session.$inferSelect;
|
|
85
|
+
export type SavedStack = typeof savedStack.$inferSelect;
|
|
86
|
+
export type Favorite = typeof favorite.$inferSelect;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"strict": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"isolatedModules": true,
|
|
13
|
+
"declaration": true,
|
|
14
|
+
"declarationMap": true,
|
|
15
|
+
"sourceMap": true,
|
|
16
|
+
"noUncheckedIndexedAccess": true,
|
|
17
|
+
"noEmitOnError": true,
|
|
18
|
+
"noUnusedLocals": true,
|
|
19
|
+
"noUnusedParameters": true,
|
|
20
|
+
"exactOptionalPropertyTypes": false,
|
|
21
|
+
"noImplicitReturns": true,
|
|
22
|
+
"noFallthroughCasesInSwitch": true
|
|
23
|
+
},
|
|
24
|
+
"exclude": ["node_modules", "dist"]
|
|
25
|
+
}
|
package/tsconfig.json
ADDED