mirror of
https://github.com/ZeroCatDev/ClassworksKV.git
synced 2026-02-03 23:23:10 +00:00
Compare commits
12 Commits
e209bd92e2
...
88d5062638
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88d5062638 | ||
|
|
2f7f78f657 | ||
|
|
80e7214860 | ||
|
|
e7f155b021 | ||
|
|
8c8ebae6b7 | ||
|
|
6e8ba54fd6 | ||
|
|
dc5de6e63a | ||
|
|
c063dcf5b6 | ||
|
|
29030f90bd | ||
|
|
ba08d2c478 | ||
|
|
a5728ac2a5 | ||
|
|
ce3c8ee41f |
@ -18,9 +18,9 @@ export const oauthProviders = {
|
|||||||
zerocat: {
|
zerocat: {
|
||||||
clientId: process.env.ZEROCAT_CLIENT_ID,
|
clientId: process.env.ZEROCAT_CLIENT_ID,
|
||||||
clientSecret: process.env.ZEROCAT_CLIENT_SECRET,
|
clientSecret: process.env.ZEROCAT_CLIENT_SECRET,
|
||||||
authorizationURL: "https://api.zcservice.houlang.cloud/oauth/authorize",
|
authorizationURL: "https://zerocat-api.houlang.cloud/oauth/authorize",
|
||||||
tokenURL: "https://api.zcservice.houlang.cloud/oauth/token",
|
tokenURL: "https://zerocat-api.houlang.cloud/oauth/token",
|
||||||
userInfoURL: "https://api.zcservice.houlang.cloud/oauth/userinfo",
|
userInfoURL: "https://zerocat-api.houlang.cloud/oauth/userinfo",
|
||||||
scope: "user:basic user:email",
|
scope: "user:basic user:email",
|
||||||
// 展示相关
|
// 展示相关
|
||||||
name: "ZeroCat",
|
name: "ZeroCat",
|
||||||
|
|||||||
91
docker/schema.prisma
Normal file
91
docker/schema.prisma
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
generator client {
|
||||||
|
provider = "prisma-client"
|
||||||
|
output = "../generated/prisma"
|
||||||
|
}
|
||||||
|
|
||||||
|
datasource db {
|
||||||
|
provider = "postgresql"
|
||||||
|
}
|
||||||
|
|
||||||
|
model KVStore {
|
||||||
|
deviceId Int
|
||||||
|
key String
|
||||||
|
value Json
|
||||||
|
creatorIp String? @default("")
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
// 关联关系
|
||||||
|
device Device @relation(fields: [deviceId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
|
@@id([deviceId, key])
|
||||||
|
}
|
||||||
|
|
||||||
|
model Account {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
provider String // OAuth提供者 (例如: google, github, gitlab等)
|
||||||
|
providerId String // 提供者返回的用户唯一ID
|
||||||
|
email String? // 用户邮箱
|
||||||
|
name String? // 用户名称
|
||||||
|
avatarUrl String? // 用户头像URL
|
||||||
|
providerData Json? // OAuth提供者返回的完整信息
|
||||||
|
accessToken String? @db.Text // 账户访问令牌
|
||||||
|
refreshToken String? @db.Text // 刷新令牌
|
||||||
|
refreshTokenExpiry DateTime? // 刷新令牌过期时间
|
||||||
|
tokenVersion Int @default(1) // 令牌版本,用于令牌失效
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
// 关联的设备
|
||||||
|
devices Device[]
|
||||||
|
|
||||||
|
@@unique([provider, providerId]) // 确保同一提供者的用户ID唯一
|
||||||
|
}
|
||||||
|
|
||||||
|
model Device {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
uuid String @unique // 设备的唯一标识符
|
||||||
|
name String?
|
||||||
|
accountId String? // 关联的账户ID
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
password String?
|
||||||
|
passwordHint String?
|
||||||
|
namespace String? @unique // 用户自定义的唯一命名空间
|
||||||
|
|
||||||
|
// 关联关系
|
||||||
|
account Account? @relation(fields: [accountId], references: [id], onDelete: SetNull)
|
||||||
|
appInstalls AppInstall[]
|
||||||
|
kvStore KVStore[] // 设备相关的KV存储
|
||||||
|
autoAuths AutoAuth[] // 自动授权配置
|
||||||
|
}
|
||||||
|
|
||||||
|
model AppInstall {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
deviceId Int // 关联的设备ID
|
||||||
|
appId String // 应用ID (SHA256 hash)
|
||||||
|
token String @unique // 应用安装的唯一访问令牌,拥有完整KV读写权限
|
||||||
|
note String? // 安装备注
|
||||||
|
isReadOnly Boolean @default(false) // 是否只读
|
||||||
|
deviceType String? // 设备类型: teacher(教师), student(学生), classroom(班级一体机), parent(家长)
|
||||||
|
installedAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
// 关联关系
|
||||||
|
device Device @relation(fields: [deviceId], references: [id], onDelete: Cascade)
|
||||||
|
}
|
||||||
|
|
||||||
|
model AutoAuth {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
deviceId Int // 关联的设备ID
|
||||||
|
password String? // 配置密码,可以为空
|
||||||
|
deviceType String? // 自动设备类型: teacher(教师), student(学生), classroom(班级一体机), parent(家长)
|
||||||
|
isReadOnly Boolean @default(false) // 是否只读
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
// 关联关系
|
||||||
|
device Device @relation(fields: [deviceId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
|
@@unique([deviceId, password]) // 同一设备的密码必须唯一
|
||||||
|
}
|
||||||
44
generated/prisma/browser.ts
Normal file
44
generated/prisma/browser.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
||||||
|
/* eslint-disable */
|
||||||
|
// biome-ignore-all lint: generated file
|
||||||
|
// @ts-nocheck
|
||||||
|
/*
|
||||||
|
* This file should be your main import to use Prisma-related types and utilities in a browser.
|
||||||
|
* Use it to get access to models, enums, and input types.
|
||||||
|
*
|
||||||
|
* This file does not contain a `PrismaClient` class, nor several other helpers that are intended as server-side only.
|
||||||
|
* See `client.ts` for the standard, server-side entry point.
|
||||||
|
*
|
||||||
|
* 🟢 You can import this file directly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as Prisma from './internal/prismaNamespaceBrowser.ts'
|
||||||
|
export { Prisma }
|
||||||
|
export * as $Enums from './enums.ts'
|
||||||
|
export * from './enums.ts';
|
||||||
|
/**
|
||||||
|
* Model Account
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type Account = Prisma.AccountModel
|
||||||
|
/**
|
||||||
|
* Model AppInstall
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type AppInstall = Prisma.AppInstallModel
|
||||||
|
/**
|
||||||
|
* Model AutoAuth
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type AutoAuth = Prisma.AutoAuthModel
|
||||||
|
/**
|
||||||
|
* Model Device
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type Device = Prisma.DeviceModel
|
||||||
|
/**
|
||||||
|
* Model KVStore
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type KVStore = Prisma.KVStoreModel
|
||||||
66
generated/prisma/client.ts
Normal file
66
generated/prisma/client.ts
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
|
||||||
|
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
||||||
|
/* eslint-disable */
|
||||||
|
// biome-ignore-all lint: generated file
|
||||||
|
// @ts-nocheck
|
||||||
|
/*
|
||||||
|
* This file should be your main import to use Prisma. Through it you get access to all the models, enums, and input types.
|
||||||
|
* If you're looking for something you can import in the client-side of your application, please refer to the `browser.ts` file instead.
|
||||||
|
*
|
||||||
|
* 🟢 You can import this file directly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as process from 'node:process'
|
||||||
|
import * as path from 'node:path'
|
||||||
|
import { fileURLToPath } from 'node:url'
|
||||||
|
globalThis['__dirname'] = path.dirname(fileURLToPath(import.meta.url))
|
||||||
|
|
||||||
|
import * as runtime from "@prisma/client/runtime/client"
|
||||||
|
import * as $Enums from "./enums.ts"
|
||||||
|
import * as $Class from "./internal/class.ts"
|
||||||
|
import * as Prisma from "./internal/prismaNamespace.ts"
|
||||||
|
|
||||||
|
export * as $Enums from './enums.ts'
|
||||||
|
export * from "./enums.ts"
|
||||||
|
/**
|
||||||
|
* ## Prisma Client
|
||||||
|
*
|
||||||
|
* Type-safe database client for TypeScript
|
||||||
|
* @example
|
||||||
|
* ```
|
||||||
|
* const prisma = new PrismaClient()
|
||||||
|
* // Fetch zero or more Accounts
|
||||||
|
* const accounts = await prisma.account.findMany()
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Read more in our [docs](https://pris.ly/d/client).
|
||||||
|
*/
|
||||||
|
export const PrismaClient = $Class.getPrismaClientClass()
|
||||||
|
export type PrismaClient<LogOpts extends Prisma.LogLevel = never, OmitOpts extends Prisma.PrismaClientOptions["omit"] = Prisma.PrismaClientOptions["omit"], ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = $Class.PrismaClient<LogOpts, OmitOpts, ExtArgs>
|
||||||
|
export { Prisma }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model Account
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type Account = Prisma.AccountModel
|
||||||
|
/**
|
||||||
|
* Model AppInstall
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type AppInstall = Prisma.AppInstallModel
|
||||||
|
/**
|
||||||
|
* Model AutoAuth
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type AutoAuth = Prisma.AutoAuthModel
|
||||||
|
/**
|
||||||
|
* Model Device
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type Device = Prisma.DeviceModel
|
||||||
|
/**
|
||||||
|
* Model KVStore
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type KVStore = Prisma.KVStoreModel
|
||||||
502
generated/prisma/commonInputTypes.ts
Normal file
502
generated/prisma/commonInputTypes.ts
Normal file
@ -0,0 +1,502 @@
|
|||||||
|
|
||||||
|
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
||||||
|
/* eslint-disable */
|
||||||
|
// biome-ignore-all lint: generated file
|
||||||
|
// @ts-nocheck
|
||||||
|
/*
|
||||||
|
* This file exports various common sort, input & filter types that are not directly linked to a particular model.
|
||||||
|
*
|
||||||
|
* 🟢 You can import this file directly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type * as runtime from "@prisma/client/runtime/client"
|
||||||
|
import * as $Enums from "./enums.ts"
|
||||||
|
import type * as Prisma from "./internal/prismaNamespace.ts"
|
||||||
|
|
||||||
|
|
||||||
|
export type StringFilter<$PrismaModel = never> = {
|
||||||
|
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||||
|
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||||
|
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
mode?: Prisma.QueryMode
|
||||||
|
not?: Prisma.NestedStringFilter<$PrismaModel> | string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type StringNullableFilter<$PrismaModel = never> = {
|
||||||
|
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
||||||
|
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||||
|
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
mode?: Prisma.QueryMode
|
||||||
|
not?: Prisma.NestedStringNullableFilter<$PrismaModel> | string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export type JsonNullableFilter<$PrismaModel = never> =
|
||||||
|
| Prisma.PatchUndefined<
|
||||||
|
Prisma.Either<Required<JsonNullableFilterBase<$PrismaModel>>, Exclude<keyof Required<JsonNullableFilterBase<$PrismaModel>>, 'path'>>,
|
||||||
|
Required<JsonNullableFilterBase<$PrismaModel>>
|
||||||
|
>
|
||||||
|
| Prisma.OptionalFlat<Omit<Required<JsonNullableFilterBase<$PrismaModel>>, 'path'>>
|
||||||
|
|
||||||
|
export type JsonNullableFilterBase<$PrismaModel = never> = {
|
||||||
|
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
path?: string[]
|
||||||
|
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
|
||||||
|
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DateTimeFilter<$PrismaModel = never> = {
|
||||||
|
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||||
|
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||||
|
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedDateTimeFilter<$PrismaModel> | Date | string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DateTimeNullableFilter<$PrismaModel = never> = {
|
||||||
|
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
|
||||||
|
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||||
|
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> | Date | string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IntFilter<$PrismaModel = never> = {
|
||||||
|
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||||
|
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||||
|
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedIntFilter<$PrismaModel> | number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SortOrderInput = {
|
||||||
|
sort: Prisma.SortOrder
|
||||||
|
nulls?: Prisma.NullsOrder
|
||||||
|
}
|
||||||
|
|
||||||
|
export type StringWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||||
|
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||||
|
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
mode?: Prisma.QueryMode
|
||||||
|
not?: Prisma.NestedStringWithAggregatesFilter<$PrismaModel> | string
|
||||||
|
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedStringFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedStringFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type StringNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
||||||
|
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||||
|
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
mode?: Prisma.QueryMode
|
||||||
|
not?: Prisma.NestedStringNullableWithAggregatesFilter<$PrismaModel> | string | null
|
||||||
|
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedStringNullableFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedStringNullableFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type JsonNullableWithAggregatesFilter<$PrismaModel = never> =
|
||||||
|
| Prisma.PatchUndefined<
|
||||||
|
Prisma.Either<Required<JsonNullableWithAggregatesFilterBase<$PrismaModel>>, Exclude<keyof Required<JsonNullableWithAggregatesFilterBase<$PrismaModel>>, 'path'>>,
|
||||||
|
Required<JsonNullableWithAggregatesFilterBase<$PrismaModel>>
|
||||||
|
>
|
||||||
|
| Prisma.OptionalFlat<Omit<Required<JsonNullableWithAggregatesFilterBase<$PrismaModel>>, 'path'>>
|
||||||
|
|
||||||
|
export type JsonNullableWithAggregatesFilterBase<$PrismaModel = never> = {
|
||||||
|
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
path?: string[]
|
||||||
|
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
|
||||||
|
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedJsonNullableFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedJsonNullableFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||||
|
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||||
|
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedDateTimeWithAggregatesFilter<$PrismaModel> | Date | string
|
||||||
|
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedDateTimeFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedDateTimeFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DateTimeNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
|
||||||
|
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||||
|
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedDateTimeNullableWithAggregatesFilter<$PrismaModel> | Date | string | null
|
||||||
|
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IntWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||||
|
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||||
|
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedIntWithAggregatesFilter<$PrismaModel> | number
|
||||||
|
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_avg?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||||
|
_sum?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BoolFilter<$PrismaModel = never> = {
|
||||||
|
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BoolWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedBoolWithAggregatesFilter<$PrismaModel> | boolean
|
||||||
|
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type JsonFilter<$PrismaModel = never> =
|
||||||
|
| Prisma.PatchUndefined<
|
||||||
|
Prisma.Either<Required<JsonFilterBase<$PrismaModel>>, Exclude<keyof Required<JsonFilterBase<$PrismaModel>>, 'path'>>,
|
||||||
|
Required<JsonFilterBase<$PrismaModel>>
|
||||||
|
>
|
||||||
|
| Prisma.OptionalFlat<Omit<Required<JsonFilterBase<$PrismaModel>>, 'path'>>
|
||||||
|
|
||||||
|
export type JsonFilterBase<$PrismaModel = never> = {
|
||||||
|
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
path?: string[]
|
||||||
|
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
|
||||||
|
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
export type JsonWithAggregatesFilter<$PrismaModel = never> =
|
||||||
|
| Prisma.PatchUndefined<
|
||||||
|
Prisma.Either<Required<JsonWithAggregatesFilterBase<$PrismaModel>>, Exclude<keyof Required<JsonWithAggregatesFilterBase<$PrismaModel>>, 'path'>>,
|
||||||
|
Required<JsonWithAggregatesFilterBase<$PrismaModel>>
|
||||||
|
>
|
||||||
|
| Prisma.OptionalFlat<Omit<Required<JsonWithAggregatesFilterBase<$PrismaModel>>, 'path'>>
|
||||||
|
|
||||||
|
export type JsonWithAggregatesFilterBase<$PrismaModel = never> = {
|
||||||
|
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
path?: string[]
|
||||||
|
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
|
||||||
|
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedJsonFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedJsonFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedStringFilter<$PrismaModel = never> = {
|
||||||
|
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||||
|
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||||
|
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedStringFilter<$PrismaModel> | string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedStringNullableFilter<$PrismaModel = never> = {
|
||||||
|
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
||||||
|
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||||
|
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedStringNullableFilter<$PrismaModel> | string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedDateTimeFilter<$PrismaModel = never> = {
|
||||||
|
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||||
|
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||||
|
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedDateTimeFilter<$PrismaModel> | Date | string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedDateTimeNullableFilter<$PrismaModel = never> = {
|
||||||
|
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
|
||||||
|
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||||
|
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> | Date | string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedIntFilter<$PrismaModel = never> = {
|
||||||
|
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||||
|
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||||
|
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedIntFilter<$PrismaModel> | number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedStringWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||||
|
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||||
|
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedStringWithAggregatesFilter<$PrismaModel> | string
|
||||||
|
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedStringFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedStringFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedStringNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
||||||
|
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||||
|
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
gte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedStringNullableWithAggregatesFilter<$PrismaModel> | string | null
|
||||||
|
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedStringNullableFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedStringNullableFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedIntNullableFilter<$PrismaModel = never> = {
|
||||||
|
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
|
||||||
|
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||||
|
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedIntNullableFilter<$PrismaModel> | number | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedJsonNullableFilter<$PrismaModel = never> =
|
||||||
|
| Prisma.PatchUndefined<
|
||||||
|
Prisma.Either<Required<NestedJsonNullableFilterBase<$PrismaModel>>, Exclude<keyof Required<NestedJsonNullableFilterBase<$PrismaModel>>, 'path'>>,
|
||||||
|
Required<NestedJsonNullableFilterBase<$PrismaModel>>
|
||||||
|
>
|
||||||
|
| Prisma.OptionalFlat<Omit<Required<NestedJsonNullableFilterBase<$PrismaModel>>, 'path'>>
|
||||||
|
|
||||||
|
export type NestedJsonNullableFilterBase<$PrismaModel = never> = {
|
||||||
|
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
path?: string[]
|
||||||
|
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
|
||||||
|
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedDateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||||
|
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||||
|
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedDateTimeWithAggregatesFilter<$PrismaModel> | Date | string
|
||||||
|
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedDateTimeFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedDateTimeFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedDateTimeNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
|
||||||
|
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||||
|
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedDateTimeNullableWithAggregatesFilter<$PrismaModel> | Date | string | null
|
||||||
|
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedDateTimeNullableFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedIntWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||||
|
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||||
|
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
gte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedIntWithAggregatesFilter<$PrismaModel> | number
|
||||||
|
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_avg?: Prisma.NestedFloatFilter<$PrismaModel>
|
||||||
|
_sum?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedFloatFilter<$PrismaModel = never> = {
|
||||||
|
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
|
||||||
|
notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
|
||||||
|
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
gte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedFloatFilter<$PrismaModel> | number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedBoolFilter<$PrismaModel = never> = {
|
||||||
|
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedBoolWithAggregatesFilter<$PrismaModel = never> = {
|
||||||
|
equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel>
|
||||||
|
not?: Prisma.NestedBoolWithAggregatesFilter<$PrismaModel> | boolean
|
||||||
|
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||||
|
_min?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||||
|
_max?: Prisma.NestedBoolFilter<$PrismaModel>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NestedJsonFilter<$PrismaModel = never> =
|
||||||
|
| Prisma.PatchUndefined<
|
||||||
|
Prisma.Either<Required<NestedJsonFilterBase<$PrismaModel>>, Exclude<keyof Required<NestedJsonFilterBase<$PrismaModel>>, 'path'>>,
|
||||||
|
Required<NestedJsonFilterBase<$PrismaModel>>
|
||||||
|
>
|
||||||
|
| Prisma.OptionalFlat<Omit<Required<NestedJsonFilterBase<$PrismaModel>>, 'path'>>
|
||||||
|
|
||||||
|
export type NestedJsonFilterBase<$PrismaModel = never> = {
|
||||||
|
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
path?: string[]
|
||||||
|
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
|
||||||
|
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
string_ends_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||||
|
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||||
|
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||||
|
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
15
generated/prisma/enums.ts
Normal file
15
generated/prisma/enums.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
||||||
|
/* eslint-disable */
|
||||||
|
// biome-ignore-all lint: generated file
|
||||||
|
// @ts-nocheck
|
||||||
|
/*
|
||||||
|
* This file exports all enum related types from the schema.
|
||||||
|
*
|
||||||
|
* 🟢 You can import this file directly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// This file is empty because there are no enums in the schema.
|
||||||
|
export {}
|
||||||
232
generated/prisma/internal/class.ts
Normal file
232
generated/prisma/internal/class.ts
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
|
||||||
|
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
||||||
|
/* eslint-disable */
|
||||||
|
// biome-ignore-all lint: generated file
|
||||||
|
// @ts-nocheck
|
||||||
|
/*
|
||||||
|
* WARNING: This is an internal file that is subject to change!
|
||||||
|
*
|
||||||
|
* 🛑 Under no circumstances should you import this file directly! 🛑
|
||||||
|
*
|
||||||
|
* Please import the `PrismaClient` class from the `client.ts` file instead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as runtime from "@prisma/client/runtime/client"
|
||||||
|
import type * as Prisma from "./prismaNamespace.ts"
|
||||||
|
|
||||||
|
|
||||||
|
const config: runtime.GetPrismaClientConfig = {
|
||||||
|
"previewFeatures": [],
|
||||||
|
"clientVersion": "7.3.0",
|
||||||
|
"engineVersion": "9d6ad21cbbceab97458517b147a6a09ff43aa735",
|
||||||
|
"activeProvider": "postgresql",
|
||||||
|
"inlineSchema": "generator client {\n provider = \"prisma-client\"\n output = \"../generated/prisma\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\nmodel Account {\n id String @id(map: \"idx_18303_PRIMARY\") @db.VarChar(191)\n provider String @db.VarChar(191)\n providerId String @db.VarChar(191)\n email String? @db.VarChar(191)\n name String? @db.VarChar(191)\n avatarUrl String? @db.VarChar(191)\n providerData Json? @db.Json\n accessToken String?\n createdAt DateTime @default(now()) @db.Timestamptz(6)\n updatedAt DateTime @default(now()) @updatedAt @db.Timestamptz(6)\n refreshToken String?\n refreshTokenExpiry DateTime? @db.Timestamptz(6)\n tokenVersion Int @default(1)\n\n devices Device[]\n\n @@unique([provider, providerId], map: \"idx_18303_Account_provider_providerId_key\")\n}\n\nmodel AppInstall {\n id String @id(map: \"idx_18310_PRIMARY\") @db.VarChar(191)\n deviceId Int\n appId String @db.VarChar(191)\n token String @unique(map: \"idx_18310_AppInstall_token_key\") @db.VarChar(191)\n note String? @db.VarChar(191)\n installedAt DateTime @default(now()) @db.Timestamptz(6)\n updatedAt DateTime @default(now()) @updatedAt @db.Timestamptz(6)\n deviceType String? @db.VarChar(191)\n isReadOnly Boolean @default(false)\n\n device Device @relation(fields: [deviceId], references: [id], onDelete: Cascade)\n\n @@index([deviceId], map: \"idx_18310_AppInstall_deviceId_fkey\")\n}\n\nmodel AutoAuth {\n id String @id(map: \"idx_18317_PRIMARY\") @db.VarChar(191)\n deviceId Int\n password String? @db.VarChar(191)\n deviceType String? @db.VarChar(191)\n isReadOnly Boolean @default(false)\n createdAt DateTime @default(now()) @db.Timestamptz(6)\n updatedAt DateTime @default(now()) @updatedAt @db.Timestamptz(6)\n\n device Device @relation(fields: [deviceId], references: [id], onDelete: Cascade)\n\n @@unique([deviceId, password], map: \"idx_18317_AutoAuth_deviceId_password_key\")\n}\n\nmodel Device {\n id Int @id(map: \"idx_18324_PRIMARY\")\n uuid String @unique(map: \"idx_18324_Device_uuid_key\") @db.VarChar(191)\n name String? @db.VarChar(191)\n accountId String? @db.VarChar(191)\n createdAt DateTime @default(now()) @db.Timestamptz(6)\n updatedAt DateTime @default(now()) @updatedAt @db.Timestamptz(6)\n password String? @db.VarChar(191)\n passwordHint String? @db.VarChar(191)\n namespace String? @unique(map: \"idx_18324_Device_namespace_key\") @db.VarChar(191)\n\n // 关联关系\n account Account? @relation(fields: [accountId], references: [id], onDelete: SetNull)\n appInstalls AppInstall[]\n kvStore KVStore[] // 设备相关的KV存储\n autoAuths AutoAuth[] // 自动授权配置\n\n @@index([accountId], map: \"idx_18324_Device_accountId_fkey\")\n}\n\nmodel KVStore {\n deviceId Int\n key String @db.VarChar(191)\n value Json @db.Json\n creatorIp String? @default(\"\") @db.VarChar(191)\n createdAt DateTime @default(now()) @db.Timestamptz(6)\n updatedAt DateTime @default(now()) @updatedAt @db.Timestamptz(6)\n\n device Device @relation(fields: [deviceId], references: [id], onDelete: Cascade)\n\n @@id([deviceId, key], map: \"idx_18330_PRIMARY\")\n}\n",
|
||||||
|
"runtimeDataModel": {
|
||||||
|
"models": {},
|
||||||
|
"enums": {},
|
||||||
|
"types": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config.runtimeDataModel = JSON.parse("{\"models\":{\"Account\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"provider\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"providerId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"avatarUrl\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"providerData\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"accessToken\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"refreshToken\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"refreshTokenExpiry\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"tokenVersion\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"devices\",\"kind\":\"object\",\"type\":\"Device\",\"relationName\":\"AccountToDevice\"}],\"dbName\":null},\"AppInstall\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"deviceId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"appId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"token\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"note\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"installedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"deviceType\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"isReadOnly\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"device\",\"kind\":\"object\",\"type\":\"Device\",\"relationName\":\"AppInstallToDevice\"}],\"dbName\":null},\"AutoAuth\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"deviceId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"password\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"deviceType\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"isReadOnly\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"device\",\"kind\":\"object\",\"type\":\"Device\",\"relationName\":\"AutoAuthToDevice\"}],\"dbName\":null},\"Device\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"uuid\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"accountId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"password\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"passwordHint\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"namespace\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"account\",\"kind\":\"object\",\"type\":\"Account\",\"relationName\":\"AccountToDevice\"},{\"name\":\"appInstalls\",\"kind\":\"object\",\"type\":\"AppInstall\",\"relationName\":\"AppInstallToDevice\"},{\"name\":\"kvStore\",\"kind\":\"object\",\"type\":\"KVStore\",\"relationName\":\"DeviceToKVStore\"},{\"name\":\"autoAuths\",\"kind\":\"object\",\"type\":\"AutoAuth\",\"relationName\":\"AutoAuthToDevice\"}],\"dbName\":null},\"KVStore\":{\"fields\":[{\"name\":\"deviceId\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"key\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"value\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"creatorIp\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"device\",\"kind\":\"object\",\"type\":\"Device\",\"relationName\":\"DeviceToKVStore\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}")
|
||||||
|
|
||||||
|
async function decodeBase64AsWasm(wasmBase64: string): Promise<WebAssembly.Module> {
|
||||||
|
const { Buffer } = await import('node:buffer')
|
||||||
|
const wasmArray = Buffer.from(wasmBase64, 'base64')
|
||||||
|
return new WebAssembly.Module(wasmArray)
|
||||||
|
}
|
||||||
|
|
||||||
|
config.compilerWasm = {
|
||||||
|
getRuntime: async () => await import("@prisma/client/runtime/query_compiler_fast_bg.postgresql.mjs"),
|
||||||
|
|
||||||
|
getQueryCompilerWasmModule: async () => {
|
||||||
|
const { wasm } = await import("@prisma/client/runtime/query_compiler_fast_bg.postgresql.wasm-base64.mjs")
|
||||||
|
return await decodeBase64AsWasm(wasm)
|
||||||
|
},
|
||||||
|
|
||||||
|
importName: "./query_compiler_fast_bg.js"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export type LogOptions<ClientOptions extends Prisma.PrismaClientOptions> =
|
||||||
|
'log' extends keyof ClientOptions ? ClientOptions['log'] extends Array<Prisma.LogLevel | Prisma.LogDefinition> ? Prisma.GetEvents<ClientOptions['log']> : never : never
|
||||||
|
|
||||||
|
export interface PrismaClientConstructor {
|
||||||
|
/**
|
||||||
|
* ## Prisma Client
|
||||||
|
*
|
||||||
|
* Type-safe database client for TypeScript
|
||||||
|
* @example
|
||||||
|
* ```
|
||||||
|
* const prisma = new PrismaClient()
|
||||||
|
* // Fetch zero or more Accounts
|
||||||
|
* const accounts = await prisma.account.findMany()
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Read more in our [docs](https://pris.ly/d/client).
|
||||||
|
*/
|
||||||
|
|
||||||
|
new <
|
||||||
|
Options extends Prisma.PrismaClientOptions = Prisma.PrismaClientOptions,
|
||||||
|
LogOpts extends LogOptions<Options> = LogOptions<Options>,
|
||||||
|
OmitOpts extends Prisma.PrismaClientOptions['omit'] = Options extends { omit: infer U } ? U : Prisma.PrismaClientOptions['omit'],
|
||||||
|
ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs
|
||||||
|
>(options: Prisma.Subset<Options, Prisma.PrismaClientOptions> ): PrismaClient<LogOpts, OmitOpts, ExtArgs>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ## Prisma Client
|
||||||
|
*
|
||||||
|
* Type-safe database client for TypeScript
|
||||||
|
* @example
|
||||||
|
* ```
|
||||||
|
* const prisma = new PrismaClient()
|
||||||
|
* // Fetch zero or more Accounts
|
||||||
|
* const accounts = await prisma.account.findMany()
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Read more in our [docs](https://pris.ly/d/client).
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface PrismaClient<
|
||||||
|
in LogOpts extends Prisma.LogLevel = never,
|
||||||
|
in out OmitOpts extends Prisma.PrismaClientOptions['omit'] = undefined,
|
||||||
|
in out ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs
|
||||||
|
> {
|
||||||
|
[K: symbol]: { types: Prisma.TypeMap<ExtArgs>['other'] }
|
||||||
|
|
||||||
|
$on<V extends LogOpts>(eventType: V, callback: (event: V extends 'query' ? Prisma.QueryEvent : Prisma.LogEvent) => void): PrismaClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect with the database
|
||||||
|
*/
|
||||||
|
$connect(): runtime.Types.Utils.JsPromise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnect from the database
|
||||||
|
*/
|
||||||
|
$disconnect(): runtime.Types.Utils.JsPromise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes a prepared raw query and returns the number of affected rows.
|
||||||
|
* @example
|
||||||
|
* ```
|
||||||
|
* const result = await prisma.$executeRaw`UPDATE User SET cool = ${true} WHERE email = ${'user@email.com'};`
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Read more in our [docs](https://pris.ly/d/raw-queries).
|
||||||
|
*/
|
||||||
|
$executeRaw<T = unknown>(query: TemplateStringsArray | Prisma.Sql, ...values: any[]): Prisma.PrismaPromise<number>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes a raw query and returns the number of affected rows.
|
||||||
|
* Susceptible to SQL injections, see documentation.
|
||||||
|
* @example
|
||||||
|
* ```
|
||||||
|
* const result = await prisma.$executeRawUnsafe('UPDATE User SET cool = $1 WHERE email = $2 ;', true, 'user@email.com')
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Read more in our [docs](https://pris.ly/d/raw-queries).
|
||||||
|
*/
|
||||||
|
$executeRawUnsafe<T = unknown>(query: string, ...values: any[]): Prisma.PrismaPromise<number>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a prepared raw query and returns the `SELECT` data.
|
||||||
|
* @example
|
||||||
|
* ```
|
||||||
|
* const result = await prisma.$queryRaw`SELECT * FROM User WHERE id = ${1} OR email = ${'user@email.com'};`
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Read more in our [docs](https://pris.ly/d/raw-queries).
|
||||||
|
*/
|
||||||
|
$queryRaw<T = unknown>(query: TemplateStringsArray | Prisma.Sql, ...values: any[]): Prisma.PrismaPromise<T>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a raw query and returns the `SELECT` data.
|
||||||
|
* Susceptible to SQL injections, see documentation.
|
||||||
|
* @example
|
||||||
|
* ```
|
||||||
|
* const result = await prisma.$queryRawUnsafe('SELECT * FROM User WHERE id = $1 OR email = $2;', 1, 'user@email.com')
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Read more in our [docs](https://pris.ly/d/raw-queries).
|
||||||
|
*/
|
||||||
|
$queryRawUnsafe<T = unknown>(query: string, ...values: any[]): Prisma.PrismaPromise<T>;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows the running of a sequence of read/write operations that are guaranteed to either succeed or fail as a whole.
|
||||||
|
* @example
|
||||||
|
* ```
|
||||||
|
* const [george, bob, alice] = await prisma.$transaction([
|
||||||
|
* prisma.user.create({ data: { name: 'George' } }),
|
||||||
|
* prisma.user.create({ data: { name: 'Bob' } }),
|
||||||
|
* prisma.user.create({ data: { name: 'Alice' } }),
|
||||||
|
* ])
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Read more in our [docs](https://www.prisma.io/docs/concepts/components/prisma-client/transactions).
|
||||||
|
*/
|
||||||
|
$transaction<P extends Prisma.PrismaPromise<any>[]>(arg: [...P], options?: { isolationLevel?: Prisma.TransactionIsolationLevel }): runtime.Types.Utils.JsPromise<runtime.Types.Utils.UnwrapTuple<P>>
|
||||||
|
|
||||||
|
$transaction<R>(fn: (prisma: Omit<PrismaClient, runtime.ITXClientDenyList>) => runtime.Types.Utils.JsPromise<R>, options?: { maxWait?: number, timeout?: number, isolationLevel?: Prisma.TransactionIsolationLevel }): runtime.Types.Utils.JsPromise<R>
|
||||||
|
|
||||||
|
$extends: runtime.Types.Extensions.ExtendsHook<"extends", Prisma.TypeMapCb<OmitOpts>, ExtArgs, runtime.Types.Utils.Call<Prisma.TypeMapCb<OmitOpts>, {
|
||||||
|
extArgs: ExtArgs
|
||||||
|
}>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `prisma.account`: Exposes CRUD operations for the **Account** model.
|
||||||
|
* Example usage:
|
||||||
|
* ```ts
|
||||||
|
* // Fetch zero or more Accounts
|
||||||
|
* const accounts = await prisma.account.findMany()
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
get account(): Prisma.AccountDelegate<ExtArgs, { omit: OmitOpts }>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `prisma.appInstall`: Exposes CRUD operations for the **AppInstall** model.
|
||||||
|
* Example usage:
|
||||||
|
* ```ts
|
||||||
|
* // Fetch zero or more AppInstalls
|
||||||
|
* const appInstalls = await prisma.appInstall.findMany()
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
get appInstall(): Prisma.AppInstallDelegate<ExtArgs, { omit: OmitOpts }>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `prisma.autoAuth`: Exposes CRUD operations for the **AutoAuth** model.
|
||||||
|
* Example usage:
|
||||||
|
* ```ts
|
||||||
|
* // Fetch zero or more AutoAuths
|
||||||
|
* const autoAuths = await prisma.autoAuth.findMany()
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
get autoAuth(): Prisma.AutoAuthDelegate<ExtArgs, { omit: OmitOpts }>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `prisma.device`: Exposes CRUD operations for the **Device** model.
|
||||||
|
* Example usage:
|
||||||
|
* ```ts
|
||||||
|
* // Fetch zero or more Devices
|
||||||
|
* const devices = await prisma.device.findMany()
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
get device(): Prisma.DeviceDelegate<ExtArgs, { omit: OmitOpts }>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `prisma.kVStore`: Exposes CRUD operations for the **KVStore** model.
|
||||||
|
* Example usage:
|
||||||
|
* ```ts
|
||||||
|
* // Fetch zero or more KVStores
|
||||||
|
* const kVStores = await prisma.kVStore.findMany()
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
get kVStore(): Prisma.KVStoreDelegate<ExtArgs, { omit: OmitOpts }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPrismaClientClass(): PrismaClientConstructor {
|
||||||
|
return runtime.getPrismaClient(config) as unknown as PrismaClientConstructor
|
||||||
|
}
|
||||||
1186
generated/prisma/internal/prismaNamespace.ts
Normal file
1186
generated/prisma/internal/prismaNamespace.ts
Normal file
File diff suppressed because it is too large
Load Diff
197
generated/prisma/internal/prismaNamespaceBrowser.ts
Normal file
197
generated/prisma/internal/prismaNamespaceBrowser.ts
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
|
||||||
|
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
||||||
|
/* eslint-disable */
|
||||||
|
// biome-ignore-all lint: generated file
|
||||||
|
// @ts-nocheck
|
||||||
|
/*
|
||||||
|
* WARNING: This is an internal file that is subject to change!
|
||||||
|
*
|
||||||
|
* 🛑 Under no circumstances should you import this file directly! 🛑
|
||||||
|
*
|
||||||
|
* All exports from this file are wrapped under a `Prisma` namespace object in the browser.ts file.
|
||||||
|
* While this enables partial backward compatibility, it is not part of the stable public API.
|
||||||
|
*
|
||||||
|
* If you are looking for your Models, Enums, and Input Types, please import them from the respective
|
||||||
|
* model files in the `model` directory!
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as runtime from "@prisma/client/runtime/index-browser"
|
||||||
|
|
||||||
|
export type * from '../models.ts'
|
||||||
|
export type * from './prismaNamespace.ts'
|
||||||
|
|
||||||
|
export const Decimal = runtime.Decimal
|
||||||
|
|
||||||
|
|
||||||
|
export const NullTypes = {
|
||||||
|
DbNull: runtime.NullTypes.DbNull as (new (secret: never) => typeof runtime.DbNull),
|
||||||
|
JsonNull: runtime.NullTypes.JsonNull as (new (secret: never) => typeof runtime.JsonNull),
|
||||||
|
AnyNull: runtime.NullTypes.AnyNull as (new (secret: never) => typeof runtime.AnyNull),
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Helper for filtering JSON entries that have `null` on the database (empty on the db)
|
||||||
|
*
|
||||||
|
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
|
||||||
|
*/
|
||||||
|
export const DbNull = runtime.DbNull
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for filtering JSON entries that have JSON `null` values (not empty on the db)
|
||||||
|
*
|
||||||
|
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
|
||||||
|
*/
|
||||||
|
export const JsonNull = runtime.JsonNull
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for filtering JSON entries that are `Prisma.DbNull` or `Prisma.JsonNull`
|
||||||
|
*
|
||||||
|
* @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field
|
||||||
|
*/
|
||||||
|
export const AnyNull = runtime.AnyNull
|
||||||
|
|
||||||
|
|
||||||
|
export const ModelName = {
|
||||||
|
Account: 'Account',
|
||||||
|
AppInstall: 'AppInstall',
|
||||||
|
AutoAuth: 'AutoAuth',
|
||||||
|
Device: 'Device',
|
||||||
|
KVStore: 'KVStore'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type ModelName = (typeof ModelName)[keyof typeof ModelName]
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enums
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const TransactionIsolationLevel = runtime.makeStrictEnum({
|
||||||
|
ReadUncommitted: 'ReadUncommitted',
|
||||||
|
ReadCommitted: 'ReadCommitted',
|
||||||
|
RepeatableRead: 'RepeatableRead',
|
||||||
|
Serializable: 'Serializable'
|
||||||
|
} as const)
|
||||||
|
|
||||||
|
export type TransactionIsolationLevel = (typeof TransactionIsolationLevel)[keyof typeof TransactionIsolationLevel]
|
||||||
|
|
||||||
|
|
||||||
|
export const AccountScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
provider: 'provider',
|
||||||
|
providerId: 'providerId',
|
||||||
|
email: 'email',
|
||||||
|
name: 'name',
|
||||||
|
avatarUrl: 'avatarUrl',
|
||||||
|
providerData: 'providerData',
|
||||||
|
accessToken: 'accessToken',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt',
|
||||||
|
refreshToken: 'refreshToken',
|
||||||
|
refreshTokenExpiry: 'refreshTokenExpiry',
|
||||||
|
tokenVersion: 'tokenVersion'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type AccountScalarFieldEnum = (typeof AccountScalarFieldEnum)[keyof typeof AccountScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const AppInstallScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
deviceId: 'deviceId',
|
||||||
|
appId: 'appId',
|
||||||
|
token: 'token',
|
||||||
|
note: 'note',
|
||||||
|
installedAt: 'installedAt',
|
||||||
|
updatedAt: 'updatedAt',
|
||||||
|
deviceType: 'deviceType',
|
||||||
|
isReadOnly: 'isReadOnly'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type AppInstallScalarFieldEnum = (typeof AppInstallScalarFieldEnum)[keyof typeof AppInstallScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const AutoAuthScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
deviceId: 'deviceId',
|
||||||
|
password: 'password',
|
||||||
|
deviceType: 'deviceType',
|
||||||
|
isReadOnly: 'isReadOnly',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type AutoAuthScalarFieldEnum = (typeof AutoAuthScalarFieldEnum)[keyof typeof AutoAuthScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const DeviceScalarFieldEnum = {
|
||||||
|
id: 'id',
|
||||||
|
uuid: 'uuid',
|
||||||
|
name: 'name',
|
||||||
|
accountId: 'accountId',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt',
|
||||||
|
password: 'password',
|
||||||
|
passwordHint: 'passwordHint',
|
||||||
|
namespace: 'namespace'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type DeviceScalarFieldEnum = (typeof DeviceScalarFieldEnum)[keyof typeof DeviceScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const KVStoreScalarFieldEnum = {
|
||||||
|
deviceId: 'deviceId',
|
||||||
|
key: 'key',
|
||||||
|
value: 'value',
|
||||||
|
creatorIp: 'creatorIp',
|
||||||
|
createdAt: 'createdAt',
|
||||||
|
updatedAt: 'updatedAt'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type KVStoreScalarFieldEnum = (typeof KVStoreScalarFieldEnum)[keyof typeof KVStoreScalarFieldEnum]
|
||||||
|
|
||||||
|
|
||||||
|
export const SortOrder = {
|
||||||
|
asc: 'asc',
|
||||||
|
desc: 'desc'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type SortOrder = (typeof SortOrder)[keyof typeof SortOrder]
|
||||||
|
|
||||||
|
|
||||||
|
export const NullableJsonNullValueInput = {
|
||||||
|
DbNull: DbNull,
|
||||||
|
JsonNull: JsonNull
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type NullableJsonNullValueInput = (typeof NullableJsonNullValueInput)[keyof typeof NullableJsonNullValueInput]
|
||||||
|
|
||||||
|
|
||||||
|
export const JsonNullValueInput = {
|
||||||
|
JsonNull: JsonNull
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type JsonNullValueInput = (typeof JsonNullValueInput)[keyof typeof JsonNullValueInput]
|
||||||
|
|
||||||
|
|
||||||
|
export const QueryMode = {
|
||||||
|
default: 'default',
|
||||||
|
insensitive: 'insensitive'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type QueryMode = (typeof QueryMode)[keyof typeof QueryMode]
|
||||||
|
|
||||||
|
|
||||||
|
export const JsonNullValueFilter = {
|
||||||
|
DbNull: DbNull,
|
||||||
|
JsonNull: JsonNull,
|
||||||
|
AnyNull: AnyNull
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type JsonNullValueFilter = (typeof JsonNullValueFilter)[keyof typeof JsonNullValueFilter]
|
||||||
|
|
||||||
|
|
||||||
|
export const NullsOrder = {
|
||||||
|
first: 'first',
|
||||||
|
last: 'last'
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type NullsOrder = (typeof NullsOrder)[keyof typeof NullsOrder]
|
||||||
|
|
||||||
16
generated/prisma/models.ts
Normal file
16
generated/prisma/models.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
/* !!! This is code generated by Prisma. Do not edit directly. !!! */
|
||||||
|
/* eslint-disable */
|
||||||
|
// biome-ignore-all lint: generated file
|
||||||
|
// @ts-nocheck
|
||||||
|
/*
|
||||||
|
* This is a barrel export file for all models and their related types.
|
||||||
|
*
|
||||||
|
* 🟢 You can import this file directly.
|
||||||
|
*/
|
||||||
|
export type * from './models/Account.ts'
|
||||||
|
export type * from './models/AppInstall.ts'
|
||||||
|
export type * from './models/AutoAuth.ts'
|
||||||
|
export type * from './models/Device.ts'
|
||||||
|
export type * from './models/KVStore.ts'
|
||||||
|
export type * from './commonInputTypes.ts'
|
||||||
1648
generated/prisma/models/Account.ts
Normal file
1648
generated/prisma/models/Account.ts
Normal file
File diff suppressed because it is too large
Load Diff
1528
generated/prisma/models/AppInstall.ts
Normal file
1528
generated/prisma/models/AppInstall.ts
Normal file
File diff suppressed because it is too large
Load Diff
1460
generated/prisma/models/AutoAuth.ts
Normal file
1460
generated/prisma/models/AutoAuth.ts
Normal file
File diff suppressed because it is too large
Load Diff
1972
generated/prisma/models/Device.ts
Normal file
1972
generated/prisma/models/Device.ts
Normal file
File diff suppressed because it is too large
Load Diff
1419
generated/prisma/models/KVStore.ts
Normal file
1419
generated/prisma/models/KVStore.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -6,13 +6,10 @@
|
|||||||
* 2. deviceInfoMiddleware - 仅获取设备信息,不创建新设备
|
* 2. deviceInfoMiddleware - 仅获取设备信息,不创建新设备
|
||||||
* 3. passwordMiddleware - 验证设备密码
|
* 3. passwordMiddleware - 验证设备密码
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {PrismaClient} from "@prisma/client";
|
|
||||||
import errors from "../utils/errors.js";
|
import errors from "../utils/errors.js";
|
||||||
import {verifyDevicePassword} from "../utils/crypto.js";
|
import {verifyDevicePassword} from "../utils/crypto.js";
|
||||||
import {analyzeDevice} from "../utils/deviceDetector.js";
|
import {analyzeDevice} from "../utils/deviceDetector.js";
|
||||||
|
import { prisma } from "../utils/prisma.js";
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 为新设备创建默认的自动登录配置
|
* 为新设备创建默认的自动登录配置
|
||||||
|
|||||||
@ -8,10 +8,8 @@
|
|||||||
|
|
||||||
import {generateAccessToken, validateAccountToken, verifyAccessToken} from "../utils/tokenManager.js";
|
import {generateAccessToken, validateAccountToken, verifyAccessToken} from "../utils/tokenManager.js";
|
||||||
import {verifyToken} from "../utils/jwt.js";
|
import {verifyToken} from "../utils/jwt.js";
|
||||||
import {PrismaClient} from "@prisma/client";
|
|
||||||
import errors from "../utils/errors.js";
|
import errors from "../utils/errors.js";
|
||||||
|
import { prisma } from "../utils/prisma.js";
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新的JWT认证中间件(支持refresh token系统)
|
* 新的JWT认证中间件(支持refresh token系统)
|
||||||
|
|||||||
@ -4,11 +4,8 @@
|
|||||||
* 仅验证app token,设置设备和应用信息到res.locals
|
* 仅验证app token,设置设备和应用信息到res.locals
|
||||||
* 适用于所有KV相关的接口
|
* 适用于所有KV相关的接口
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {PrismaClient} from "@prisma/client";
|
|
||||||
import errors from "../utils/errors.js";
|
import errors from "../utils/errors.js";
|
||||||
|
import { prisma } from "../utils/prisma.js";
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* KV Token认证中间件
|
* KV Token认证中间件
|
||||||
|
|||||||
@ -5,13 +5,10 @@
|
|||||||
* 2. 验证密码或账户JWT(二选一)
|
* 2. 验证密码或账户JWT(二选一)
|
||||||
* 3. 适用于需要设备上下文的接口
|
* 3. 适用于需要设备上下文的接口
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {PrismaClient} from "@prisma/client";
|
|
||||||
import errors from "../utils/errors.js";
|
import errors from "../utils/errors.js";
|
||||||
import {verifyToken as verifyAccountJWT} from "../utils/jwt.js";
|
import {verifyToken as verifyAccountJWT} from "../utils/jwt.js";
|
||||||
import {verifyDevicePassword} from "../utils/crypto.js";
|
import {verifyDevicePassword} from "../utils/crypto.js";
|
||||||
|
import { prisma } from "../utils/prisma.js";
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UUID+密码/JWT混合认证中间件
|
* UUID+密码/JWT混合认证中间件
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "ClassworksKV",
|
"name": "ClassworksKV",
|
||||||
"version": "1.3.9",
|
"version": "1.3.15",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ClassworksKV",
|
"name": "ClassworksKV",
|
||||||
"version": "1.3.9",
|
"version": "1.3.15",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@opentelemetry/auto-instrumentations-node": "^0.59.0",
|
"@opentelemetry/auto-instrumentations-node": "^0.59.0",
|
||||||
"@opentelemetry/exporter-trace-otlp-proto": "^0.205.0",
|
"@opentelemetry/exporter-trace-otlp-proto": "^0.205.0",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ClassworksKV",
|
"name": "ClassworksKV",
|
||||||
"version": "1.3.9",
|
"version": "1.3.15",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node ./bin/www",
|
"start": "node ./bin/www",
|
||||||
@ -15,7 +15,8 @@
|
|||||||
"@opentelemetry/sdk-node": "^0.201.1",
|
"@opentelemetry/sdk-node": "^0.201.1",
|
||||||
"@opentelemetry/sdk-trace-base": "^2.0.1",
|
"@opentelemetry/sdk-trace-base": "^2.0.1",
|
||||||
"@opentelemetry/semantic-conventions": "^1.34.0",
|
"@opentelemetry/semantic-conventions": "^1.34.0",
|
||||||
"@prisma/client": "6.16.2",
|
"@prisma/adapter-pg": "^7.3.0",
|
||||||
|
"@prisma/client": "^7.3.0",
|
||||||
"axios": "^1.9.0",
|
"axios": "^1.9.0",
|
||||||
"bcrypt": "^6.0.0",
|
"bcrypt": "^6.0.0",
|
||||||
"body-parser": "^2.2.0",
|
"body-parser": "^2.2.0",
|
||||||
@ -32,10 +33,12 @@
|
|||||||
"morgan": "~1.10.0",
|
"morgan": "~1.10.0",
|
||||||
"node-device-detector": "^2.2.4",
|
"node-device-detector": "^2.2.4",
|
||||||
"prom-client": "^15.1.3",
|
"prom-client": "^15.1.3",
|
||||||
|
"pg": "^8.18.0",
|
||||||
"socket.io": "^4.8.1",
|
"socket.io": "^4.8.1",
|
||||||
"uuid": "^11.1.0"
|
"uuid": "^11.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prisma": "^6.18.0"
|
"dotenv": "^16.5.0",
|
||||||
|
"prisma": "^7.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
584
pnpm-lock.yaml
generated
584
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
14
prisma.config.js
Normal file
14
prisma.config.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// This file was generated by Prisma, and assumes you have installed the following:
|
||||||
|
// npm install --save-dev prisma dotenv
|
||||||
|
import "dotenv/config";
|
||||||
|
import { defineConfig } from "prisma/config";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
schema: "prisma/schema.prisma",
|
||||||
|
migrations: {
|
||||||
|
path: "prisma/migrations",
|
||||||
|
},
|
||||||
|
datasource: {
|
||||||
|
url: process.env["DATABASE_URL"],
|
||||||
|
},
|
||||||
|
});
|
||||||
110
prisma/migrations/0_init/migration.sql
Normal file
110
prisma/migrations/0_init/migration.sql
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
-- CreateSchema
|
||||||
|
CREATE SCHEMA IF NOT EXISTS "public";
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "Account" (
|
||||||
|
"id" VARCHAR(191) NOT NULL,
|
||||||
|
"provider" VARCHAR(191) NOT NULL,
|
||||||
|
"providerId" VARCHAR(191) NOT NULL,
|
||||||
|
"email" VARCHAR(191),
|
||||||
|
"name" VARCHAR(191),
|
||||||
|
"avatarUrl" VARCHAR(191),
|
||||||
|
"providerData" JSON,
|
||||||
|
"accessToken" TEXT,
|
||||||
|
"createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMPTZ(6) NOT NULL,
|
||||||
|
"refreshToken" TEXT,
|
||||||
|
"refreshTokenExpiry" TIMESTAMPTZ(6),
|
||||||
|
"tokenVersion" INTEGER NOT NULL DEFAULT 1,
|
||||||
|
|
||||||
|
CONSTRAINT "idx_18303_PRIMARY" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "AppInstall" (
|
||||||
|
"id" VARCHAR(191) NOT NULL,
|
||||||
|
"deviceId" INTEGER NOT NULL,
|
||||||
|
"appId" VARCHAR(191) NOT NULL,
|
||||||
|
"token" VARCHAR(191) NOT NULL,
|
||||||
|
"note" VARCHAR(191),
|
||||||
|
"installedAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMPTZ(6) NOT NULL,
|
||||||
|
"deviceType" VARCHAR(191),
|
||||||
|
"isReadOnly" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
|
||||||
|
CONSTRAINT "idx_18310_PRIMARY" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "AutoAuth" (
|
||||||
|
"id" VARCHAR(191) NOT NULL,
|
||||||
|
"deviceId" INTEGER NOT NULL,
|
||||||
|
"password" VARCHAR(191),
|
||||||
|
"deviceType" VARCHAR(191),
|
||||||
|
"isReadOnly" BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
"createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMPTZ(6) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "idx_18317_PRIMARY" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "Device" (
|
||||||
|
"id" INTEGER NOT NULL,
|
||||||
|
"uuid" VARCHAR(191) NOT NULL,
|
||||||
|
"name" VARCHAR(191),
|
||||||
|
"accountId" VARCHAR(191),
|
||||||
|
"createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMPTZ(6) NOT NULL,
|
||||||
|
"password" VARCHAR(191),
|
||||||
|
"passwordHint" VARCHAR(191),
|
||||||
|
"namespace" VARCHAR(191),
|
||||||
|
|
||||||
|
CONSTRAINT "idx_18324_PRIMARY" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "KVStore" (
|
||||||
|
"deviceId" INTEGER NOT NULL,
|
||||||
|
"key" VARCHAR(191) NOT NULL,
|
||||||
|
"value" JSON NOT NULL,
|
||||||
|
"creatorIp" VARCHAR(191) DEFAULT '',
|
||||||
|
"createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMPTZ(6) NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "idx_18330_PRIMARY" PRIMARY KEY ("deviceId","key")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "idx_18303_Account_provider_providerId_key" ON "Account"("provider", "providerId");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "idx_18310_AppInstall_token_key" ON "AppInstall"("token");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "idx_18310_AppInstall_deviceId_fkey" ON "AppInstall"("deviceId");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "idx_18317_AutoAuth_deviceId_password_key" ON "AutoAuth"("deviceId", "password");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "idx_18324_Device_uuid_key" ON "Device"("uuid");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "idx_18324_Device_namespace_key" ON "Device"("namespace");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "idx_18324_Device_accountId_fkey" ON "Device"("accountId");
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "AppInstall" ADD CONSTRAINT "AppInstall_deviceId_fkey" FOREIGN KEY ("deviceId") REFERENCES "Device"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "AutoAuth" ADD CONSTRAINT "AutoAuth_deviceId_fkey" FOREIGN KEY ("deviceId") REFERENCES "Device"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "Device" ADD CONSTRAINT "Device_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "KVStore" ADD CONSTRAINT "KVStore_deviceId_fkey" FOREIGN KEY ("deviceId") REFERENCES "Device"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
-- CreateTable
|
|
||||||
CREATE TABLE `KVStore` (
|
|
||||||
`deviceId` INTEGER NOT NULL,
|
|
||||||
`key` VARCHAR(191) NOT NULL,
|
|
||||||
`value` JSON NOT NULL,
|
|
||||||
`creatorIp` VARCHAR(191) NULL DEFAULT '',
|
|
||||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
||||||
`updatedAt` DATETIME(3) NOT NULL,
|
|
||||||
|
|
||||||
PRIMARY KEY (`deviceId`, `key`)
|
|
||||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE `Account` (
|
|
||||||
`id` VARCHAR(191) NOT NULL,
|
|
||||||
`provider` VARCHAR(191) NOT NULL,
|
|
||||||
`providerId` VARCHAR(191) NOT NULL,
|
|
||||||
`email` VARCHAR(191) NULL,
|
|
||||||
`name` VARCHAR(191) NULL,
|
|
||||||
`avatarUrl` VARCHAR(191) NULL,
|
|
||||||
`providerData` JSON NULL,
|
|
||||||
`accessToken` VARCHAR(191) NOT NULL,
|
|
||||||
`refreshToken` VARCHAR(191) NULL,
|
|
||||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
||||||
`updatedAt` DATETIME(3) NOT NULL,
|
|
||||||
|
|
||||||
UNIQUE INDEX `Account_accessToken_key`(`accessToken`),
|
|
||||||
UNIQUE INDEX `Account_provider_providerId_key`(`provider`, `providerId`),
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE `Device` (
|
|
||||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
|
||||||
`uuid` VARCHAR(191) NOT NULL,
|
|
||||||
`name` VARCHAR(191) NULL,
|
|
||||||
`accountId` VARCHAR(191) NULL,
|
|
||||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
||||||
`updatedAt` DATETIME(3) NOT NULL,
|
|
||||||
`password` VARCHAR(191) NULL,
|
|
||||||
`passwordHint` VARCHAR(191) NULL,
|
|
||||||
|
|
||||||
UNIQUE INDEX `Device_uuid_key`(`uuid`),
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE `AppInstall` (
|
|
||||||
`id` VARCHAR(191) NOT NULL,
|
|
||||||
`deviceId` INTEGER NOT NULL,
|
|
||||||
`appId` VARCHAR(191) NOT NULL,
|
|
||||||
`token` VARCHAR(191) NOT NULL,
|
|
||||||
`note` VARCHAR(191) NULL,
|
|
||||||
`installedAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
||||||
`updatedAt` DATETIME(3) NOT NULL,
|
|
||||||
|
|
||||||
UNIQUE INDEX `AppInstall_token_key`(`token`),
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE `KVStore` ADD CONSTRAINT `KVStore_deviceId_fkey` FOREIGN KEY (`deviceId`) REFERENCES `Device`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE `Device` ADD CONSTRAINT `Device_accountId_fkey` FOREIGN KEY (`accountId`) REFERENCES `Account`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE `AppInstall` ADD CONSTRAINT `AppInstall_deviceId_fkey` FOREIGN KEY (`deviceId`) REFERENCES `Device`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
-- AlterTable
|
|
||||||
ALTER TABLE `Account` MODIFY `refreshToken` TEXT NULL;
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
-- DropIndex
|
|
||||||
DROP INDEX `Account_accessToken_key` ON `Account`;
|
|
||||||
|
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE `Account` MODIFY `accessToken` TEXT NOT NULL;
|
|
||||||
@ -1 +0,0 @@
|
|||||||
-- This is an empty migration.
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
/*
|
|
||||||
Warnings:
|
|
||||||
|
|
||||||
- You are about to drop the column `refreshToken` on the `Account` table. All the data in the column will be lost.
|
|
||||||
|
|
||||||
*/
|
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE `Account` DROP COLUMN `refreshToken`,
|
|
||||||
MODIFY `accessToken` TEXT NULL;
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
Warnings:
|
|
||||||
|
|
||||||
- A unique constraint covering the columns `[namespace]` on the table `Device` will be added. If there are existing duplicate values, this will fail.
|
|
||||||
|
|
||||||
*/
|
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE `AppInstall` ADD COLUMN `deviceType` VARCHAR(191) NULL,
|
|
||||||
ADD COLUMN `isReadOnly` BOOLEAN NOT NULL DEFAULT false;
|
|
||||||
|
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE `Device` ADD COLUMN `namespace` VARCHAR(191) NULL;
|
|
||||||
|
|
||||||
-- 将所有设备的 namespace 设置为对应的 uuid 值,避免唯一键冲突
|
|
||||||
UPDATE `Device` SET `namespace` = `uuid` WHERE `namespace` IS NULL;
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE `AutoAuth` (
|
|
||||||
`id` VARCHAR(191) NOT NULL,
|
|
||||||
`deviceId` INTEGER NOT NULL,
|
|
||||||
`password` VARCHAR(191) NULL,
|
|
||||||
`deviceType` VARCHAR(191) NULL,
|
|
||||||
`isReadOnly` BOOLEAN NOT NULL DEFAULT false,
|
|
||||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
||||||
`updatedAt` DATETIME(3) NOT NULL,
|
|
||||||
|
|
||||||
UNIQUE INDEX `AutoAuth_deviceId_password_key`(`deviceId`, `password`),
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
||||||
|
|
||||||
-- 为每个设备创建默认的 AutoAuth 记录,将 Device.password 复制为 AutoAuth.password
|
|
||||||
INSERT INTO `AutoAuth` (`id`, `deviceId`, `password`, `deviceType`, `isReadOnly`, `createdAt`, `updatedAt`)
|
|
||||||
SELECT
|
|
||||||
CONCAT('autoauth_', UUID()),
|
|
||||||
`id`,
|
|
||||||
`password`,
|
|
||||||
NULL,
|
|
||||||
false,
|
|
||||||
CURRENT_TIMESTAMP(3),
|
|
||||||
CURRENT_TIMESTAMP(3)
|
|
||||||
FROM `Device`;
|
|
||||||
|
|
||||||
-- CreateIndex
|
|
||||||
CREATE UNIQUE INDEX `Device_namespace_key` ON `Device`(`namespace`);
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE `AutoAuth` ADD CONSTRAINT `AutoAuth_deviceId_fkey` FOREIGN KEY (`deviceId`) REFERENCES `Device`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
-- AlterTable
|
|
||||||
ALTER TABLE `Account` ADD COLUMN `refreshToken` TEXT NULL,
|
|
||||||
ADD COLUMN `refreshTokenExpiry` DATETIME(3) NULL,
|
|
||||||
ADD COLUMN `tokenVersion` INTEGER NOT NULL DEFAULT 1;
|
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Account" ALTER COLUMN "updatedAt" SET DEFAULT CURRENT_TIMESTAMP;
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "AppInstall" ALTER COLUMN "updatedAt" SET DEFAULT CURRENT_TIMESTAMP;
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "AutoAuth" ALTER COLUMN "updatedAt" SET DEFAULT CURRENT_TIMESTAMP;
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Device" ALTER COLUMN "updatedAt" SET DEFAULT CURRENT_TIMESTAMP;
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "KVStore" ALTER COLUMN "updatedAt" SET DEFAULT CURRENT_TIMESTAMP;
|
||||||
4
prisma/migrations/20260201131541_fix_idbug/migration.sql
Normal file
4
prisma/migrations/20260201131541_fix_idbug/migration.sql
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
-- AlterTable
|
||||||
|
CREATE SEQUENCE device_id_seq;
|
||||||
|
ALTER TABLE "Device" ALTER COLUMN "id" SET DEFAULT nextval('device_id_seq');
|
||||||
|
ALTER SEQUENCE device_id_seq OWNED BY "Device"."id";
|
||||||
@ -1,3 +1,3 @@
|
|||||||
# Please do not edit this file manually
|
# Please do not edit this file manually
|
||||||
# It should be added in your version-control system (e.g., Git)
|
# It should be added in your version-control system (e.g., Git)
|
||||||
provider = "mysql"
|
provider = "postgresql"
|
||||||
|
|||||||
@ -1,91 +1,90 @@
|
|||||||
generator client {
|
generator client {
|
||||||
provider = "prisma-client-js"
|
provider = "prisma-client"
|
||||||
|
output = "../generated/prisma"
|
||||||
}
|
}
|
||||||
|
|
||||||
datasource db {
|
datasource db {
|
||||||
provider = "mysql"
|
provider = "postgresql"
|
||||||
url = env("DATABASE_URL")
|
|
||||||
}
|
|
||||||
|
|
||||||
model KVStore {
|
|
||||||
deviceId Int
|
|
||||||
key String
|
|
||||||
value Json
|
|
||||||
creatorIp String? @default("")
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @updatedAt
|
|
||||||
|
|
||||||
// 关联关系
|
|
||||||
device Device @relation(fields: [deviceId], references: [id], onDelete: Cascade)
|
|
||||||
|
|
||||||
@@id([deviceId, key])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model Account {
|
model Account {
|
||||||
id String @id @default(cuid())
|
id String @id(map: "idx_18303_PRIMARY") @db.VarChar(191) @default(cuid())
|
||||||
provider String // OAuth提供者 (例如: google, github, gitlab等)
|
provider String @db.VarChar(191)
|
||||||
providerId String // 提供者返回的用户唯一ID
|
providerId String @db.VarChar(191)
|
||||||
email String? // 用户邮箱
|
email String? @db.VarChar(191)
|
||||||
name String? // 用户名称
|
name String? @db.VarChar(191)
|
||||||
avatarUrl String? // 用户头像URL
|
avatarUrl String? @db.VarChar(191)
|
||||||
providerData Json? // OAuth提供者返回的完整信息
|
providerData Json? @db.Json
|
||||||
accessToken String? @db.Text // 账户访问令牌
|
accessToken String?
|
||||||
refreshToken String? @db.Text // 刷新令牌
|
createdAt DateTime @default(now()) @db.Timestamptz(6)
|
||||||
refreshTokenExpiry DateTime? // 刷新令牌过期时间
|
updatedAt DateTime @default(now()) @updatedAt @db.Timestamptz(6)
|
||||||
tokenVersion Int @default(1) // 令牌版本,用于令牌失效
|
refreshToken String?
|
||||||
createdAt DateTime @default(now())
|
refreshTokenExpiry DateTime? @db.Timestamptz(6)
|
||||||
updatedAt DateTime @updatedAt
|
tokenVersion Int @default(1)
|
||||||
|
|
||||||
// 关联的设备
|
|
||||||
devices Device[]
|
devices Device[]
|
||||||
|
|
||||||
@@unique([provider, providerId]) // 确保同一提供者的用户ID唯一
|
@@unique([provider, providerId], map: "idx_18303_Account_provider_providerId_key")
|
||||||
|
}
|
||||||
|
|
||||||
|
model AppInstall {
|
||||||
|
id String @id(map: "idx_18310_PRIMARY") @default(cuid()) @db.VarChar(191)
|
||||||
|
deviceId Int
|
||||||
|
appId String @db.VarChar(191)
|
||||||
|
token String @unique(map: "idx_18310_AppInstall_token_key") @db.VarChar(191)
|
||||||
|
note String? @db.VarChar(191)
|
||||||
|
installedAt DateTime @default(now()) @db.Timestamptz(6)
|
||||||
|
updatedAt DateTime @default(now()) @updatedAt @db.Timestamptz(6)
|
||||||
|
deviceType String? @db.VarChar(191)
|
||||||
|
isReadOnly Boolean @default(false)
|
||||||
|
|
||||||
|
device Device @relation(fields: [deviceId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
|
@@index([deviceId], map: "idx_18310_AppInstall_deviceId_fkey")
|
||||||
|
}
|
||||||
|
|
||||||
|
model AutoAuth {
|
||||||
|
id String @id(map: "idx_18317_PRIMARY") @default(cuid()) @db.VarChar(191)
|
||||||
|
deviceId Int
|
||||||
|
password String? @db.VarChar(191)
|
||||||
|
deviceType String? @db.VarChar(191)
|
||||||
|
isReadOnly Boolean @default(false)
|
||||||
|
createdAt DateTime @default(now()) @db.Timestamptz(6)
|
||||||
|
updatedAt DateTime @default(now()) @updatedAt @db.Timestamptz(6)
|
||||||
|
|
||||||
|
device Device @relation(fields: [deviceId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
|
@@unique([deviceId, password], map: "idx_18317_AutoAuth_deviceId_password_key")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Device {
|
model Device {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id(map: "idx_18324_PRIMARY") @default(autoincrement())
|
||||||
uuid String @unique // 设备的唯一标识符
|
uuid String @unique(map: "idx_18324_Device_uuid_key") @db.VarChar(191)
|
||||||
name String?
|
name String? @db.VarChar(191)
|
||||||
accountId String? // 关联的账户ID
|
accountId String? @db.VarChar(191)
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now()) @db.Timestamptz(6)
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @default(now()) @updatedAt @db.Timestamptz(6)
|
||||||
password String?
|
password String? @db.VarChar(191)
|
||||||
passwordHint String?
|
passwordHint String? @db.VarChar(191)
|
||||||
namespace String? @unique // 用户自定义的唯一命名空间
|
namespace String? @unique(map: "idx_18324_Device_namespace_key") @db.VarChar(191)
|
||||||
|
|
||||||
// 关联关系
|
// 关联关系
|
||||||
account Account? @relation(fields: [accountId], references: [id], onDelete: SetNull)
|
account Account? @relation(fields: [accountId], references: [id], onDelete: SetNull)
|
||||||
appInstalls AppInstall[]
|
appInstalls AppInstall[]
|
||||||
kvStore KVStore[] // 设备相关的KV存储
|
kvStore KVStore[] // 设备相关的KV存储
|
||||||
autoAuths AutoAuth[] // 自动授权配置
|
autoAuths AutoAuth[] // 自动授权配置
|
||||||
|
@@index([accountId], map: "idx_18324_Device_accountId_fkey")
|
||||||
}
|
}
|
||||||
|
|
||||||
model AppInstall {
|
model KVStore {
|
||||||
id String @id @default(cuid())
|
deviceId Int
|
||||||
deviceId Int // 关联的设备ID
|
key String @db.VarChar(191)
|
||||||
appId String // 应用ID (SHA256 hash)
|
value Json @db.Json
|
||||||
token String @unique // 应用安装的唯一访问令牌,拥有完整KV读写权限
|
creatorIp String? @default("") @db.VarChar(191)
|
||||||
note String? // 安装备注
|
createdAt DateTime @default(now()) @db.Timestamptz(6)
|
||||||
isReadOnly Boolean @default(false) // 是否只读
|
updatedAt DateTime @default(now()) @updatedAt @db.Timestamptz(6)
|
||||||
deviceType String? // 设备类型: teacher(教师), student(学生), classroom(班级一体机), parent(家长)
|
|
||||||
installedAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @updatedAt
|
|
||||||
|
|
||||||
// 关联关系
|
device Device @relation(fields: [deviceId], references: [id], onDelete: Cascade)
|
||||||
device Device @relation(fields: [deviceId], references: [id], onDelete: Cascade)
|
|
||||||
}
|
@@id([deviceId, key], map: "idx_18330_PRIMARY")
|
||||||
|
|
||||||
model AutoAuth {
|
|
||||||
id String @id @default(cuid())
|
|
||||||
deviceId Int // 关联的设备ID
|
|
||||||
password String? // 配置密码,可以为空
|
|
||||||
deviceType String? // 自动设备类型: teacher(教师), student(学生), classroom(班级一体机), parent(家长)
|
|
||||||
isReadOnly Boolean @default(false) // 是否只读
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @updatedAt
|
|
||||||
|
|
||||||
// 关联关系
|
|
||||||
device Device @relation(fields: [deviceId], references: [id], onDelete: Cascade)
|
|
||||||
|
|
||||||
@@unique([deviceId, password]) // 同一设备的密码必须唯一
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
import {Router} from "express";
|
import {Router} from "express";
|
||||||
import {PrismaClient} from "@prisma/client";
|
|
||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import {generateState, getCallbackURL, oauthProviders} from "../config/oauth.js";
|
import {generateState, getCallbackURL, oauthProviders} from "../config/oauth.js";
|
||||||
import {generateTokenPair, refreshAccessToken, revokeAllTokens, revokeRefreshToken} from "../utils/jwt.js";
|
import {generateTokenPair, refreshAccessToken, revokeAllTokens, revokeRefreshToken} from "../utils/jwt.js";
|
||||||
import {jwtAuth} from "../middleware/jwt-auth.js";
|
import {jwtAuth} from "../middleware/jwt-auth.js";
|
||||||
import errors from "../utils/errors.js";
|
import errors from "../utils/errors.js";
|
||||||
|
import { prisma } from "../utils/prisma.js";
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
// 存储OAuth state,防止CSRF攻击(生产环境应使用Redis等)
|
// 存储OAuth state,防止CSRF攻击(生产环境应使用Redis等)
|
||||||
const oauthStates = new Map();
|
const oauthStates = new Map();
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
import {Router} from "express";
|
import {Router} from "express";
|
||||||
import {uuidAuth} from "../middleware/uuidAuth.js";
|
import {uuidAuth} from "../middleware/uuidAuth.js";
|
||||||
import {PrismaClient} from "@prisma/client";
|
|
||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import errors from "../utils/errors.js";
|
import errors from "../utils/errors.js";
|
||||||
import {verifyDevicePassword} from "../utils/crypto.js";
|
import {verifyDevicePassword} from "../utils/crypto.js";
|
||||||
|
import { prisma } from "../utils/prisma.js";
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /apps/devices/:uuid/apps
|
* GET /apps/devices/:uuid/apps
|
||||||
* 获取设备安装的应用列表 (公开接口,无需认证)
|
* 获取设备安装的应用列表 (公开接口,无需认证)
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
import {Router} from "express";
|
import {Router} from "express";
|
||||||
import {jwtAuth} from "../middleware/jwt-auth.js";
|
import {jwtAuth} from "../middleware/jwt-auth.js";
|
||||||
import {PrismaClient} from "@prisma/client";
|
|
||||||
import errors from "../utils/errors.js";
|
import errors from "../utils/errors.js";
|
||||||
|
import { prisma } from "../utils/prisma.js";
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /auto-auth/devices/:uuid/auth-configs
|
* GET /auto-auth/devices/:uuid/auth-configs
|
||||||
* 获取设备的所有自动授权配置 (需要 JWT 认证,且设备必须绑定到该账户)
|
* 获取设备的所有自动授权配置 (需要 JWT 认证,且设备必须绑定到该账户)
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
import {Router} from "express";
|
import {Router} from "express";
|
||||||
import deviceCodeStore from "../utils/deviceCodeStore.js";
|
import deviceCodeStore from "../utils/deviceCodeStore.js";
|
||||||
import errors from "../utils/errors.js";
|
import errors from "../utils/errors.js";
|
||||||
import {PrismaClient} from "@prisma/client";
|
import { prisma } from "../utils/prisma.js";
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
import {Router} from "express";
|
import {Router} from "express";
|
||||||
import {extractDeviceInfo} from "../middleware/uuidAuth.js";
|
import {extractDeviceInfo} from "../middleware/uuidAuth.js";
|
||||||
import {PrismaClient} from "@prisma/client";
|
|
||||||
import errors from "../utils/errors.js";
|
import errors from "../utils/errors.js";
|
||||||
import {getOnlineDevices} from "../utils/socket.js";
|
import {getOnlineDevices} from "../utils/socket.js";
|
||||||
import {registeredDevicesTotal} from "../utils/metrics.js";
|
import {registeredDevicesTotal} from "../utils/metrics.js";
|
||||||
|
import { prisma } from "../utils/prisma.js";
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 为新设备创建默认的自动登录配置
|
* 为新设备创建默认的自动登录配置
|
||||||
* @param {number} deviceId - 设备ID
|
* @param {number} deviceId - 设备ID
|
||||||
|
|||||||
@ -10,12 +10,10 @@ import {
|
|||||||
tokenWriteLimiter
|
tokenWriteLimiter
|
||||||
} from "../middleware/rateLimiter.js";
|
} from "../middleware/rateLimiter.js";
|
||||||
import errors from "../utils/errors.js";
|
import errors from "../utils/errors.js";
|
||||||
import { PrismaClient } from "@prisma/client";
|
import { prisma } from "../utils/prisma.js";
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
// 使用KV专用token认证
|
// 使用KV专用token认证
|
||||||
router.use(kvTokenAuth);
|
router.use(kvTokenAuth);
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
import {PrismaClient} from "@prisma/client";
|
|
||||||
import {keysTotal} from "./metrics.js";
|
import {keysTotal} from "./metrics.js";
|
||||||
|
import { prisma } from "./prisma.js";
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
class KVStore {
|
class KVStore {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import client from 'prom-client';
|
import client from 'prom-client';
|
||||||
|
import { prisma } from './prisma.js';
|
||||||
|
|
||||||
// 创建自定义注册表(不包含默认指标)
|
// 创建自定义注册表(不包含默认指标)
|
||||||
const register = new client.Registry();
|
const register = new client.Registry();
|
||||||
@ -27,9 +28,6 @@ export const keysTotal = new client.Gauge({
|
|||||||
// 初始化指标数据
|
// 初始化指标数据
|
||||||
export async function initializeMetrics() {
|
export async function initializeMetrics() {
|
||||||
try {
|
try {
|
||||||
const {PrismaClient} = await import('@prisma/client');
|
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
// 获取已注册设备总数
|
// 获取已注册设备总数
|
||||||
const deviceCount = await prisma.device.count();
|
const deviceCount = await prisma.device.count();
|
||||||
registeredDevicesTotal.set(deviceCount);
|
registeredDevicesTotal.set(deviceCount);
|
||||||
@ -37,8 +35,6 @@ export async function initializeMetrics() {
|
|||||||
// 获取已创建键总数
|
// 获取已创建键总数
|
||||||
const keyCount = await prisma.kVStore.count();
|
const keyCount = await prisma.kVStore.count();
|
||||||
keysTotal.set(keyCount);
|
keysTotal.set(keyCount);
|
||||||
|
|
||||||
await prisma.$disconnect();
|
|
||||||
console.log('Prometheus metrics initialized - Devices:', deviceCount, 'Keys:', keyCount);
|
console.log('Prometheus metrics initialized - Devices:', deviceCount, 'Keys:', keyCount);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to initialize metrics:', error);
|
console.error('Failed to initialize metrics:', error);
|
||||||
|
|||||||
10
utils/prisma.js
Normal file
10
utils/prisma.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import "dotenv/config";
|
||||||
|
import { PrismaPg } from '@prisma/adapter-pg'
|
||||||
|
import { PrismaClient } from '../generated/prisma/client.ts'
|
||||||
|
|
||||||
|
const connectionString = `${process.env.DATABASE_URL}`
|
||||||
|
|
||||||
|
const adapter = new PrismaPg({ connectionString })
|
||||||
|
const prisma = new PrismaClient({ adapter })
|
||||||
|
|
||||||
|
export { prisma }
|
||||||
@ -1,7 +1,5 @@
|
|||||||
import {PrismaClient} from "@prisma/client";
|
|
||||||
import kvStore from "./kvStore.js";
|
import kvStore from "./kvStore.js";
|
||||||
|
import { prisma } from "./prisma.js";
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
// 系统保留UUID用于存储站点信息
|
// 系统保留UUID用于存储站点信息
|
||||||
const SYSTEM_DEVICE_UUID = "00000000-0000-4000-8000-000000000000";
|
const SYSTEM_DEVICE_UUID = "00000000-0000-4000-8000-000000000000";
|
||||||
|
|||||||
@ -13,10 +13,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Server } from "socket.io";
|
import { Server } from "socket.io";
|
||||||
import { PrismaClient } from "@prisma/client";
|
|
||||||
import { onlineDevicesGauge } from "./metrics.js";
|
import { onlineDevicesGauge } from "./metrics.js";
|
||||||
import DeviceDetector from "node-device-detector";
|
import DeviceDetector from "node-device-detector";
|
||||||
import ClientHints from "node-device-detector/client-hints.js";
|
import ClientHints from "node-device-detector/client-hints.js";
|
||||||
|
import { prisma } from "./prisma.js";
|
||||||
|
|
||||||
// Socket.IO 单例实例
|
// Socket.IO 单例实例
|
||||||
let io = null;
|
let io = null;
|
||||||
@ -38,7 +38,6 @@ const tokenInfoCache = new Map();
|
|||||||
// 事件历史记录:每个设备最多保存1000条事件记录
|
// 事件历史记录:每个设备最多保存1000条事件记录
|
||||||
const eventHistory = new Map(); // uuid -> Array<EventRecord>
|
const eventHistory = new Map(); // uuid -> Array<EventRecord>
|
||||||
const MAX_EVENT_HISTORY = 1000;
|
const MAX_EVENT_HISTORY = 1000;
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检测设备并生成友好的设备名称
|
* 检测设备并生成友好的设备名称
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
import jwt from 'jsonwebtoken';
|
import jwt from 'jsonwebtoken';
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import {PrismaClient} from '@prisma/client';
|
import { prisma } from './prisma.js';
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
// Token 配置
|
// Token 配置
|
||||||
const ACCESS_TOKEN_SECRET = process.env.JWT_SECRET || 'your-access-token-secret-change-this-in-production';
|
const ACCESS_TOKEN_SECRET = process.env.JWT_SECRET || 'your-access-token-secret-change-this-in-production';
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user