1
6import {
7 BLOCK_TYPES,
8 PROPERTY_TYPES,
9 VIEW_TYPES,
10 type BlockType,
11 type PropertyType,
12 type ViewType,
13 type WorkspaceRole
14} from "./types";
15
16
17
18
19
20
21
22
23
24const USING_ENV_API_BASE = process.env.NEXT_PUBLIC_API_URL !== undefined;
25export const API_BASE: string = process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:4000/api/v1";
26export const WS_URL: string = process.env.NEXT_PUBLIC_WS_URL ?? "ws://localhost:4001";
27export const APP_URL: string = process.env.NEXT_PUBLIC_APP_URL ?? "http://localhost:3000";
28
29if (!USING_ENV_API_BASE) {
30 console.warn(
31 "[web] NEXT_PUBLIC_API_URL is not set — using the localhost fallback " +
32 `(${API_BASE}). If this page is served from another origin (tunnel/domain), ` +
33 "API calls will be blocked by the browser. Source the .env file " +
34 "before starting `next dev`."
35 );
36}
37
38
46export const SESSION_COOKIE = "factory_refresh";
47
48export { BLOCK_TYPES, PROPERTY_TYPES, VIEW_TYPES };
49export type { BlockType, PropertyType, ViewType, WorkspaceRole };
50
51
52export const BLOCK_TYPE_LABELS: Record<BlockType, string> = {
53 paragraph: "Text",
54 heading_1: "Heading 1",
55 heading_2: "Heading 2",
56 heading_3: "Heading 3",
57 quote: "Quote",
58 callout: "Callout",
59 bulleted_list: "Bulleted list",
60 numbered_list: "Numbered list",
61 todo: "To-do list",
62 toggle: "Toggle list",
63 image: "Image",
64 video: "Video",
65 audio: "Audio",
66 file: "File",
67 bookmark: "Bookmark",
68 embed: "Embed",
69 code: "Code",
70 equation: "Equation",
71 column: "Column",
72 column_list: "Columns",
73 divider: "Divider",
74 spacer: "Spacer",
75 database: "Database",
76 linked_database: "Linked database",
77 table: "Table",
78 chart: "Chart",
79 form: "Form",
80 synced_block: "Synced block",
81 child_page: "Page (child)",
82 child_database: "Database (child)",
83 toc: "Table of contents"
84};
85
86export const PROPERTY_TYPE_LABELS: Record<PropertyType, string> = {
87 title: "Title",
88 text: "Text",
89 rich_text: "Rich text",
90 number: "Number",
91 select: "Select",
92 multi_select: "Multi-select",
93 status: "Status",
94 date: "Date",
95 date_range: "Date range",
96 person: "Person",
97 email: "Email",
98 phone: "Phone",
99 url: "URL",
100 checkbox: "Checkbox",
101 files: "Files",
102 created_time: "Created time",
103 created_by: "Created by",
104 last_edited_time: "Last edited time",
105 last_edited_by: "Last edited by",
106 relation: "Relation",
107 rollup: "Rollup",
108 formula: "Formula",
109 button: "Button",
110 unique_id: "Unique id"
111};
112
113export const VIEW_TYPE_LABELS: Record<ViewType, string> = {
114 table: "Table",
115 board: "Board",
116 calendar: "Calendar",
117 timeline: "Timeline",
118 list: "List",
119 gallery: "Gallery",
120 chart: "Chart",
121 form: "Form",
122 dashboard: "Dashboard"
123};
124
125
133export const PERM_LEVELS = ["view", "comment", "edit", "full_edit"] as const;
134export type PermLevel = (typeof PERM_LEVELS)[number];
135export const PERM_RANK: Record<PermLevel, number> = {
136 view: 0,
137 comment: 1,
138 edit: 2,
139 full_edit: 3
140};
141
142export const SHARE_LEVELS = [...PERM_LEVELS, "public"] as const;
143export type ShareLevel = (typeof SHARE_LEVELS)[number];
144
145export const STORAGE_LIMITS = {
146 MAX_FILE_SIZE: 500 * 1024 * 1024,
147 MAX_PAGE_TITLE: 200,
148 MAX_WORKSPACE_NAME: 50,
149 MAX_BLOCK_BATCH: 500
150} as const;
151
152
153export const BLOCK_SAVE_DEBOUNCE_MS = 500;
154
155export const DEFAULT_STALE_TIME_MS = 30_000;
156