@critical-path/core 0.2.0 → 0.3.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/CHANGELOG.md +12 -0
- package/dist/engine/index.d.ts +19 -1
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +129 -6
- package/dist/engine/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/index.test.js +96 -1
- package/dist/index.test.js.map +1 -1
- package/dist/store/firebase.d.ts +19 -7
- package/dist/store/firebase.d.ts.map +1 -1
- package/dist/store/firebase.js +98 -14
- package/dist/store/firebase.js.map +1 -1
- package/dist/store/firebase.test.js +5 -2
- package/dist/store/firebase.test.js.map +1 -1
- package/dist/store/index.d.ts +34 -8
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +79 -12
- package/dist/store/index.js.map +1 -1
- package/dist/store/sqlite.d.ts +17 -4
- package/dist/store/sqlite.d.ts.map +1 -1
- package/dist/store/sqlite.js +179 -39
- package/dist/store/sqlite.js.map +1 -1
- package/dist/types/index.d.ts +70 -9
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/key.d.ts +14 -0
- package/dist/utils/key.d.ts.map +1 -0
- package/dist/utils/key.js +49 -0
- package/dist/utils/key.js.map +1 -0
- package/dist/utils/key.test.d.ts +2 -0
- package/dist/utils/key.test.d.ts.map +1 -0
- package/dist/utils/key.test.js +48 -0
- package/dist/utils/key.test.js.map +1 -0
- package/dist/utils/status.d.ts +14 -0
- package/dist/utils/status.d.ts.map +1 -0
- package/dist/utils/status.js +58 -0
- package/dist/utils/status.js.map +1 -0
- package/package.json +5 -1
- package/src/engine/index.ts +161 -8
- package/src/index.test.ts +113 -1
- package/src/index.ts +2 -0
- package/src/store/firebase.test.ts +8 -2
- package/src/store/firebase.ts +112 -18
- package/src/store/index.ts +113 -18
- package/src/store/sqlite.ts +277 -47
- package/src/types/index.ts +76 -10
- package/src/utils/index.ts +2 -0
- package/src/utils/key.test.ts +55 -0
- package/src/utils/key.ts +51 -0
- package/src/utils/status.ts +85 -0
- package/tsconfig.tsbuildinfo +1 -1
package/src/store/firebase.ts
CHANGED
|
@@ -2,13 +2,16 @@ import type { StorageAdapter } from './index.js';
|
|
|
2
2
|
import type {
|
|
3
3
|
Project,
|
|
4
4
|
Task,
|
|
5
|
-
|
|
5
|
+
Iteration,
|
|
6
|
+
Team,
|
|
7
|
+
TaskContainer,
|
|
6
8
|
Comment,
|
|
7
9
|
TimeEntry,
|
|
8
10
|
Activity,
|
|
9
11
|
Webhook,
|
|
10
12
|
TaskDependency
|
|
11
13
|
} from '../types/index.js';
|
|
14
|
+
import { generateProjectKey } from '../utils/key.js';
|
|
12
15
|
|
|
13
16
|
export interface FirestoreDBInterface {
|
|
14
17
|
collection(name: string): {
|
|
@@ -92,16 +95,21 @@ export class InMemoryFirestoreMock implements FirestoreDBInterface {
|
|
|
92
95
|
|
|
93
96
|
export interface FirebaseStoreConfig {
|
|
94
97
|
/**
|
|
95
|
-
* Firestore instance or mockable DB interface.
|
|
98
|
+
* Firestore instance or mockable DB interface. Required.
|
|
96
99
|
*/
|
|
97
|
-
db
|
|
100
|
+
db: FirestoreDBInterface;
|
|
98
101
|
}
|
|
99
102
|
|
|
100
103
|
export class FirebaseStore implements StorageAdapter {
|
|
101
104
|
private db: FirestoreDBInterface;
|
|
102
105
|
|
|
103
|
-
constructor(config: FirebaseStoreConfig
|
|
104
|
-
|
|
106
|
+
constructor(config: FirebaseStoreConfig) {
|
|
107
|
+
if (!config?.db) {
|
|
108
|
+
throw new Error(
|
|
109
|
+
'FirebaseStore requires a valid Firestore db instance (e.g. FirebaseStoreConfig.db). Automatic fallback to InMemoryFirestoreMock has been removed.'
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
this.db = config.db;
|
|
105
113
|
}
|
|
106
114
|
|
|
107
115
|
// --- Projects ---
|
|
@@ -119,7 +127,8 @@ export class FirebaseStore implements StorageAdapter {
|
|
|
119
127
|
async createProject(project: Omit<Project, 'id' | 'createdAt' | 'updatedAt'>): Promise<Project> {
|
|
120
128
|
const docRef = this.db.collection('projects').doc();
|
|
121
129
|
const now = new Date().toISOString();
|
|
122
|
-
const
|
|
130
|
+
const key = project.key || generateProjectKey(project.name);
|
|
131
|
+
const newProj: Project = { ...project, key, id: docRef.id, createdAt: now, updatedAt: now };
|
|
123
132
|
await docRef.set(newProj);
|
|
124
133
|
return newProj;
|
|
125
134
|
}
|
|
@@ -144,6 +153,78 @@ export class FirebaseStore implements StorageAdapter {
|
|
|
144
153
|
return true;
|
|
145
154
|
}
|
|
146
155
|
|
|
156
|
+
// --- Teams ---
|
|
157
|
+
async getTeams(): Promise<Team[]> {
|
|
158
|
+
const snap = await this.db.collection('teams').get();
|
|
159
|
+
return snap.docs.map((doc) => ({ ...doc.data(), id: doc.id }));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async getTeam(id: string): Promise<Team | null> {
|
|
163
|
+
const snap = await this.db.collection('teams').doc(id).get();
|
|
164
|
+
if (!snap.exists) return null;
|
|
165
|
+
return { ...snap.data(), id: snap.id };
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async createTeam(team: Omit<Team, 'id' | 'createdAt' | 'updatedAt'>): Promise<Team> {
|
|
169
|
+
const docRef = this.db.collection('teams').doc();
|
|
170
|
+
const now = new Date().toISOString();
|
|
171
|
+
const newTeam: Team = { ...team, id: docRef.id, createdAt: now, updatedAt: now };
|
|
172
|
+
await docRef.set(newTeam);
|
|
173
|
+
return newTeam;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async updateTeam(id: string, updates: Partial<Team>): Promise<Team | null> {
|
|
177
|
+
const existing = await this.getTeam(id);
|
|
178
|
+
if (!existing) return null;
|
|
179
|
+
|
|
180
|
+
const updated: Team = { ...existing, ...updates, updatedAt: new Date().toISOString() };
|
|
181
|
+
await this.db.collection('teams').doc(id).set(updated, { merge: true });
|
|
182
|
+
return updated;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async deleteTeam(id: string): Promise<boolean> {
|
|
186
|
+
const existing = await this.getTeam(id);
|
|
187
|
+
if (!existing) return false;
|
|
188
|
+
await this.db.collection('teams').doc(id).delete();
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// --- Containers ---
|
|
193
|
+
async getContainers(projectId: string): Promise<TaskContainer[]> {
|
|
194
|
+
const snap = await this.db.collection('containers').where('projectId', '==', projectId).get();
|
|
195
|
+
return snap.docs.map((doc) => ({ ...doc.data(), id: doc.id }));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async getContainer(id: string): Promise<TaskContainer | null> {
|
|
199
|
+
const snap = await this.db.collection('containers').doc(id).get();
|
|
200
|
+
if (!snap.exists) return null;
|
|
201
|
+
return { ...snap.data(), id: snap.id };
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async createContainer(container: Omit<TaskContainer, 'id' | 'createdAt' | 'updatedAt'>): Promise<TaskContainer> {
|
|
205
|
+
const docRef = this.db.collection('containers').doc();
|
|
206
|
+
const now = new Date().toISOString();
|
|
207
|
+
const newContainer: TaskContainer = { ...container, id: docRef.id, createdAt: now, updatedAt: now };
|
|
208
|
+
await docRef.set(newContainer);
|
|
209
|
+
return newContainer;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
async updateContainer(id: string, updates: Partial<TaskContainer>): Promise<TaskContainer | null> {
|
|
213
|
+
const existing = await this.getContainer(id);
|
|
214
|
+
if (!existing) return null;
|
|
215
|
+
|
|
216
|
+
const updated: TaskContainer = { ...existing, ...updates, updatedAt: new Date().toISOString() };
|
|
217
|
+
await this.db.collection('containers').doc(id).set(updated, { merge: true });
|
|
218
|
+
return updated;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
async deleteContainer(id: string): Promise<boolean> {
|
|
222
|
+
const existing = await this.getContainer(id);
|
|
223
|
+
if (!existing) return false;
|
|
224
|
+
await this.db.collection('containers').doc(id).delete();
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
|
|
147
228
|
// --- Tasks ---
|
|
148
229
|
async getTasks(projectId?: string): Promise<Task[]> {
|
|
149
230
|
let snap;
|
|
@@ -189,29 +270,42 @@ export class FirebaseStore implements StorageAdapter {
|
|
|
189
270
|
return true;
|
|
190
271
|
}
|
|
191
272
|
|
|
192
|
-
// ---
|
|
193
|
-
async
|
|
194
|
-
const snap = await this.db.collection('
|
|
273
|
+
// --- Iterations ---
|
|
274
|
+
async getIterations(projectId: string): Promise<Iteration[]> {
|
|
275
|
+
const snap = await this.db.collection('iterations').where('projectId', '==', projectId).get();
|
|
195
276
|
return snap.docs.map((doc) => ({ ...doc.data(), id: doc.id }));
|
|
196
277
|
}
|
|
197
278
|
|
|
198
|
-
async
|
|
199
|
-
const
|
|
279
|
+
async getIteration(id: string): Promise<Iteration | null> {
|
|
280
|
+
const snap = await this.db.collection('iterations').doc(id).get();
|
|
281
|
+
if (!snap.exists) return null;
|
|
282
|
+
return { ...snap.data(), id: snap.id };
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
async createIteration(iteration: Omit<Iteration, 'id' | 'createdAt'>): Promise<Iteration> {
|
|
286
|
+
const docRef = this.db.collection('iterations').doc();
|
|
200
287
|
const now = new Date().toISOString();
|
|
201
|
-
const
|
|
202
|
-
await docRef.set(
|
|
203
|
-
return
|
|
288
|
+
const newIteration: Iteration = { ...iteration, id: docRef.id, createdAt: now };
|
|
289
|
+
await docRef.set(newIteration);
|
|
290
|
+
return newIteration;
|
|
204
291
|
}
|
|
205
292
|
|
|
206
|
-
async
|
|
207
|
-
const snap = await this.db.collection('
|
|
293
|
+
async updateIteration(id: string, updates: Partial<Iteration>): Promise<Iteration | null> {
|
|
294
|
+
const snap = await this.db.collection('iterations').doc(id).get();
|
|
208
295
|
if (!snap.exists) return null;
|
|
209
296
|
|
|
210
|
-
const updated:
|
|
211
|
-
await this.db.collection('
|
|
297
|
+
const updated: Iteration = { ...snap.data(), id, ...updates };
|
|
298
|
+
await this.db.collection('iterations').doc(id).set(updated, { merge: true });
|
|
212
299
|
return updated;
|
|
213
300
|
}
|
|
214
301
|
|
|
302
|
+
async deleteIteration(id: string): Promise<boolean> {
|
|
303
|
+
const existing = await this.getIteration(id);
|
|
304
|
+
if (!existing) return false;
|
|
305
|
+
await this.db.collection('iterations').doc(id).delete();
|
|
306
|
+
return true;
|
|
307
|
+
}
|
|
308
|
+
|
|
215
309
|
// --- Comments & Activity ---
|
|
216
310
|
async getComments(taskId: string): Promise<Comment[]> {
|
|
217
311
|
const snap = await this.db.collection('comments').where('taskId', '==', taskId).get();
|
package/src/store/index.ts
CHANGED
|
@@ -4,13 +4,16 @@ export * from './firebase.js';
|
|
|
4
4
|
import type {
|
|
5
5
|
Project,
|
|
6
6
|
Task,
|
|
7
|
-
|
|
7
|
+
Iteration,
|
|
8
|
+
Team,
|
|
9
|
+
TaskContainer,
|
|
8
10
|
Comment,
|
|
9
11
|
TimeEntry,
|
|
10
12
|
Activity,
|
|
11
13
|
Webhook,
|
|
12
14
|
TaskDependency
|
|
13
15
|
} from '../types/index.js';
|
|
16
|
+
import { generateProjectKey } from '../utils/key.js';
|
|
14
17
|
|
|
15
18
|
export interface StorageAdapter {
|
|
16
19
|
// Projects
|
|
@@ -27,10 +30,26 @@ export interface StorageAdapter {
|
|
|
27
30
|
updateTask(id: string, updates: Partial<Task>): Promise<Task | null>;
|
|
28
31
|
deleteTask(id: string): Promise<boolean>;
|
|
29
32
|
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
// Teams
|
|
34
|
+
getTeams(): Promise<Team[]>;
|
|
35
|
+
getTeam(id: string): Promise<Team | null>;
|
|
36
|
+
createTeam(team: Omit<Team, 'id' | 'createdAt' | 'updatedAt'>): Promise<Team>;
|
|
37
|
+
updateTeam(id: string, updates: Partial<Team>): Promise<Team | null>;
|
|
38
|
+
deleteTeam(id: string): Promise<boolean>;
|
|
39
|
+
|
|
40
|
+
// Task Containers
|
|
41
|
+
getContainers(projectId: string): Promise<TaskContainer[]>;
|
|
42
|
+
getContainer(id: string): Promise<TaskContainer | null>;
|
|
43
|
+
createContainer(container: Omit<TaskContainer, 'id' | 'createdAt' | 'updatedAt'>): Promise<TaskContainer>;
|
|
44
|
+
updateContainer(id: string, updates: Partial<TaskContainer>): Promise<TaskContainer | null>;
|
|
45
|
+
deleteContainer(id: string): Promise<boolean>;
|
|
46
|
+
|
|
47
|
+
// Iterations
|
|
48
|
+
getIterations(projectId: string): Promise<Iteration[]>;
|
|
49
|
+
getIteration(id: string): Promise<Iteration | null>;
|
|
50
|
+
createIteration(iteration: Omit<Iteration, 'id' | 'createdAt'>): Promise<Iteration>;
|
|
51
|
+
updateIteration(id: string, updates: Partial<Iteration>): Promise<Iteration | null>;
|
|
52
|
+
deleteIteration(id: string): Promise<boolean>;
|
|
34
53
|
|
|
35
54
|
// Comments & Activity
|
|
36
55
|
getComments(taskId: string): Promise<Comment[]>;
|
|
@@ -54,7 +73,9 @@ export interface StorageAdapter {
|
|
|
54
73
|
export class InMemoryStore implements StorageAdapter {
|
|
55
74
|
private projects = new Map<string, Project>();
|
|
56
75
|
private tasks = new Map<string, Task>();
|
|
57
|
-
private
|
|
76
|
+
private teams = new Map<string, Team>();
|
|
77
|
+
private containers = new Map<string, TaskContainer>();
|
|
78
|
+
private iterations = new Map<string, Iteration>();
|
|
58
79
|
private comments = new Map<string, Comment>();
|
|
59
80
|
private activities: Activity[] = [];
|
|
60
81
|
private timeEntries = new Map<string, TimeEntry>();
|
|
@@ -72,8 +93,10 @@ export class InMemoryStore implements StorageAdapter {
|
|
|
72
93
|
async createProject(project: Omit<Project, 'id' | 'createdAt' | 'updatedAt'>): Promise<Project> {
|
|
73
94
|
const id = `proj_${Math.random().toString(36).substring(2, 9)}`;
|
|
74
95
|
const now = new Date().toISOString();
|
|
96
|
+
const key = project.key || generateProjectKey(project.name);
|
|
75
97
|
const newProject: Project = {
|
|
76
98
|
...project,
|
|
99
|
+
key,
|
|
77
100
|
id,
|
|
78
101
|
createdAt: now,
|
|
79
102
|
updatedAt: now
|
|
@@ -139,29 +162,97 @@ export class InMemoryStore implements StorageAdapter {
|
|
|
139
162
|
return this.tasks.delete(id);
|
|
140
163
|
}
|
|
141
164
|
|
|
142
|
-
|
|
143
|
-
|
|
165
|
+
// Teams
|
|
166
|
+
async getTeams(): Promise<Team[]> {
|
|
167
|
+
return Array.from(this.teams.values());
|
|
144
168
|
}
|
|
145
169
|
|
|
146
|
-
async
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
170
|
+
async getTeam(id: string): Promise<Team | null> {
|
|
171
|
+
return this.teams.get(id) || null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async createTeam(team: Omit<Team, 'id' | 'createdAt' | 'updatedAt'>): Promise<Team> {
|
|
175
|
+
const id = `team_${Math.random().toString(36).substring(2, 9)}`;
|
|
176
|
+
const now = new Date().toISOString();
|
|
177
|
+
const newTeam: Team = { ...team, id, createdAt: now, updatedAt: now };
|
|
178
|
+
this.teams.set(id, newTeam);
|
|
179
|
+
return newTeam;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async updateTeam(id: string, updates: Partial<Team>): Promise<Team | null> {
|
|
183
|
+
const existing = this.teams.get(id);
|
|
184
|
+
if (!existing) return null;
|
|
185
|
+
const updated: Team = { ...existing, ...updates, updatedAt: new Date().toISOString() };
|
|
186
|
+
this.teams.set(id, updated);
|
|
187
|
+
return updated;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async deleteTeam(id: string): Promise<boolean> {
|
|
191
|
+
return this.teams.delete(id);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Containers
|
|
195
|
+
async getContainers(projectId: string): Promise<TaskContainer[]> {
|
|
196
|
+
return Array.from(this.containers.values()).filter((c) => c.projectId === projectId);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
async getContainer(id: string): Promise<TaskContainer | null> {
|
|
200
|
+
return this.containers.get(id) || null;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async createContainer(container: Omit<TaskContainer, 'id' | 'createdAt' | 'updatedAt'>): Promise<TaskContainer> {
|
|
204
|
+
const id = `cnt_${Math.random().toString(36).substring(2, 9)}`;
|
|
205
|
+
const now = new Date().toISOString();
|
|
206
|
+
const newContainer: TaskContainer = { ...container, id, createdAt: now, updatedAt: now };
|
|
207
|
+
this.containers.set(id, newContainer);
|
|
208
|
+
return newContainer;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
async updateContainer(id: string, updates: Partial<TaskContainer>): Promise<TaskContainer | null> {
|
|
212
|
+
const existing = this.containers.get(id);
|
|
213
|
+
if (!existing) return null;
|
|
214
|
+
const updated: TaskContainer = { ...existing, ...updates, updatedAt: new Date().toISOString() };
|
|
215
|
+
this.containers.set(id, updated);
|
|
216
|
+
return updated;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
async deleteContainer(id: string): Promise<boolean> {
|
|
220
|
+
return this.containers.delete(id);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Iterations
|
|
224
|
+
async getIterations(projectId: string): Promise<Iteration[]> {
|
|
225
|
+
return Array.from(this.iterations.values()).filter((s) => s.projectId === projectId);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
async getIteration(id: string): Promise<Iteration | null> {
|
|
229
|
+
return this.iterations.get(id) || null;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
async createIteration(iteration: Omit<Iteration, 'id' | 'createdAt'>): Promise<Iteration> {
|
|
233
|
+
const id = `iter_${Math.random().toString(36).substring(2, 9)}`;
|
|
234
|
+
const newIteration: Iteration = {
|
|
235
|
+
...iteration,
|
|
150
236
|
id,
|
|
151
237
|
createdAt: new Date().toISOString()
|
|
152
238
|
};
|
|
153
|
-
this.
|
|
154
|
-
return
|
|
239
|
+
this.iterations.set(id, newIteration);
|
|
240
|
+
return newIteration;
|
|
155
241
|
}
|
|
156
242
|
|
|
157
|
-
async
|
|
158
|
-
const existing = this.
|
|
243
|
+
async updateIteration(id: string, updates: Partial<Iteration>): Promise<Iteration | null> {
|
|
244
|
+
const existing = this.iterations.get(id);
|
|
159
245
|
if (!existing) return null;
|
|
160
|
-
const updated:
|
|
161
|
-
this.
|
|
246
|
+
const updated: Iteration = { ...existing, ...updates };
|
|
247
|
+
this.iterations.set(id, updated);
|
|
162
248
|
return updated;
|
|
163
249
|
}
|
|
164
250
|
|
|
251
|
+
async deleteIteration(id: string): Promise<boolean> {
|
|
252
|
+
return this.iterations.delete(id);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Comments
|
|
165
256
|
async getComments(taskId: string): Promise<Comment[]> {
|
|
166
257
|
return Array.from(this.comments.values()).filter((c) => c.taskId === taskId);
|
|
167
258
|
}
|
|
@@ -174,6 +265,7 @@ export class InMemoryStore implements StorageAdapter {
|
|
|
174
265
|
return newComment;
|
|
175
266
|
}
|
|
176
267
|
|
|
268
|
+
// Activities
|
|
177
269
|
async getActivities(filter?: { projectId?: string; taskId?: string }): Promise<Activity[]> {
|
|
178
270
|
return this.activities.filter((a) => {
|
|
179
271
|
if (filter?.projectId && a.projectId !== filter.projectId) return false;
|
|
@@ -189,6 +281,7 @@ export class InMemoryStore implements StorageAdapter {
|
|
|
189
281
|
return newAct;
|
|
190
282
|
}
|
|
191
283
|
|
|
284
|
+
// Time Entries
|
|
192
285
|
async getTimeEntries(taskId: string): Promise<TimeEntry[]> {
|
|
193
286
|
return Array.from(this.timeEntries.values()).filter((e) => e.taskId === taskId);
|
|
194
287
|
}
|
|
@@ -200,6 +293,7 @@ export class InMemoryStore implements StorageAdapter {
|
|
|
200
293
|
return newEntry;
|
|
201
294
|
}
|
|
202
295
|
|
|
296
|
+
// Dependencies
|
|
203
297
|
async getDependencies(taskId: string): Promise<TaskDependency[]> {
|
|
204
298
|
return Array.from(this.dependencies.values()).filter(
|
|
205
299
|
(d) => d.taskId === taskId || d.dependsOnTaskId === taskId
|
|
@@ -213,6 +307,7 @@ export class InMemoryStore implements StorageAdapter {
|
|
|
213
307
|
return newDep;
|
|
214
308
|
}
|
|
215
309
|
|
|
310
|
+
// Webhooks
|
|
216
311
|
async getWebhooks(): Promise<Webhook[]> {
|
|
217
312
|
return Array.from(this.webhooks.values());
|
|
218
313
|
}
|