@critical-path/core 0.6.0 → 0.7.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.
Files changed (64) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +6 -0
  3. package/dist/domain/events.d.ts +32 -4
  4. package/dist/domain/events.d.ts.map +1 -1
  5. package/dist/domain/events.js.map +1 -1
  6. package/dist/engine/index.d.ts +23 -1
  7. package/dist/engine/index.d.ts.map +1 -1
  8. package/dist/engine/index.js +130 -2
  9. package/dist/engine/index.js.map +1 -1
  10. package/dist/index.d.ts +1 -0
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +1 -0
  13. package/dist/index.js.map +1 -1
  14. package/dist/storage/file-storage.d.ts +24 -0
  15. package/dist/storage/file-storage.d.ts.map +1 -0
  16. package/dist/storage/file-storage.js +73 -0
  17. package/dist/storage/file-storage.js.map +1 -0
  18. package/dist/storage/firebase-storage.d.ts +48 -0
  19. package/dist/storage/firebase-storage.d.ts.map +1 -0
  20. package/dist/storage/firebase-storage.js +142 -0
  21. package/dist/storage/firebase-storage.js.map +1 -0
  22. package/dist/storage/index.d.ts +4 -0
  23. package/dist/storage/index.d.ts.map +1 -0
  24. package/dist/storage/index.js +4 -0
  25. package/dist/storage/index.js.map +1 -0
  26. package/dist/storage/s3.d.ts +36 -0
  27. package/dist/storage/s3.d.ts.map +1 -0
  28. package/dist/storage/s3.js +135 -0
  29. package/dist/storage/s3.js.map +1 -0
  30. package/dist/storage/storage.test.d.ts +2 -0
  31. package/dist/storage/storage.test.d.ts.map +1 -0
  32. package/dist/storage/storage.test.js +117 -0
  33. package/dist/storage/storage.test.js.map +1 -0
  34. package/dist/store/firebase.d.ts +12 -1
  35. package/dist/store/firebase.d.ts.map +1 -1
  36. package/dist/store/firebase.js +63 -1
  37. package/dist/store/firebase.js.map +1 -1
  38. package/dist/store/index.d.ts +27 -2
  39. package/dist/store/index.d.ts.map +1 -1
  40. package/dist/store/index.js +49 -0
  41. package/dist/store/index.js.map +1 -1
  42. package/dist/store/sqlite.d.ts +12 -1
  43. package/dist/store/sqlite.d.ts.map +1 -1
  44. package/dist/store/sqlite.js +128 -6
  45. package/dist/store/sqlite.js.map +1 -1
  46. package/dist/store/sqlite.test.js +47 -1
  47. package/dist/store/sqlite.test.js.map +1 -1
  48. package/dist/types/index.d.ts +52 -1
  49. package/dist/types/index.d.ts.map +1 -1
  50. package/package.json +1 -1
  51. package/src/domain/events.ts +28 -3
  52. package/src/engine/index.ts +166 -3
  53. package/src/index.ts +2 -0
  54. package/src/storage/file-storage.ts +96 -0
  55. package/src/storage/firebase-storage.ts +177 -0
  56. package/src/storage/index.ts +3 -0
  57. package/src/storage/s3.ts +165 -0
  58. package/src/storage/storage.test.ts +146 -0
  59. package/src/store/firebase.ts +64 -1
  60. package/src/store/index.ts +64 -0
  61. package/src/store/sqlite.test.ts +59 -1
  62. package/src/store/sqlite.ts +172 -6
  63. package/src/types/index.ts +63 -0
  64. package/tsconfig.tsbuildinfo +1 -1
@@ -8,6 +8,7 @@ import type {
8
8
  Team,
9
9
  TaskContainer,
10
10
  Comment,
11
+ Attachment,
11
12
  TimeEntry,
12
13
  Activity,
13
14
  Webhook,
@@ -66,7 +67,17 @@ export interface IterationRepository {
66
67
 
67
68
  export interface CommentRepository {
68
69
  getComments(taskId: string): Promise<Comment[]>;
70
+ getComment(id: string): Promise<Comment | null>;
69
71
  addComment(comment: Omit<Comment, 'id' | 'createdAt' | 'updatedAt'>): Promise<Comment>;
72
+ updateComment(id: string, updates: Partial<Comment>): Promise<Comment | null>;
73
+ deleteComment(id: string): Promise<boolean>;
74
+ }
75
+
76
+ export interface AttachmentRepository {
77
+ getAttachments(filter?: { taskId?: string; projectId?: string; commentId?: string }): Promise<Attachment[]>;
78
+ getAttachment(id: string): Promise<Attachment | null>;
79
+ createAttachment(attachment: Omit<Attachment, 'id' | 'createdAt' | 'updatedAt'>): Promise<Attachment>;
80
+ deleteAttachment(id: string): Promise<boolean>;
70
81
  }
71
82
 
72
83
  export interface ActivityRepository {
@@ -97,6 +108,7 @@ export interface StorageAdapter
97
108
  ContainerRepository,
98
109
  IterationRepository,
99
110
  CommentRepository,
111
+ AttachmentRepository,
100
112
  ActivityRepository,
101
113
  TimeEntryRepository,
102
114
  DependencyRepository,
@@ -110,6 +122,7 @@ export class InMemoryStore implements StorageAdapter {
110
122
  private containers = new Map<string, TaskContainer>();
111
123
  private iterations = new Map<string, Iteration>();
112
124
  private comments = new Map<string, Comment>();
125
+ private attachments = new Map<string, Attachment>();
113
126
  private activities: Activity[] = [];
114
127
  private timeEntries = new Map<string, TimeEntry>();
115
128
  private dependencies = new Map<string, TaskDependency>();
@@ -328,6 +341,10 @@ export class InMemoryStore implements StorageAdapter {
328
341
  return Array.from(this.comments.values()).filter((c) => c.taskId === taskId);
329
342
  }
330
343
 
344
+ async getComment(id: string): Promise<Comment | null> {
345
+ return this.comments.get(id) || null;
346
+ }
347
+
331
348
  async addComment(comment: Omit<Comment, 'id' | 'createdAt' | 'updatedAt'>): Promise<Comment> {
332
349
  const id = `cmt_${Math.random().toString(36).substring(2, 9)}`;
333
350
  const now = new Date().toISOString();
@@ -336,6 +353,53 @@ export class InMemoryStore implements StorageAdapter {
336
353
  return newComment;
337
354
  }
338
355
 
356
+ async updateComment(id: string, updates: Partial<Comment>): Promise<Comment | null> {
357
+ const existing = this.comments.get(id);
358
+ if (!existing) return null;
359
+ const updated: Comment = {
360
+ ...existing,
361
+ ...updates,
362
+ updatedAt: new Date().toISOString()
363
+ };
364
+ this.comments.set(id, updated);
365
+ return updated;
366
+ }
367
+
368
+ async deleteComment(id: string): Promise<boolean> {
369
+ return this.comments.delete(id);
370
+ }
371
+
372
+ // Attachments
373
+ async getAttachments(filter?: { taskId?: string; projectId?: string; commentId?: string }): Promise<Attachment[]> {
374
+ return Array.from(this.attachments.values()).filter((a) => {
375
+ if (filter?.taskId && a.taskId !== filter.taskId) return false;
376
+ if (filter?.projectId && a.projectId !== filter.projectId) return false;
377
+ if (filter?.commentId && a.commentId !== filter.commentId) return false;
378
+ return true;
379
+ });
380
+ }
381
+
382
+ async getAttachment(id: string): Promise<Attachment | null> {
383
+ return this.attachments.get(id) || null;
384
+ }
385
+
386
+ async createAttachment(attachment: Omit<Attachment, 'id' | 'createdAt' | 'updatedAt'>): Promise<Attachment> {
387
+ const id = `att_${Math.random().toString(36).substring(2, 9)}`;
388
+ const now = new Date().toISOString();
389
+ const newAttachment: Attachment = {
390
+ ...attachment,
391
+ id,
392
+ createdAt: now,
393
+ updatedAt: now
394
+ };
395
+ this.attachments.set(id, newAttachment);
396
+ return newAttachment;
397
+ }
398
+
399
+ async deleteAttachment(id: string): Promise<boolean> {
400
+ return this.attachments.delete(id);
401
+ }
402
+
339
403
  // Activities
340
404
  async getActivities(filter?: { projectId?: string; taskId?: string }): Promise<Activity[]> {
341
405
  return this.activities.filter((a) => {
@@ -57,12 +57,31 @@ describe('SQLiteStore', () => {
57
57
  const comment = await store.addComment({
58
58
  taskId: 'task_1',
59
59
  authorId: 'user_1',
60
+ authorType: 'user',
60
61
  content: 'Great work!'
61
62
  });
62
63
  expect(comment.id).toMatch(/^cmt_/);
64
+ expect(comment.authorType).toBe('user');
65
+
66
+ // Threaded reply
67
+ const reply = await store.addComment({
68
+ taskId: 'task_1',
69
+ authorId: 'agent_1',
70
+ authorType: 'agent',
71
+ parentId: comment.id,
72
+ content: 'I agree!'
73
+ });
74
+ expect(reply.parentId).toBe(comment.id);
75
+ expect(reply.authorType).toBe('agent');
63
76
 
64
77
  const comments = await store.getComments('task_1');
65
- expect(comments).toHaveLength(1);
78
+ expect(comments).toHaveLength(2);
79
+
80
+ const updatedComment = await store.updateComment(comment.id, { content: 'Updated content' });
81
+ expect(updatedComment?.content).toBe('Updated content');
82
+
83
+ const fetchedComment = await store.getComment(comment.id);
84
+ expect(fetchedComment?.content).toBe('Updated content');
66
85
 
67
86
  const timeEntry = await store.logTime({
68
87
  taskId: 'task_1',
@@ -74,6 +93,45 @@ describe('SQLiteStore', () => {
74
93
 
75
94
  const entries = await store.getTimeEntries('task_1');
76
95
  expect(entries).toHaveLength(1);
96
+
97
+ const deletedComment = await store.deleteComment(reply.id);
98
+ expect(deletedComment).toBe(true);
99
+ expect(await store.getComments('task_1')).toHaveLength(1);
100
+ });
101
+
102
+ it('should create, filter, retrieve, and delete attachments', async () => {
103
+ const attachment = await store.createAttachment({
104
+ filename: 'design-mockup.fig',
105
+ url: 'https://storage.example.com/design-mockup.fig',
106
+ storageKey: 'attachments/task_1/design-mockup.fig',
107
+ mimeType: 'application/octet-stream',
108
+ sizeBytes: 2048,
109
+ taskId: 'task_1',
110
+ projectId: 'proj_1',
111
+ uploaderId: 'user_1',
112
+ uploaderType: 'user'
113
+ });
114
+
115
+ expect(attachment.id).toMatch(/^att_/);
116
+ expect(attachment.filename).toBe('design-mockup.fig');
117
+
118
+ const fetched = await store.getAttachment(attachment.id);
119
+ expect(fetched?.url).toBe('https://storage.example.com/design-mockup.fig');
120
+
121
+ const taskAttachments = await store.getAttachments({ taskId: 'task_1' });
122
+ expect(taskAttachments).toHaveLength(1);
123
+
124
+ const projectAttachments = await store.getAttachments({ projectId: 'proj_1' });
125
+ expect(projectAttachments).toHaveLength(1);
126
+
127
+ const nonExistent = await store.getAttachments({ taskId: 'other_task' });
128
+ expect(nonExistent).toHaveLength(0);
129
+
130
+ const deleted = await store.deleteAttachment(attachment.id);
131
+ expect(deleted).toBe(true);
132
+
133
+ const remaining = await store.getAttachments({ taskId: 'task_1' });
134
+ expect(remaining).toHaveLength(0);
77
135
  });
78
136
 
79
137
  it('should create, retrieve, update, and delete workflows', async () => {
@@ -7,6 +7,7 @@ import type {
7
7
  Team,
8
8
  TaskContainer,
9
9
  Comment,
10
+ Attachment,
10
11
  TimeEntry,
11
12
  Activity,
12
13
  Webhook,
@@ -150,7 +151,27 @@ export class SQLiteStore implements StorageAdapter {
150
151
  id TEXT PRIMARY KEY,
151
152
  taskId TEXT NOT NULL,
152
153
  authorId TEXT NOT NULL,
154
+ authorType TEXT,
155
+ parentId TEXT,
153
156
  content TEXT NOT NULL,
157
+ metadata TEXT,
158
+ createdAt TEXT NOT NULL,
159
+ updatedAt TEXT NOT NULL
160
+ );
161
+
162
+ CREATE TABLE IF NOT EXISTS attachments (
163
+ id TEXT PRIMARY KEY,
164
+ taskId TEXT,
165
+ projectId TEXT,
166
+ commentId TEXT,
167
+ uploaderId TEXT NOT NULL,
168
+ uploaderType TEXT,
169
+ filename TEXT NOT NULL,
170
+ mimeType TEXT NOT NULL,
171
+ sizeBytes INTEGER NOT NULL,
172
+ url TEXT NOT NULL,
173
+ storageKey TEXT,
174
+ metadata TEXT,
154
175
  createdAt TEXT NOT NULL,
155
176
  updatedAt TEXT NOT NULL
156
177
  );
@@ -660,10 +681,24 @@ export class SQLiteStore implements StorageAdapter {
660
681
  return (result.changes ?? 0) > 0;
661
682
  }
662
683
 
663
- // --- Comments & Activity ---
684
+ // --- Comments ---
664
685
  async getComments(taskId: string): Promise<Comment[]> {
665
- const stmt = this.db.prepare('SELECT * FROM comments WHERE taskId = ?');
666
- return stmt.all(taskId) as any[];
686
+ const stmt = this.db.prepare('SELECT * FROM comments WHERE taskId = ? ORDER BY createdAt ASC');
687
+ const rows = stmt.all(taskId) as any[];
688
+ return rows.map((r) => ({
689
+ ...r,
690
+ metadata: r.metadata ? JSON.parse(r.metadata) : undefined
691
+ }));
692
+ }
693
+
694
+ async getComment(id: string): Promise<Comment | null> {
695
+ const stmt = this.db.prepare('SELECT * FROM comments WHERE id = ?');
696
+ const row = stmt.get(id) as any;
697
+ if (!row) return null;
698
+ return {
699
+ ...row,
700
+ metadata: row.metadata ? JSON.parse(row.metadata) : undefined
701
+ };
667
702
  }
668
703
 
669
704
  async addComment(comment: Omit<Comment, 'id' | 'createdAt' | 'updatedAt'>): Promise<Comment> {
@@ -672,13 +707,144 @@ export class SQLiteStore implements StorageAdapter {
672
707
  const newComment: Comment = { ...comment, id, createdAt: now, updatedAt: now };
673
708
 
674
709
  const stmt = this.db.prepare(`
675
- INSERT INTO comments (id, taskId, authorId, content, createdAt, updatedAt)
676
- VALUES (?, ?, ?, ?, ?, ?)
710
+ INSERT INTO comments (id, taskId, authorId, authorType, parentId, content, metadata, createdAt, updatedAt)
711
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
677
712
  `);
678
- stmt.run(newComment.id, newComment.taskId, newComment.authorId, newComment.content, newComment.createdAt, newComment.updatedAt);
713
+ stmt.run(
714
+ newComment.id,
715
+ newComment.taskId,
716
+ newComment.authorId,
717
+ newComment.authorType || 'user',
718
+ newComment.parentId || null,
719
+ newComment.content,
720
+ newComment.metadata ? JSON.stringify(newComment.metadata) : null,
721
+ newComment.createdAt,
722
+ newComment.updatedAt
723
+ );
679
724
  return newComment;
680
725
  }
681
726
 
727
+ async updateComment(id: string, updates: Partial<Comment>): Promise<Comment | null> {
728
+ const existing = await this.getComment(id);
729
+ if (!existing) return null;
730
+
731
+ const updated: Comment = {
732
+ ...existing,
733
+ ...updates,
734
+ updatedAt: new Date().toISOString()
735
+ };
736
+
737
+ const stmt = this.db.prepare(`
738
+ UPDATE comments SET
739
+ authorId = ?,
740
+ authorType = ?,
741
+ parentId = ?,
742
+ content = ?,
743
+ metadata = ?,
744
+ updatedAt = ?
745
+ WHERE id = ?
746
+ `);
747
+ stmt.run(
748
+ updated.authorId,
749
+ updated.authorType || 'user',
750
+ updated.parentId || null,
751
+ updated.content,
752
+ updated.metadata ? JSON.stringify(updated.metadata) : null,
753
+ updated.updatedAt,
754
+ id
755
+ );
756
+ return updated;
757
+ }
758
+
759
+ async deleteComment(id: string): Promise<boolean> {
760
+ const stmt = this.db.prepare('DELETE FROM comments WHERE id = ?');
761
+ const result = stmt.run(id);
762
+ return (result.changes ?? 0) > 0;
763
+ }
764
+
765
+ // --- Attachments ---
766
+ async getAttachments(filter?: { taskId?: string; projectId?: string; commentId?: string }): Promise<Attachment[]> {
767
+ let sql = 'SELECT * FROM attachments';
768
+ const params: any[] = [];
769
+ const conditions: string[] = [];
770
+
771
+ if (filter?.taskId) {
772
+ conditions.push('taskId = ?');
773
+ params.push(filter.taskId);
774
+ }
775
+ if (filter?.projectId) {
776
+ conditions.push('projectId = ?');
777
+ params.push(filter.projectId);
778
+ }
779
+ if (filter?.commentId) {
780
+ conditions.push('commentId = ?');
781
+ params.push(filter.commentId);
782
+ }
783
+
784
+ if (conditions.length > 0) {
785
+ sql += ' WHERE ' + conditions.join(' AND ');
786
+ }
787
+ sql += ' ORDER BY createdAt DESC';
788
+
789
+ const stmt = this.db.prepare(sql);
790
+ const rows = stmt.all(...params) as any[];
791
+ return rows.map((r) => ({
792
+ ...r,
793
+ sizeBytes: Number(r.sizeBytes),
794
+ metadata: r.metadata ? JSON.parse(r.metadata) : undefined
795
+ }));
796
+ }
797
+
798
+ async getAttachment(id: string): Promise<Attachment | null> {
799
+ const stmt = this.db.prepare('SELECT * FROM attachments WHERE id = ?');
800
+ const row = stmt.get(id) as any;
801
+ if (!row) return null;
802
+ return {
803
+ ...row,
804
+ sizeBytes: Number(row.sizeBytes),
805
+ metadata: row.metadata ? JSON.parse(row.metadata) : undefined
806
+ };
807
+ }
808
+
809
+ async createAttachment(attachment: Omit<Attachment, 'id' | 'createdAt' | 'updatedAt'>): Promise<Attachment> {
810
+ const id = `att_${Math.random().toString(36).substring(2, 9)}`;
811
+ const now = new Date().toISOString();
812
+ const newAtt: Attachment = {
813
+ ...attachment,
814
+ id,
815
+ createdAt: now,
816
+ updatedAt: now
817
+ };
818
+
819
+ const stmt = this.db.prepare(`
820
+ INSERT INTO attachments (id, taskId, projectId, commentId, uploaderId, uploaderType, filename, mimeType, sizeBytes, url, storageKey, metadata, createdAt, updatedAt)
821
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
822
+ `);
823
+ stmt.run(
824
+ newAtt.id,
825
+ newAtt.taskId || null,
826
+ newAtt.projectId || null,
827
+ newAtt.commentId || null,
828
+ newAtt.uploaderId,
829
+ newAtt.uploaderType || 'user',
830
+ newAtt.filename,
831
+ newAtt.mimeType,
832
+ newAtt.sizeBytes,
833
+ newAtt.url,
834
+ newAtt.storageKey || null,
835
+ newAtt.metadata ? JSON.stringify(newAtt.metadata) : null,
836
+ newAtt.createdAt,
837
+ newAtt.updatedAt
838
+ );
839
+ return newAtt;
840
+ }
841
+
842
+ async deleteAttachment(id: string): Promise<boolean> {
843
+ const stmt = this.db.prepare('DELETE FROM attachments WHERE id = ?');
844
+ const result = stmt.run(id);
845
+ return (result.changes ?? 0) > 0;
846
+ }
847
+
682
848
  async getActivities(filter?: { projectId?: string; taskId?: string }): Promise<Activity[]> {
683
849
  let sql = 'SELECT * FROM activities';
684
850
  const params: any[] = [];
@@ -174,15 +174,73 @@ export interface Iteration {
174
174
  createdAt: string;
175
175
  }
176
176
 
177
+ export type AuthorType = 'user' | 'agent' | 'system';
178
+
177
179
  export interface Comment {
178
180
  id: string;
179
181
  taskId: string;
180
182
  authorId: string;
183
+ authorType?: AuthorType;
184
+ parentId?: string; // Threaded reply support
181
185
  content: string;
186
+ metadata?: Record<string, unknown>;
182
187
  createdAt: string;
183
188
  updatedAt: string;
184
189
  }
185
190
 
191
+ export interface Attachment {
192
+ id: string;
193
+ taskId?: string;
194
+ projectId?: string;
195
+ commentId?: string;
196
+ uploaderId: string;
197
+ uploaderType?: AuthorType;
198
+ filename: string;
199
+ mimeType: string;
200
+ sizeBytes: number;
201
+ url: string;
202
+ storageKey?: string;
203
+ metadata?: Record<string, unknown>;
204
+ createdAt: string;
205
+ updatedAt: string;
206
+ }
207
+
208
+ export type CreateAttachmentInput = Omit<Attachment, 'id' | 'createdAt' | 'updatedAt'>;
209
+
210
+ export interface UploadFileInput {
211
+ filename: string;
212
+ data: Uint8Array | ArrayBuffer | Buffer | Blob | string;
213
+ mimeType?: string;
214
+ pathPrefix?: string;
215
+ }
216
+
217
+ export interface UploadFileResult {
218
+ storageKey: string;
219
+ url: string;
220
+ sizeBytes: number;
221
+ mimeType: string;
222
+ }
223
+
224
+ export interface PresignedUrlOptions {
225
+ storageKey: string;
226
+ expiresInSeconds?: number;
227
+ contentType?: string;
228
+ }
229
+
230
+ export interface PresignedUploadResult {
231
+ uploadUrl: string;
232
+ storageKey: string;
233
+ method?: 'PUT' | 'POST';
234
+ headers?: Record<string, string>;
235
+ }
236
+
237
+ export interface FileStorageAdapter {
238
+ upload(input: UploadFileInput): Promise<UploadFileResult>;
239
+ delete(storageKey: string): Promise<boolean>;
240
+ getDownloadUrl?(storageKey: string): Promise<string>;
241
+ getPresignedUploadUrl?(options: PresignedUrlOptions): Promise<PresignedUploadResult>;
242
+ }
243
+
186
244
  export interface TimeEntry {
187
245
  id: string;
188
246
  taskId: string;
@@ -221,6 +279,10 @@ export type WebhookEvent =
221
279
  | 'task.deleted'
222
280
  | 'task.status_changed'
223
281
  | 'comment.created'
282
+ | 'comment.updated'
283
+ | 'comment.deleted'
284
+ | 'attachment.created'
285
+ | 'attachment.deleted'
224
286
  | 'iteration.started'
225
287
  | 'iteration.completed'
226
288
  | 'team.created'
@@ -250,6 +312,7 @@ export interface CriticalPathPlugin {
250
312
 
251
313
  export interface CriticalPathConfig {
252
314
  store?: 'memory' | 'sqlite' | unknown;
315
+ fileStorage?: FileStorageAdapter;
253
316
  plugins?: CriticalPathPlugin[];
254
317
  webhooks?: Omit<Webhook, 'id' | 'createdAt'>[];
255
318
  initialData?: {
@@ -1 +1 @@
1
- {"root":["./src/index.test.ts","./src/index.ts","./src/use-case-validation.test.ts","./src/domain/custom-fields.ts","./src/domain/ddd.test.ts","./src/domain/entities.ts","./src/domain/events.ts","./src/domain/graph.ts","./src/domain/index.ts","./src/engine/index.ts","./src/plugins/index.ts","./src/store/firebase.test.ts","./src/store/firebase.ts","./src/store/index.ts","./src/store/sqlite.test.ts","./src/store/sqlite.ts","./src/types/index.ts","./src/utils/index.ts","./src/utils/key.test.ts","./src/utils/key.ts","./src/utils/status.ts","./src/utils/workflow.ts"],"version":"5.9.3"}
1
+ {"root":["./src/index.test.ts","./src/index.ts","./src/use-case-validation.test.ts","./src/domain/custom-fields.ts","./src/domain/ddd.test.ts","./src/domain/entities.ts","./src/domain/events.ts","./src/domain/graph.ts","./src/domain/index.ts","./src/engine/index.ts","./src/plugins/index.ts","./src/storage/file-storage.ts","./src/storage/firebase-storage.ts","./src/storage/index.ts","./src/storage/s3.ts","./src/storage/storage.test.ts","./src/store/firebase.test.ts","./src/store/firebase.ts","./src/store/index.ts","./src/store/sqlite.test.ts","./src/store/sqlite.ts","./src/types/index.ts","./src/utils/index.ts","./src/utils/key.test.ts","./src/utils/key.ts","./src/utils/status.ts","./src/utils/workflow.ts"],"version":"5.9.3"}