@synap-core/types 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/.turbo/turbo-build.log +30 -0
- package/dist/documents/index.d.ts +66 -0
- package/dist/documents/index.js +1 -0
- package/dist/documents/index.js.map +1 -0
- package/dist/entities/index.d.ts +327 -0
- package/dist/entities/index.js +84 -0
- package/dist/entities/index.js.map +1 -0
- package/dist/inbox/index.d.ts +162 -0
- package/dist/inbox/index.js +49 -0
- package/dist/inbox/index.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +131 -0
- package/dist/index.js.map +1 -0
- package/dist/users/index.d.ts +65 -0
- package/dist/users/index.js +1 -0
- package/dist/users/index.js.map +1 -0
- package/package.json +45 -0
- package/src/documents/index.ts +81 -0
- package/src/entities/guards.ts +52 -0
- package/src/entities/index.ts +14 -0
- package/src/entities/schemas.ts +96 -0
- package/src/entities/types.ts +66 -0
- package/src/inbox/index.ts +116 -0
- package/src/index.ts +18 -0
- package/src/users/index.ts +98 -0
- package/tsconfig.json +18 -0
- package/tsup.config.ts +16 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> @synap-core/types@0.1.0 build /Users/antoine/Documents/Code/synap/synap-backend/packages/types
|
|
4
|
+
> tsup
|
|
5
|
+
|
|
6
|
+
[34mCLI[39m Building entry: {"index":"src/index.ts","entities/index":"src/entities/index.ts","documents/index":"src/documents/index.ts","users/index":"src/users/index.ts","inbox/index":"src/inbox/index.ts"}
|
|
7
|
+
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
8
|
+
[34mCLI[39m tsup v8.5.1
|
|
9
|
+
[34mCLI[39m Using tsup config: /Users/antoine/Documents/Code/synap/synap-backend/packages/types/tsup.config.ts
|
|
10
|
+
[34mCLI[39m Target: es2022
|
|
11
|
+
[34mCLI[39m Cleaning output folder
|
|
12
|
+
[34mESM[39m Build start
|
|
13
|
+
[32mESM[39m [1mdist/index.js [22m[32m3.57 KB[39m
|
|
14
|
+
[32mESM[39m [1mdist/users/index.js [22m[32m33.00 B[39m
|
|
15
|
+
[32mESM[39m [1mdist/entities/index.js [22m[32m2.40 KB[39m
|
|
16
|
+
[32mESM[39m [1mdist/inbox/index.js [22m[32m1.18 KB[39m
|
|
17
|
+
[32mESM[39m [1mdist/documents/index.js [22m[32m33.00 B[39m
|
|
18
|
+
[32mESM[39m [1mdist/entities/index.js.map [22m[32m6.12 KB[39m
|
|
19
|
+
[32mESM[39m [1mdist/inbox/index.js.map [22m[32m3.91 KB[39m
|
|
20
|
+
[32mESM[39m [1mdist/users/index.js.map [22m[32m71.00 B[39m
|
|
21
|
+
[32mESM[39m [1mdist/index.js.map [22m[32m9.99 KB[39m
|
|
22
|
+
[32mESM[39m [1mdist/documents/index.js.map [22m[32m71.00 B[39m
|
|
23
|
+
[32mESM[39m ⚡️ Build success in 15ms
|
|
24
|
+
DTS Build start
|
|
25
|
+
DTS ⚡️ Build success in 1457ms
|
|
26
|
+
DTS dist/index.d.ts 687.00 B
|
|
27
|
+
DTS dist/documents/index.d.ts 1.49 KB
|
|
28
|
+
DTS dist/users/index.d.ts 1.55 KB
|
|
29
|
+
DTS dist/inbox/index.d.ts 4.45 KB
|
|
30
|
+
DTS dist/entities/index.d.ts 10.23 KB
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Document Types
|
|
3
|
+
*
|
|
4
|
+
* Types for document storage and versioning.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Document - stores file content with versioning
|
|
8
|
+
*/
|
|
9
|
+
interface Document {
|
|
10
|
+
id: string;
|
|
11
|
+
userId: string;
|
|
12
|
+
title: string;
|
|
13
|
+
type: 'text' | 'markdown' | 'code' | 'pdf' | 'docx';
|
|
14
|
+
language?: string;
|
|
15
|
+
storageUrl: string;
|
|
16
|
+
storageKey: string;
|
|
17
|
+
size: number;
|
|
18
|
+
mimeType?: string;
|
|
19
|
+
currentVersion: number;
|
|
20
|
+
projectId?: string;
|
|
21
|
+
metadata?: Record<string, unknown>;
|
|
22
|
+
createdAt: Date;
|
|
23
|
+
updatedAt: Date;
|
|
24
|
+
deletedAt?: Date;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Document version - stores historical versions
|
|
28
|
+
*/
|
|
29
|
+
interface DocumentVersion {
|
|
30
|
+
id: string;
|
|
31
|
+
documentId: string;
|
|
32
|
+
version: number;
|
|
33
|
+
content: string;
|
|
34
|
+
delta?: unknown;
|
|
35
|
+
author: 'user' | 'ai';
|
|
36
|
+
authorId: string;
|
|
37
|
+
message?: string;
|
|
38
|
+
createdAt: Date;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Document session - for real-time collaboration
|
|
42
|
+
*/
|
|
43
|
+
interface DocumentSession {
|
|
44
|
+
id: string;
|
|
45
|
+
documentId: string;
|
|
46
|
+
userId: string;
|
|
47
|
+
chatThreadId: string;
|
|
48
|
+
isActive: boolean;
|
|
49
|
+
activeCollaborators?: Array<{
|
|
50
|
+
type: 'user' | 'ai';
|
|
51
|
+
id: string;
|
|
52
|
+
cursor?: unknown;
|
|
53
|
+
}>;
|
|
54
|
+
startedAt: Date;
|
|
55
|
+
endedAt?: Date;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* New document (for creation)
|
|
59
|
+
*/
|
|
60
|
+
type NewDocument = Omit<Document, 'id' | 'currentVersion' | 'createdAt' | 'updatedAt'>;
|
|
61
|
+
/**
|
|
62
|
+
* Document update (for updates)
|
|
63
|
+
*/
|
|
64
|
+
type UpdateDocument = Partial<Omit<Document, 'id' | 'userId' | 'createdAt' | 'updatedAt'>>;
|
|
65
|
+
|
|
66
|
+
export type { Document, DocumentSession, DocumentVersion, NewDocument, UpdateDocument };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Entity Metadata Schemas
|
|
5
|
+
*
|
|
6
|
+
* Defines Zod schemas for all entity types.
|
|
7
|
+
* TypeScript types are auto-generated from these schemas.
|
|
8
|
+
*
|
|
9
|
+
* Adding a new entity type: Just add to ENTITY_SCHEMAS!
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Entity metadata schemas - one per entity type
|
|
14
|
+
*
|
|
15
|
+
* The type key MUST match the entity.type field in the database
|
|
16
|
+
*/
|
|
17
|
+
declare const ENTITY_SCHEMAS: {
|
|
18
|
+
readonly task: z.ZodObject<{
|
|
19
|
+
status: z.ZodDefault<z.ZodEnum<["todo", "in_progress", "done", "archived"]>>;
|
|
20
|
+
priority: z.ZodOptional<z.ZodEnum<["low", "medium", "high", "urgent"]>>;
|
|
21
|
+
dueDate: z.ZodOptional<z.ZodString>;
|
|
22
|
+
completedAt: z.ZodOptional<z.ZodString>;
|
|
23
|
+
assignee: z.ZodOptional<z.ZodString>;
|
|
24
|
+
estimatedMinutes: z.ZodOptional<z.ZodNumber>;
|
|
25
|
+
actualMinutes: z.ZodOptional<z.ZodNumber>;
|
|
26
|
+
}, "strip", z.ZodTypeAny, {
|
|
27
|
+
status: "todo" | "in_progress" | "done" | "archived";
|
|
28
|
+
priority?: "low" | "medium" | "high" | "urgent" | undefined;
|
|
29
|
+
dueDate?: string | undefined;
|
|
30
|
+
completedAt?: string | undefined;
|
|
31
|
+
assignee?: string | undefined;
|
|
32
|
+
estimatedMinutes?: number | undefined;
|
|
33
|
+
actualMinutes?: number | undefined;
|
|
34
|
+
}, {
|
|
35
|
+
status?: "todo" | "in_progress" | "done" | "archived" | undefined;
|
|
36
|
+
priority?: "low" | "medium" | "high" | "urgent" | undefined;
|
|
37
|
+
dueDate?: string | undefined;
|
|
38
|
+
completedAt?: string | undefined;
|
|
39
|
+
assignee?: string | undefined;
|
|
40
|
+
estimatedMinutes?: number | undefined;
|
|
41
|
+
actualMinutes?: number | undefined;
|
|
42
|
+
}>;
|
|
43
|
+
readonly note: z.ZodObject<{
|
|
44
|
+
tags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
45
|
+
format: z.ZodDefault<z.ZodEnum<["markdown", "plain", "rich"]>>;
|
|
46
|
+
linkedEntities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
47
|
+
isFavorite: z.ZodDefault<z.ZodBoolean>;
|
|
48
|
+
}, "strip", z.ZodTypeAny, {
|
|
49
|
+
tags: string[];
|
|
50
|
+
format: "markdown" | "plain" | "rich";
|
|
51
|
+
isFavorite: boolean;
|
|
52
|
+
linkedEntities?: string[] | undefined;
|
|
53
|
+
}, {
|
|
54
|
+
tags?: string[] | undefined;
|
|
55
|
+
format?: "markdown" | "plain" | "rich" | undefined;
|
|
56
|
+
linkedEntities?: string[] | undefined;
|
|
57
|
+
isFavorite?: boolean | undefined;
|
|
58
|
+
}>;
|
|
59
|
+
readonly person: z.ZodObject<{
|
|
60
|
+
email: z.ZodOptional<z.ZodString>;
|
|
61
|
+
phone: z.ZodOptional<z.ZodString>;
|
|
62
|
+
company: z.ZodOptional<z.ZodString>;
|
|
63
|
+
role: z.ZodOptional<z.ZodString>;
|
|
64
|
+
linkedInUrl: z.ZodOptional<z.ZodString>;
|
|
65
|
+
twitterHandle: z.ZodOptional<z.ZodString>;
|
|
66
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
67
|
+
}, "strip", z.ZodTypeAny, {
|
|
68
|
+
email?: string | undefined;
|
|
69
|
+
phone?: string | undefined;
|
|
70
|
+
company?: string | undefined;
|
|
71
|
+
role?: string | undefined;
|
|
72
|
+
linkedInUrl?: string | undefined;
|
|
73
|
+
twitterHandle?: string | undefined;
|
|
74
|
+
notes?: string | undefined;
|
|
75
|
+
}, {
|
|
76
|
+
email?: string | undefined;
|
|
77
|
+
phone?: string | undefined;
|
|
78
|
+
company?: string | undefined;
|
|
79
|
+
role?: string | undefined;
|
|
80
|
+
linkedInUrl?: string | undefined;
|
|
81
|
+
twitterHandle?: string | undefined;
|
|
82
|
+
notes?: string | undefined;
|
|
83
|
+
}>;
|
|
84
|
+
readonly event: z.ZodObject<{
|
|
85
|
+
startTime: z.ZodString;
|
|
86
|
+
endTime: z.ZodString;
|
|
87
|
+
location: z.ZodOptional<z.ZodString>;
|
|
88
|
+
attendees: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
89
|
+
recurring: z.ZodDefault<z.ZodBoolean>;
|
|
90
|
+
recurrenceRule: z.ZodOptional<z.ZodString>;
|
|
91
|
+
isAllDay: z.ZodDefault<z.ZodBoolean>;
|
|
92
|
+
reminderMinutes: z.ZodOptional<z.ZodNumber>;
|
|
93
|
+
}, "strip", z.ZodTypeAny, {
|
|
94
|
+
startTime: string;
|
|
95
|
+
endTime: string;
|
|
96
|
+
recurring: boolean;
|
|
97
|
+
isAllDay: boolean;
|
|
98
|
+
location?: string | undefined;
|
|
99
|
+
attendees?: string[] | undefined;
|
|
100
|
+
recurrenceRule?: string | undefined;
|
|
101
|
+
reminderMinutes?: number | undefined;
|
|
102
|
+
}, {
|
|
103
|
+
startTime: string;
|
|
104
|
+
endTime: string;
|
|
105
|
+
location?: string | undefined;
|
|
106
|
+
attendees?: string[] | undefined;
|
|
107
|
+
recurring?: boolean | undefined;
|
|
108
|
+
recurrenceRule?: string | undefined;
|
|
109
|
+
isAllDay?: boolean | undefined;
|
|
110
|
+
reminderMinutes?: number | undefined;
|
|
111
|
+
}>;
|
|
112
|
+
readonly file: z.ZodObject<{
|
|
113
|
+
mimeType: z.ZodString;
|
|
114
|
+
sizeBytes: z.ZodNumber;
|
|
115
|
+
extension: z.ZodString;
|
|
116
|
+
thumbnailUrl: z.ZodOptional<z.ZodString>;
|
|
117
|
+
downloadUrl: z.ZodOptional<z.ZodString>;
|
|
118
|
+
}, "strip", z.ZodTypeAny, {
|
|
119
|
+
mimeType: string;
|
|
120
|
+
sizeBytes: number;
|
|
121
|
+
extension: string;
|
|
122
|
+
thumbnailUrl?: string | undefined;
|
|
123
|
+
downloadUrl?: string | undefined;
|
|
124
|
+
}, {
|
|
125
|
+
mimeType: string;
|
|
126
|
+
sizeBytes: number;
|
|
127
|
+
extension: string;
|
|
128
|
+
thumbnailUrl?: string | undefined;
|
|
129
|
+
downloadUrl?: string | undefined;
|
|
130
|
+
}>;
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* Entity type enum - auto-generated from schema keys
|
|
134
|
+
*/
|
|
135
|
+
type EntityType = keyof typeof ENTITY_SCHEMAS;
|
|
136
|
+
/**
|
|
137
|
+
* Entity metadata types - auto-generated from schemas
|
|
138
|
+
*/
|
|
139
|
+
type EntityMetadata = {
|
|
140
|
+
[K in EntityType]: z.infer<typeof ENTITY_SCHEMAS[K]>;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Validation helper - validates metadata for a specific entity type
|
|
144
|
+
* Returns parsed metadata with proper typing
|
|
145
|
+
*/
|
|
146
|
+
declare function validateEntityMetadata<T extends EntityType>(type: T, metadata: unknown): z.infer<typeof ENTITY_SCHEMAS[T]>;
|
|
147
|
+
/**
|
|
148
|
+
* Safe validation helper - returns result with success/error
|
|
149
|
+
*/
|
|
150
|
+
declare function safeValidateEntityMetadata<T extends EntityType>(type: T, metadata: unknown): z.SafeParseReturnType<{
|
|
151
|
+
status?: "todo" | "in_progress" | "done" | "archived" | undefined;
|
|
152
|
+
priority?: "low" | "medium" | "high" | "urgent" | undefined;
|
|
153
|
+
dueDate?: string | undefined;
|
|
154
|
+
completedAt?: string | undefined;
|
|
155
|
+
assignee?: string | undefined;
|
|
156
|
+
estimatedMinutes?: number | undefined;
|
|
157
|
+
actualMinutes?: number | undefined;
|
|
158
|
+
}, {
|
|
159
|
+
status: "todo" | "in_progress" | "done" | "archived";
|
|
160
|
+
priority?: "low" | "medium" | "high" | "urgent" | undefined;
|
|
161
|
+
dueDate?: string | undefined;
|
|
162
|
+
completedAt?: string | undefined;
|
|
163
|
+
assignee?: string | undefined;
|
|
164
|
+
estimatedMinutes?: number | undefined;
|
|
165
|
+
actualMinutes?: number | undefined;
|
|
166
|
+
}> | z.SafeParseReturnType<{
|
|
167
|
+
tags?: string[] | undefined;
|
|
168
|
+
format?: "markdown" | "plain" | "rich" | undefined;
|
|
169
|
+
linkedEntities?: string[] | undefined;
|
|
170
|
+
isFavorite?: boolean | undefined;
|
|
171
|
+
}, {
|
|
172
|
+
tags: string[];
|
|
173
|
+
format: "markdown" | "plain" | "rich";
|
|
174
|
+
isFavorite: boolean;
|
|
175
|
+
linkedEntities?: string[] | undefined;
|
|
176
|
+
}> | z.SafeParseReturnType<{
|
|
177
|
+
email?: string | undefined;
|
|
178
|
+
phone?: string | undefined;
|
|
179
|
+
company?: string | undefined;
|
|
180
|
+
role?: string | undefined;
|
|
181
|
+
linkedInUrl?: string | undefined;
|
|
182
|
+
twitterHandle?: string | undefined;
|
|
183
|
+
notes?: string | undefined;
|
|
184
|
+
}, {
|
|
185
|
+
email?: string | undefined;
|
|
186
|
+
phone?: string | undefined;
|
|
187
|
+
company?: string | undefined;
|
|
188
|
+
role?: string | undefined;
|
|
189
|
+
linkedInUrl?: string | undefined;
|
|
190
|
+
twitterHandle?: string | undefined;
|
|
191
|
+
notes?: string | undefined;
|
|
192
|
+
}> | z.SafeParseReturnType<{
|
|
193
|
+
startTime: string;
|
|
194
|
+
endTime: string;
|
|
195
|
+
location?: string | undefined;
|
|
196
|
+
attendees?: string[] | undefined;
|
|
197
|
+
recurring?: boolean | undefined;
|
|
198
|
+
recurrenceRule?: string | undefined;
|
|
199
|
+
isAllDay?: boolean | undefined;
|
|
200
|
+
reminderMinutes?: number | undefined;
|
|
201
|
+
}, {
|
|
202
|
+
startTime: string;
|
|
203
|
+
endTime: string;
|
|
204
|
+
recurring: boolean;
|
|
205
|
+
isAllDay: boolean;
|
|
206
|
+
location?: string | undefined;
|
|
207
|
+
attendees?: string[] | undefined;
|
|
208
|
+
recurrenceRule?: string | undefined;
|
|
209
|
+
reminderMinutes?: number | undefined;
|
|
210
|
+
}> | z.SafeParseReturnType<{
|
|
211
|
+
mimeType: string;
|
|
212
|
+
sizeBytes: number;
|
|
213
|
+
extension: string;
|
|
214
|
+
thumbnailUrl?: string | undefined;
|
|
215
|
+
downloadUrl?: string | undefined;
|
|
216
|
+
}, {
|
|
217
|
+
mimeType: string;
|
|
218
|
+
sizeBytes: number;
|
|
219
|
+
extension: string;
|
|
220
|
+
thumbnailUrl?: string | undefined;
|
|
221
|
+
downloadUrl?: string | undefined;
|
|
222
|
+
}>;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Entity Types
|
|
226
|
+
*
|
|
227
|
+
* TypeScript types for entities with discriminated unions.
|
|
228
|
+
* Types are automatically generated from Zod schemas.
|
|
229
|
+
*/
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Base entity - common fields for all entity types
|
|
233
|
+
*/
|
|
234
|
+
interface BaseEntity {
|
|
235
|
+
id: string;
|
|
236
|
+
userId: string;
|
|
237
|
+
type: EntityType;
|
|
238
|
+
title?: string;
|
|
239
|
+
preview?: string;
|
|
240
|
+
documentId?: string;
|
|
241
|
+
version: number;
|
|
242
|
+
createdAt: Date;
|
|
243
|
+
updatedAt: Date;
|
|
244
|
+
deletedAt?: Date;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Entity - Discriminated union of all entity types
|
|
248
|
+
*
|
|
249
|
+
* TypeScript automatically narrows the type based on the `type` field:
|
|
250
|
+
*
|
|
251
|
+
* ```ts
|
|
252
|
+
* if (entity.type === 'task') {
|
|
253
|
+
* // entity.metadata.status is accessible and type-safe!
|
|
254
|
+
* }
|
|
255
|
+
* ```
|
|
256
|
+
*/
|
|
257
|
+
type Entity = {
|
|
258
|
+
[K in EntityType]: BaseEntity & {
|
|
259
|
+
type: K;
|
|
260
|
+
metadata: EntityMetadata[K];
|
|
261
|
+
};
|
|
262
|
+
}[EntityType];
|
|
263
|
+
/**
|
|
264
|
+
* Specific entity types (for explicit typing)
|
|
265
|
+
*/
|
|
266
|
+
type Task = Extract<Entity, {
|
|
267
|
+
type: 'task';
|
|
268
|
+
}>;
|
|
269
|
+
type Note = Extract<Entity, {
|
|
270
|
+
type: 'note';
|
|
271
|
+
}>;
|
|
272
|
+
type Person = Extract<Entity, {
|
|
273
|
+
type: 'person';
|
|
274
|
+
}>;
|
|
275
|
+
type Event = Extract<Entity, {
|
|
276
|
+
type: 'event';
|
|
277
|
+
}>;
|
|
278
|
+
type File = Extract<Entity, {
|
|
279
|
+
type: 'file';
|
|
280
|
+
}>;
|
|
281
|
+
/**
|
|
282
|
+
* New entity type (for creation)
|
|
283
|
+
*/
|
|
284
|
+
type NewEntity<T extends EntityType = EntityType> = Omit<Extract<Entity, {
|
|
285
|
+
type: T;
|
|
286
|
+
}>, 'id' | 'version' | 'createdAt' | 'updatedAt'>;
|
|
287
|
+
/**
|
|
288
|
+
* Entity update type (for updates)
|
|
289
|
+
*/
|
|
290
|
+
type UpdateEntity<T extends EntityType = EntityType> = Partial<Omit<Extract<Entity, {
|
|
291
|
+
type: T;
|
|
292
|
+
}>, 'id' | 'userId' | 'type' | 'createdAt' | 'updatedAt'>>;
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Entity Type Guards
|
|
296
|
+
*
|
|
297
|
+
* Type guard functions for narrowing entity types.
|
|
298
|
+
*/
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Type guard for Task entities
|
|
302
|
+
*/
|
|
303
|
+
declare function isTask(entity: Entity): entity is Task;
|
|
304
|
+
/**
|
|
305
|
+
* Type guard for Note entities
|
|
306
|
+
*/
|
|
307
|
+
declare function isNote(entity: Entity): entity is Note;
|
|
308
|
+
/**
|
|
309
|
+
* Type guard for Person entities
|
|
310
|
+
*/
|
|
311
|
+
declare function isPerson(entity: Entity): entity is Person;
|
|
312
|
+
/**
|
|
313
|
+
* Type guard for Event entities
|
|
314
|
+
*/
|
|
315
|
+
declare function isEvent(entity: Entity): entity is Event;
|
|
316
|
+
/**
|
|
317
|
+
* Type guard for File entities
|
|
318
|
+
*/
|
|
319
|
+
declare function isFile(entity: Entity): entity is File;
|
|
320
|
+
/**
|
|
321
|
+
* Generic type guard for any entity type
|
|
322
|
+
*/
|
|
323
|
+
declare function isEntityOfType<T extends Entity['type']>(entity: Entity, type: T): entity is Extract<Entity, {
|
|
324
|
+
type: T;
|
|
325
|
+
}>;
|
|
326
|
+
|
|
327
|
+
export { type BaseEntity, ENTITY_SCHEMAS, type Entity, type EntityMetadata, type EntityType, type Event, type File, type NewEntity, type Note, type Person, type Task, type UpdateEntity, isEntityOfType, isEvent, isFile, isNote, isPerson, isTask, safeValidateEntityMetadata, validateEntityMetadata };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// src/entities/schemas.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
var ENTITY_SCHEMAS = {
|
|
4
|
+
task: z.object({
|
|
5
|
+
status: z.enum(["todo", "in_progress", "done", "archived"]).default("todo"),
|
|
6
|
+
priority: z.enum(["low", "medium", "high", "urgent"]).optional(),
|
|
7
|
+
dueDate: z.string().datetime().optional(),
|
|
8
|
+
completedAt: z.string().datetime().optional(),
|
|
9
|
+
assignee: z.string().uuid().optional(),
|
|
10
|
+
estimatedMinutes: z.number().int().positive().optional(),
|
|
11
|
+
actualMinutes: z.number().int().positive().optional()
|
|
12
|
+
}),
|
|
13
|
+
note: z.object({
|
|
14
|
+
tags: z.array(z.string()).default([]),
|
|
15
|
+
format: z.enum(["markdown", "plain", "rich"]).default("markdown"),
|
|
16
|
+
linkedEntities: z.array(z.string().uuid()).optional(),
|
|
17
|
+
isFavorite: z.boolean().default(false)
|
|
18
|
+
}),
|
|
19
|
+
person: z.object({
|
|
20
|
+
email: z.string().email().optional(),
|
|
21
|
+
phone: z.string().optional(),
|
|
22
|
+
company: z.string().optional(),
|
|
23
|
+
role: z.string().optional(),
|
|
24
|
+
linkedInUrl: z.string().url().optional(),
|
|
25
|
+
twitterHandle: z.string().optional(),
|
|
26
|
+
notes: z.string().optional()
|
|
27
|
+
}),
|
|
28
|
+
event: z.object({
|
|
29
|
+
startTime: z.string().datetime(),
|
|
30
|
+
endTime: z.string().datetime(),
|
|
31
|
+
location: z.string().optional(),
|
|
32
|
+
attendees: z.array(z.string().uuid()).optional(),
|
|
33
|
+
recurring: z.boolean().default(false),
|
|
34
|
+
recurrenceRule: z.string().optional(),
|
|
35
|
+
// iCal RRULE format
|
|
36
|
+
isAllDay: z.boolean().default(false),
|
|
37
|
+
reminderMinutes: z.number().int().optional()
|
|
38
|
+
}),
|
|
39
|
+
file: z.object({
|
|
40
|
+
mimeType: z.string(),
|
|
41
|
+
sizeBytes: z.number().int().positive(),
|
|
42
|
+
extension: z.string(),
|
|
43
|
+
thumbnailUrl: z.string().url().optional(),
|
|
44
|
+
downloadUrl: z.string().url().optional()
|
|
45
|
+
})
|
|
46
|
+
};
|
|
47
|
+
function validateEntityMetadata(type, metadata) {
|
|
48
|
+
return ENTITY_SCHEMAS[type].parse(metadata);
|
|
49
|
+
}
|
|
50
|
+
function safeValidateEntityMetadata(type, metadata) {
|
|
51
|
+
return ENTITY_SCHEMAS[type].safeParse(metadata);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// src/entities/guards.ts
|
|
55
|
+
function isTask(entity) {
|
|
56
|
+
return entity.type === "task";
|
|
57
|
+
}
|
|
58
|
+
function isNote(entity) {
|
|
59
|
+
return entity.type === "note";
|
|
60
|
+
}
|
|
61
|
+
function isPerson(entity) {
|
|
62
|
+
return entity.type === "person";
|
|
63
|
+
}
|
|
64
|
+
function isEvent(entity) {
|
|
65
|
+
return entity.type === "event";
|
|
66
|
+
}
|
|
67
|
+
function isFile(entity) {
|
|
68
|
+
return entity.type === "file";
|
|
69
|
+
}
|
|
70
|
+
function isEntityOfType(entity, type) {
|
|
71
|
+
return entity.type === type;
|
|
72
|
+
}
|
|
73
|
+
export {
|
|
74
|
+
ENTITY_SCHEMAS,
|
|
75
|
+
isEntityOfType,
|
|
76
|
+
isEvent,
|
|
77
|
+
isFile,
|
|
78
|
+
isNote,
|
|
79
|
+
isPerson,
|
|
80
|
+
isTask,
|
|
81
|
+
safeValidateEntityMetadata,
|
|
82
|
+
validateEntityMetadata
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/entities/schemas.ts","../../src/entities/guards.ts"],"sourcesContent":["/**\n * Entity Metadata Schemas\n * \n * Defines Zod schemas for all entity types.\n * TypeScript types are auto-generated from these schemas.\n * \n * Adding a new entity type: Just add to ENTITY_SCHEMAS!\n */\n\nimport { z } from 'zod';\n\n/**\n * Entity metadata schemas - one per entity type\n * \n * The type key MUST match the entity.type field in the database\n */\nexport const ENTITY_SCHEMAS = {\n task: z.object({\n status: z.enum(['todo', 'in_progress', 'done', 'archived']).default('todo'),\n priority: z.enum(['low', 'medium', 'high', 'urgent']).optional(),\n dueDate: z.string().datetime().optional(),\n completedAt: z.string().datetime().optional(),\n assignee: z.string().uuid().optional(),\n estimatedMinutes: z.number().int().positive().optional(),\n actualMinutes: z.number().int().positive().optional(),\n }),\n \n note: z.object({\n tags: z.array(z.string()).default([]),\n format: z.enum(['markdown', 'plain', 'rich']).default('markdown'),\n linkedEntities: z.array(z.string().uuid()).optional(),\n isFavorite: z.boolean().default(false),\n }),\n \n person: z.object({\n email: z.string().email().optional(),\n phone: z.string().optional(),\n company: z.string().optional(),\n role: z.string().optional(),\n linkedInUrl: z.string().url().optional(),\n twitterHandle: z.string().optional(),\n notes: z.string().optional(),\n }),\n \n event: z.object({\n startTime: z.string().datetime(),\n endTime: z.string().datetime(),\n location: z.string().optional(),\n attendees: z.array(z.string().uuid()).optional(),\n recurring: z.boolean().default(false),\n recurrenceRule: z.string().optional(), // iCal RRULE format\n isAllDay: z.boolean().default(false),\n reminderMinutes: z.number().int().optional(),\n }),\n \n file: z.object({\n mimeType: z.string(),\n sizeBytes: z.number().int().positive(),\n extension: z.string(),\n thumbnailUrl: z.string().url().optional(),\n downloadUrl: z.string().url().optional(),\n }),\n} as const;\n\n/**\n * Entity type enum - auto-generated from schema keys\n */\nexport type EntityType = keyof typeof ENTITY_SCHEMAS;\n\n/**\n * Entity metadata types - auto-generated from schemas\n */\nexport type EntityMetadata = {\n [K in EntityType]: z.infer<typeof ENTITY_SCHEMAS[K]>\n};\n\n/**\n * Validation helper - validates metadata for a specific entity type\n * Returns parsed metadata with proper typing\n */\nexport function validateEntityMetadata<T extends EntityType>(\n type: T,\n metadata: unknown\n): z.infer<typeof ENTITY_SCHEMAS[T]> {\n return ENTITY_SCHEMAS[type].parse(metadata) as z.infer<typeof ENTITY_SCHEMAS[T]>;\n}\n\n/**\n * Safe validation helper - returns result with success/error\n */\nexport function safeValidateEntityMetadata<T extends EntityType>(\n type: T,\n metadata: unknown\n) {\n return ENTITY_SCHEMAS[type].safeParse(metadata);\n}\n","/**\n * Entity Type Guards\n * \n * Type guard functions for narrowing entity types.\n */\n\nimport type { Entity, Task, Note, Person, Event, File } from './types.js';\n\n/**\n * Type guard for Task entities\n */\nexport function isTask(entity: Entity): entity is Task {\n return entity.type === 'task';\n}\n\n/**\n * Type guard for Note entities\n */\nexport function isNote(entity: Entity): entity is Note {\n return entity.type === 'note';\n}\n\n/**\n * Type guard for Person entities\n */\nexport function isPerson(entity: Entity): entity is Person {\n return entity.type === 'person';\n}\n\n/**\n * Type guard for Event entities\n */\nexport function isEvent(entity: Entity): entity is Event {\n return entity.type === 'event';\n}\n\n/**\n * Type guard for File entities\n */\nexport function isFile(entity: Entity): entity is File {\n return entity.type === 'file';\n}\n\n/**\n * Generic type guard for any entity type\n */\nexport function isEntityOfType<T extends Entity['type']>(\n entity: Entity,\n type: T\n): entity is Extract<Entity, { type: T }> {\n return entity.type === type;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Inbox Item Schemas & Types
|
|
5
|
+
*
|
|
6
|
+
* Types for external items (emails, calendar events, etc.)
|
|
7
|
+
* that are staged in the inbox before becoming entities.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Inbox item data schemas - provider-specific
|
|
12
|
+
*/
|
|
13
|
+
declare const INBOX_SCHEMAS: {
|
|
14
|
+
readonly email: z.ZodObject<{
|
|
15
|
+
from: z.ZodString;
|
|
16
|
+
to: z.ZodArray<z.ZodString, "many">;
|
|
17
|
+
subject: z.ZodString;
|
|
18
|
+
snippet: z.ZodString;
|
|
19
|
+
threadId: z.ZodOptional<z.ZodString>;
|
|
20
|
+
labels: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
21
|
+
}, "strip", z.ZodTypeAny, {
|
|
22
|
+
from: string;
|
|
23
|
+
to: string[];
|
|
24
|
+
subject: string;
|
|
25
|
+
snippet: string;
|
|
26
|
+
threadId?: string | undefined;
|
|
27
|
+
labels?: string[] | undefined;
|
|
28
|
+
}, {
|
|
29
|
+
from: string;
|
|
30
|
+
to: string[];
|
|
31
|
+
subject: string;
|
|
32
|
+
snippet: string;
|
|
33
|
+
threadId?: string | undefined;
|
|
34
|
+
labels?: string[] | undefined;
|
|
35
|
+
}>;
|
|
36
|
+
readonly calendar_event: z.ZodObject<{
|
|
37
|
+
summary: z.ZodString;
|
|
38
|
+
description: z.ZodOptional<z.ZodString>;
|
|
39
|
+
location: z.ZodOptional<z.ZodString>;
|
|
40
|
+
start: z.ZodString;
|
|
41
|
+
end: z.ZodString;
|
|
42
|
+
attendees: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
43
|
+
email: z.ZodString;
|
|
44
|
+
name: z.ZodOptional<z.ZodString>;
|
|
45
|
+
}, "strip", z.ZodTypeAny, {
|
|
46
|
+
email: string;
|
|
47
|
+
name?: string | undefined;
|
|
48
|
+
}, {
|
|
49
|
+
email: string;
|
|
50
|
+
name?: string | undefined;
|
|
51
|
+
}>, "many">>;
|
|
52
|
+
}, "strip", z.ZodTypeAny, {
|
|
53
|
+
summary: string;
|
|
54
|
+
start: string;
|
|
55
|
+
end: string;
|
|
56
|
+
location?: string | undefined;
|
|
57
|
+
attendees?: {
|
|
58
|
+
email: string;
|
|
59
|
+
name?: string | undefined;
|
|
60
|
+
}[] | undefined;
|
|
61
|
+
description?: string | undefined;
|
|
62
|
+
}, {
|
|
63
|
+
summary: string;
|
|
64
|
+
start: string;
|
|
65
|
+
end: string;
|
|
66
|
+
location?: string | undefined;
|
|
67
|
+
attendees?: {
|
|
68
|
+
email: string;
|
|
69
|
+
name?: string | undefined;
|
|
70
|
+
}[] | undefined;
|
|
71
|
+
description?: string | undefined;
|
|
72
|
+
}>;
|
|
73
|
+
readonly slack_message: z.ZodObject<{
|
|
74
|
+
channel: z.ZodString;
|
|
75
|
+
user: z.ZodString;
|
|
76
|
+
text: z.ZodString;
|
|
77
|
+
threadTs: z.ZodOptional<z.ZodString>;
|
|
78
|
+
reactions: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
79
|
+
name: z.ZodString;
|
|
80
|
+
count: z.ZodNumber;
|
|
81
|
+
}, "strip", z.ZodTypeAny, {
|
|
82
|
+
name: string;
|
|
83
|
+
count: number;
|
|
84
|
+
}, {
|
|
85
|
+
name: string;
|
|
86
|
+
count: number;
|
|
87
|
+
}>, "many">>;
|
|
88
|
+
}, "strip", z.ZodTypeAny, {
|
|
89
|
+
text: string;
|
|
90
|
+
user: string;
|
|
91
|
+
channel: string;
|
|
92
|
+
threadTs?: string | undefined;
|
|
93
|
+
reactions?: {
|
|
94
|
+
name: string;
|
|
95
|
+
count: number;
|
|
96
|
+
}[] | undefined;
|
|
97
|
+
}, {
|
|
98
|
+
text: string;
|
|
99
|
+
user: string;
|
|
100
|
+
channel: string;
|
|
101
|
+
threadTs?: string | undefined;
|
|
102
|
+
reactions?: {
|
|
103
|
+
name: string;
|
|
104
|
+
count: number;
|
|
105
|
+
}[] | undefined;
|
|
106
|
+
}>;
|
|
107
|
+
};
|
|
108
|
+
type InboxItemType = keyof typeof INBOX_SCHEMAS;
|
|
109
|
+
type InboxItemData = {
|
|
110
|
+
[K in InboxItemType]: z.infer<typeof INBOX_SCHEMAS[K]>;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Base inbox item fields
|
|
114
|
+
*/
|
|
115
|
+
interface BaseInboxItem {
|
|
116
|
+
id: string;
|
|
117
|
+
userId: string;
|
|
118
|
+
provider: 'gmail' | 'google_calendar' | 'slack';
|
|
119
|
+
account: string;
|
|
120
|
+
externalId: string;
|
|
121
|
+
deepLink?: string;
|
|
122
|
+
type: InboxItemType;
|
|
123
|
+
title: string;
|
|
124
|
+
preview?: string;
|
|
125
|
+
timestamp: Date;
|
|
126
|
+
status: 'unread' | 'read' | 'archived' | 'snoozed';
|
|
127
|
+
snoozedUntil?: Date;
|
|
128
|
+
priority?: 'urgent' | 'high' | 'normal' | 'low';
|
|
129
|
+
tags: string[];
|
|
130
|
+
processedAt?: Date;
|
|
131
|
+
createdAt: Date;
|
|
132
|
+
updatedAt: Date;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Inbox item - discriminated union
|
|
136
|
+
*/
|
|
137
|
+
type InboxItem = {
|
|
138
|
+
[K in InboxItemType]: BaseInboxItem & {
|
|
139
|
+
type: K;
|
|
140
|
+
data: InboxItemData[K];
|
|
141
|
+
};
|
|
142
|
+
}[InboxItemType];
|
|
143
|
+
/**
|
|
144
|
+
* Specific inbox item types
|
|
145
|
+
*/
|
|
146
|
+
type EmailInboxItem = Extract<InboxItem, {
|
|
147
|
+
type: 'email';
|
|
148
|
+
}>;
|
|
149
|
+
type CalendarInboxItem = Extract<InboxItem, {
|
|
150
|
+
type: 'calendar_event';
|
|
151
|
+
}>;
|
|
152
|
+
type SlackInboxItem = Extract<InboxItem, {
|
|
153
|
+
type: 'slack_message';
|
|
154
|
+
}>;
|
|
155
|
+
/**
|
|
156
|
+
* Type guards
|
|
157
|
+
*/
|
|
158
|
+
declare function isEmailInboxItem(item: InboxItem): item is EmailInboxItem;
|
|
159
|
+
declare function isCalendarInboxItem(item: InboxItem): item is CalendarInboxItem;
|
|
160
|
+
declare function isSlackInboxItem(item: InboxItem): item is SlackInboxItem;
|
|
161
|
+
|
|
162
|
+
export { type CalendarInboxItem, type EmailInboxItem, INBOX_SCHEMAS, type InboxItem, type InboxItemType, type SlackInboxItem, isCalendarInboxItem, isEmailInboxItem, isSlackInboxItem };
|