react-embed-docs 0.4.0 → 0.5.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/dist/client/components/DocumentEdit.d.ts.map +1 -1
- package/dist/client/components/DocumentEdit.js +92 -4
- package/dist/server/FilesService.d.ts +29 -4
- package/dist/server/FilesService.d.ts.map +1 -1
- package/dist/server/FilesService.js +67 -8
- package/dist/server/schema.d.ts +12 -0
- package/dist/server/schema.d.ts.map +1 -1
- package/dist/server/schema.js +3 -0
- package/drizzle/migrations/0001_omniscient_fallen_one.sql +2 -0
- package/drizzle/migrations/meta/0001_snapshot.json +595 -0
- package/drizzle/migrations/meta/_journal.json +7 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocumentEdit.d.ts","sourceRoot":"","sources":["../../../src/client/components/DocumentEdit.tsx"],"names":[],"mappings":"AAIA,OAAO,8BAA8B,CAAA;AAgBrC,UAAU,iBAAiB;CAAG;AAwU9B,wBAAgB,YAAY,CAAC,EAAE,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"DocumentEdit.d.ts","sourceRoot":"","sources":["../../../src/client/components/DocumentEdit.tsx"],"names":[],"mappings":"AAIA,OAAO,8BAA8B,CAAA;AAgBrC,UAAU,iBAAiB;CAAG;AAwU9B,wBAAgB,YAAY,CAAC,EAAE,EAAE,iBAAiB,2CAmYjD"}
|
|
@@ -4,7 +4,7 @@ import { BlockNoteView } from '@blocknote/mantine';
|
|
|
4
4
|
import '@blocknote/mantine/style.css';
|
|
5
5
|
import { useCreateBlockNote } from '@blocknote/react';
|
|
6
6
|
import { Eye, ImageIcon, Loader2, Save, X } from 'lucide-react';
|
|
7
|
-
import { useEffect, useState } from 'react';
|
|
7
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
8
8
|
import { useCreateDocumentMutation, useDocumentQuery, useUpdateDocumentMutation, } from '../hooks/useDocsQuery.js';
|
|
9
9
|
import { useFileUpload } from '../hooks/useFileUpload.js';
|
|
10
10
|
import { useTranslation } from '../hooks/useTranslation.js';
|
|
@@ -346,17 +346,94 @@ export function DocumentEdit({}) {
|
|
|
346
346
|
const [isSlugManuallyEdited, setIsSlugManuallyEdited] = useState(false);
|
|
347
347
|
const [emoji, setEmoji] = useState(undefined);
|
|
348
348
|
const [cover, setCover] = useState(null);
|
|
349
|
+
const [previousCover, setPreviousCover] = useState(null);
|
|
349
350
|
const [isSaving, setIsSaving] = useState(false);
|
|
350
351
|
const [hasLoaded, setHasLoaded] = useState(false);
|
|
351
|
-
//
|
|
352
|
+
// Track image URLs for cleanup when deleted
|
|
353
|
+
const [previousImageUrls, setPreviousImageUrls] = useState(new Set());
|
|
354
|
+
// Helper to extract image URLs from blocks
|
|
355
|
+
const extractImageUrls = useCallback((blocks) => {
|
|
356
|
+
const urls = [];
|
|
357
|
+
for (const block of blocks) {
|
|
358
|
+
if (block.type === 'image' && block.props?.url) {
|
|
359
|
+
urls.push(block.props.url);
|
|
360
|
+
}
|
|
361
|
+
// Check nested content
|
|
362
|
+
if (block.children && block.children.length > 0) {
|
|
363
|
+
urls.push(...extractImageUrls(block.children));
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return urls;
|
|
367
|
+
}, []);
|
|
368
|
+
// File upload hook for cover
|
|
352
369
|
const { isUploading: isUploadingCover, uploadFile: uploadCover } = useFileUpload({
|
|
353
370
|
maxSize: 5 * 1024 * 1024, // 5MB
|
|
354
371
|
acceptedTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
|
|
355
372
|
});
|
|
356
|
-
//
|
|
373
|
+
// File upload hook for editor images
|
|
374
|
+
const { uploadFile: uploadEditorFile } = useFileUpload({
|
|
375
|
+
maxSize: 5 * 1024 * 1024, // 5MB
|
|
376
|
+
acceptedTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml'],
|
|
377
|
+
});
|
|
378
|
+
// Upload file handler for BlockNote editor
|
|
379
|
+
const handleUploadFile = useCallback(async (file) => {
|
|
380
|
+
const result = await uploadEditorFile(file);
|
|
381
|
+
return result.url;
|
|
382
|
+
}, [uploadEditorFile]);
|
|
383
|
+
// Initialize editor with file upload support
|
|
357
384
|
const editor = useCreateBlockNote({
|
|
358
385
|
initialContent: getDefaultContent(),
|
|
386
|
+
uploadFile: handleUploadFile,
|
|
359
387
|
});
|
|
388
|
+
// Helper to extract file ID from URL
|
|
389
|
+
const extractFileIdFromUrl = useCallback((url) => {
|
|
390
|
+
// URL format: /api/docs/files/{id}
|
|
391
|
+
const match = url.match(/\/api\/docs\/files\/([a-zA-Z0-9_-]+)/);
|
|
392
|
+
return match?.[1] ?? null;
|
|
393
|
+
}, []);
|
|
394
|
+
// Soft delete file from server
|
|
395
|
+
const softDeleteFile = useCallback(async (fileId) => {
|
|
396
|
+
try {
|
|
397
|
+
const res = await fetch(`/api/docs/files/${fileId}`, {
|
|
398
|
+
method: 'DELETE',
|
|
399
|
+
});
|
|
400
|
+
if (!res.ok) {
|
|
401
|
+
console.error(`Failed to soft delete file ${fileId}:`, res.statusText);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
catch (error) {
|
|
405
|
+
console.error(`Error soft deleting file ${fileId}:`, error);
|
|
406
|
+
}
|
|
407
|
+
}, []);
|
|
408
|
+
// Monitor editor changes and soft delete removed images
|
|
409
|
+
useEffect(() => {
|
|
410
|
+
if (!editor)
|
|
411
|
+
return;
|
|
412
|
+
const unsubscribe = editor.onChange(() => {
|
|
413
|
+
const currentBlocks = editor.document;
|
|
414
|
+
const currentImageUrls = new Set(extractImageUrls(currentBlocks));
|
|
415
|
+
// Find images that were in previous but not in current
|
|
416
|
+
for (const url of previousImageUrls) {
|
|
417
|
+
if (!currentImageUrls.has(url)) {
|
|
418
|
+
const fileId = extractFileIdFromUrl(url);
|
|
419
|
+
if (fileId) {
|
|
420
|
+
softDeleteFile(fileId);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
setPreviousImageUrls(currentImageUrls);
|
|
425
|
+
});
|
|
426
|
+
return () => {
|
|
427
|
+
unsubscribe();
|
|
428
|
+
};
|
|
429
|
+
}, [editor, extractImageUrls, extractFileIdFromUrl, softDeleteFile, previousImageUrls]);
|
|
430
|
+
// Initialize previousImageUrls when document loads
|
|
431
|
+
useEffect(() => {
|
|
432
|
+
if (editor && hasLoaded && existingDoc) {
|
|
433
|
+
const urls = new Set(extractImageUrls(editor.document));
|
|
434
|
+
setPreviousImageUrls(urls);
|
|
435
|
+
}
|
|
436
|
+
}, [editor, hasLoaded, existingDoc, extractImageUrls]);
|
|
360
437
|
// Load existing document data when available
|
|
361
438
|
useEffect(() => {
|
|
362
439
|
if (existingDoc && !hasLoaded) {
|
|
@@ -364,8 +441,10 @@ export function DocumentEdit({}) {
|
|
|
364
441
|
setSlug(existingDoc.slug);
|
|
365
442
|
if (existingDoc.emoji)
|
|
366
443
|
setEmoji(existingDoc.emoji);
|
|
367
|
-
if (existingDoc.cover)
|
|
444
|
+
if (existingDoc.cover) {
|
|
368
445
|
setCover(existingDoc.cover);
|
|
446
|
+
setPreviousCover(existingDoc.cover);
|
|
447
|
+
}
|
|
369
448
|
if (editor && existingDoc.content) {
|
|
370
449
|
try {
|
|
371
450
|
const content = typeof existingDoc.content === 'string'
|
|
@@ -405,6 +484,13 @@ export function DocumentEdit({}) {
|
|
|
405
484
|
try {
|
|
406
485
|
const content = editor.document;
|
|
407
486
|
const finalSlug = slug.trim() || generateSlug(title);
|
|
487
|
+
// Check if cover was removed and soft delete the old file
|
|
488
|
+
if (previousCover && !cover) {
|
|
489
|
+
const fileId = extractFileIdFromUrl(previousCover);
|
|
490
|
+
if (fileId) {
|
|
491
|
+
await softDeleteFile(fileId);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
408
494
|
if (!existingDoc) {
|
|
409
495
|
// Create new document (with parentId if it's a child document)
|
|
410
496
|
const newDoc = await createMutation.mutateAsync({
|
|
@@ -431,6 +517,8 @@ export function DocumentEdit({}) {
|
|
|
431
517
|
},
|
|
432
518
|
});
|
|
433
519
|
}
|
|
520
|
+
// Update previousCover after successful save
|
|
521
|
+
setPreviousCover(cover);
|
|
434
522
|
}
|
|
435
523
|
catch (error) {
|
|
436
524
|
console.error('Failed to save document:', error);
|
|
@@ -17,25 +17,50 @@ export declare class FilesService {
|
|
|
17
17
|
*/
|
|
18
18
|
upload(data: InsertFileUpload): Promise<File>;
|
|
19
19
|
/**
|
|
20
|
-
* Get a file by its ID
|
|
20
|
+
* Get a file by its ID (excludes soft-deleted files)
|
|
21
21
|
* @param id - The file ID
|
|
22
22
|
* @returns The file record or undefined if not found
|
|
23
23
|
*/
|
|
24
24
|
getById(id: string): Promise<File | undefined>;
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
26
|
+
* Soft delete a file by its ID (sets deletedAt timestamp)
|
|
27
27
|
* @param id - The file ID to delete
|
|
28
28
|
* @throws Error if deletion fails
|
|
29
29
|
*/
|
|
30
30
|
delete(id: string): Promise<void>;
|
|
31
31
|
/**
|
|
32
|
-
*
|
|
33
|
-
* @param
|
|
32
|
+
* Hard delete a file by its ID (permanent deletion)
|
|
33
|
+
* @param id - The file ID to delete
|
|
34
|
+
* @throws Error if deletion fails
|
|
35
|
+
*/
|
|
36
|
+
hardDelete(id: string): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Restore a soft-deleted file
|
|
39
|
+
* @param id - The file ID to restore
|
|
40
|
+
* @throws Error if restoration fails
|
|
41
|
+
*/
|
|
42
|
+
restore(id: string): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* List all non-deleted files with optional pagination
|
|
45
|
+
* @param options - Pagination options and includeDeleted flag
|
|
34
46
|
* @returns Array of files and total count
|
|
35
47
|
*/
|
|
36
48
|
list(options?: {
|
|
37
49
|
limit?: number;
|
|
38
50
|
offset?: number;
|
|
51
|
+
includeDeleted?: boolean;
|
|
52
|
+
}): Promise<{
|
|
53
|
+
files: File[];
|
|
54
|
+
total: number;
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* List soft-deleted files (for cleanup purposes)
|
|
58
|
+
* @param options - Pagination options
|
|
59
|
+
* @returns Array of deleted files and total count
|
|
60
|
+
*/
|
|
61
|
+
listDeleted(options?: {
|
|
62
|
+
limit?: number;
|
|
63
|
+
offset?: number;
|
|
39
64
|
}): Promise<{
|
|
40
65
|
files: File[];
|
|
41
66
|
total: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilesService.d.ts","sourceRoot":"","sources":["../../src/server/FilesService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAA;AAC5B,OAAO,EAEL,KAAK,IAAI,EACV,MAAM,aAAa,CAAA;AAEpB;;;;GAIG;AACH,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,EAAE;IAEnC;;;;;OAKG;IACG,MAAM,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBnD;;;;OAIG;IACG,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"FilesService.d.ts","sourceRoot":"","sources":["../../src/server/FilesService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAA;AAC5B,OAAO,EAEL,KAAK,IAAI,EACV,MAAM,aAAa,CAAA;AAEpB;;;;GAIG;AACH,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,EAAE;IAEnC;;;;;OAKG;IACG,MAAM,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBnD;;;;OAIG;IACG,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAapD;;;;OAIG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvC;;;;OAIG;IACG,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW3C;;;;OAIG;IACG,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYxC;;;;OAIG;IACG,IAAI,CAAC,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAwBlI;;;;OAIG;IACG,WAAW,CAAC,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAoBhH"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { eq, sql } from 'drizzle-orm';
|
|
1
|
+
import { eq, isNull, sql } from 'drizzle-orm';
|
|
2
2
|
import { nanoid } from 'nanoid';
|
|
3
3
|
import { filesTable } from './schema.js';
|
|
4
4
|
/**
|
|
@@ -32,7 +32,7 @@ export class FilesService {
|
|
|
32
32
|
return result;
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
|
-
* Get a file by its ID
|
|
35
|
+
* Get a file by its ID (excludes soft-deleted files)
|
|
36
36
|
* @param id - The file ID
|
|
37
37
|
* @returns The file record or undefined if not found
|
|
38
38
|
*/
|
|
@@ -40,14 +40,33 @@ export class FilesService {
|
|
|
40
40
|
const file = await this.db.query.filesTable.findFirst({
|
|
41
41
|
where: eq(filesTable.id, id),
|
|
42
42
|
});
|
|
43
|
+
// Return undefined if file is soft-deleted
|
|
44
|
+
if (file?.deletedAt) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
43
47
|
return file;
|
|
44
48
|
}
|
|
45
49
|
/**
|
|
46
|
-
*
|
|
50
|
+
* Soft delete a file by its ID (sets deletedAt timestamp)
|
|
47
51
|
* @param id - The file ID to delete
|
|
48
52
|
* @throws Error if deletion fails
|
|
49
53
|
*/
|
|
50
54
|
async delete(id) {
|
|
55
|
+
const [result] = await this.db
|
|
56
|
+
.update(filesTable)
|
|
57
|
+
.set({ deletedAt: new Date() })
|
|
58
|
+
.where(eq(filesTable.id, id))
|
|
59
|
+
.returning();
|
|
60
|
+
if (!result) {
|
|
61
|
+
throw new Error('File not found');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Hard delete a file by its ID (permanent deletion)
|
|
66
|
+
* @param id - The file ID to delete
|
|
67
|
+
* @throws Error if deletion fails
|
|
68
|
+
*/
|
|
69
|
+
async hardDelete(id) {
|
|
51
70
|
const [result] = await this.db
|
|
52
71
|
.delete(filesTable)
|
|
53
72
|
.where(eq(filesTable.id, id))
|
|
@@ -57,21 +76,61 @@ export class FilesService {
|
|
|
57
76
|
}
|
|
58
77
|
}
|
|
59
78
|
/**
|
|
60
|
-
*
|
|
61
|
-
* @param
|
|
79
|
+
* Restore a soft-deleted file
|
|
80
|
+
* @param id - The file ID to restore
|
|
81
|
+
* @throws Error if restoration fails
|
|
82
|
+
*/
|
|
83
|
+
async restore(id) {
|
|
84
|
+
const [result] = await this.db
|
|
85
|
+
.update(filesTable)
|
|
86
|
+
.set({ deletedAt: null })
|
|
87
|
+
.where(eq(filesTable.id, id))
|
|
88
|
+
.returning();
|
|
89
|
+
if (!result) {
|
|
90
|
+
throw new Error('File not found');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* List all non-deleted files with optional pagination
|
|
95
|
+
* @param options - Pagination options and includeDeleted flag
|
|
62
96
|
* @returns Array of files and total count
|
|
63
97
|
*/
|
|
64
98
|
async list(options = {}) {
|
|
65
|
-
const { limit = 50, offset = 0 } = options;
|
|
99
|
+
const { limit = 50, offset = 0, includeDeleted = false } = options;
|
|
100
|
+
// Build where condition based on includeDeleted flag
|
|
101
|
+
const whereCondition = includeDeleted ? undefined : isNull(filesTable.deletedAt);
|
|
66
102
|
const files = await this.db.query.filesTable.findMany({
|
|
103
|
+
where: whereCondition,
|
|
67
104
|
limit,
|
|
68
105
|
offset,
|
|
69
106
|
orderBy: (files, { desc }) => [desc(files.createdAt)],
|
|
70
107
|
});
|
|
71
|
-
// Get total count
|
|
108
|
+
// Get total count (filtered by deleted status)
|
|
109
|
+
const totalResult = await this.db
|
|
110
|
+
.select({ count: sql `count(*)::int` })
|
|
111
|
+
.from(filesTable)
|
|
112
|
+
.where(whereCondition ?? sql `TRUE`);
|
|
113
|
+
const total = Number(totalResult[0]?.count ?? 0);
|
|
114
|
+
return { files, total };
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* List soft-deleted files (for cleanup purposes)
|
|
118
|
+
* @param options - Pagination options
|
|
119
|
+
* @returns Array of deleted files and total count
|
|
120
|
+
*/
|
|
121
|
+
async listDeleted(options = {}) {
|
|
122
|
+
const { limit = 50, offset = 0 } = options;
|
|
123
|
+
const files = await this.db.query.filesTable.findMany({
|
|
124
|
+
where: sql `${filesTable.deletedAt} IS NOT NULL`,
|
|
125
|
+
limit,
|
|
126
|
+
offset,
|
|
127
|
+
orderBy: (files, { desc }) => [desc(files.deletedAt)],
|
|
128
|
+
});
|
|
129
|
+
// Get total count of deleted files
|
|
72
130
|
const totalResult = await this.db
|
|
73
131
|
.select({ count: sql `count(*)::int` })
|
|
74
|
-
.from(filesTable)
|
|
132
|
+
.from(filesTable)
|
|
133
|
+
.where(sql `${filesTable.deletedAt} IS NOT NULL`);
|
|
75
134
|
const total = Number(totalResult[0]?.count ?? 0);
|
|
76
135
|
return { files, total };
|
|
77
136
|
}
|
package/dist/server/schema.d.ts
CHANGED
|
@@ -307,6 +307,18 @@ export declare const filesTable: import("drizzle-orm/pg-core").PgTableWithColumn
|
|
|
307
307
|
enumValues: undefined;
|
|
308
308
|
baseColumn: never;
|
|
309
309
|
}, {}, {}>;
|
|
310
|
+
deletedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
311
|
+
name: "deletedAt";
|
|
312
|
+
tableName: "files";
|
|
313
|
+
dataType: "date";
|
|
314
|
+
columnType: "PgTimestamp";
|
|
315
|
+
data: Date;
|
|
316
|
+
driverParam: string;
|
|
317
|
+
notNull: false;
|
|
318
|
+
hasDefault: false;
|
|
319
|
+
enumValues: undefined;
|
|
320
|
+
baseColumn: never;
|
|
321
|
+
}, {}, {}>;
|
|
310
322
|
};
|
|
311
323
|
dialect: "pg";
|
|
312
324
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/server/schema.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAErD;;;GAGG;AACH,eAAO,MAAM,eAAe,gDAAmB,CAAA;AAE/C;;;GAGG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2CxB,CAAA;AAEH;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;EAM3B,CAAA;AAEH;;;GAGG;AACH,eAAO,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/server/schema.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAErD;;;GAGG;AACH,eAAO,MAAM,eAAe,gDAAmB,CAAA;AAE/C;;;GAGG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2CxB,CAAA;AAEH;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;EAM3B,CAAA;AAEH;;;GAGG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBpB,CAAA;AAEH;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuB/B,CAAA;AAEH;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAa/B,CAAA;AAEH;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC,YAAY,CAAA;AAC/D,MAAM,MAAM,QAAQ,GAAG,OAAO,cAAc,CAAC,YAAY,CAAA;AACzD,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;AAEpD,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,YAAY,CAAA;AACvD,MAAM,MAAM,IAAI,GAAG,OAAO,UAAU,CAAC,YAAY,CAAA;AAEjD,MAAM,MAAM,qBAAqB,GAAG,OAAO,qBAAqB,CAAC,YAAY,CAAA;AAC7E,MAAM,MAAM,eAAe,GAAG,OAAO,qBAAqB,CAAC,YAAY,CAAA;AAEvE,MAAM,MAAM,sBAAsB,GAAG,OAAO,qBAAqB,CAAC,YAAY,CAAA;AAC9E,MAAM,MAAM,gBAAgB,GAAG,OAAO,qBAAqB,CAAC,YAAY,CAAA"}
|
package/dist/server/schema.js
CHANGED
|
@@ -75,11 +75,14 @@ export const filesTable = docsTableSchema.table('files', {
|
|
|
75
75
|
createdAt: timestamp('createdAt')
|
|
76
76
|
.default(sql `NOW()`)
|
|
77
77
|
.notNull(),
|
|
78
|
+
deletedAt: timestamp('deletedAt'), // Soft delete for files
|
|
78
79
|
}, (table) => ({
|
|
79
80
|
// Index for file lookups
|
|
80
81
|
filenameIdx: index('filename_idx').on(table.filename),
|
|
81
82
|
// Index for mime type filtering
|
|
82
83
|
mimeTypeIdx: index('mime_type_idx').on(table.mimeType),
|
|
84
|
+
// Index for soft delete queries
|
|
85
|
+
filesDeletedAtIdx: index('files_deleted_at_idx').on(table.deletedAt),
|
|
83
86
|
}));
|
|
84
87
|
/**
|
|
85
88
|
* Document versions table
|
|
@@ -0,0 +1,595 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "cd711252-7226-4bb5-a58d-0867586c7463",
|
|
3
|
+
"prevId": "31106a8d-1ede-402b-9721-ead67be66c4d",
|
|
4
|
+
"version": "7",
|
|
5
|
+
"dialect": "postgresql",
|
|
6
|
+
"tables": {
|
|
7
|
+
"docs.document_presence": {
|
|
8
|
+
"name": "document_presence",
|
|
9
|
+
"schema": "docs",
|
|
10
|
+
"columns": {
|
|
11
|
+
"id": {
|
|
12
|
+
"name": "id",
|
|
13
|
+
"type": "uuid",
|
|
14
|
+
"primaryKey": true,
|
|
15
|
+
"notNull": true,
|
|
16
|
+
"default": "gen_random_uuid()"
|
|
17
|
+
},
|
|
18
|
+
"document_id": {
|
|
19
|
+
"name": "document_id",
|
|
20
|
+
"type": "varchar(21)",
|
|
21
|
+
"primaryKey": false,
|
|
22
|
+
"notNull": true
|
|
23
|
+
},
|
|
24
|
+
"user_id": {
|
|
25
|
+
"name": "user_id",
|
|
26
|
+
"type": "varchar(255)",
|
|
27
|
+
"primaryKey": false,
|
|
28
|
+
"notNull": true
|
|
29
|
+
},
|
|
30
|
+
"user_name": {
|
|
31
|
+
"name": "user_name",
|
|
32
|
+
"type": "varchar(255)",
|
|
33
|
+
"primaryKey": false,
|
|
34
|
+
"notNull": false
|
|
35
|
+
},
|
|
36
|
+
"user_color": {
|
|
37
|
+
"name": "user_color",
|
|
38
|
+
"type": "varchar(7)",
|
|
39
|
+
"primaryKey": false,
|
|
40
|
+
"notNull": false
|
|
41
|
+
},
|
|
42
|
+
"cursor_position": {
|
|
43
|
+
"name": "cursor_position",
|
|
44
|
+
"type": "jsonb",
|
|
45
|
+
"primaryKey": false,
|
|
46
|
+
"notNull": false
|
|
47
|
+
},
|
|
48
|
+
"selection": {
|
|
49
|
+
"name": "selection",
|
|
50
|
+
"type": "jsonb",
|
|
51
|
+
"primaryKey": false,
|
|
52
|
+
"notNull": false
|
|
53
|
+
},
|
|
54
|
+
"last_seen_at": {
|
|
55
|
+
"name": "last_seen_at",
|
|
56
|
+
"type": "timestamp",
|
|
57
|
+
"primaryKey": false,
|
|
58
|
+
"notNull": true,
|
|
59
|
+
"default": "NOW()"
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"indexes": {
|
|
63
|
+
"presence_idx": {
|
|
64
|
+
"name": "presence_idx",
|
|
65
|
+
"columns": [
|
|
66
|
+
{
|
|
67
|
+
"expression": "document_id",
|
|
68
|
+
"isExpression": false,
|
|
69
|
+
"asc": true,
|
|
70
|
+
"nulls": "last"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"expression": "user_id",
|
|
74
|
+
"isExpression": false,
|
|
75
|
+
"asc": true,
|
|
76
|
+
"nulls": "last"
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
"isUnique": false,
|
|
80
|
+
"concurrently": false,
|
|
81
|
+
"method": "btree",
|
|
82
|
+
"with": {}
|
|
83
|
+
},
|
|
84
|
+
"last_seen_idx": {
|
|
85
|
+
"name": "last_seen_idx",
|
|
86
|
+
"columns": [
|
|
87
|
+
{
|
|
88
|
+
"expression": "last_seen_at",
|
|
89
|
+
"isExpression": false,
|
|
90
|
+
"asc": true,
|
|
91
|
+
"nulls": "last"
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
"isUnique": false,
|
|
95
|
+
"concurrently": false,
|
|
96
|
+
"method": "btree",
|
|
97
|
+
"with": {}
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"foreignKeys": {
|
|
101
|
+
"document_presence_document_id_documents_id_fk": {
|
|
102
|
+
"name": "document_presence_document_id_documents_id_fk",
|
|
103
|
+
"tableFrom": "document_presence",
|
|
104
|
+
"tableTo": "documents",
|
|
105
|
+
"schemaTo": "docs",
|
|
106
|
+
"columnsFrom": [
|
|
107
|
+
"document_id"
|
|
108
|
+
],
|
|
109
|
+
"columnsTo": [
|
|
110
|
+
"id"
|
|
111
|
+
],
|
|
112
|
+
"onDelete": "no action",
|
|
113
|
+
"onUpdate": "no action"
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
"compositePrimaryKeys": {},
|
|
117
|
+
"uniqueConstraints": {}
|
|
118
|
+
},
|
|
119
|
+
"docs.document_versions": {
|
|
120
|
+
"name": "document_versions",
|
|
121
|
+
"schema": "docs",
|
|
122
|
+
"columns": {
|
|
123
|
+
"id": {
|
|
124
|
+
"name": "id",
|
|
125
|
+
"type": "uuid",
|
|
126
|
+
"primaryKey": true,
|
|
127
|
+
"notNull": true,
|
|
128
|
+
"default": "gen_random_uuid()"
|
|
129
|
+
},
|
|
130
|
+
"document_id": {
|
|
131
|
+
"name": "document_id",
|
|
132
|
+
"type": "varchar(21)",
|
|
133
|
+
"primaryKey": false,
|
|
134
|
+
"notNull": true
|
|
135
|
+
},
|
|
136
|
+
"version_number": {
|
|
137
|
+
"name": "version_number",
|
|
138
|
+
"type": "integer",
|
|
139
|
+
"primaryKey": false,
|
|
140
|
+
"notNull": true
|
|
141
|
+
},
|
|
142
|
+
"change_description": {
|
|
143
|
+
"name": "change_description",
|
|
144
|
+
"type": "text",
|
|
145
|
+
"primaryKey": false,
|
|
146
|
+
"notNull": false
|
|
147
|
+
},
|
|
148
|
+
"title": {
|
|
149
|
+
"name": "title",
|
|
150
|
+
"type": "varchar(255)",
|
|
151
|
+
"primaryKey": false,
|
|
152
|
+
"notNull": true
|
|
153
|
+
},
|
|
154
|
+
"content": {
|
|
155
|
+
"name": "content",
|
|
156
|
+
"type": "jsonb",
|
|
157
|
+
"primaryKey": false,
|
|
158
|
+
"notNull": true
|
|
159
|
+
},
|
|
160
|
+
"emoji": {
|
|
161
|
+
"name": "emoji",
|
|
162
|
+
"type": "varchar(10)",
|
|
163
|
+
"primaryKey": false,
|
|
164
|
+
"notNull": false
|
|
165
|
+
},
|
|
166
|
+
"cover": {
|
|
167
|
+
"name": "cover",
|
|
168
|
+
"type": "varchar(500)",
|
|
169
|
+
"primaryKey": false,
|
|
170
|
+
"notNull": false
|
|
171
|
+
},
|
|
172
|
+
"ydoc_state": {
|
|
173
|
+
"name": "ydoc_state",
|
|
174
|
+
"type": "text",
|
|
175
|
+
"primaryKey": false,
|
|
176
|
+
"notNull": false
|
|
177
|
+
},
|
|
178
|
+
"created_by": {
|
|
179
|
+
"name": "created_by",
|
|
180
|
+
"type": "varchar(255)",
|
|
181
|
+
"primaryKey": false,
|
|
182
|
+
"notNull": false
|
|
183
|
+
},
|
|
184
|
+
"created_by_name": {
|
|
185
|
+
"name": "created_by_name",
|
|
186
|
+
"type": "varchar(255)",
|
|
187
|
+
"primaryKey": false,
|
|
188
|
+
"notNull": false
|
|
189
|
+
},
|
|
190
|
+
"created_at": {
|
|
191
|
+
"name": "created_at",
|
|
192
|
+
"type": "timestamp",
|
|
193
|
+
"primaryKey": false,
|
|
194
|
+
"notNull": true,
|
|
195
|
+
"default": "NOW()"
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
"indexes": {
|
|
199
|
+
"document_version_idx": {
|
|
200
|
+
"name": "document_version_idx",
|
|
201
|
+
"columns": [
|
|
202
|
+
{
|
|
203
|
+
"expression": "document_id",
|
|
204
|
+
"isExpression": false,
|
|
205
|
+
"asc": true,
|
|
206
|
+
"nulls": "last"
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"expression": "version_number",
|
|
210
|
+
"isExpression": false,
|
|
211
|
+
"asc": true,
|
|
212
|
+
"nulls": "last"
|
|
213
|
+
}
|
|
214
|
+
],
|
|
215
|
+
"isUnique": false,
|
|
216
|
+
"concurrently": false,
|
|
217
|
+
"method": "btree",
|
|
218
|
+
"with": {}
|
|
219
|
+
},
|
|
220
|
+
"version_created_at_idx": {
|
|
221
|
+
"name": "version_created_at_idx",
|
|
222
|
+
"columns": [
|
|
223
|
+
{
|
|
224
|
+
"expression": "created_at",
|
|
225
|
+
"isExpression": false,
|
|
226
|
+
"asc": true,
|
|
227
|
+
"nulls": "last"
|
|
228
|
+
}
|
|
229
|
+
],
|
|
230
|
+
"isUnique": false,
|
|
231
|
+
"concurrently": false,
|
|
232
|
+
"method": "btree",
|
|
233
|
+
"with": {}
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
"foreignKeys": {
|
|
237
|
+
"document_versions_document_id_documents_id_fk": {
|
|
238
|
+
"name": "document_versions_document_id_documents_id_fk",
|
|
239
|
+
"tableFrom": "document_versions",
|
|
240
|
+
"tableTo": "documents",
|
|
241
|
+
"schemaTo": "docs",
|
|
242
|
+
"columnsFrom": [
|
|
243
|
+
"document_id"
|
|
244
|
+
],
|
|
245
|
+
"columnsTo": [
|
|
246
|
+
"id"
|
|
247
|
+
],
|
|
248
|
+
"onDelete": "no action",
|
|
249
|
+
"onUpdate": "no action"
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
"compositePrimaryKeys": {},
|
|
253
|
+
"uniqueConstraints": {}
|
|
254
|
+
},
|
|
255
|
+
"docs.documents": {
|
|
256
|
+
"name": "documents",
|
|
257
|
+
"schema": "docs",
|
|
258
|
+
"columns": {
|
|
259
|
+
"id": {
|
|
260
|
+
"name": "id",
|
|
261
|
+
"type": "varchar(21)",
|
|
262
|
+
"primaryKey": true,
|
|
263
|
+
"notNull": true
|
|
264
|
+
},
|
|
265
|
+
"title": {
|
|
266
|
+
"name": "title",
|
|
267
|
+
"type": "varchar(255)",
|
|
268
|
+
"primaryKey": false,
|
|
269
|
+
"notNull": true
|
|
270
|
+
},
|
|
271
|
+
"slug": {
|
|
272
|
+
"name": "slug",
|
|
273
|
+
"type": "varchar(255)",
|
|
274
|
+
"primaryKey": false,
|
|
275
|
+
"notNull": true
|
|
276
|
+
},
|
|
277
|
+
"content": {
|
|
278
|
+
"name": "content",
|
|
279
|
+
"type": "jsonb",
|
|
280
|
+
"primaryKey": false,
|
|
281
|
+
"notNull": true,
|
|
282
|
+
"default": "'[]'"
|
|
283
|
+
},
|
|
284
|
+
"search_index": {
|
|
285
|
+
"name": "search_index",
|
|
286
|
+
"type": "text",
|
|
287
|
+
"primaryKey": false,
|
|
288
|
+
"notNull": false
|
|
289
|
+
},
|
|
290
|
+
"emoji": {
|
|
291
|
+
"name": "emoji",
|
|
292
|
+
"type": "varchar(10)",
|
|
293
|
+
"primaryKey": false,
|
|
294
|
+
"notNull": false
|
|
295
|
+
},
|
|
296
|
+
"cover": {
|
|
297
|
+
"name": "cover",
|
|
298
|
+
"type": "varchar(500)",
|
|
299
|
+
"primaryKey": false,
|
|
300
|
+
"notNull": false
|
|
301
|
+
},
|
|
302
|
+
"isPublished": {
|
|
303
|
+
"name": "isPublished",
|
|
304
|
+
"type": "boolean",
|
|
305
|
+
"primaryKey": false,
|
|
306
|
+
"notNull": true,
|
|
307
|
+
"default": true
|
|
308
|
+
},
|
|
309
|
+
"parentId": {
|
|
310
|
+
"name": "parentId",
|
|
311
|
+
"type": "varchar(21)",
|
|
312
|
+
"primaryKey": false,
|
|
313
|
+
"notNull": false
|
|
314
|
+
},
|
|
315
|
+
"order": {
|
|
316
|
+
"name": "order",
|
|
317
|
+
"type": "integer",
|
|
318
|
+
"primaryKey": false,
|
|
319
|
+
"notNull": true,
|
|
320
|
+
"default": 0
|
|
321
|
+
},
|
|
322
|
+
"authorId": {
|
|
323
|
+
"name": "authorId",
|
|
324
|
+
"type": "integer",
|
|
325
|
+
"primaryKey": false,
|
|
326
|
+
"notNull": false
|
|
327
|
+
},
|
|
328
|
+
"ydoc_state": {
|
|
329
|
+
"name": "ydoc_state",
|
|
330
|
+
"type": "text",
|
|
331
|
+
"primaryKey": false,
|
|
332
|
+
"notNull": false
|
|
333
|
+
},
|
|
334
|
+
"last_modified_by": {
|
|
335
|
+
"name": "last_modified_by",
|
|
336
|
+
"type": "varchar(255)",
|
|
337
|
+
"primaryKey": false,
|
|
338
|
+
"notNull": false
|
|
339
|
+
},
|
|
340
|
+
"last_modified_at": {
|
|
341
|
+
"name": "last_modified_at",
|
|
342
|
+
"type": "timestamp",
|
|
343
|
+
"primaryKey": false,
|
|
344
|
+
"notNull": false
|
|
345
|
+
},
|
|
346
|
+
"createdAt": {
|
|
347
|
+
"name": "createdAt",
|
|
348
|
+
"type": "timestamp",
|
|
349
|
+
"primaryKey": false,
|
|
350
|
+
"notNull": true,
|
|
351
|
+
"default": "NOW()"
|
|
352
|
+
},
|
|
353
|
+
"updatedAt": {
|
|
354
|
+
"name": "updatedAt",
|
|
355
|
+
"type": "timestamp",
|
|
356
|
+
"primaryKey": false,
|
|
357
|
+
"notNull": true,
|
|
358
|
+
"default": "NOW()"
|
|
359
|
+
},
|
|
360
|
+
"deletedAt": {
|
|
361
|
+
"name": "deletedAt",
|
|
362
|
+
"type": "timestamp",
|
|
363
|
+
"primaryKey": false,
|
|
364
|
+
"notNull": false
|
|
365
|
+
}
|
|
366
|
+
},
|
|
367
|
+
"indexes": {
|
|
368
|
+
"content_search_idx": {
|
|
369
|
+
"name": "content_search_idx",
|
|
370
|
+
"columns": [
|
|
371
|
+
{
|
|
372
|
+
"expression": "content",
|
|
373
|
+
"isExpression": false,
|
|
374
|
+
"asc": true,
|
|
375
|
+
"nulls": "last"
|
|
376
|
+
}
|
|
377
|
+
],
|
|
378
|
+
"isUnique": false,
|
|
379
|
+
"concurrently": false,
|
|
380
|
+
"method": "gin",
|
|
381
|
+
"with": {}
|
|
382
|
+
},
|
|
383
|
+
"title_search_idx": {
|
|
384
|
+
"name": "title_search_idx",
|
|
385
|
+
"columns": [
|
|
386
|
+
{
|
|
387
|
+
"expression": "title",
|
|
388
|
+
"isExpression": false,
|
|
389
|
+
"asc": true,
|
|
390
|
+
"nulls": "last"
|
|
391
|
+
}
|
|
392
|
+
],
|
|
393
|
+
"isUnique": false,
|
|
394
|
+
"concurrently": false,
|
|
395
|
+
"method": "btree",
|
|
396
|
+
"with": {}
|
|
397
|
+
},
|
|
398
|
+
"search_index_idx": {
|
|
399
|
+
"name": "search_index_idx",
|
|
400
|
+
"columns": [
|
|
401
|
+
{
|
|
402
|
+
"expression": "search_index",
|
|
403
|
+
"isExpression": false,
|
|
404
|
+
"asc": true,
|
|
405
|
+
"nulls": "last"
|
|
406
|
+
}
|
|
407
|
+
],
|
|
408
|
+
"isUnique": false,
|
|
409
|
+
"concurrently": false,
|
|
410
|
+
"method": "btree",
|
|
411
|
+
"with": {}
|
|
412
|
+
},
|
|
413
|
+
"deleted_at_idx": {
|
|
414
|
+
"name": "deleted_at_idx",
|
|
415
|
+
"columns": [
|
|
416
|
+
{
|
|
417
|
+
"expression": "deletedAt",
|
|
418
|
+
"isExpression": false,
|
|
419
|
+
"asc": true,
|
|
420
|
+
"nulls": "last"
|
|
421
|
+
}
|
|
422
|
+
],
|
|
423
|
+
"isUnique": false,
|
|
424
|
+
"concurrently": false,
|
|
425
|
+
"method": "btree",
|
|
426
|
+
"with": {}
|
|
427
|
+
},
|
|
428
|
+
"parent_id_idx": {
|
|
429
|
+
"name": "parent_id_idx",
|
|
430
|
+
"columns": [
|
|
431
|
+
{
|
|
432
|
+
"expression": "parentId",
|
|
433
|
+
"isExpression": false,
|
|
434
|
+
"asc": true,
|
|
435
|
+
"nulls": "last"
|
|
436
|
+
}
|
|
437
|
+
],
|
|
438
|
+
"isUnique": false,
|
|
439
|
+
"concurrently": false,
|
|
440
|
+
"method": "btree",
|
|
441
|
+
"with": {}
|
|
442
|
+
},
|
|
443
|
+
"order_idx": {
|
|
444
|
+
"name": "order_idx",
|
|
445
|
+
"columns": [
|
|
446
|
+
{
|
|
447
|
+
"expression": "order",
|
|
448
|
+
"isExpression": false,
|
|
449
|
+
"asc": true,
|
|
450
|
+
"nulls": "last"
|
|
451
|
+
}
|
|
452
|
+
],
|
|
453
|
+
"isUnique": false,
|
|
454
|
+
"concurrently": false,
|
|
455
|
+
"method": "btree",
|
|
456
|
+
"with": {}
|
|
457
|
+
}
|
|
458
|
+
},
|
|
459
|
+
"foreignKeys": {
|
|
460
|
+
"documents_parentId_documents_id_fk": {
|
|
461
|
+
"name": "documents_parentId_documents_id_fk",
|
|
462
|
+
"tableFrom": "documents",
|
|
463
|
+
"tableTo": "documents",
|
|
464
|
+
"schemaTo": "docs",
|
|
465
|
+
"columnsFrom": [
|
|
466
|
+
"parentId"
|
|
467
|
+
],
|
|
468
|
+
"columnsTo": [
|
|
469
|
+
"id"
|
|
470
|
+
],
|
|
471
|
+
"onDelete": "no action",
|
|
472
|
+
"onUpdate": "no action"
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
"compositePrimaryKeys": {},
|
|
476
|
+
"uniqueConstraints": {
|
|
477
|
+
"documents_slug_unique": {
|
|
478
|
+
"name": "documents_slug_unique",
|
|
479
|
+
"nullsNotDistinct": false,
|
|
480
|
+
"columns": [
|
|
481
|
+
"slug"
|
|
482
|
+
]
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
},
|
|
486
|
+
"docs.files": {
|
|
487
|
+
"name": "files",
|
|
488
|
+
"schema": "docs",
|
|
489
|
+
"columns": {
|
|
490
|
+
"id": {
|
|
491
|
+
"name": "id",
|
|
492
|
+
"type": "varchar(21)",
|
|
493
|
+
"primaryKey": true,
|
|
494
|
+
"notNull": true
|
|
495
|
+
},
|
|
496
|
+
"filename": {
|
|
497
|
+
"name": "filename",
|
|
498
|
+
"type": "varchar(255)",
|
|
499
|
+
"primaryKey": false,
|
|
500
|
+
"notNull": true
|
|
501
|
+
},
|
|
502
|
+
"mimeType": {
|
|
503
|
+
"name": "mimeType",
|
|
504
|
+
"type": "varchar(100)",
|
|
505
|
+
"primaryKey": false,
|
|
506
|
+
"notNull": true
|
|
507
|
+
},
|
|
508
|
+
"size": {
|
|
509
|
+
"name": "size",
|
|
510
|
+
"type": "integer",
|
|
511
|
+
"primaryKey": false,
|
|
512
|
+
"notNull": true
|
|
513
|
+
},
|
|
514
|
+
"content": {
|
|
515
|
+
"name": "content",
|
|
516
|
+
"type": "text",
|
|
517
|
+
"primaryKey": false,
|
|
518
|
+
"notNull": true
|
|
519
|
+
},
|
|
520
|
+
"createdAt": {
|
|
521
|
+
"name": "createdAt",
|
|
522
|
+
"type": "timestamp",
|
|
523
|
+
"primaryKey": false,
|
|
524
|
+
"notNull": true,
|
|
525
|
+
"default": "NOW()"
|
|
526
|
+
},
|
|
527
|
+
"deletedAt": {
|
|
528
|
+
"name": "deletedAt",
|
|
529
|
+
"type": "timestamp",
|
|
530
|
+
"primaryKey": false,
|
|
531
|
+
"notNull": false
|
|
532
|
+
}
|
|
533
|
+
},
|
|
534
|
+
"indexes": {
|
|
535
|
+
"filename_idx": {
|
|
536
|
+
"name": "filename_idx",
|
|
537
|
+
"columns": [
|
|
538
|
+
{
|
|
539
|
+
"expression": "filename",
|
|
540
|
+
"isExpression": false,
|
|
541
|
+
"asc": true,
|
|
542
|
+
"nulls": "last"
|
|
543
|
+
}
|
|
544
|
+
],
|
|
545
|
+
"isUnique": false,
|
|
546
|
+
"concurrently": false,
|
|
547
|
+
"method": "btree",
|
|
548
|
+
"with": {}
|
|
549
|
+
},
|
|
550
|
+
"mime_type_idx": {
|
|
551
|
+
"name": "mime_type_idx",
|
|
552
|
+
"columns": [
|
|
553
|
+
{
|
|
554
|
+
"expression": "mimeType",
|
|
555
|
+
"isExpression": false,
|
|
556
|
+
"asc": true,
|
|
557
|
+
"nulls": "last"
|
|
558
|
+
}
|
|
559
|
+
],
|
|
560
|
+
"isUnique": false,
|
|
561
|
+
"concurrently": false,
|
|
562
|
+
"method": "btree",
|
|
563
|
+
"with": {}
|
|
564
|
+
},
|
|
565
|
+
"files_deleted_at_idx": {
|
|
566
|
+
"name": "files_deleted_at_idx",
|
|
567
|
+
"columns": [
|
|
568
|
+
{
|
|
569
|
+
"expression": "deletedAt",
|
|
570
|
+
"isExpression": false,
|
|
571
|
+
"asc": true,
|
|
572
|
+
"nulls": "last"
|
|
573
|
+
}
|
|
574
|
+
],
|
|
575
|
+
"isUnique": false,
|
|
576
|
+
"concurrently": false,
|
|
577
|
+
"method": "btree",
|
|
578
|
+
"with": {}
|
|
579
|
+
}
|
|
580
|
+
},
|
|
581
|
+
"foreignKeys": {},
|
|
582
|
+
"compositePrimaryKeys": {},
|
|
583
|
+
"uniqueConstraints": {}
|
|
584
|
+
}
|
|
585
|
+
},
|
|
586
|
+
"enums": {},
|
|
587
|
+
"schemas": {
|
|
588
|
+
"docs": "docs"
|
|
589
|
+
},
|
|
590
|
+
"_meta": {
|
|
591
|
+
"columns": {},
|
|
592
|
+
"schemas": {},
|
|
593
|
+
"tables": {}
|
|
594
|
+
}
|
|
595
|
+
}
|
package/package.json
CHANGED