mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-11 20:08:37 +00:00
Compare commits
1 Commits
eyhn/init-
...
xp/07-31-f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31071c8308 |
@@ -1,146 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "_data_migrations" ALTER COLUMN "id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "started_at" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "finished_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "ai_prompts_messages" ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "ai_prompts_metadata" ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "ai_sessions_messages" ALTER COLUMN "id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "session_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "updated_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "ai_sessions_metadata" ALTER COLUMN "id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "user_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "workspace_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "doc_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "deleted_at" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "parent_session_id" SET DATA TYPE VARCHAR;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "app_runtime_settings" ALTER COLUMN "updated_at" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "deleted_at" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "last_updated_by" SET DATA TYPE VARCHAR;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "features" ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "multiple_users_sessions" ALTER COLUMN "id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "expires_at" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "snapshot_histories"
|
||||
ALTER COLUMN "workspace_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "guid" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "timestamp" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "expired_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "snapshots" ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "updated_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "updates" ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "user_connected_accounts" ALTER COLUMN "id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "user_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "expires_at" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "updated_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "user_features" ALTER COLUMN "user_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "expired_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "user_invoices" ALTER COLUMN "user_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "updated_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "user_sessions" ALTER COLUMN "id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "session_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "user_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "expires_at" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "user_stripe_customers" ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "user_subscriptions" ALTER COLUMN "user_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "start" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "end" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "next_bill_at" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "canceled_at" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "trial_start" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "trial_end" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "updated_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "users" ALTER COLUMN "name" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "email" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "verification_tokens" ALTER COLUMN "token" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "expiresAt" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "workspace_features" ALTER COLUMN "workspace_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3),
|
||||
ALTER COLUMN "expired_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "workspace_page_user_permissions"
|
||||
ALTER COLUMN "id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "workspace_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "page_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "user_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "workspace_pages" ALTER COLUMN "workspace_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "page_id" SET DATA TYPE VARCHAR;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "workspace_user_permissions" ALTER COLUMN "id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "workspace_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "user_id" SET DATA TYPE VARCHAR,
|
||||
ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "workspaces" ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(3);
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE "accounts";
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE "blobs";
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE "new_features_waiting_list";
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE "optimized_blobs";
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE "sessions";
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE "user_workspace_permissions";
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE "verificationtokens";
|
||||
@@ -11,18 +11,18 @@ datasource db {
|
||||
|
||||
model User {
|
||||
id String @id @default(uuid()) @db.VarChar
|
||||
name String @db.VarChar
|
||||
email String @unique @db.VarChar
|
||||
emailVerifiedAt DateTime? @map("email_verified") @db.Timestamp(3)
|
||||
name String
|
||||
email String @unique
|
||||
emailVerifiedAt DateTime? @map("email_verified")
|
||||
avatarUrl String? @map("avatar_url") @db.VarChar
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
/// Not available if user signed up through OAuth providers
|
||||
password String? @db.VarChar
|
||||
/// Indicate whether the user finished the signup progress.
|
||||
/// for example, the value will be false if user never registered and invited into a workspace by others.
|
||||
registered Boolean @default(true)
|
||||
|
||||
features UserFeature[]
|
||||
features UserFeatures[]
|
||||
customer UserStripeCustomer?
|
||||
subscriptions UserSubscription[]
|
||||
invoices UserInvoice[]
|
||||
@@ -38,16 +38,16 @@ model User {
|
||||
}
|
||||
|
||||
model ConnectedAccount {
|
||||
id String @id @default(uuid()) @db.VarChar
|
||||
userId String @map("user_id") @db.VarChar
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
userId String @map("user_id") @db.VarChar(36)
|
||||
provider String @db.VarChar
|
||||
providerAccountId String @map("provider_account_id") @db.VarChar
|
||||
scope String? @db.Text
|
||||
accessToken String? @map("access_token") @db.Text
|
||||
refreshToken String? @map("refresh_token") @db.Text
|
||||
expiresAt DateTime? @map("expires_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamp(3)
|
||||
expiresAt DateTime? @map("expires_at") @db.Timestamptz(6)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@ -57,9 +57,9 @@ model ConnectedAccount {
|
||||
}
|
||||
|
||||
model Session {
|
||||
id String @id @default(uuid()) @db.VarChar
|
||||
expiresAt DateTime? @map("expires_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
expiresAt DateTime? @map("expires_at") @db.Timestamptz(6)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
|
||||
userSessions UserSession[]
|
||||
|
||||
@@ -67,11 +67,11 @@ model Session {
|
||||
}
|
||||
|
||||
model UserSession {
|
||||
id String @id @default(uuid()) @db.VarChar
|
||||
sessionId String @map("session_id") @db.VarChar
|
||||
userId String @map("user_id") @db.VarChar
|
||||
expiresAt DateTime? @map("expires_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
sessionId String @map("session_id") @db.VarChar(36)
|
||||
userId String @map("user_id") @db.VarChar(36)
|
||||
expiresAt DateTime? @map("expires_at") @db.Timestamptz(6)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
|
||||
session Session @relation(fields: [sessionId], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
@@ -81,10 +81,10 @@ model UserSession {
|
||||
}
|
||||
|
||||
model VerificationToken {
|
||||
token String @db.VarChar
|
||||
token String @db.VarChar(36)
|
||||
type Int @db.SmallInt
|
||||
credential String? @db.Text
|
||||
expiresAt DateTime @db.Timestamp(3)
|
||||
expiresAt DateTime @db.Timestamptz(6)
|
||||
|
||||
@@unique([type, token])
|
||||
@@map("verification_tokens")
|
||||
@@ -93,12 +93,12 @@ model VerificationToken {
|
||||
model Workspace {
|
||||
id String @id @default(uuid()) @db.VarChar
|
||||
public Boolean
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
|
||||
pages WorkspacePage[]
|
||||
permissions WorkspaceUserPermission[]
|
||||
pagePermissions WorkspacePageUserPermission[]
|
||||
features WorkspaceFeature[]
|
||||
features WorkspaceFeatures[]
|
||||
|
||||
@@map("workspaces")
|
||||
}
|
||||
@@ -109,8 +109,8 @@ model Workspace {
|
||||
// Only the ones that have ever changed will have records here,
|
||||
// and for others we will make sure it's has a default value return in our bussiness logic.
|
||||
model WorkspacePage {
|
||||
workspaceId String @map("workspace_id") @db.VarChar
|
||||
pageId String @map("page_id") @db.VarChar
|
||||
workspaceId String @map("workspace_id") @db.VarChar(36)
|
||||
pageId String @map("page_id") @db.VarChar(36)
|
||||
public Boolean @default(false)
|
||||
// Page/Edgeless
|
||||
mode Int @default(0) @db.SmallInt
|
||||
@@ -121,15 +121,31 @@ model WorkspacePage {
|
||||
@@map("workspace_pages")
|
||||
}
|
||||
|
||||
model WorkspaceUserPermission {
|
||||
// @deprecated, use WorkspaceUserPermission
|
||||
model DeprecatedUserWorkspacePermission {
|
||||
id String @id @default(uuid()) @db.VarChar
|
||||
workspaceId String @map("workspace_id") @db.VarChar
|
||||
userId String @map("user_id") @db.VarChar
|
||||
subPageId String? @map("sub_page_id") @db.VarChar
|
||||
userId String? @map("entity_id") @db.VarChar
|
||||
/// Read/Write/Admin/Owner
|
||||
type Int @db.SmallInt
|
||||
/// Whether the permission invitation is accepted by the user
|
||||
accepted Boolean @default(false)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
|
||||
@@unique([workspaceId, subPageId, userId])
|
||||
@@map("user_workspace_permissions")
|
||||
}
|
||||
|
||||
model WorkspaceUserPermission {
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
workspaceId String @map("workspace_id") @db.VarChar(36)
|
||||
userId String @map("user_id") @db.VarChar(36)
|
||||
// Read/Write
|
||||
type Int @db.SmallInt
|
||||
/// Whether the permission invitation is accepted by the user
|
||||
accepted Boolean @default(false)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
||||
@@ -139,15 +155,15 @@ model WorkspaceUserPermission {
|
||||
}
|
||||
|
||||
model WorkspacePageUserPermission {
|
||||
id String @id @default(uuid()) @db.VarChar
|
||||
workspaceId String @map("workspace_id") @db.VarChar
|
||||
pageId String @map("page_id") @db.VarChar
|
||||
userId String @map("user_id") @db.VarChar
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
workspaceId String @map("workspace_id") @db.VarChar(36)
|
||||
pageId String @map("page_id") @db.VarChar(36)
|
||||
userId String @map("user_id") @db.VarChar(36)
|
||||
// Read/Write
|
||||
type Int @db.SmallInt
|
||||
/// Whether the permission invitation is accepted by the user
|
||||
accepted Boolean @default(false)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
||||
@@ -160,9 +176,9 @@ model WorkspacePageUserPermission {
|
||||
// for example:
|
||||
// - early access is a feature that allow some users to access the insider version
|
||||
// - pro plan is a quota that allow some users access to more resources after they pay
|
||||
model UserFeature {
|
||||
model UserFeatures {
|
||||
id Int @id @default(autoincrement())
|
||||
userId String @map("user_id") @db.VarChar
|
||||
userId String @map("user_id") @db.VarChar(36)
|
||||
featureId Int @map("feature_id") @db.Integer
|
||||
|
||||
// we will record the reason why the feature is enabled/disabled
|
||||
@@ -170,16 +186,16 @@ model UserFeature {
|
||||
// - pro_plan_v1: "user buy the pro plan"
|
||||
reason String @db.VarChar
|
||||
// record the quota enabled time
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
// record the quota expired time, pay plan is a subscription, so it will expired
|
||||
expiredAt DateTime? @map("expired_at") @db.Timestamp(3)
|
||||
expiredAt DateTime? @map("expired_at") @db.Timestamptz(6)
|
||||
// whether the feature is activated
|
||||
// for example:
|
||||
// - if we switch the user to another plan, we will set the old plan to deactivated, but dont delete it
|
||||
activated Boolean @default(false)
|
||||
|
||||
feature Feature @relation(fields: [featureId], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
feature Features @relation(fields: [featureId], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([userId])
|
||||
@@map("user_features")
|
||||
@@ -188,9 +204,9 @@ model UserFeature {
|
||||
// feature gates is a way to enable/disable features for a workspace
|
||||
// for example:
|
||||
// - copilet is a feature that allow some users in a workspace to access the copilet feature
|
||||
model WorkspaceFeature {
|
||||
model WorkspaceFeatures {
|
||||
id Int @id @default(autoincrement())
|
||||
workspaceId String @map("workspace_id") @db.VarChar
|
||||
workspaceId String @map("workspace_id") @db.VarChar(36)
|
||||
featureId Int @map("feature_id") @db.Integer
|
||||
|
||||
// we will record the reason why the feature is enabled/disabled
|
||||
@@ -198,21 +214,21 @@ model WorkspaceFeature {
|
||||
// - copilet_v1: "owner buy the copilet feature package"
|
||||
reason String @db.VarChar
|
||||
// record the feature enabled time
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
// record the quota expired time, pay plan is a subscription, so it will expired
|
||||
expiredAt DateTime? @map("expired_at") @db.Timestamp(3)
|
||||
expiredAt DateTime? @map("expired_at") @db.Timestamptz(6)
|
||||
// whether the feature is activated
|
||||
// for example:
|
||||
// - if owner unsubscribe a feature package, we will set the feature to deactivated, but dont delete it
|
||||
activated Boolean @default(false)
|
||||
|
||||
feature Feature @relation(fields: [featureId], references: [id], onDelete: Cascade)
|
||||
feature Features @relation(fields: [featureId], references: [id], onDelete: Cascade)
|
||||
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@map("workspace_features")
|
||||
}
|
||||
|
||||
model Feature {
|
||||
model Features {
|
||||
id Int @id @default(autoincrement())
|
||||
feature String @db.VarChar
|
||||
version Int @default(0) @db.Integer
|
||||
@@ -220,15 +236,82 @@ model Feature {
|
||||
type Int @db.Integer
|
||||
// configs, define by feature conntroller
|
||||
configs Json @db.Json
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
|
||||
UserFeatureGates UserFeature[]
|
||||
WorkspaceFeatures WorkspaceFeature[]
|
||||
UserFeatureGates UserFeatures[]
|
||||
WorkspaceFeatures WorkspaceFeatures[]
|
||||
|
||||
@@unique([feature, version])
|
||||
@@map("features")
|
||||
}
|
||||
|
||||
model DeprecatedNextAuthAccount {
|
||||
id String @id @default(cuid())
|
||||
userId String @map("user_id")
|
||||
type String
|
||||
provider String
|
||||
providerAccountId String @map("provider_account_id")
|
||||
refresh_token String? @db.Text
|
||||
access_token String? @db.Text
|
||||
expires_at Int?
|
||||
token_type String?
|
||||
scope String?
|
||||
id_token String? @db.Text
|
||||
session_state String?
|
||||
|
||||
@@unique([provider, providerAccountId])
|
||||
@@map("accounts")
|
||||
}
|
||||
|
||||
model DeprecatedNextAuthSession {
|
||||
id String @id @default(cuid())
|
||||
sessionToken String @unique @map("session_token")
|
||||
userId String @map("user_id")
|
||||
expires DateTime
|
||||
|
||||
@@map("sessions")
|
||||
}
|
||||
|
||||
model DeprecatedNextAuthVerificationToken {
|
||||
identifier String
|
||||
token String @unique
|
||||
expires DateTime
|
||||
|
||||
@@unique([identifier, token])
|
||||
@@map("verificationtokens")
|
||||
}
|
||||
|
||||
// deprecated, use [ObjectStorage]
|
||||
model Blob {
|
||||
id Int @id @default(autoincrement()) @db.Integer
|
||||
hash String @db.VarChar
|
||||
workspaceId String @map("workspace_id") @db.VarChar
|
||||
blob Bytes @db.ByteA
|
||||
length BigInt
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
// not for keeping, but for snapshot history
|
||||
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
|
||||
|
||||
@@unique([workspaceId, hash])
|
||||
@@map("blobs")
|
||||
}
|
||||
|
||||
// deprecated, use [ObjectStorage]
|
||||
model OptimizedBlob {
|
||||
id Int @id @default(autoincrement()) @db.Integer
|
||||
hash String @db.VarChar
|
||||
workspaceId String @map("workspace_id") @db.VarChar
|
||||
params String @db.VarChar
|
||||
blob Bytes @db.ByteA
|
||||
length BigInt
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
// not for keeping, but for snapshot history
|
||||
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
|
||||
|
||||
@@unique([workspaceId, hash, params])
|
||||
@@map("optimized_blobs")
|
||||
}
|
||||
|
||||
// the latest snapshot of each doc that we've seen
|
||||
// Snapshot + Updates are the latest state of the doc
|
||||
model Snapshot {
|
||||
@@ -237,10 +320,10 @@ model Snapshot {
|
||||
blob Bytes @db.ByteA
|
||||
seq Int @default(0) @db.Integer
|
||||
state Bytes? @db.ByteA
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
// the `updated_at` field will not record the time of record changed,
|
||||
// but the created time of last seen update that has been merged into snapshot.
|
||||
updatedAt DateTime @map("updated_at") @db.Timestamp(3)
|
||||
updatedAt DateTime @map("updated_at") @db.Timestamptz(6)
|
||||
|
||||
@@id([id, workspaceId])
|
||||
@@map("snapshots")
|
||||
@@ -251,28 +334,37 @@ model Update {
|
||||
id String @map("guid") @db.VarChar
|
||||
seq Int @db.Integer
|
||||
blob Bytes @db.ByteA
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
|
||||
@@id([workspaceId, id, seq])
|
||||
@@map("updates")
|
||||
}
|
||||
|
||||
model SnapshotHistory {
|
||||
workspaceId String @map("workspace_id") @db.VarChar
|
||||
id String @map("guid") @db.VarChar
|
||||
timestamp DateTime @db.Timestamp(3)
|
||||
workspaceId String @map("workspace_id") @db.VarChar(36)
|
||||
id String @map("guid") @db.VarChar(36)
|
||||
timestamp DateTime @db.Timestamptz(6)
|
||||
blob Bytes @db.ByteA
|
||||
state Bytes? @db.ByteA
|
||||
expiredAt DateTime @map("expired_at") @db.Timestamp(3)
|
||||
expiredAt DateTime @map("expired_at") @db.Timestamptz(6)
|
||||
|
||||
@@id([workspaceId, id, timestamp])
|
||||
@@map("snapshot_histories")
|
||||
}
|
||||
|
||||
model NewFeaturesWaitingList {
|
||||
id String @id @default(uuid()) @db.VarChar
|
||||
email String @unique
|
||||
type Int @db.SmallInt
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
|
||||
@@map("new_features_waiting_list")
|
||||
}
|
||||
|
||||
model UserStripeCustomer {
|
||||
userId String @id @map("user_id") @db.VarChar
|
||||
stripeCustomerId String @unique @map("stripe_customer_id") @db.VarChar
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@ -281,7 +373,7 @@ model UserStripeCustomer {
|
||||
|
||||
model UserSubscription {
|
||||
id Int @id @default(autoincrement()) @db.Integer
|
||||
userId String @map("user_id") @db.VarChar
|
||||
userId String @map("user_id") @db.VarChar(36)
|
||||
plan String @db.VarChar(20)
|
||||
// yearly/monthly
|
||||
recurring String @db.VarChar(20)
|
||||
@@ -290,21 +382,21 @@ model UserSubscription {
|
||||
// subscription.status, active/past_due/canceled/unpaid...
|
||||
status String @db.VarChar(20)
|
||||
// subscription.current_period_start
|
||||
start DateTime @map("start") @db.Timestamp(3)
|
||||
start DateTime @map("start") @db.Timestamptz(6)
|
||||
// subscription.current_period_end, null for lifetime payment
|
||||
end DateTime? @map("end") @db.Timestamp(3)
|
||||
end DateTime? @map("end") @db.Timestamptz(6)
|
||||
// subscription.billing_cycle_anchor
|
||||
nextBillAt DateTime? @map("next_bill_at") @db.Timestamp(3)
|
||||
nextBillAt DateTime? @map("next_bill_at") @db.Timestamptz(6)
|
||||
// subscription.canceled_at
|
||||
canceledAt DateTime? @map("canceled_at") @db.Timestamp(3)
|
||||
canceledAt DateTime? @map("canceled_at") @db.Timestamptz(6)
|
||||
// subscription.trial_start
|
||||
trialStart DateTime? @map("trial_start") @db.Timestamp(3)
|
||||
trialStart DateTime? @map("trial_start") @db.Timestamptz(6)
|
||||
// subscription.trial_end
|
||||
trialEnd DateTime? @map("trial_end") @db.Timestamp(3)
|
||||
trialEnd DateTime? @map("trial_end") @db.Timestamptz(6)
|
||||
stripeScheduleId String? @map("stripe_schedule_id") @db.VarChar
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([userId, plan])
|
||||
@@ -313,7 +405,7 @@ model UserSubscription {
|
||||
|
||||
model UserInvoice {
|
||||
id Int @id @default(autoincrement()) @db.Integer
|
||||
userId String @map("user_id") @db.VarChar
|
||||
userId String @map("user_id") @db.VarChar(36)
|
||||
stripeInvoiceId String @unique @map("stripe_invoice_id")
|
||||
currency String @db.VarChar(3)
|
||||
// CNY 12.50 stored as 1250
|
||||
@@ -321,8 +413,8 @@ model UserInvoice {
|
||||
status String @db.VarChar(20)
|
||||
plan String @db.VarChar(20)
|
||||
recurring String @db.VarChar(20)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
// billing reason
|
||||
reason String @db.VarChar
|
||||
lastPaymentError String? @map("last_payment_error") @db.Text
|
||||
@@ -350,7 +442,7 @@ model AiPromptMessage {
|
||||
content String @db.Text
|
||||
attachments Json? @db.Json
|
||||
params Json? @db.Json
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
|
||||
prompt AiPrompt @relation(fields: [promptId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@ -366,7 +458,7 @@ model AiPrompt {
|
||||
action String? @db.VarChar
|
||||
model String @db.VarChar
|
||||
config Json? @db.Json
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
|
||||
messages AiPromptMessage[]
|
||||
sessions AiSession[]
|
||||
@@ -375,14 +467,14 @@ model AiPrompt {
|
||||
}
|
||||
|
||||
model AiSessionMessage {
|
||||
id String @id @default(uuid()) @db.VarChar
|
||||
sessionId String @map("session_id") @db.VarChar
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
sessionId String @map("session_id") @db.VarChar(36)
|
||||
role AiPromptRole
|
||||
content String @db.Text
|
||||
attachments Json? @db.Json
|
||||
params Json? @db.Json
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
|
||||
session AiSession @relation(fields: [sessionId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@ -390,17 +482,17 @@ model AiSessionMessage {
|
||||
}
|
||||
|
||||
model AiSession {
|
||||
id String @id @default(uuid()) @db.VarChar
|
||||
userId String @map("user_id") @db.VarChar
|
||||
workspaceId String @map("workspace_id") @db.VarChar
|
||||
docId String @map("doc_id") @db.VarChar
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
userId String @map("user_id") @db.VarChar(36)
|
||||
workspaceId String @map("workspace_id") @db.VarChar(36)
|
||||
docId String @map("doc_id") @db.VarChar(36)
|
||||
promptName String @map("prompt_name") @db.VarChar(32)
|
||||
// the session id of the parent session if this session is a forked session
|
||||
parentSessionId String? @map("parent_session_id") @db.VarChar
|
||||
parentSessionId String? @map("parent_session_id") @db.VarChar(36)
|
||||
messageCost Int @default(0)
|
||||
tokenCost Int @default(0)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(3)
|
||||
deletedAt DateTime? @map("deleted_at") @db.Timestamp(3)
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6)
|
||||
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
prompt AiPrompt @relation(fields: [promptName], references: [name], onDelete: Cascade)
|
||||
@@ -410,10 +502,10 @@ model AiSession {
|
||||
}
|
||||
|
||||
model DataMigration {
|
||||
id String @id @default(uuid()) @db.VarChar
|
||||
id String @id @default(uuid()) @db.VarChar(36)
|
||||
name String @db.VarChar
|
||||
startedAt DateTime @default(now()) @map("started_at") @db.Timestamp(3)
|
||||
finishedAt DateTime? @map("finished_at") @db.Timestamp(3)
|
||||
startedAt DateTime @default(now()) @map("started_at") @db.Timestamptz(6)
|
||||
finishedAt DateTime? @map("finished_at") @db.Timestamptz(6)
|
||||
|
||||
@@map("_data_migrations")
|
||||
}
|
||||
@@ -433,9 +525,9 @@ model RuntimeConfig {
|
||||
key String @db.VarChar
|
||||
value Json @db.Json
|
||||
description String @db.Text
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamp(3)
|
||||
deletedAt DateTime? @map("deleted_at") @db.Timestamp(3)
|
||||
lastUpdatedBy String? @map("last_updated_by") @db.VarChar
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(6)
|
||||
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(6)
|
||||
lastUpdatedBy String? @map("last_updated_by") @db.VarChar(36)
|
||||
|
||||
lastUpdatedByUser User? @relation(fields: [lastUpdatedBy], references: [id])
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ export async function getFeature(prisma: PrismaTransaction, featureId: number) {
|
||||
return cachedFeature;
|
||||
}
|
||||
|
||||
const feature = await prisma.feature.findFirst({
|
||||
const feature = await prisma.features.findFirst({
|
||||
where: {
|
||||
id: featureId,
|
||||
},
|
||||
|
||||
@@ -10,7 +10,7 @@ export class FeatureService {
|
||||
constructor(private readonly prisma: PrismaClient) {}
|
||||
|
||||
async getFeature<F extends FeatureType>(feature: F) {
|
||||
const data = await this.prisma.feature.findFirst({
|
||||
const data = await this.prisma.features.findFirst({
|
||||
where: {
|
||||
feature,
|
||||
type: FeatureKind.Feature,
|
||||
@@ -36,7 +36,7 @@ export class FeatureService {
|
||||
expiredAt?: Date | string
|
||||
) {
|
||||
return this.prisma.$transaction(async tx => {
|
||||
const latestFlag = await tx.userFeature.findFirst({
|
||||
const latestFlag = await tx.userFeatures.findFirst({
|
||||
where: {
|
||||
userId,
|
||||
feature: {
|
||||
@@ -53,7 +53,7 @@ export class FeatureService {
|
||||
if (latestFlag) {
|
||||
return latestFlag.id;
|
||||
} else {
|
||||
const featureId = await tx.feature
|
||||
const featureId = await tx.features
|
||||
.findFirst({
|
||||
where: { feature, type: FeatureKind.Feature },
|
||||
orderBy: { version: 'desc' },
|
||||
@@ -65,7 +65,7 @@ export class FeatureService {
|
||||
throw new Error(`Feature ${feature} not found`);
|
||||
}
|
||||
|
||||
return tx.userFeature
|
||||
return tx.userFeatures
|
||||
.create({
|
||||
data: {
|
||||
reason,
|
||||
@@ -81,7 +81,7 @@ export class FeatureService {
|
||||
}
|
||||
|
||||
async removeUserFeature(userId: string, feature: FeatureType) {
|
||||
return this.prisma.userFeature
|
||||
return this.prisma.userFeatures
|
||||
.updateMany({
|
||||
where: {
|
||||
userId,
|
||||
@@ -104,7 +104,7 @@ export class FeatureService {
|
||||
* @returns list of features
|
||||
*/
|
||||
async getUserFeatures(userId: string) {
|
||||
const features = await this.prisma.userFeature.findMany({
|
||||
const features = await this.prisma.userFeatures.findMany({
|
||||
where: {
|
||||
userId,
|
||||
feature: { type: FeatureKind.Feature },
|
||||
@@ -129,7 +129,7 @@ export class FeatureService {
|
||||
}
|
||||
|
||||
async getActivatedUserFeatures(userId: string) {
|
||||
const features = await this.prisma.userFeature.findMany({
|
||||
const features = await this.prisma.userFeatures.findMany({
|
||||
where: {
|
||||
userId,
|
||||
feature: { type: FeatureKind.Feature },
|
||||
@@ -156,7 +156,7 @@ export class FeatureService {
|
||||
}
|
||||
|
||||
async listFeatureUsers(feature: FeatureType) {
|
||||
return this.prisma.userFeature
|
||||
return this.prisma.userFeatures
|
||||
.findMany({
|
||||
where: {
|
||||
activated: true,
|
||||
@@ -182,7 +182,7 @@ export class FeatureService {
|
||||
}
|
||||
|
||||
async hasUserFeature(userId: string, feature: FeatureType) {
|
||||
return this.prisma.userFeature
|
||||
return this.prisma.userFeatures
|
||||
.count({
|
||||
where: {
|
||||
userId,
|
||||
@@ -206,7 +206,7 @@ export class FeatureService {
|
||||
expiredAt?: Date | string
|
||||
) {
|
||||
return this.prisma.$transaction(async tx => {
|
||||
const latestFlag = await tx.workspaceFeature.findFirst({
|
||||
const latestFlag = await tx.workspaceFeatures.findFirst({
|
||||
where: {
|
||||
workspaceId,
|
||||
feature: {
|
||||
@@ -223,7 +223,7 @@ export class FeatureService {
|
||||
return latestFlag.id;
|
||||
} else {
|
||||
// use latest version of feature
|
||||
const featureId = await tx.feature
|
||||
const featureId = await tx.features
|
||||
.findFirst({
|
||||
where: { feature, type: FeatureKind.Feature },
|
||||
select: { id: true },
|
||||
@@ -235,7 +235,7 @@ export class FeatureService {
|
||||
throw new Error(`Feature ${feature} not found`);
|
||||
}
|
||||
|
||||
return tx.workspaceFeature
|
||||
return tx.workspaceFeatures
|
||||
.create({
|
||||
data: {
|
||||
reason,
|
||||
@@ -251,7 +251,7 @@ export class FeatureService {
|
||||
}
|
||||
|
||||
async removeWorkspaceFeature(workspaceId: string, feature: FeatureType) {
|
||||
return this.prisma.workspaceFeature
|
||||
return this.prisma.workspaceFeatures
|
||||
.updateMany({
|
||||
where: {
|
||||
workspaceId,
|
||||
@@ -274,7 +274,7 @@ export class FeatureService {
|
||||
* @returns list of features
|
||||
*/
|
||||
async getWorkspaceFeatures(workspaceId: string) {
|
||||
const features = await this.prisma.workspaceFeature.findMany({
|
||||
const features = await this.prisma.workspaceFeatures.findMany({
|
||||
where: {
|
||||
workspace: { id: workspaceId },
|
||||
feature: {
|
||||
@@ -301,7 +301,7 @@ export class FeatureService {
|
||||
}
|
||||
|
||||
async listFeatureWorkspaces(feature: FeatureType): Promise<WorkspaceType[]> {
|
||||
return this.prisma.workspaceFeature
|
||||
return this.prisma.workspaceFeatures
|
||||
.findMany({
|
||||
where: {
|
||||
activated: true,
|
||||
@@ -324,7 +324,7 @@ export class FeatureService {
|
||||
}
|
||||
|
||||
async hasWorkspaceFeature(workspaceId: string, feature: FeatureType) {
|
||||
return this.prisma.workspaceFeature
|
||||
return this.prisma.workspaceFeatures
|
||||
.count({
|
||||
where: {
|
||||
workspaceId,
|
||||
|
||||
@@ -13,7 +13,7 @@ export class QuotaConfig {
|
||||
return cachedQuota;
|
||||
}
|
||||
|
||||
const quota = await tx.feature.findFirst({
|
||||
const quota = await tx.features.findFirst({
|
||||
where: {
|
||||
id: featureId,
|
||||
},
|
||||
|
||||
@@ -17,7 +17,7 @@ export class QuotaService {
|
||||
|
||||
// get activated user quota
|
||||
async getUserQuota(userId: string) {
|
||||
const quota = await this.prisma.userFeature.findFirst({
|
||||
const quota = await this.prisma.userFeatures.findFirst({
|
||||
where: {
|
||||
userId,
|
||||
feature: {
|
||||
@@ -44,7 +44,7 @@ export class QuotaService {
|
||||
|
||||
// get user all quota records
|
||||
async getUserQuotas(userId: string) {
|
||||
const quotas = await this.prisma.userFeature.findMany({
|
||||
const quotas = await this.prisma.userFeatures.findMany({
|
||||
where: {
|
||||
userId,
|
||||
feature: {
|
||||
@@ -58,9 +58,6 @@ export class QuotaService {
|
||||
expiredAt: true,
|
||||
featureId: true,
|
||||
},
|
||||
orderBy: {
|
||||
id: 'asc',
|
||||
},
|
||||
});
|
||||
const configs = await Promise.all(
|
||||
quotas.map(async quota => {
|
||||
@@ -95,7 +92,7 @@ export class QuotaService {
|
||||
return;
|
||||
}
|
||||
|
||||
const featureId = await tx.feature
|
||||
const featureId = await tx.features
|
||||
.findFirst({
|
||||
where: { feature: quota, type: FeatureKind.Quota },
|
||||
select: { id: true },
|
||||
@@ -108,7 +105,7 @@ export class QuotaService {
|
||||
}
|
||||
|
||||
// we will deactivate all exists quota for this user
|
||||
await tx.userFeature.updateMany({
|
||||
await tx.userFeatures.updateMany({
|
||||
where: {
|
||||
id: undefined,
|
||||
userId,
|
||||
@@ -121,7 +118,7 @@ export class QuotaService {
|
||||
},
|
||||
});
|
||||
|
||||
await tx.userFeature.create({
|
||||
await tx.userFeatures.create({
|
||||
data: {
|
||||
userId,
|
||||
featureId,
|
||||
@@ -136,7 +133,7 @@ export class QuotaService {
|
||||
async hasQuota(userId: string, quota: QuotaType, tx?: PrismaTransaction) {
|
||||
const executor = tx ?? this.prisma;
|
||||
|
||||
return executor.userFeature
|
||||
return executor.userFeatures
|
||||
.count({
|
||||
where: {
|
||||
userId,
|
||||
|
||||
@@ -2,7 +2,7 @@ import { PrismaClient } from '@prisma/client';
|
||||
|
||||
import { Features } from '../../core/features';
|
||||
import { Quotas } from '../../core/quota/schema';
|
||||
import { upsertFeature } from './utils/user-features';
|
||||
import { migrateNewFeatureTable, upsertFeature } from './utils/user-features';
|
||||
|
||||
export class UserFeaturesInit1698652531198 {
|
||||
// do the migration
|
||||
@@ -11,6 +11,7 @@ export class UserFeaturesInit1698652531198 {
|
||||
for (const feature of Features) {
|
||||
await upsertFeature(db, feature);
|
||||
}
|
||||
await migrateNewFeatureTable(db);
|
||||
|
||||
for (const quota of Quotas) {
|
||||
await upsertFeature(db, quota);
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
export class PagePermission1699005339766 {
|
||||
// do the migration
|
||||
static async up(db: PrismaClient) {
|
||||
let turn = 0;
|
||||
let lastTurnCount = 50;
|
||||
const done = new Set<string>();
|
||||
|
||||
while (lastTurnCount === 50) {
|
||||
const workspaces = await db.workspace.findMany({
|
||||
skip: turn * 50,
|
||||
take: 50,
|
||||
orderBy: {
|
||||
createdAt: 'asc',
|
||||
},
|
||||
});
|
||||
lastTurnCount = workspaces.length;
|
||||
|
||||
for (const workspace of workspaces) {
|
||||
if (done.has(workspace.id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const oldPermissions =
|
||||
await db.deprecatedUserWorkspacePermission.findMany({
|
||||
where: {
|
||||
workspaceId: workspace.id,
|
||||
},
|
||||
});
|
||||
|
||||
for (const oldPermission of oldPermissions) {
|
||||
// mark subpage public
|
||||
if (oldPermission.subPageId) {
|
||||
const existed = await db.workspacePage.findUnique({
|
||||
where: {
|
||||
workspaceId_pageId: {
|
||||
workspaceId: oldPermission.workspaceId,
|
||||
pageId: oldPermission.subPageId,
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!existed) {
|
||||
await db.workspacePage.create({
|
||||
select: null,
|
||||
data: {
|
||||
workspaceId: oldPermission.workspaceId,
|
||||
pageId: oldPermission.subPageId,
|
||||
public: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
} else if (oldPermission.userId) {
|
||||
// workspace user permission
|
||||
const existed = await db.workspaceUserPermission.findUnique({
|
||||
where: {
|
||||
id: oldPermission.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (!existed) {
|
||||
await db.workspaceUserPermission
|
||||
.create({
|
||||
select: null,
|
||||
data: {
|
||||
// this id is used at invite email, should keep
|
||||
id: oldPermission.id,
|
||||
workspaceId: oldPermission.workspaceId,
|
||||
userId: oldPermission.userId,
|
||||
type: oldPermission.type,
|
||||
accepted: oldPermission.accepted,
|
||||
},
|
||||
})
|
||||
.catch(() => {
|
||||
// duplicated
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// ignore wrong data
|
||||
}
|
||||
}
|
||||
|
||||
done.add(workspace.id);
|
||||
}
|
||||
|
||||
turn++;
|
||||
}
|
||||
}
|
||||
|
||||
// revert the migration
|
||||
static async down(db: PrismaClient) {
|
||||
await db.workspaceUserPermission.deleteMany({});
|
||||
await db.workspacePageUserPermission.deleteMany({});
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ export class OldUserFeature1702620653283 {
|
||||
// do the migration
|
||||
static async up(db: PrismaClient) {
|
||||
await db.$transaction(async tx => {
|
||||
const latestFreePlan = await tx.feature.findFirstOrThrow({
|
||||
const latestFreePlan = await tx.features.findFirstOrThrow({
|
||||
where: { feature: QuotaType.FreePlanV1 },
|
||||
orderBy: { version: 'desc' },
|
||||
select: { id: true },
|
||||
@@ -17,7 +17,7 @@ export class OldUserFeature1702620653283 {
|
||||
select: { id: true },
|
||||
});
|
||||
|
||||
await tx.userFeature.createMany({
|
||||
await tx.userFeatures.createMany({
|
||||
data: userIds.map(({ id: userId }) => ({
|
||||
userId,
|
||||
featureId: latestFreePlan.id,
|
||||
@@ -31,6 +31,6 @@ export class OldUserFeature1702620653283 {
|
||||
// revert the migration
|
||||
// WARN: this will drop all user features
|
||||
static async down(db: PrismaClient) {
|
||||
await db.userFeature.deleteMany({});
|
||||
await db.userFeatures.deleteMany({});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { ModuleRef } from '@nestjs/core';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
import { WorkspaceBlobStorage } from '../../core/storage';
|
||||
|
||||
export class WorkspaceBlobs1703828796699 {
|
||||
// do the migration
|
||||
static async up(db: PrismaClient, injector: ModuleRef) {
|
||||
const blobStorage = injector.get(WorkspaceBlobStorage, { strict: false });
|
||||
let hasMore = true;
|
||||
let turn = 0;
|
||||
const eachTurnCount = 50;
|
||||
|
||||
while (hasMore) {
|
||||
const blobs = await db.blob.findMany({
|
||||
skip: turn * eachTurnCount,
|
||||
take: eachTurnCount,
|
||||
orderBy: {
|
||||
createdAt: 'asc',
|
||||
},
|
||||
});
|
||||
|
||||
hasMore = blobs.length === eachTurnCount;
|
||||
turn += 1;
|
||||
|
||||
await Promise.all(
|
||||
blobs.map(async ({ workspaceId, hash, blob }) =>
|
||||
blobStorage.put(workspaceId, hash, blob)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// revert the migration
|
||||
static async down(_db: PrismaClient) {
|
||||
// old data kept, no need to downgrade the migration
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
import { loop } from './utils/loop';
|
||||
|
||||
export class Oauth1710319359062 {
|
||||
// do the migration
|
||||
static async up(db: PrismaClient) {
|
||||
await loop(async (skip, take) => {
|
||||
const oldRecords = await db.deprecatedNextAuthAccount.findMany({
|
||||
skip,
|
||||
take,
|
||||
orderBy: {
|
||||
providerAccountId: 'asc',
|
||||
},
|
||||
});
|
||||
|
||||
await db.connectedAccount.createMany({
|
||||
data: oldRecords.map(record => ({
|
||||
userId: record.userId,
|
||||
provider: record.provider,
|
||||
scope: record.scope,
|
||||
providerAccountId: record.providerAccountId,
|
||||
accessToken: record.access_token,
|
||||
refreshToken: record.refresh_token,
|
||||
expiresAt: record.expires_at
|
||||
? new Date(record.expires_at * 1000)
|
||||
: null,
|
||||
})),
|
||||
});
|
||||
|
||||
return oldRecords.length;
|
||||
}, 10);
|
||||
}
|
||||
|
||||
// revert the migration
|
||||
static async down(db: PrismaClient) {
|
||||
await db.connectedAccount.deleteMany({});
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
import { Prisma, PrismaClient } from '@prisma/client';
|
||||
|
||||
import { CommonFeature, Features, FeatureType } from '../../../core/features';
|
||||
import {
|
||||
CommonFeature,
|
||||
FeatureKind,
|
||||
Features,
|
||||
FeatureType,
|
||||
} from '../../../core/features';
|
||||
|
||||
// upgrade features from lower version to higher version
|
||||
export async function upsertFeature(
|
||||
@@ -8,7 +13,7 @@ export async function upsertFeature(
|
||||
feature: CommonFeature
|
||||
): Promise<void> {
|
||||
const hasEqualOrGreaterVersion =
|
||||
(await db.feature.count({
|
||||
(await db.features.count({
|
||||
where: {
|
||||
feature: feature.feature,
|
||||
version: {
|
||||
@@ -18,7 +23,7 @@ export async function upsertFeature(
|
||||
})) > 0;
|
||||
// will not update exists version
|
||||
if (!hasEqualOrGreaterVersion) {
|
||||
await db.feature.create({
|
||||
await db.features.create({
|
||||
data: {
|
||||
feature: feature.feature,
|
||||
type: feature.type,
|
||||
@@ -38,3 +43,66 @@ export async function upsertLatestFeatureVersion(
|
||||
const latestFeature = feature[0];
|
||||
await upsertFeature(db, latestFeature);
|
||||
}
|
||||
|
||||
export async function migrateNewFeatureTable(prisma: PrismaClient) {
|
||||
const waitingList = await prisma.newFeaturesWaitingList.findMany();
|
||||
const latestEarlyAccessFeatureId = await prisma.features
|
||||
.findFirst({
|
||||
where: { feature: FeatureType.EarlyAccess, type: FeatureKind.Feature },
|
||||
select: { id: true },
|
||||
orderBy: { version: 'desc' },
|
||||
})
|
||||
.then(r => r?.id);
|
||||
if (!latestEarlyAccessFeatureId) {
|
||||
throw new Error('Feature EarlyAccess not found');
|
||||
}
|
||||
for (const oldUser of waitingList) {
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
email: oldUser.email,
|
||||
},
|
||||
});
|
||||
if (user) {
|
||||
const hasEarlyAccess = await prisma.userFeatures.count({
|
||||
where: {
|
||||
userId: user.id,
|
||||
feature: {
|
||||
feature: FeatureType.EarlyAccess,
|
||||
},
|
||||
activated: true,
|
||||
},
|
||||
});
|
||||
if (hasEarlyAccess === 0) {
|
||||
await prisma.$transaction(async tx => {
|
||||
const latestFlag = await tx.userFeatures.findFirst({
|
||||
where: {
|
||||
userId: user.id,
|
||||
feature: {
|
||||
feature: FeatureType.EarlyAccess,
|
||||
type: FeatureKind.Feature,
|
||||
},
|
||||
activated: true,
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: 'desc',
|
||||
},
|
||||
});
|
||||
if (latestFlag) {
|
||||
return latestFlag.id;
|
||||
} else {
|
||||
return tx.userFeatures
|
||||
.create({
|
||||
data: {
|
||||
reason: 'Early access user',
|
||||
activated: true,
|
||||
userId: user.id,
|
||||
featureId: latestEarlyAccessFeatureId,
|
||||
},
|
||||
})
|
||||
.then(r => r.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ export async function upgradeQuotaVersion(
|
||||
// migrate all users that using old quota to new quota
|
||||
await db.$transaction(
|
||||
async tx => {
|
||||
const latestQuotaVersion = await tx.feature.findFirstOrThrow({
|
||||
const latestQuotaVersion = await tx.features.findFirstOrThrow({
|
||||
where: { feature: quota.feature },
|
||||
orderBy: { version: 'desc' },
|
||||
select: { id: true },
|
||||
@@ -39,7 +39,7 @@ export async function upgradeQuotaVersion(
|
||||
});
|
||||
|
||||
// deactivate all old quota for the user
|
||||
await tx.userFeature.updateMany({
|
||||
await tx.userFeatures.updateMany({
|
||||
where: {
|
||||
id: undefined,
|
||||
userId: {
|
||||
@@ -55,7 +55,7 @@ export async function upgradeQuotaVersion(
|
||||
},
|
||||
});
|
||||
|
||||
await tx.userFeature.createMany({
|
||||
await tx.userFeatures.createMany({
|
||||
data: userIds.map(({ id: userId }) => ({
|
||||
userId,
|
||||
featureId: latestQuotaVersion.id,
|
||||
|
||||
@@ -84,17 +84,17 @@ export class SubscriptionService {
|
||||
private readonly db: PrismaClient,
|
||||
private readonly scheduleManager: ScheduleManager,
|
||||
private readonly event: EventEmitter,
|
||||
private readonly feature: FeatureManagementService
|
||||
private readonly features: FeatureManagementService
|
||||
) {}
|
||||
|
||||
async listPrices(user?: CurrentUser) {
|
||||
let canHaveEarlyAccessDiscount = false;
|
||||
let canHaveAIEarlyAccessDiscount = false;
|
||||
if (user) {
|
||||
canHaveEarlyAccessDiscount = await this.feature.isEarlyAccessUser(
|
||||
canHaveEarlyAccessDiscount = await this.features.isEarlyAccessUser(
|
||||
user.id
|
||||
);
|
||||
canHaveAIEarlyAccessDiscount = await this.feature.isEarlyAccessUser(
|
||||
canHaveAIEarlyAccessDiscount = await this.features.isEarlyAccessUser(
|
||||
user.id,
|
||||
EarlyAccessType.AI
|
||||
);
|
||||
@@ -181,7 +181,7 @@ export class SubscriptionService {
|
||||
if (
|
||||
this.config.deploy &&
|
||||
this.config.affine.canary &&
|
||||
!this.feature.isStaff(user.email)
|
||||
!this.features.isStaff(user.email)
|
||||
) {
|
||||
throw new ActionForbidden();
|
||||
}
|
||||
@@ -847,7 +847,7 @@ export class SubscriptionService {
|
||||
plan: SubscriptionPlan,
|
||||
recurring: SubscriptionRecurring
|
||||
): Promise<{ price: string; coupon?: string }> {
|
||||
const isEaUser = await this.feature.isEarlyAccessUser(customer.userId);
|
||||
const isEaUser = await this.features.isEarlyAccessUser(customer.userId);
|
||||
const oldSubscriptions = await this.stripe.subscriptions.list({
|
||||
customer: customer.stripeCustomerId,
|
||||
status: 'all',
|
||||
@@ -876,7 +876,7 @@ export class SubscriptionService {
|
||||
: undefined,
|
||||
};
|
||||
} else {
|
||||
const isAIEaUser = await this.feature.isEarlyAccessUser(
|
||||
const isAIEaUser = await this.features.isEarlyAccessUser(
|
||||
customer.userId,
|
||||
EarlyAccessType.AI
|
||||
);
|
||||
|
||||
@@ -129,13 +129,23 @@ export class AuthService extends Service {
|
||||
}
|
||||
|
||||
async signInPassword(credential: { email: string; password: string }) {
|
||||
const res = await this.fetchService.fetch('/api/auth/sign-in', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(credential),
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
});
|
||||
const searchParams = new URLSearchParams();
|
||||
const redirectUri = new URL(location.href);
|
||||
if (environment.isDesktop) {
|
||||
redirectUri.pathname = this.buildRedirectUri('/open-app/signin-redirect');
|
||||
}
|
||||
searchParams.set('redirect_uri', redirectUri.toString());
|
||||
|
||||
const res = await this.fetchService.fetch(
|
||||
'/api/auth/sign-in?' + searchParams.toString(),
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify(credential),
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
}
|
||||
);
|
||||
if (!res.ok) {
|
||||
throw new Error('Failed to sign in');
|
||||
}
|
||||
|
||||
@@ -5,9 +5,6 @@ import { fromPromise, Service } from '@toeverything/infra';
|
||||
import { BackendError, NetworkError } from '../error';
|
||||
|
||||
export function getAffineCloudBaseUrl(): string {
|
||||
if ((globalThis as any)['__AFFINE_CLOUD_BASE_URL__']) {
|
||||
return (globalThis as any)['__AFFINE_CLOUD_BASE_URL__'];
|
||||
}
|
||||
if (environment.isDesktop) {
|
||||
return runtimeConfig.serverUrlPrefix;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Location } from 'history';
|
||||
import { useEffect } from 'react';
|
||||
import { useEffect, useRef } from 'react';
|
||||
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
@@ -21,6 +21,7 @@ export function useBindWorkbenchToDesktopRouter(
|
||||
basename: string
|
||||
) {
|
||||
const browserLocation = useLocation();
|
||||
const firstNavigation = useRef(false);
|
||||
useEffect(() => {
|
||||
const newLocation = browserLocationToViewLocation(
|
||||
browserLocation,
|
||||
@@ -36,8 +37,19 @@ export function useBindWorkbenchToDesktopRouter(
|
||||
) {
|
||||
return;
|
||||
}
|
||||
workbench.open(newLocation);
|
||||
// skipping default location initialization since we will init the views
|
||||
// using WorkbenchDefaultState
|
||||
if (firstNavigation.current) {
|
||||
workbench.open(newLocation);
|
||||
}
|
||||
}, [basename, browserLocation, workbench]);
|
||||
|
||||
useEffect(() => {
|
||||
firstNavigation.current = true;
|
||||
return () => {
|
||||
firstNavigation.current = false;
|
||||
};
|
||||
}, []);
|
||||
}
|
||||
|
||||
function browserLocationToViewLocation(
|
||||
|
||||
@@ -10,9 +10,6 @@ import { gqlFetcherFactory } from './fetcher';
|
||||
setupGlobal();
|
||||
|
||||
export function getBaseUrl(): string {
|
||||
if ((globalThis as any)['__AFFINE_CLOUD_BASE_URL__']) {
|
||||
return (globalThis as any)['__AFFINE_CLOUD_BASE_URL__'];
|
||||
}
|
||||
if (environment.isDesktop) {
|
||||
return runtimeConfig.serverUrlPrefix;
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"name": "@affine/ios-bridge",
|
||||
"version": "0.0.0",
|
||||
"description": "AFFiNE API For iOS app",
|
||||
"private": true,
|
||||
"browser": "src/index.ts",
|
||||
"scripts": {
|
||||
"build": "DISTRIBUTION=ios-bridge yarn workspace @affine/cli build",
|
||||
"dev": "DISTRIBUTION=ios-bridge yarn workspace @affine/cli dev",
|
||||
"static-server": "DISTRIBUTION=ios-bridge yarn workspace @affine/cli dev --static"
|
||||
},
|
||||
"dependencies": {
|
||||
"@affine/core": "workspace:*",
|
||||
"@affine/env": "workspace:*",
|
||||
"@sentry/react": "^7.109.0",
|
||||
"core-js": "^3.36.1",
|
||||
"intl-segmenter-polyfill-rs": "^0.1.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@affine/cli": "workspace:*",
|
||||
"typescript": "^5.4.5"
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
import './polyfill/dispose';
|
||||
import './polyfill/intl-segmenter';
|
||||
import './polyfill/request-idle-callback';
|
||||
import '@affine/core/bootstrap/preload';
|
||||
|
||||
import { configureCommonModules } from '@affine/core/modules';
|
||||
import { AuthService } from '@affine/core/modules/cloud';
|
||||
import { configureLocalStorageStateStorageImpls } from '@affine/core/modules/storage';
|
||||
import {
|
||||
configureBrowserWorkspaceFlavours,
|
||||
configureIndexedDBWorkspaceEngineStorageProvider,
|
||||
} from '@affine/core/modules/workspace-engine';
|
||||
import {
|
||||
DocsService,
|
||||
Framework,
|
||||
LifecycleService,
|
||||
type WorkspaceMetadata,
|
||||
WorkspacesService,
|
||||
} from '@toeverything/infra';
|
||||
|
||||
const framework = new Framework();
|
||||
configureCommonModules(framework);
|
||||
configureLocalStorageStateStorageImpls(framework);
|
||||
configureBrowserWorkspaceFlavours(framework);
|
||||
configureIndexedDBWorkspaceEngineStorageProvider(framework);
|
||||
const frameworkProvider = framework.provider();
|
||||
|
||||
// start the application
|
||||
frameworkProvider.get(LifecycleService).applicationStart();
|
||||
|
||||
const jsb = {
|
||||
signInPassword(email: string, password: string) {
|
||||
return frameworkProvider
|
||||
.get(AuthService)
|
||||
.signInPassword({ email, password });
|
||||
},
|
||||
|
||||
getWorkspacesList() {
|
||||
return frameworkProvider.get(WorkspacesService).list.workspaces$;
|
||||
},
|
||||
|
||||
getWorkspacesDocs(workspaceMeta: WorkspaceMetadata) {
|
||||
return frameworkProvider
|
||||
.get(WorkspacesService)
|
||||
.open({ metadata: workspaceMeta })
|
||||
.workspace.scope.get(DocsService)
|
||||
.list.docs$.map(docs => docs.map(d => d.meta$.value));
|
||||
},
|
||||
// ... add more methods here
|
||||
};
|
||||
|
||||
(window as any).jsb = jsb;
|
||||
(window as any).workspacesService = frameworkProvider.get(WorkspacesService);
|
||||
@@ -1,2 +0,0 @@
|
||||
import 'core-js/modules/esnext.symbol.async-dispose';
|
||||
import 'core-js/modules/esnext.symbol.dispose';
|
||||
@@ -1,11 +0,0 @@
|
||||
if (Intl.Segmenter === undefined) {
|
||||
await import('intl-segmenter-polyfill-rs').then(({ Segmenter }) => {
|
||||
Object.defineProperty(Intl, 'Segmenter', {
|
||||
value: Segmenter,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export {};
|
||||
@@ -1,19 +0,0 @@
|
||||
window.requestIdleCallback =
|
||||
window.requestIdleCallback ||
|
||||
function (cb) {
|
||||
const start = Date.now();
|
||||
return setTimeout(function () {
|
||||
cb({
|
||||
didTimeout: false,
|
||||
timeRemaining: function () {
|
||||
return Math.max(0, 50 - (Date.now() - start));
|
||||
},
|
||||
});
|
||||
}, 1);
|
||||
};
|
||||
|
||||
window.cancelIdleCallback =
|
||||
window.cancelIdleCallback ||
|
||||
function (id) {
|
||||
clearTimeout(id);
|
||||
};
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"outDir": "lib",
|
||||
"moduleResolution": "Bundler",
|
||||
"types": ["affine__env"],
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": ["./src"],
|
||||
"references": [{ "path": "../core" }]
|
||||
}
|
||||
@@ -111,7 +111,7 @@ export async function createRandomUser(): Promise<{
|
||||
password: '123456',
|
||||
};
|
||||
const result = await runPrisma(async client => {
|
||||
const featureId = await client.feature
|
||||
const featureId = await client.features
|
||||
.findFirst({
|
||||
where: { feature: 'free_plan_v1' },
|
||||
select: { id: true },
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { join } from 'node:path';
|
||||
|
||||
import webpack from 'webpack';
|
||||
|
||||
import { getCwdFromDistribution } from '../config/cwd.cjs';
|
||||
@@ -41,10 +39,6 @@ if (DISTRIBUTION === 'desktop') {
|
||||
entry = { app: './index.tsx', shell: './shell/index.tsx' };
|
||||
}
|
||||
|
||||
if (DISTRIBUTION === 'ios-bridge') {
|
||||
entry = join(cwd, 'src', 'index.ts');
|
||||
}
|
||||
|
||||
const flags = {
|
||||
distribution: DISTRIBUTION as BuildFlags['distribution'],
|
||||
mode: 'production',
|
||||
|
||||
@@ -46,9 +46,6 @@ const buildFlags = process.argv.includes('--static')
|
||||
{
|
||||
value: 'desktop',
|
||||
},
|
||||
{
|
||||
value: 'ios-bridge',
|
||||
},
|
||||
{
|
||||
value: 'admin',
|
||||
},
|
||||
@@ -120,10 +117,6 @@ if (flags.distribution === 'desktop') {
|
||||
};
|
||||
}
|
||||
|
||||
if (flags.distribution === 'ios-bridge') {
|
||||
flags.entry = join(cwd, 'src', 'index.ts');
|
||||
}
|
||||
|
||||
if (buildFlags.debugBlockSuite) {
|
||||
const { config } = await import('dotenv');
|
||||
const envLocal = config({
|
||||
|
||||
@@ -23,8 +23,6 @@ module.exports.getCwdFromDistribution = function getCwdFromDistribution(
|
||||
return join(projectRoot, 'packages/frontend/electron/renderer');
|
||||
case 'admin':
|
||||
return join(projectRoot, 'packages/frontend/admin');
|
||||
case 'ios-bridge':
|
||||
return join(projectRoot, 'packages/frontend/ios-bridge');
|
||||
default: {
|
||||
throw new Error('DISTRIBUTION must be one of browser, desktop');
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export type BuildFlags = {
|
||||
distribution: 'browser' | 'desktop' | 'admin' | 'ios-bridge';
|
||||
distribution: 'browser' | 'desktop' | 'admin';
|
||||
mode: 'development' | 'production';
|
||||
channel: 'stable' | 'beta' | 'canary' | 'internal';
|
||||
coverage?: boolean;
|
||||
|
||||
@@ -76,15 +76,11 @@ export const getPublicPath = (buildFlags: BuildFlags) => {
|
||||
return publicPath;
|
||||
}
|
||||
|
||||
if (buildFlags.distribution === 'ios-bridge') {
|
||||
return '/';
|
||||
}
|
||||
|
||||
if (BUILD_TYPE === 'canary') {
|
||||
return `https://dev.affineassets.com/`;
|
||||
} else if (BUILD_TYPE === 'beta') {
|
||||
return `https://beta.affineassets.com/`;
|
||||
} else if (BUILD_TYPE === 'stable') {
|
||||
} else if (BUILD_TYPE === 'prod') {
|
||||
return `https://prod.affineassets.com/`;
|
||||
}
|
||||
return publicPath;
|
||||
|
||||
93
yarn.lock
93
yarn.lock
@@ -629,20 +629,6 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@affine/ios-bridge@workspace:packages/frontend/ios-bridge":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@affine/ios-bridge@workspace:packages/frontend/ios-bridge"
|
||||
dependencies:
|
||||
"@affine/cli": "workspace:*"
|
||||
"@affine/core": "workspace:*"
|
||||
"@affine/env": "workspace:*"
|
||||
"@sentry/react": "npm:^7.109.0"
|
||||
core-js: "npm:^3.36.1"
|
||||
intl-segmenter-polyfill-rs: "npm:^0.1.7"
|
||||
typescript: "npm:^5.4.5"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@affine/monorepo@workspace:.":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@affine/monorepo@workspace:."
|
||||
@@ -12597,17 +12583,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sentry-internal/feedback@npm:7.118.0":
|
||||
version: 7.118.0
|
||||
resolution: "@sentry-internal/feedback@npm:7.118.0"
|
||||
dependencies:
|
||||
"@sentry/core": "npm:7.118.0"
|
||||
"@sentry/types": "npm:7.118.0"
|
||||
"@sentry/utils": "npm:7.118.0"
|
||||
checksum: 10/b6df5ff545aa5e15a6f055f99d5e405c819206b86d2521511d22e03b5bff1c6116c4f1416a49f1ed15df3b0be13653be807041649b5d67d3ae984173a0b1cd6c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sentry-internal/feedback@npm:8.20.0":
|
||||
version: 8.20.0
|
||||
resolution: "@sentry-internal/feedback@npm:8.20.0"
|
||||
@@ -12619,18 +12594,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sentry-internal/replay-canvas@npm:7.118.0":
|
||||
version: 7.118.0
|
||||
resolution: "@sentry-internal/replay-canvas@npm:7.118.0"
|
||||
dependencies:
|
||||
"@sentry/core": "npm:7.118.0"
|
||||
"@sentry/replay": "npm:7.118.0"
|
||||
"@sentry/types": "npm:7.118.0"
|
||||
"@sentry/utils": "npm:7.118.0"
|
||||
checksum: 10/448c07c1e3837318ac75e4c96ee177b82dac14c3beb7f755889b036d78ad6a68dea86d4aaad873e2c3d259afabdddbbe1ac61282e3ab9003d8b0a6c101af569a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sentry-internal/replay-canvas@npm:8.20.0":
|
||||
version: 8.20.0
|
||||
resolution: "@sentry-internal/replay-canvas@npm:8.20.0"
|
||||
@@ -12655,17 +12618,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sentry-internal/tracing@npm:7.118.0":
|
||||
version: 7.118.0
|
||||
resolution: "@sentry-internal/tracing@npm:7.118.0"
|
||||
dependencies:
|
||||
"@sentry/core": "npm:7.118.0"
|
||||
"@sentry/types": "npm:7.118.0"
|
||||
"@sentry/utils": "npm:7.118.0"
|
||||
checksum: 10/267a31c3b539999193b977bdb03a2c0342ffe4b2d09a697918a137ec49f1ef6bcf22d79de2cf1b72c14ebd0da2fe0c25eaecc6ee3df6c4b5de79a0b9754e73b3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sentry/babel-plugin-component-annotate@npm:2.21.1":
|
||||
version: 2.21.1
|
||||
resolution: "@sentry/babel-plugin-component-annotate@npm:2.21.1"
|
||||
@@ -12673,22 +12625,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sentry/browser@npm:7.118.0":
|
||||
version: 7.118.0
|
||||
resolution: "@sentry/browser@npm:7.118.0"
|
||||
dependencies:
|
||||
"@sentry-internal/feedback": "npm:7.118.0"
|
||||
"@sentry-internal/replay-canvas": "npm:7.118.0"
|
||||
"@sentry-internal/tracing": "npm:7.118.0"
|
||||
"@sentry/core": "npm:7.118.0"
|
||||
"@sentry/integrations": "npm:7.118.0"
|
||||
"@sentry/replay": "npm:7.118.0"
|
||||
"@sentry/types": "npm:7.118.0"
|
||||
"@sentry/utils": "npm:7.118.0"
|
||||
checksum: 10/525dc1f5a829c4c703560ab3e8200f06bdf291288ba88911b463dac520f4be59e9170b60f299a1d8c05eedd652460d037b5f12f09e2725190d5bac4fb6714f82
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sentry/browser@npm:8.20.0":
|
||||
version: 8.20.0
|
||||
resolution: "@sentry/browser@npm:8.20.0"
|
||||
@@ -12837,7 +12773,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sentry/integrations@npm:7.118.0, @sentry/integrations@npm:^7.109.0":
|
||||
"@sentry/integrations@npm:^7.109.0":
|
||||
version: 7.118.0
|
||||
resolution: "@sentry/integrations@npm:7.118.0"
|
||||
dependencies:
|
||||
@@ -12849,21 +12785,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sentry/react@npm:^7.109.0":
|
||||
version: 7.118.0
|
||||
resolution: "@sentry/react@npm:7.118.0"
|
||||
dependencies:
|
||||
"@sentry/browser": "npm:7.118.0"
|
||||
"@sentry/core": "npm:7.118.0"
|
||||
"@sentry/types": "npm:7.118.0"
|
||||
"@sentry/utils": "npm:7.118.0"
|
||||
hoist-non-react-statics: "npm:^3.3.2"
|
||||
peerDependencies:
|
||||
react: 15.x || 16.x || 17.x || 18.x
|
||||
checksum: 10/06ad396e96fef6e5a61cca2741eb3def43e05c817a76b5768275f58301aab5d68c765f04d7a22f0934788852dfd1d5547e99f837e0ca6a10d15c2d0cc5dd0948
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sentry/react@npm:^8.0.0, @sentry/react@npm:^8.9.0":
|
||||
version: 8.20.0
|
||||
resolution: "@sentry/react@npm:8.20.0"
|
||||
@@ -12879,18 +12800,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sentry/replay@npm:7.118.0":
|
||||
version: 7.118.0
|
||||
resolution: "@sentry/replay@npm:7.118.0"
|
||||
dependencies:
|
||||
"@sentry-internal/tracing": "npm:7.118.0"
|
||||
"@sentry/core": "npm:7.118.0"
|
||||
"@sentry/types": "npm:7.118.0"
|
||||
"@sentry/utils": "npm:7.118.0"
|
||||
checksum: 10/61ef0f515cd4c611bcd60f49801f5a8a8836a3a3f3333a40e51f2d5d77dee959f9cae1735dce62d9424289d60a9103a4460b588e6086cb5037c82f56b73677df
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sentry/types@npm:7.118.0":
|
||||
version: 7.118.0
|
||||
resolution: "@sentry/types@npm:7.118.0"
|
||||
|
||||
Reference in New Issue
Block a user