react-embed-docs 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +422 -0
- package/dist/client/components/Breadcrumbs.d.ts +21 -0
- package/dist/client/components/Breadcrumbs.d.ts.map +1 -0
- package/dist/client/components/Breadcrumbs.js +123 -0
- package/dist/client/components/DocsLayout.d.ts +20 -0
- package/dist/client/components/DocsLayout.d.ts.map +1 -0
- package/dist/client/components/DocsLayout.js +387 -0
- package/dist/client/components/DocumentContent.d.ts +5 -0
- package/dist/client/components/DocumentContent.d.ts.map +1 -0
- package/dist/client/components/DocumentContent.js +15 -0
- package/dist/client/components/DocumentEdit.d.ts +6 -0
- package/dist/client/components/DocumentEdit.d.ts.map +1 -0
- package/dist/client/components/DocumentEdit.js +153 -0
- package/dist/client/components/DocumentList.d.ts +5 -0
- package/dist/client/components/DocumentList.d.ts.map +1 -0
- package/dist/client/components/DocumentList.js +39 -0
- package/dist/client/components/DocumentProvider.d.ts +42 -0
- package/dist/client/components/DocumentProvider.d.ts.map +1 -0
- package/dist/client/components/DocumentProvider.js +47 -0
- package/dist/client/components/DocumentView.d.ts +6 -0
- package/dist/client/components/DocumentView.d.ts.map +1 -0
- package/dist/client/components/DocumentView.js +58 -0
- package/dist/client/components/DragOverlayItem.d.ts +5 -0
- package/dist/client/components/DragOverlayItem.d.ts.map +1 -0
- package/dist/client/components/DragOverlayItem.js +9 -0
- package/dist/client/components/EmojiPicker.d.ts +8 -0
- package/dist/client/components/EmojiPicker.d.ts.map +1 -0
- package/dist/client/components/EmojiPicker.js +48 -0
- package/dist/client/components/ExportButton.d.ts +22 -0
- package/dist/client/components/ExportButton.d.ts.map +1 -0
- package/dist/client/components/ExportButton.js +97 -0
- package/dist/client/components/Layout.d.ts +7 -0
- package/dist/client/components/Layout.d.ts.map +1 -0
- package/dist/client/components/Layout.js +172 -0
- package/dist/client/components/ReactEmbedDocs.d.ts +8 -0
- package/dist/client/components/ReactEmbedDocs.d.ts.map +1 -0
- package/dist/client/components/ReactEmbedDocs.js +8 -0
- package/dist/client/components/SearchInput.d.ts +2 -0
- package/dist/client/components/SearchInput.d.ts.map +1 -0
- package/dist/client/components/SearchInput.js +7 -0
- package/dist/client/components/Sidebar.d.ts +10 -0
- package/dist/client/components/Sidebar.d.ts.map +1 -0
- package/dist/client/components/Sidebar.js +176 -0
- package/dist/client/components/SortableTreeItem.d.ts +13 -0
- package/dist/client/components/SortableTreeItem.d.ts.map +1 -0
- package/dist/client/components/SortableTreeItem.js +24 -0
- package/dist/client/components/VersionHistory.d.ts +14 -0
- package/dist/client/components/VersionHistory.d.ts.map +1 -0
- package/dist/client/components/VersionHistory.js +102 -0
- package/dist/client/hooks/useCollaboration.d.ts +99 -0
- package/dist/client/hooks/useCollaboration.d.ts.map +1 -0
- package/dist/client/hooks/useCollaboration.js +180 -0
- package/dist/client/hooks/useDocsQuery.d.ts +84 -0
- package/dist/client/hooks/useDocsQuery.d.ts.map +1 -0
- package/dist/client/hooks/useDocsQuery.js +241 -0
- package/dist/client/hooks/useExport.d.ts +31 -0
- package/dist/client/hooks/useExport.d.ts.map +1 -0
- package/dist/client/hooks/useExport.js +66 -0
- package/dist/client/hooks/useFileUpload.d.ts +44 -0
- package/dist/client/hooks/useFileUpload.d.ts.map +1 -0
- package/dist/client/hooks/useFileUpload.js +193 -0
- package/dist/client/hooks/useSystemTheme.d.ts +2 -0
- package/dist/client/hooks/useSystemTheme.d.ts.map +1 -0
- package/dist/client/hooks/useSystemTheme.js +19 -0
- package/dist/client/hooks/useVersions.d.ts +105 -0
- package/dist/client/hooks/useVersions.d.ts.map +1 -0
- package/dist/client/hooks/useVersions.js +129 -0
- package/dist/client/index.d.ts +23 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +18 -0
- package/dist/client/lib/blocknoteTheme.d.ts +13 -0
- package/dist/client/lib/blocknoteTheme.d.ts.map +1 -0
- package/dist/client/lib/blocknoteTheme.js +76 -0
- package/dist/client/lib/path.d.ts +8 -0
- package/dist/client/lib/path.d.ts.map +1 -0
- package/dist/client/lib/path.js +30 -0
- package/dist/client/providers/DocumentProvider.d.ts +1 -0
- package/dist/client/providers/DocumentProvider.d.ts.map +1 -0
- package/dist/client/providers/DocumentProvider.js +1 -0
- package/dist/server/CollaborationService.d.ts +134 -0
- package/dist/server/CollaborationService.d.ts.map +1 -0
- package/dist/server/CollaborationService.js +307 -0
- package/dist/server/DocsService.d.ts +115 -0
- package/dist/server/DocsService.d.ts.map +1 -0
- package/dist/server/DocsService.js +512 -0
- package/dist/server/ExportService.d.ts +106 -0
- package/dist/server/ExportService.d.ts.map +1 -0
- package/dist/server/ExportService.js +501 -0
- package/dist/server/FilesService.d.ts +44 -0
- package/dist/server/FilesService.d.ts.map +1 -0
- package/dist/server/FilesService.js +78 -0
- package/dist/server/VersioningService.d.ts +112 -0
- package/dist/server/VersioningService.d.ts.map +1 -0
- package/dist/server/VersioningService.js +264 -0
- package/dist/server/db.d.ts +7 -0
- package/dist/server/db.d.ts.map +1 -0
- package/dist/server/db.js +22 -0
- package/dist/server/index.d.ts +55 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +36 -0
- package/dist/server/routes.d.ts +9 -0
- package/dist/server/routes.d.ts.map +1 -0
- package/dist/server/routes.js +483 -0
- package/dist/server/schema.d.ts +587 -0
- package/dist/server/schema.d.ts.map +1 -0
- package/dist/server/schema.js +126 -0
- package/dist/shared/types.d.ts +314 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +48 -0
- package/drizzle/migrations/0000_gray_monster_badoon.sql +88 -0
- package/drizzle/migrations/meta/0000_snapshot.json +574 -0
- package/drizzle/migrations/meta/_journal.json +13 -0
- package/package.json +109 -0
- package/styles/docs.css +981 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { relations, sql } from 'drizzle-orm';
|
|
2
|
+
import { boolean, foreignKey, index, integer, jsonb, pgSchema, text, timestamp, uuid, varchar } from 'drizzle-orm/pg-core';
|
|
3
|
+
/**
|
|
4
|
+
* Documents schema
|
|
5
|
+
* Uses 'docs' PostgreSQL schema for document storage
|
|
6
|
+
*/
|
|
7
|
+
export const docsTableSchema = pgSchema('docs');
|
|
8
|
+
/**
|
|
9
|
+
* Documents table
|
|
10
|
+
* Stores documentation pages with BlockNote content
|
|
11
|
+
*/
|
|
12
|
+
export const documentsTable = docsTableSchema.table('documents', {
|
|
13
|
+
id: varchar('id', { length: 21 }).primaryKey(), // nanoid length is 21
|
|
14
|
+
title: varchar('title', { length: 255 }).notNull(),
|
|
15
|
+
slug: varchar('slug', { length: 255 }).unique().notNull(),
|
|
16
|
+
content: jsonb('content').notNull().default('[]').$type(), // BlockNote JSON content
|
|
17
|
+
searchIndex: text('search_index'), // Concatenated text from title + content for full-text search
|
|
18
|
+
emoji: varchar('emoji', { length: 10 }), // Emoji/icon for the document (nullable)
|
|
19
|
+
cover: varchar('cover', { length: 500 }), // Cover image URL (nullable)
|
|
20
|
+
isPublished: boolean('isPublished').default(true).notNull(),
|
|
21
|
+
parentId: varchar('parentId', { length: 21 }),
|
|
22
|
+
order: integer('order').default(0).notNull(), // For sorting documents within a parent
|
|
23
|
+
authorId: integer('authorId'), // Optional author reference (not tied to system users)
|
|
24
|
+
// Collaboration fields
|
|
25
|
+
ydocState: text('ydoc_state'), // Base64 encoded Yjs state vector
|
|
26
|
+
lastModifiedBy: varchar('last_modified_by', { length: 255 }),
|
|
27
|
+
lastModifiedAt: timestamp('last_modified_at'),
|
|
28
|
+
createdAt: timestamp('createdAt')
|
|
29
|
+
.default(sql `NOW()`)
|
|
30
|
+
.notNull(),
|
|
31
|
+
updatedAt: timestamp('updatedAt')
|
|
32
|
+
.default(sql `NOW()`)
|
|
33
|
+
.notNull(),
|
|
34
|
+
deletedAt: timestamp('deletedAt'), // Soft delete
|
|
35
|
+
}, (table) => ({
|
|
36
|
+
// Self-referential foreign key for parent-child relationships
|
|
37
|
+
parentFk: foreignKey({
|
|
38
|
+
columns: [table.parentId],
|
|
39
|
+
foreignColumns: [table.id],
|
|
40
|
+
}),
|
|
41
|
+
// GIN index for JSONB content search
|
|
42
|
+
contentSearchIdx: index('content_search_idx').using('gin', table.content),
|
|
43
|
+
// Index for title search
|
|
44
|
+
titleSearchIdx: index('title_search_idx').on(table.title),
|
|
45
|
+
// Index for full-text search using searchIndex column
|
|
46
|
+
searchIndexIdx: index('search_index_idx').on(table.searchIndex),
|
|
47
|
+
// Index for soft delete queries
|
|
48
|
+
deletedAtIdx: index('deleted_at_idx').on(table.deletedAt),
|
|
49
|
+
// Index for parent queries
|
|
50
|
+
parentIdIdx: index('parent_id_idx').on(table.parentId),
|
|
51
|
+
// Index for ordering
|
|
52
|
+
orderIdx: index('order_idx').on(table.order),
|
|
53
|
+
}));
|
|
54
|
+
/**
|
|
55
|
+
* Document relations
|
|
56
|
+
* Supports hierarchical document structure
|
|
57
|
+
*/
|
|
58
|
+
export const documentRelations = relations(documentsTable, ({ one, many }) => ({
|
|
59
|
+
parent: one(documentsTable, {
|
|
60
|
+
fields: [documentsTable.parentId],
|
|
61
|
+
references: [documentsTable.id],
|
|
62
|
+
}),
|
|
63
|
+
children: many(documentsTable),
|
|
64
|
+
}));
|
|
65
|
+
/**
|
|
66
|
+
* Files table
|
|
67
|
+
* Stores uploaded files directly in database as base64
|
|
68
|
+
*/
|
|
69
|
+
export const filesTable = docsTableSchema.table('files', {
|
|
70
|
+
id: varchar('id', { length: 21 }).primaryKey(), // nanoid
|
|
71
|
+
filename: varchar('filename', { length: 255 }).notNull(),
|
|
72
|
+
mimeType: varchar('mimeType', { length: 100 }).notNull(),
|
|
73
|
+
size: integer('size').notNull(), // file size in bytes
|
|
74
|
+
content: text('content').notNull(), // base64 encoded file content
|
|
75
|
+
createdAt: timestamp('createdAt')
|
|
76
|
+
.default(sql `NOW()`)
|
|
77
|
+
.notNull(),
|
|
78
|
+
}, (table) => ({
|
|
79
|
+
// Index for file lookups
|
|
80
|
+
filenameIdx: index('filename_idx').on(table.filename),
|
|
81
|
+
// Index for mime type filtering
|
|
82
|
+
mimeTypeIdx: index('mime_type_idx').on(table.mimeType),
|
|
83
|
+
}));
|
|
84
|
+
/**
|
|
85
|
+
* Document versions table
|
|
86
|
+
* Stores version history for documents
|
|
87
|
+
*/
|
|
88
|
+
export const documentVersionsTable = docsTableSchema.table('document_versions', {
|
|
89
|
+
id: uuid('id').defaultRandom().primaryKey(),
|
|
90
|
+
documentId: varchar('document_id', { length: 21 }).notNull().references(() => documentsTable.id),
|
|
91
|
+
// Version info
|
|
92
|
+
versionNumber: integer('version_number').notNull(),
|
|
93
|
+
changeDescription: text('change_description'),
|
|
94
|
+
// Snapshot
|
|
95
|
+
title: varchar('title', { length: 255 }).notNull(),
|
|
96
|
+
content: jsonb('content').notNull().$type(),
|
|
97
|
+
emoji: varchar('emoji', { length: 10 }),
|
|
98
|
+
cover: varchar('cover', { length: 500 }),
|
|
99
|
+
ydocState: text('ydoc_state'), // Base64 encoded Yjs state for collab restore
|
|
100
|
+
// Metadata
|
|
101
|
+
createdBy: varchar('created_by', { length: 255 }),
|
|
102
|
+
createdByName: varchar('created_by_name', { length: 255 }),
|
|
103
|
+
createdAt: timestamp('created_at').default(sql `NOW()`).notNull(),
|
|
104
|
+
}, (table) => ({
|
|
105
|
+
// Index for document versions
|
|
106
|
+
documentVersionIdx: index('document_version_idx').on(table.documentId, table.versionNumber),
|
|
107
|
+
createdAtIdx: index('version_created_at_idx').on(table.createdAt),
|
|
108
|
+
}));
|
|
109
|
+
/**
|
|
110
|
+
* Document presence table
|
|
111
|
+
* Tracks active users editing documents (for real-time collaboration)
|
|
112
|
+
*/
|
|
113
|
+
export const documentPresenceTable = docsTableSchema.table('document_presence', {
|
|
114
|
+
id: uuid('id').defaultRandom().primaryKey(),
|
|
115
|
+
documentId: varchar('document_id', { length: 21 }).notNull().references(() => documentsTable.id),
|
|
116
|
+
userId: varchar('user_id', { length: 255 }).notNull(),
|
|
117
|
+
userName: varchar('user_name', { length: 255 }),
|
|
118
|
+
userColor: varchar('user_color', { length: 7 }), // #RRGGBB
|
|
119
|
+
cursorPosition: jsonb('cursor_position'), // { blockId, index }
|
|
120
|
+
selection: jsonb('selection'), // { anchor, head }
|
|
121
|
+
lastSeenAt: timestamp('last_seen_at').default(sql `NOW()`).notNull(),
|
|
122
|
+
}, (table) => ({
|
|
123
|
+
// Index for presence lookups
|
|
124
|
+
presenceIdx: index('presence_idx').on(table.documentId, table.userId),
|
|
125
|
+
lastSeenIdx: index('last_seen_idx').on(table.lastSeenAt),
|
|
126
|
+
}));
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* BlockNote content types
|
|
4
|
+
* BlockNote editor outputs an array of blocks with nested content
|
|
5
|
+
*/
|
|
6
|
+
export interface BlockNoteContentItem {
|
|
7
|
+
type: string;
|
|
8
|
+
text?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface BlockNoteBlock {
|
|
11
|
+
type: string;
|
|
12
|
+
content?: BlockNoteContentItem[] | BlockNoteContentItem[][];
|
|
13
|
+
}
|
|
14
|
+
export type BlockNoteContent = BlockNoteBlock[];
|
|
15
|
+
/**
|
|
16
|
+
* Document interfaces
|
|
17
|
+
*/
|
|
18
|
+
export interface Document {
|
|
19
|
+
id: string;
|
|
20
|
+
title: string;
|
|
21
|
+
slug: string;
|
|
22
|
+
content: BlockNoteContent;
|
|
23
|
+
searchIndex?: string | null;
|
|
24
|
+
emoji?: string | null;
|
|
25
|
+
cover?: string | null;
|
|
26
|
+
isPublished: boolean;
|
|
27
|
+
parentId?: string | null;
|
|
28
|
+
order: number;
|
|
29
|
+
authorId?: number | null;
|
|
30
|
+
createdAt: Date;
|
|
31
|
+
updatedAt: Date;
|
|
32
|
+
deletedAt?: Date | null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Document without content - used for list/tree views
|
|
36
|
+
* to reduce payload size
|
|
37
|
+
*/
|
|
38
|
+
export type DocumentSummary = Omit<Document, 'content' | 'searchIndex'>;
|
|
39
|
+
export type DocumentMode = 'view' | 'edit' | 'create';
|
|
40
|
+
export interface FlattenedItem extends DocumentSummary {
|
|
41
|
+
depth: number;
|
|
42
|
+
hasChildren: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Search result types
|
|
46
|
+
*/
|
|
47
|
+
export interface SearchResult {
|
|
48
|
+
document: Document;
|
|
49
|
+
rank: number;
|
|
50
|
+
highlights: string[];
|
|
51
|
+
}
|
|
52
|
+
export interface SearchTextResult {
|
|
53
|
+
document: Document;
|
|
54
|
+
rank: number;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* File upload types
|
|
58
|
+
*/
|
|
59
|
+
export interface FileUpload {
|
|
60
|
+
id: string;
|
|
61
|
+
filename: string;
|
|
62
|
+
mimeType: string;
|
|
63
|
+
size: number;
|
|
64
|
+
content: string;
|
|
65
|
+
createdAt: Date;
|
|
66
|
+
}
|
|
67
|
+
export interface InsertFileUpload {
|
|
68
|
+
filename: string;
|
|
69
|
+
mimeType: string;
|
|
70
|
+
size: number;
|
|
71
|
+
content: string;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* List documents filters and options
|
|
75
|
+
*/
|
|
76
|
+
export interface ListDocumentsFilters {
|
|
77
|
+
search?: string;
|
|
78
|
+
parentId?: string | null;
|
|
79
|
+
isPublished?: boolean;
|
|
80
|
+
}
|
|
81
|
+
export interface ListDocumentsOptions {
|
|
82
|
+
offset?: number;
|
|
83
|
+
limit?: number;
|
|
84
|
+
sortBy?: keyof Document;
|
|
85
|
+
sortDir?: 'asc' | 'desc';
|
|
86
|
+
}
|
|
87
|
+
export interface ListDocumentsResult {
|
|
88
|
+
documents: DocumentSummary[];
|
|
89
|
+
total: number;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Zod schemas for validation
|
|
93
|
+
*/
|
|
94
|
+
export declare const documentSchema: z.ZodObject<{
|
|
95
|
+
id: z.ZodString;
|
|
96
|
+
title: z.ZodString;
|
|
97
|
+
slug: z.ZodString;
|
|
98
|
+
content: z.ZodAny;
|
|
99
|
+
searchIndex: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
100
|
+
emoji: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
101
|
+
cover: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
102
|
+
isPublished: z.ZodBoolean;
|
|
103
|
+
parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
104
|
+
order: z.ZodNumber;
|
|
105
|
+
authorId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
106
|
+
createdAt: z.ZodDate;
|
|
107
|
+
updatedAt: z.ZodDate;
|
|
108
|
+
deletedAt: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
|
|
109
|
+
}, "strip", z.ZodTypeAny, {
|
|
110
|
+
slug: string;
|
|
111
|
+
id: string;
|
|
112
|
+
order: number;
|
|
113
|
+
title: string;
|
|
114
|
+
isPublished: boolean;
|
|
115
|
+
createdAt: Date;
|
|
116
|
+
updatedAt: Date;
|
|
117
|
+
content?: any;
|
|
118
|
+
searchIndex?: string | null | undefined;
|
|
119
|
+
emoji?: string | null | undefined;
|
|
120
|
+
cover?: string | null | undefined;
|
|
121
|
+
parentId?: string | null | undefined;
|
|
122
|
+
authorId?: number | null | undefined;
|
|
123
|
+
deletedAt?: Date | null | undefined;
|
|
124
|
+
}, {
|
|
125
|
+
slug: string;
|
|
126
|
+
id: string;
|
|
127
|
+
order: number;
|
|
128
|
+
title: string;
|
|
129
|
+
isPublished: boolean;
|
|
130
|
+
createdAt: Date;
|
|
131
|
+
updatedAt: Date;
|
|
132
|
+
content?: any;
|
|
133
|
+
searchIndex?: string | null | undefined;
|
|
134
|
+
emoji?: string | null | undefined;
|
|
135
|
+
cover?: string | null | undefined;
|
|
136
|
+
parentId?: string | null | undefined;
|
|
137
|
+
authorId?: number | null | undefined;
|
|
138
|
+
deletedAt?: Date | null | undefined;
|
|
139
|
+
}>;
|
|
140
|
+
export declare const createDocumentSchema: z.ZodObject<{
|
|
141
|
+
title: z.ZodString;
|
|
142
|
+
slug: z.ZodString;
|
|
143
|
+
content: z.ZodDefault<z.ZodOptional<z.ZodAny>>;
|
|
144
|
+
emoji: z.ZodOptional<z.ZodString>;
|
|
145
|
+
cover: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
146
|
+
isPublished: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
147
|
+
parentSlugs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
148
|
+
authorId: z.ZodOptional<z.ZodNumber>;
|
|
149
|
+
}, "strip", z.ZodTypeAny, {
|
|
150
|
+
slug: string;
|
|
151
|
+
title: string;
|
|
152
|
+
isPublished: boolean;
|
|
153
|
+
content?: any;
|
|
154
|
+
emoji?: string | undefined;
|
|
155
|
+
cover?: string | null | undefined;
|
|
156
|
+
authorId?: number | undefined;
|
|
157
|
+
parentSlugs?: string[] | undefined;
|
|
158
|
+
}, {
|
|
159
|
+
slug: string;
|
|
160
|
+
title: string;
|
|
161
|
+
content?: any;
|
|
162
|
+
emoji?: string | undefined;
|
|
163
|
+
cover?: string | null | undefined;
|
|
164
|
+
isPublished?: boolean | undefined;
|
|
165
|
+
authorId?: number | undefined;
|
|
166
|
+
parentSlugs?: string[] | undefined;
|
|
167
|
+
}>;
|
|
168
|
+
export type CreateDocument = z.infer<typeof createDocumentSchema>;
|
|
169
|
+
export declare const updateDocumentSchema: z.ZodObject<{
|
|
170
|
+
title: z.ZodOptional<z.ZodString>;
|
|
171
|
+
slug: z.ZodOptional<z.ZodString>;
|
|
172
|
+
content: z.ZodOptional<z.ZodDefault<z.ZodOptional<z.ZodAny>>>;
|
|
173
|
+
emoji: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
|
174
|
+
cover: z.ZodOptional<z.ZodNullable<z.ZodOptional<z.ZodString>>>;
|
|
175
|
+
isPublished: z.ZodOptional<z.ZodDefault<z.ZodOptional<z.ZodBoolean>>>;
|
|
176
|
+
parentSlugs: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
|
|
177
|
+
authorId: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
178
|
+
}, "strip", z.ZodTypeAny, {
|
|
179
|
+
slug?: string | undefined;
|
|
180
|
+
title?: string | undefined;
|
|
181
|
+
content?: any;
|
|
182
|
+
emoji?: string | undefined;
|
|
183
|
+
cover?: string | null | undefined;
|
|
184
|
+
isPublished?: boolean | undefined;
|
|
185
|
+
authorId?: number | undefined;
|
|
186
|
+
parentSlugs?: string[] | undefined;
|
|
187
|
+
}, {
|
|
188
|
+
slug?: string | undefined;
|
|
189
|
+
title?: string | undefined;
|
|
190
|
+
content?: any;
|
|
191
|
+
emoji?: string | undefined;
|
|
192
|
+
cover?: string | null | undefined;
|
|
193
|
+
isPublished?: boolean | undefined;
|
|
194
|
+
authorId?: number | undefined;
|
|
195
|
+
parentSlugs?: string[] | undefined;
|
|
196
|
+
}>;
|
|
197
|
+
export type UpdateDocument = z.infer<typeof updateDocumentSchema>;
|
|
198
|
+
export declare const documentListSchema: z.ZodObject<{
|
|
199
|
+
items: z.ZodArray<z.ZodObject<Omit<{
|
|
200
|
+
id: z.ZodString;
|
|
201
|
+
title: z.ZodString;
|
|
202
|
+
slug: z.ZodString;
|
|
203
|
+
content: z.ZodAny;
|
|
204
|
+
searchIndex: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
205
|
+
emoji: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
206
|
+
cover: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
207
|
+
isPublished: z.ZodBoolean;
|
|
208
|
+
parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
209
|
+
order: z.ZodNumber;
|
|
210
|
+
authorId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
211
|
+
createdAt: z.ZodDate;
|
|
212
|
+
updatedAt: z.ZodDate;
|
|
213
|
+
deletedAt: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
|
|
214
|
+
}, "content">, "strip", z.ZodTypeAny, {
|
|
215
|
+
slug: string;
|
|
216
|
+
id: string;
|
|
217
|
+
order: number;
|
|
218
|
+
title: string;
|
|
219
|
+
isPublished: boolean;
|
|
220
|
+
createdAt: Date;
|
|
221
|
+
updatedAt: Date;
|
|
222
|
+
searchIndex?: string | null | undefined;
|
|
223
|
+
emoji?: string | null | undefined;
|
|
224
|
+
cover?: string | null | undefined;
|
|
225
|
+
parentId?: string | null | undefined;
|
|
226
|
+
authorId?: number | null | undefined;
|
|
227
|
+
deletedAt?: Date | null | undefined;
|
|
228
|
+
}, {
|
|
229
|
+
slug: string;
|
|
230
|
+
id: string;
|
|
231
|
+
order: number;
|
|
232
|
+
title: string;
|
|
233
|
+
isPublished: boolean;
|
|
234
|
+
createdAt: Date;
|
|
235
|
+
updatedAt: Date;
|
|
236
|
+
searchIndex?: string | null | undefined;
|
|
237
|
+
emoji?: string | null | undefined;
|
|
238
|
+
cover?: string | null | undefined;
|
|
239
|
+
parentId?: string | null | undefined;
|
|
240
|
+
authorId?: number | null | undefined;
|
|
241
|
+
deletedAt?: Date | null | undefined;
|
|
242
|
+
}>, "many">;
|
|
243
|
+
total: z.ZodNumber;
|
|
244
|
+
}, "strip", z.ZodTypeAny, {
|
|
245
|
+
items: {
|
|
246
|
+
slug: string;
|
|
247
|
+
id: string;
|
|
248
|
+
order: number;
|
|
249
|
+
title: string;
|
|
250
|
+
isPublished: boolean;
|
|
251
|
+
createdAt: Date;
|
|
252
|
+
updatedAt: Date;
|
|
253
|
+
searchIndex?: string | null | undefined;
|
|
254
|
+
emoji?: string | null | undefined;
|
|
255
|
+
cover?: string | null | undefined;
|
|
256
|
+
parentId?: string | null | undefined;
|
|
257
|
+
authorId?: number | null | undefined;
|
|
258
|
+
deletedAt?: Date | null | undefined;
|
|
259
|
+
}[];
|
|
260
|
+
total: number;
|
|
261
|
+
}, {
|
|
262
|
+
items: {
|
|
263
|
+
slug: string;
|
|
264
|
+
id: string;
|
|
265
|
+
order: number;
|
|
266
|
+
title: string;
|
|
267
|
+
isPublished: boolean;
|
|
268
|
+
createdAt: Date;
|
|
269
|
+
updatedAt: Date;
|
|
270
|
+
searchIndex?: string | null | undefined;
|
|
271
|
+
emoji?: string | null | undefined;
|
|
272
|
+
cover?: string | null | undefined;
|
|
273
|
+
parentId?: string | null | undefined;
|
|
274
|
+
authorId?: number | null | undefined;
|
|
275
|
+
deletedAt?: Date | null | undefined;
|
|
276
|
+
}[];
|
|
277
|
+
total: number;
|
|
278
|
+
}>;
|
|
279
|
+
export declare const fileSchema: z.ZodObject<{
|
|
280
|
+
id: z.ZodString;
|
|
281
|
+
filename: z.ZodString;
|
|
282
|
+
mimeType: z.ZodString;
|
|
283
|
+
size: z.ZodNumber;
|
|
284
|
+
content: z.ZodString;
|
|
285
|
+
createdAt: z.ZodDate;
|
|
286
|
+
}, "strip", z.ZodTypeAny, {
|
|
287
|
+
id: string;
|
|
288
|
+
size: number;
|
|
289
|
+
content: string;
|
|
290
|
+
createdAt: Date;
|
|
291
|
+
filename: string;
|
|
292
|
+
mimeType: string;
|
|
293
|
+
}, {
|
|
294
|
+
id: string;
|
|
295
|
+
size: number;
|
|
296
|
+
content: string;
|
|
297
|
+
createdAt: Date;
|
|
298
|
+
filename: string;
|
|
299
|
+
mimeType: string;
|
|
300
|
+
}>;
|
|
301
|
+
export declare const uploadFileSchema: z.ZodObject<{
|
|
302
|
+
filename: z.ZodString;
|
|
303
|
+
mimeType: z.ZodString;
|
|
304
|
+
content: z.ZodString;
|
|
305
|
+
}, "strip", z.ZodTypeAny, {
|
|
306
|
+
content: string;
|
|
307
|
+
filename: string;
|
|
308
|
+
mimeType: string;
|
|
309
|
+
}, {
|
|
310
|
+
content: string;
|
|
311
|
+
filename: string;
|
|
312
|
+
mimeType: string;
|
|
313
|
+
}>;
|
|
314
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Zod schemas for validation
|
|
4
|
+
*/
|
|
5
|
+
export const documentSchema = z.object({
|
|
6
|
+
id: z.string(),
|
|
7
|
+
title: z.string(),
|
|
8
|
+
slug: z.string(),
|
|
9
|
+
content: z.any().describe('BlockNote JSON content'),
|
|
10
|
+
searchIndex: z.string().nullable().optional(),
|
|
11
|
+
emoji: z.string().nullable().optional(),
|
|
12
|
+
cover: z.string().nullable().optional(),
|
|
13
|
+
isPublished: z.boolean(),
|
|
14
|
+
parentId: z.string().nullable().optional(),
|
|
15
|
+
order: z.number(),
|
|
16
|
+
authorId: z.number().nullable().optional(),
|
|
17
|
+
createdAt: z.date(),
|
|
18
|
+
updatedAt: z.date(),
|
|
19
|
+
deletedAt: z.date().nullable().optional(),
|
|
20
|
+
});
|
|
21
|
+
export const createDocumentSchema = z.object({
|
|
22
|
+
title: z.string().min(1).max(255),
|
|
23
|
+
slug: z.string().min(1).max(255),
|
|
24
|
+
content: z.any().optional().default([]).describe('BlockNote JSON content'),
|
|
25
|
+
emoji: z.string().max(10).optional(),
|
|
26
|
+
cover: z.string().max(500).optional().nullable(),
|
|
27
|
+
isPublished: z.boolean().optional().default(true),
|
|
28
|
+
parentSlugs: z.array(z.string()).optional(),
|
|
29
|
+
authorId: z.number().optional(),
|
|
30
|
+
});
|
|
31
|
+
export const updateDocumentSchema = createDocumentSchema.partial();
|
|
32
|
+
export const documentListSchema = z.object({
|
|
33
|
+
items: z.array(documentSchema.omit({ content: true })),
|
|
34
|
+
total: z.number(),
|
|
35
|
+
});
|
|
36
|
+
export const fileSchema = z.object({
|
|
37
|
+
id: z.string(),
|
|
38
|
+
filename: z.string(),
|
|
39
|
+
mimeType: z.string(),
|
|
40
|
+
size: z.number(),
|
|
41
|
+
content: z.string(),
|
|
42
|
+
createdAt: z.date(),
|
|
43
|
+
});
|
|
44
|
+
export const uploadFileSchema = z.object({
|
|
45
|
+
filename: z.string().min(1).max(255),
|
|
46
|
+
mimeType: z.string().min(1).max(100),
|
|
47
|
+
content: z.string().min(1).describe('Base64 encoded file content'),
|
|
48
|
+
});
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
CREATE SCHEMA IF NOT EXISTS "docs";
|
|
2
|
+
--> statement-breakpoint
|
|
3
|
+
CREATE TABLE IF NOT EXISTS "docs"."document_presence" (
|
|
4
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
5
|
+
"document_id" varchar(21) NOT NULL,
|
|
6
|
+
"user_id" varchar(255) NOT NULL,
|
|
7
|
+
"user_name" varchar(255),
|
|
8
|
+
"user_color" varchar(7),
|
|
9
|
+
"cursor_position" jsonb,
|
|
10
|
+
"selection" jsonb,
|
|
11
|
+
"last_seen_at" timestamp DEFAULT NOW() NOT NULL
|
|
12
|
+
);
|
|
13
|
+
--> statement-breakpoint
|
|
14
|
+
CREATE TABLE IF NOT EXISTS "docs"."document_versions" (
|
|
15
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
16
|
+
"document_id" varchar(21) NOT NULL,
|
|
17
|
+
"version_number" integer NOT NULL,
|
|
18
|
+
"change_description" text,
|
|
19
|
+
"title" varchar(255) NOT NULL,
|
|
20
|
+
"content" jsonb NOT NULL,
|
|
21
|
+
"emoji" varchar(10),
|
|
22
|
+
"cover" varchar(500),
|
|
23
|
+
"ydoc_state" text,
|
|
24
|
+
"created_by" varchar(255),
|
|
25
|
+
"created_by_name" varchar(255),
|
|
26
|
+
"created_at" timestamp DEFAULT NOW() NOT NULL
|
|
27
|
+
);
|
|
28
|
+
--> statement-breakpoint
|
|
29
|
+
CREATE TABLE IF NOT EXISTS "docs"."documents" (
|
|
30
|
+
"id" varchar(21) PRIMARY KEY NOT NULL,
|
|
31
|
+
"title" varchar(255) NOT NULL,
|
|
32
|
+
"slug" varchar(255) NOT NULL,
|
|
33
|
+
"content" jsonb DEFAULT '[]' NOT NULL,
|
|
34
|
+
"search_index" text,
|
|
35
|
+
"emoji" varchar(10),
|
|
36
|
+
"cover" varchar(500),
|
|
37
|
+
"isPublished" boolean DEFAULT true NOT NULL,
|
|
38
|
+
"parentId" varchar(21),
|
|
39
|
+
"order" integer DEFAULT 0 NOT NULL,
|
|
40
|
+
"authorId" integer,
|
|
41
|
+
"ydoc_state" text,
|
|
42
|
+
"last_modified_by" varchar(255),
|
|
43
|
+
"last_modified_at" timestamp,
|
|
44
|
+
"createdAt" timestamp DEFAULT NOW() NOT NULL,
|
|
45
|
+
"updatedAt" timestamp DEFAULT NOW() NOT NULL,
|
|
46
|
+
"deletedAt" timestamp,
|
|
47
|
+
CONSTRAINT "documents_slug_unique" UNIQUE("slug")
|
|
48
|
+
);
|
|
49
|
+
--> statement-breakpoint
|
|
50
|
+
CREATE TABLE IF NOT EXISTS "docs"."files" (
|
|
51
|
+
"id" varchar(21) PRIMARY KEY NOT NULL,
|
|
52
|
+
"filename" varchar(255) NOT NULL,
|
|
53
|
+
"mimeType" varchar(100) NOT NULL,
|
|
54
|
+
"size" integer NOT NULL,
|
|
55
|
+
"content" text NOT NULL,
|
|
56
|
+
"createdAt" timestamp DEFAULT NOW() NOT NULL
|
|
57
|
+
);
|
|
58
|
+
--> statement-breakpoint
|
|
59
|
+
DO $$ BEGIN
|
|
60
|
+
ALTER TABLE "docs"."document_presence" ADD CONSTRAINT "document_presence_document_id_documents_id_fk" FOREIGN KEY ("document_id") REFERENCES "docs"."documents"("id") ON DELETE no action ON UPDATE no action;
|
|
61
|
+
EXCEPTION
|
|
62
|
+
WHEN duplicate_object THEN null;
|
|
63
|
+
END $$;
|
|
64
|
+
--> statement-breakpoint
|
|
65
|
+
DO $$ BEGIN
|
|
66
|
+
ALTER TABLE "docs"."document_versions" ADD CONSTRAINT "document_versions_document_id_documents_id_fk" FOREIGN KEY ("document_id") REFERENCES "docs"."documents"("id") ON DELETE no action ON UPDATE no action;
|
|
67
|
+
EXCEPTION
|
|
68
|
+
WHEN duplicate_object THEN null;
|
|
69
|
+
END $$;
|
|
70
|
+
--> statement-breakpoint
|
|
71
|
+
DO $$ BEGIN
|
|
72
|
+
ALTER TABLE "docs"."documents" ADD CONSTRAINT "documents_parentId_documents_id_fk" FOREIGN KEY ("parentId") REFERENCES "docs"."documents"("id") ON DELETE no action ON UPDATE no action;
|
|
73
|
+
EXCEPTION
|
|
74
|
+
WHEN duplicate_object THEN null;
|
|
75
|
+
END $$;
|
|
76
|
+
--> statement-breakpoint
|
|
77
|
+
CREATE INDEX IF NOT EXISTS "presence_idx" ON "docs"."document_presence" USING btree ("document_id","user_id");--> statement-breakpoint
|
|
78
|
+
CREATE INDEX IF NOT EXISTS "last_seen_idx" ON "docs"."document_presence" USING btree ("last_seen_at");--> statement-breakpoint
|
|
79
|
+
CREATE INDEX IF NOT EXISTS "document_version_idx" ON "docs"."document_versions" USING btree ("document_id","version_number");--> statement-breakpoint
|
|
80
|
+
CREATE INDEX IF NOT EXISTS "version_created_at_idx" ON "docs"."document_versions" USING btree ("created_at");--> statement-breakpoint
|
|
81
|
+
CREATE INDEX IF NOT EXISTS "content_search_idx" ON "docs"."documents" USING gin ("content");--> statement-breakpoint
|
|
82
|
+
CREATE INDEX IF NOT EXISTS "title_search_idx" ON "docs"."documents" USING btree ("title");--> statement-breakpoint
|
|
83
|
+
CREATE INDEX IF NOT EXISTS "search_index_idx" ON "docs"."documents" USING btree ("search_index");--> statement-breakpoint
|
|
84
|
+
CREATE INDEX IF NOT EXISTS "deleted_at_idx" ON "docs"."documents" USING btree ("deletedAt");--> statement-breakpoint
|
|
85
|
+
CREATE INDEX IF NOT EXISTS "parent_id_idx" ON "docs"."documents" USING btree ("parentId");--> statement-breakpoint
|
|
86
|
+
CREATE INDEX IF NOT EXISTS "order_idx" ON "docs"."documents" USING btree ("order");--> statement-breakpoint
|
|
87
|
+
CREATE INDEX IF NOT EXISTS "filename_idx" ON "docs"."files" USING btree ("filename");--> statement-breakpoint
|
|
88
|
+
CREATE INDEX IF NOT EXISTS "mime_type_idx" ON "docs"."files" USING btree ("mimeType");
|