@critical-path/core 0.26.0 → 0.28.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 (83) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +15 -0
  3. package/dist/domain/custom-fields.d.ts +7 -2
  4. package/dist/domain/custom-fields.d.ts.map +1 -1
  5. package/dist/domain/custom-fields.js +23 -1
  6. package/dist/domain/custom-fields.js.map +1 -1
  7. package/dist/domain/events.d.ts +5 -0
  8. package/dist/domain/events.d.ts.map +1 -1
  9. package/dist/domain/events.js +34 -0
  10. package/dist/domain/events.js.map +1 -1
  11. package/dist/engine/index.d.ts +30 -2
  12. package/dist/engine/index.d.ts.map +1 -1
  13. package/dist/engine/index.js +133 -77
  14. package/dist/engine/index.js.map +1 -1
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +1 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/plugins/index.d.ts +13 -3
  20. package/dist/plugins/index.d.ts.map +1 -1
  21. package/dist/plugins/index.js +44 -15
  22. package/dist/plugins/index.js.map +1 -1
  23. package/dist/plugins/plugins.test.d.ts +2 -0
  24. package/dist/plugins/plugins.test.d.ts.map +1 -0
  25. package/dist/plugins/plugins.test.js +137 -0
  26. package/dist/plugins/plugins.test.js.map +1 -0
  27. package/dist/schemas/index.d.ts +167 -121
  28. package/dist/schemas/index.d.ts.map +1 -1
  29. package/dist/schemas/index.js +15 -1
  30. package/dist/schemas/index.js.map +1 -1
  31. package/dist/schemas/schemas.test.js +1 -0
  32. package/dist/schemas/schemas.test.js.map +1 -1
  33. package/dist/store/firebase.d.ts +3 -0
  34. package/dist/store/firebase.d.ts.map +1 -1
  35. package/dist/store/firebase.js +21 -0
  36. package/dist/store/firebase.js.map +1 -1
  37. package/dist/store/firebase.test.js +17 -0
  38. package/dist/store/firebase.test.js.map +1 -1
  39. package/dist/store/index.d.ts +6 -0
  40. package/dist/store/index.d.ts.map +1 -1
  41. package/dist/store/index.js +14 -0
  42. package/dist/store/index.js.map +1 -1
  43. package/dist/store/sqlite.d.ts +4 -0
  44. package/dist/store/sqlite.d.ts.map +1 -1
  45. package/dist/store/sqlite.js +42 -8
  46. package/dist/store/sqlite.js.map +1 -1
  47. package/dist/types/index.d.ts +67 -6
  48. package/dist/types/index.d.ts.map +1 -1
  49. package/dist/webhooks/dispatcher.d.ts +80 -0
  50. package/dist/webhooks/dispatcher.d.ts.map +1 -0
  51. package/dist/webhooks/dispatcher.js +133 -0
  52. package/dist/webhooks/dispatcher.js.map +1 -0
  53. package/dist/webhooks/index.d.ts +3 -0
  54. package/dist/webhooks/index.d.ts.map +1 -0
  55. package/dist/webhooks/index.js +3 -0
  56. package/dist/webhooks/index.js.map +1 -0
  57. package/dist/webhooks/signature.d.ts +28 -0
  58. package/dist/webhooks/signature.d.ts.map +1 -0
  59. package/dist/webhooks/signature.js +42 -0
  60. package/dist/webhooks/signature.js.map +1 -0
  61. package/dist/webhooks/webhooks.test.d.ts +2 -0
  62. package/dist/webhooks/webhooks.test.d.ts.map +1 -0
  63. package/dist/webhooks/webhooks.test.js +153 -0
  64. package/dist/webhooks/webhooks.test.js.map +1 -0
  65. package/package.json +1 -1
  66. package/src/domain/custom-fields.ts +43 -2
  67. package/src/domain/events.ts +42 -3
  68. package/src/engine/index.ts +170 -84
  69. package/src/index.ts +1 -0
  70. package/src/plugins/index.ts +51 -16
  71. package/src/plugins/plugins.test.ts +161 -0
  72. package/src/schemas/index.ts +19 -1
  73. package/src/schemas/schemas.test.ts +6 -3
  74. package/src/store/firebase.test.ts +20 -0
  75. package/src/store/firebase.ts +22 -0
  76. package/src/store/index.ts +19 -0
  77. package/src/store/sqlite.ts +54 -7
  78. package/src/types/index.ts +72 -33
  79. package/src/webhooks/dispatcher.ts +190 -0
  80. package/src/webhooks/index.ts +2 -0
  81. package/src/webhooks/signature.ts +57 -0
  82. package/src/webhooks/webhooks.test.ts +200 -0
  83. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,137 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { CriticalPathEngine, CustomFieldValidationError, ValidationError, WorkflowValidationError } from '../index.js';
3
+ const strictWorkflow = {
4
+ name: 'Strict',
5
+ defaultStatusKey: 'todo',
6
+ statuses: [
7
+ { key: 'todo', label: 'To Do', category: 'not_started' },
8
+ { key: 'doing', label: 'Doing', category: 'in_progress' },
9
+ { key: 'done', label: 'Done', category: 'completed' }
10
+ ],
11
+ transitions: [
12
+ { fromStatusKey: 'todo', toStatusKey: 'doing' },
13
+ { fromStatusKey: 'doing', toStatusKey: 'done' }
14
+ ]
15
+ };
16
+ describe('plugin system', () => {
17
+ it('runs init once with the engine before ready resolves', async () => {
18
+ const init = vi.fn(async (engine) => {
19
+ await engine.createProject({ name: 'Seeded by plugin' });
20
+ });
21
+ const engine = new CriticalPathEngine({ plugins: [{ id: 'seed', name: 'Seed', version: '1', init }] });
22
+ await engine.ready;
23
+ expect(init).toHaveBeenCalledTimes(1);
24
+ expect(init).toHaveBeenCalledWith(engine);
25
+ expect(await engine.getProjects()).toHaveLength(1);
26
+ });
27
+ it('surfaces init failures through ready without unhandled rejections', async () => {
28
+ const engine = new CriticalPathEngine({
29
+ plugins: [{ id: 'bad', name: 'Bad', version: '1', init: () => Promise.reject(new Error('boom')) }]
30
+ });
31
+ await expect(engine.ready).rejects.toThrow('boom');
32
+ });
33
+ it('validates values of plugin-registered custom field types and rejects unknown types', async () => {
34
+ const urlField = {
35
+ id: 'url-field',
36
+ name: 'URL field',
37
+ version: '1',
38
+ customFieldTypes: [
39
+ { type: 'url', validate: (value) => (typeof value === 'string' && /^https?:\/\//.test(value) ? null : 'must be an http(s) URL') }
40
+ ]
41
+ };
42
+ const engine = new CriticalPathEngine({ plugins: [urlField] });
43
+ const project = await engine.createProject({
44
+ name: 'Links',
45
+ customFieldDefinitions: [{ id: 'f1', key: 'spec', label: 'Spec', type: 'url' }]
46
+ });
47
+ await engine.createTask({ projectId: project.id, title: 'ok', customFields: { spec: 'https://example.com' } });
48
+ await expect(engine.createTask({ projectId: project.id, title: 'bad', customFields: { spec: 'ftp://x' } })).rejects.toThrow(/must be an http\(s\) URL/);
49
+ await expect(engine.createProject({ name: 'Unknown', customFieldDefinitions: [{ id: 'f', key: 'x', label: 'X', type: 'nope' }] })).rejects.toThrow(CustomFieldValidationError);
50
+ });
51
+ it('refuses custom field types that clash with built-in or already registered types', () => {
52
+ const clash = (type) => ({
53
+ id: `p-${type}-${Math.random()}`,
54
+ name: 'Clash',
55
+ version: '1',
56
+ customFieldTypes: [{ type, validate: () => null }]
57
+ });
58
+ expect(() => new CriticalPathEngine({ plugins: [clash('number')] })).toThrow(/already exists/);
59
+ expect(() => new CriticalPathEngine({ plugins: [clash('money'), clash('money')] })).toThrow(/already exists/);
60
+ });
61
+ it('validates the output of before-hooks, so plugins cannot bypass workflow rules', async () => {
62
+ const skipAhead = {
63
+ id: 'skip',
64
+ name: 'Skip ahead',
65
+ version: '1',
66
+ hooks: { beforeTaskUpdate: (_id, updates) => ({ ...updates, status: 'done' }) }
67
+ };
68
+ const engine = new CriticalPathEngine({ plugins: [skipAhead] });
69
+ const workflow = await engine.createWorkflow(strictWorkflow);
70
+ const project = await engine.createProject({ name: 'Strict', workflowId: workflow.id });
71
+ const task = await engine.createTask({ projectId: project.id, title: 'T' });
72
+ await expect(engine.updateTask(task.id, { title: 'renamed' })).rejects.toThrow(WorkflowValidationError);
73
+ expect((await engine.getTask(task.id))?.status).toBe('todo');
74
+ });
75
+ it('prevents before-hooks from moving tasks between projects', async () => {
76
+ let otherProjectId = '';
77
+ const mover = {
78
+ id: 'mover',
79
+ name: 'Mover',
80
+ version: '1',
81
+ hooks: {
82
+ beforeTaskCreate: (task) => (task.title === 'move me' ? { ...task, projectId: otherProjectId } : task),
83
+ beforeTaskUpdate: (_id, updates) => ({ ...updates, projectId: otherProjectId })
84
+ }
85
+ };
86
+ const engine = new CriticalPathEngine({ plugins: [mover] });
87
+ const home = await engine.createProject({ name: 'Home' });
88
+ otherProjectId = (await engine.createProject({ name: 'Other' })).id;
89
+ await expect(engine.createTask({ projectId: home.id, title: 'move me' })).rejects.toThrow(ValidationError);
90
+ const task = await engine.createTask({ projectId: home.id, title: 'stay' });
91
+ await engine.updateTask(task.id, { title: 'still here' });
92
+ expect((await engine.getTask(task.id))?.projectId).toBe(home.id);
93
+ });
94
+ it('enforces required custom fields even when none are supplied', async () => {
95
+ const engine = new CriticalPathEngine();
96
+ const project = await engine.createProject({
97
+ name: 'Required',
98
+ customFieldDefinitions: [{ id: 'f', key: 'client', label: 'Client', type: 'text', required: true }]
99
+ });
100
+ await expect(engine.createTask({ projectId: project.id, title: 'missing' })).rejects.toThrow(/required/);
101
+ });
102
+ it('logs after-hook failures without failing the write or skipping events', async () => {
103
+ const consoleError = vi.spyOn(console, 'error').mockImplementation(() => { });
104
+ const engine = new CriticalPathEngine({
105
+ plugins: [{ id: 'flaky', name: 'Flaky', version: '1', hooks: { afterTaskCreate: () => { throw new Error('downstream'); } } }]
106
+ });
107
+ const published = [];
108
+ engine.events.subscribe('task.created', (e) => void published.push(e.name));
109
+ const project = await engine.createProject({ name: 'After' });
110
+ const task = await engine.createTask({ projectId: project.id, title: 'stored' });
111
+ expect(await engine.getTask(task.id)).not.toBeNull();
112
+ expect(published).toEqual(['task.created']);
113
+ expect(consoleError).toHaveBeenCalledWith(expect.stringContaining('"flaky" afterTaskCreate'), expect.any(Error));
114
+ consoleError.mockRestore();
115
+ });
116
+ it('passes the deleted task to delete hooks', async () => {
117
+ const seen = [];
118
+ const engine = new CriticalPathEngine({
119
+ plugins: [
120
+ {
121
+ id: 'audit',
122
+ name: 'Audit',
123
+ version: '1',
124
+ hooks: {
125
+ beforeTaskDelete: (_id, task) => void seen.push(`before:${task.title}`),
126
+ afterTaskDelete: (_id, task) => void seen.push(`after:${task.title}`)
127
+ }
128
+ }
129
+ ]
130
+ });
131
+ const project = await engine.createProject({ name: 'Del' });
132
+ const task = await engine.createTask({ projectId: project.id, title: 'gone' });
133
+ await engine.deleteTask(task.id);
134
+ expect(seen).toEqual(['before:gone', 'after:gone']);
135
+ });
136
+ });
137
+ //# sourceMappingURL=plugins.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugins.test.js","sourceRoot":"","sources":["../../src/plugins/plugins.test.ts"],"names":[],"mappings":"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"}