1
8
9export const LIMITS = {
10
11 MAX_BLOCK_BATCH: 500,
12
13 MAX_PAGE_TITLE: 200,
14
15 MAX_WORKSPACE_NAME: 50,
16
17 MAX_COMMENT: 20_000,
18
19 MIN_COMMENT: 1,
20
21 MAX_FILE_SIZE: 500 * 1024 * 1024,
22
23 MAX_RECORDS_PER_PAGE: 200,
24
25 MAX_SEARCH_LIMIT: 50,
26
27 MAX_PASSWORD: 72,
28
29 MIN_PASSWORD: 10,
30
31 MAX_SLUG: 50,
32
33 MAX_BLOCK_TEXT: 100_000,
34
35 MAX_POSITION_LENGTH: 64,
36
37 MAX_INLINE_CHILDREN: 1000,
38
39 MAX_CLIENT_SIDE_ROWS: 5000,
40} as const;
41
42export const TOKEN_LIFETIMES = {
43
44 ACCESS_TOKEN: "15m",
45 ACCESS_TOKEN_MS: 15 * 60 * 1000,
46
47 REFRESH_TOKEN_MS: 30 * 24 * 60 * 60 * 1000,
48
49 PASSWORD_RESET_MS: 60 * 60 * 1000,
50
51 EMAIL_VERIFY_MS: 24 * 60 * 60 * 1000,
52
53 INVITATION_MS: 7 * 24 * 60 * 60 * 1000,
54
55 PRESET_URL_MS: 15 * 60 * 1000,
56} as const;
57
58export const RATE_LIMITS = {
59
60 WINDOW_MS: 60_000,
61
62 MAX: 300,
63
64 AUTH: { WINDOW_MS: 60_000, MAX: 20 },
65
66 LOGIN: { WINDOW_MS: 15 * 60 * 1000, MAX: 10 },
67
68 PASSWORD_RESET: { WINDOW_MS: 60 * 60 * 1000, MAX: 5 },
69
70 AI: { WINDOW_MS: 60_000, MAX: 30 },
71} as const;
72
73export const BCRYPT_ROUNDS_DEFAULT = 12;
74
75export const ID_PREFIXES = {
76 user: "usr",
77 workspace: "wsp",
78 team: "tms",
79 page: "pg",
80 block: "blk",
81 database: "db",
82 databaseProperty: "dprop",
83 databaseView: "dview",
84 record: "rec",
85 recordProperty: "rprop",
86 comment: "cmt",
87 file: "file",
88 share: "shr",
89 template: "tpl",
90 automation: "auto",
91 webhook: "wh",
92 apiKey: "key",
93 notification: "ntf",
94 session: "ses",
95 refreshToken: "rt",
96} as const;
97
98
108export interface BlockColor {
109
110 name: string;
111
112 token: string;
113
114 hex: string;
115
116 background: boolean;
117}
118
119const text = (name: string, hex: string): BlockColor => ({
120 name,
121 token: name,
122 hex,
123 background: false,
124});
125const bg = (name: string, hex: string): BlockColor => ({
126 name,
127 token: `${name}_bg`,
128 hex,
129 background: true,
130});
131
132export const BLOCK_COLORS: readonly BlockColor[] = [
133 text("gray", "#787774"),
134 text("brown", "#9f6b53"),
135 text("orange", "#d9730d"),
136 text("yellow", "#cb912f"),
137 text("green", "#448361"),
138 text("blue", "#337ea9"),
139 text("purple", "#9065b0"),
140 text("pink", "#c14c8a"),
141 text("red", "#d44c47"),
142 bg("gray", "#f1f1ef"),
143 bg("brown", "#f7e9e7"),
144 bg("orange", "#fbecdd"),
145 bg("yellow", "#fdf3d0"),
146 bg("green", "#edf3ec"),
147 bg("blue", "#e7f0f6"),
148 bg("purple", "#f1edf7"),
149 bg("pink", "#faedf3"),
150 bg("red", "#fdebec"),
151] as const;
152
153
154export const STATUS_COLORS: readonly string[] = [
155 "gray",
156 "brown",
157 "orange",
158 "yellow",
159 "green",
160 "blue",
161 "purple",
162 "pink",
163 "red",
164] as const;
165
166
167export const DENSITIES = ["cozy", "default", "compact"] as const;
168export type Density = (typeof DENSITIES)[number];
169
170
171export const TEXT_COLOR_NAMES = BLOCK_COLORS.filter((c) => !c.token.endsWith("_bg")).map(
172 (c) => c.name,
173) as readonly string[];
174
175
176export const BACKGROUND_COLOR_NAMES = ["default", ...STATUS_COLORS] as readonly string[];
177