@pgflow/dsl 0.0.5 → 0.0.6

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 (71) hide show
  1. package/package.json +4 -1
  2. package/CHANGELOG.md +0 -7
  3. package/__tests__/runtime/flow.test.ts +0 -121
  4. package/__tests__/runtime/steps.test.ts +0 -183
  5. package/__tests__/runtime/utils.test.ts +0 -149
  6. package/__tests__/types/dsl-types.test-d.ts +0 -103
  7. package/__tests__/types/example-flow.test-d.ts +0 -76
  8. package/__tests__/types/extract-flow-input.test-d.ts +0 -71
  9. package/__tests__/types/extract-flow-steps.test-d.ts +0 -74
  10. package/__tests__/types/getStepDefinition.test-d.ts +0 -65
  11. package/__tests__/types/step-input.test-d.ts +0 -212
  12. package/__tests__/types/step-output.test-d.ts +0 -55
  13. package/brainstorming/condition/condition-alternatives.md +0 -219
  14. package/brainstorming/condition/condition-with-flexibility.md +0 -303
  15. package/brainstorming/condition/condition.md +0 -139
  16. package/brainstorming/condition/implementation-plan.md +0 -372
  17. package/brainstorming/dsl/cli-json-schema.md +0 -225
  18. package/brainstorming/dsl/cli.md +0 -179
  19. package/brainstorming/dsl/create-compilator.md +0 -25
  20. package/brainstorming/dsl/dsl-analysis-2.md +0 -166
  21. package/brainstorming/dsl/dsl-analysis.md +0 -512
  22. package/brainstorming/dsl/dsl-critique.md +0 -41
  23. package/brainstorming/fanouts/fanout-subflows-flattened-vs-subruns.md +0 -213
  24. package/brainstorming/fanouts/fanouts-task-index.md +0 -150
  25. package/brainstorming/fanouts/fanouts-with-conditions-and-subflows.md +0 -239
  26. package/brainstorming/subflows/branching.ts.md +0 -38
  27. package/brainstorming/subflows/subflows-callbacks.ts.md +0 -124
  28. package/brainstorming/subflows/subflows-classes.ts.md +0 -83
  29. package/brainstorming/subflows/subflows-flattening-versioned.md +0 -119
  30. package/brainstorming/subflows/subflows-flattening.md +0 -138
  31. package/brainstorming/subflows/subflows.md +0 -118
  32. package/brainstorming/subflows/subruns-table.md +0 -282
  33. package/brainstorming/subflows/subruns.md +0 -315
  34. package/brainstorming/versioning/breaking-and-non-breaking-flow-changes.md +0 -259
  35. package/docs/refactor-edge-worker.md +0 -146
  36. package/docs/versioning.md +0 -19
  37. package/eslint.config.cjs +0 -22
  38. package/out-tsc/vitest/__tests__/runtime/flow.test.d.ts +0 -2
  39. package/out-tsc/vitest/__tests__/runtime/flow.test.d.ts.map +0 -1
  40. package/out-tsc/vitest/__tests__/runtime/steps.test.d.ts +0 -2
  41. package/out-tsc/vitest/__tests__/runtime/steps.test.d.ts.map +0 -1
  42. package/out-tsc/vitest/__tests__/runtime/utils.test.d.ts +0 -2
  43. package/out-tsc/vitest/__tests__/runtime/utils.test.d.ts.map +0 -1
  44. package/out-tsc/vitest/__tests__/types/dsl-types.test-d.d.ts +0 -2
  45. package/out-tsc/vitest/__tests__/types/dsl-types.test-d.d.ts.map +0 -1
  46. package/out-tsc/vitest/__tests__/types/example-flow.test-d.d.ts +0 -2
  47. package/out-tsc/vitest/__tests__/types/example-flow.test-d.d.ts.map +0 -1
  48. package/out-tsc/vitest/__tests__/types/extract-flow-input.test-d.d.ts +0 -2
  49. package/out-tsc/vitest/__tests__/types/extract-flow-input.test-d.d.ts.map +0 -1
  50. package/out-tsc/vitest/__tests__/types/extract-flow-steps.test-d.d.ts +0 -2
  51. package/out-tsc/vitest/__tests__/types/extract-flow-steps.test-d.d.ts.map +0 -1
  52. package/out-tsc/vitest/__tests__/types/getStepDefinition.test-d.d.ts +0 -2
  53. package/out-tsc/vitest/__tests__/types/getStepDefinition.test-d.d.ts.map +0 -1
  54. package/out-tsc/vitest/__tests__/types/step-input.test-d.d.ts +0 -2
  55. package/out-tsc/vitest/__tests__/types/step-input.test-d.d.ts.map +0 -1
  56. package/out-tsc/vitest/__tests__/types/step-output.test-d.d.ts +0 -2
  57. package/out-tsc/vitest/__tests__/types/step-output.test-d.d.ts.map +0 -1
  58. package/out-tsc/vitest/tsconfig.spec.tsbuildinfo +0 -1
  59. package/out-tsc/vitest/vite.config.d.ts +0 -3
  60. package/out-tsc/vitest/vite.config.d.ts.map +0 -1
  61. package/project.json +0 -28
  62. package/prompts/edge-worker-refactor.md +0 -105
  63. package/src/dsl.ts +0 -318
  64. package/src/example-flow.ts +0 -67
  65. package/src/index.ts +0 -1
  66. package/src/utils.ts +0 -84
  67. package/tsconfig.json +0 -13
  68. package/tsconfig.lib.json +0 -26
  69. package/tsconfig.spec.json +0 -35
  70. package/typecheck.log +0 -120
  71. package/vite.config.ts +0 -57
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pgflow/dsl",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "dependencies": {
5
5
  "vitest": "*"
6
6
  },
@@ -15,6 +15,9 @@
15
15
  "import": "./dist/index.js"
16
16
  }
17
17
  },
18
+ "files": [
19
+ "dist"
20
+ ],
18
21
  "types": "./dist/index.d.ts",
19
22
  "type": "module",
20
23
  "publishConfig": {
package/CHANGELOG.md DELETED
@@ -1,7 +0,0 @@
1
- # @pgflow/dsl
2
-
3
- ## 0.0.5
4
-
5
- ### Patch Changes
6
-
7
- - b4b0809: test changesets
@@ -1,121 +0,0 @@
1
- import { describe, it, vi, expect } from 'vitest';
2
- import { Flow } from '../../src/dsl.ts';
3
- import * as utils from '../../src/utils.ts';
4
-
5
- const noop = () => null;
6
-
7
- describe('Flow', () => {
8
- describe('constructor', () => {
9
- it('creates a flow with valid defaults', () => {
10
- const flow = new Flow({ slug: 'valid_flow' });
11
- expect(flow.slug).toBe('valid_flow');
12
- expect(flow.options).toEqual({});
13
- });
14
-
15
- it('creates a flow with custom runtime options', () => {
16
- const flow = new Flow({
17
- slug: 'custom_flow',
18
- maxAttempts: 3,
19
- baseDelay: 100,
20
- timeout: 30,
21
- });
22
- expect(flow.slug).toBe('custom_flow');
23
- expect(flow.options).toEqual({
24
- maxAttempts: 3,
25
- baseDelay: 100,
26
- timeout: 30,
27
- });
28
- });
29
- });
30
-
31
- describe('slug validation', () => {
32
- it('calls validateSlug with the correct slug', () => {
33
- const validateSlugSpy = vi.spyOn(utils, 'validateSlug');
34
- new Flow({ slug: 'hello_world' });
35
- expect(validateSlugSpy).toHaveBeenCalledWith('hello_world');
36
- validateSlugSpy.mockRestore();
37
- });
38
-
39
- it('propagates errors from validateSlug', () => {
40
- const validateSlugSpy = vi.spyOn(utils, 'validateSlug');
41
- validateSlugSpy.mockImplementation(() => {
42
- throw new Error('Mock validation error');
43
- });
44
- expect(() => new Flow({ slug: 'test' })).toThrowError(
45
- 'Mock validation error'
46
- );
47
- validateSlugSpy.mockRestore();
48
- });
49
-
50
- // Integration tests for invalid slugs
51
- it('rejects invalid slugs during flow creation', () => {
52
- expect(() => new Flow({ slug: '1invalid' })).toThrowError();
53
- });
54
- });
55
-
56
- describe('runtime options validation', () => {
57
- it('calls validateRuntimeOptions with the correct options', () => {
58
- const validateRuntimeOptionsSpy = vi.spyOn(
59
- utils,
60
- 'validateRuntimeOptions'
61
- );
62
- new Flow({
63
- slug: 'test_flow',
64
- maxAttempts: 3,
65
- baseDelay: 100,
66
- timeout: 30,
67
- });
68
- expect(validateRuntimeOptionsSpy).toHaveBeenCalledWith(
69
- { maxAttempts: 3, baseDelay: 100, timeout: 30 },
70
- { optional: true }
71
- );
72
- validateRuntimeOptionsSpy.mockRestore();
73
- });
74
-
75
- it('propagates errors from validateRuntimeOptions', () => {
76
- const validateRuntimeOptionsSpy = vi.spyOn(
77
- utils,
78
- 'validateRuntimeOptions'
79
- );
80
- validateRuntimeOptionsSpy.mockImplementation(() => {
81
- throw new Error('Mock validation error');
82
- });
83
- expect(
84
- () => new Flow({ slug: 'test_flow', maxAttempts: 0 })
85
- ).toThrowError('Mock validation error');
86
- validateRuntimeOptionsSpy.mockRestore();
87
- });
88
- });
89
-
90
- describe('getStepDefinition', () => {
91
- it('returns the root step definition when step exists', () => {
92
- const flow = new Flow<{ value: number }>({ slug: 'test_flow' }).step(
93
- { slug: 'root_step' },
94
- noop
95
- );
96
-
97
- const stepDef = flow.getStepDefinition('root_step');
98
- expect(stepDef.slug).toBe('root_step');
99
- expect(stepDef.dependencies).toEqual([]);
100
- });
101
-
102
- it('returns the normal step definition when step exists', () => {
103
- const flow = new Flow<{ value: number }>({ slug: 'test_flow' })
104
- .step({ slug: 'root_step' }, noop)
105
- .step({ slug: 'last_step', dependsOn: ['root_step'] }, noop);
106
-
107
- const stepDef = flow.getStepDefinition('last_step');
108
- expect(stepDef.slug).toBe('last_step');
109
- expect(stepDef.dependencies).toEqual(['root_step']);
110
- });
111
-
112
- it('throws error when step does not exist', () => {
113
- const flow = new Flow<{ value: number }>({ slug: 'test_flow' });
114
-
115
- // @ts-expect-error - intentionally testing invalid slug
116
- expect(() => flow.getStepDefinition('non_existent')).toThrowError(
117
- 'Step "non_existent" does not exist in flow "test_flow"'
118
- );
119
- });
120
- });
121
- });
@@ -1,183 +0,0 @@
1
- import { describe, it, vi, beforeEach, expect } from 'vitest';
2
- import { Flow } from '../../src/dsl.ts';
3
- import * as utils from '../../src/utils.ts';
4
-
5
- describe('Steps', () => {
6
- let flow: Flow<any>;
7
- const noop = () => null;
8
-
9
- beforeEach(() => {
10
- flow = new Flow({ slug: 'test_flow' });
11
- });
12
-
13
- describe('step addition', () => {
14
- it('adds a step with the correct handler', () => {
15
- const handler = () => ({ result: 42 });
16
- const newFlow = flow.step({ slug: 'test_step' }, handler);
17
-
18
- expect(newFlow.getStepDefinition('test_step').handler).toBe(handler);
19
- });
20
-
21
- it('throws when adding step with the same slug', () => {
22
- const newFlow = flow.step({ slug: 'test_step' }, noop);
23
-
24
- expect(() => newFlow.step({ slug: 'test_step' }, noop)).toThrowError(
25
- 'Step "test_step" already exists in flow "test_flow"'
26
- );
27
- });
28
- });
29
-
30
- describe('slug validation', () => {
31
- it('calls validateSlug with the correct slug', () => {
32
- const validateSlugSpy = vi.spyOn(utils, 'validateSlug');
33
- flow.step({ slug: 'test_step' }, noop);
34
- expect(validateSlugSpy).toHaveBeenCalledWith('test_step');
35
- validateSlugSpy.mockRestore();
36
- });
37
-
38
- it('propagates errors from validateSlug', () => {
39
- const validateSlugSpy = vi.spyOn(utils, 'validateSlug');
40
- validateSlugSpy.mockImplementation(() => {
41
- throw new Error('Mock validation error');
42
- });
43
- expect(() => flow.step({ slug: 'test' }, noop)).toThrowError(
44
- 'Mock validation error'
45
- );
46
- validateSlugSpy.mockRestore();
47
- });
48
- });
49
-
50
- describe('dependencies', () => {
51
- it('can add step without dependencies', () => {
52
- expect(() => flow.step({ slug: 'no_deps' }, noop)).not.toThrowError();
53
- });
54
-
55
- it('can add step with explicit empty array of dependencies', () => {
56
- expect(() =>
57
- flow.step({ slug: 'empty_deps', dependsOn: [] }, noop)
58
- ).not.toThrowError();
59
- });
60
-
61
- it('allows adding step with valid dependencies', () => {
62
- const newFlow = flow.step({ slug: 'first_step' }, noop);
63
-
64
- expect(() =>
65
- newFlow.step({ slug: 'second_step', dependsOn: ['first_step'] }, noop)
66
- ).not.toThrowError();
67
- });
68
-
69
- it('does not allow adding step with non-existing dependencies', () => {
70
- expect(() =>
71
- flow.step(
72
- // @ts-expect-error - dependsOn references non-existing step
73
- { slug: 'invalid_deps', dependsOn: ['non_existing_step'] },
74
- noop
75
- )
76
- ).toThrowError(
77
- 'Step "invalid_deps" depends on undefined step "non_existing_step"'
78
- );
79
- });
80
-
81
- it('does not allow adding step with non-string dependencies', () => {
82
- expect(() =>
83
- // @ts-expect-error - dependsOn contains non-string value
84
- flow.step({ slug: 'invalid_deps', dependsOn: [12345] }, noop)
85
- ).toThrowError('Step "invalid_deps" depends on undefined step "12345"');
86
- });
87
- });
88
-
89
- describe('runtime options', () => {
90
- it('calls validateRuntimeOptions with the correct options', () => {
91
- const validateRuntimeOptionsSpy = vi.spyOn(
92
- utils,
93
- 'validateRuntimeOptions'
94
- );
95
- flow.step(
96
- {
97
- slug: 'test_step',
98
- maxAttempts: 3,
99
- baseDelay: 100,
100
- timeout: 30,
101
- },
102
- noop
103
- );
104
- expect(validateRuntimeOptionsSpy).toHaveBeenCalledWith(
105
- { maxAttempts: 3, baseDelay: 100, timeout: 30 },
106
- { optional: true }
107
- );
108
- validateRuntimeOptionsSpy.mockRestore();
109
- });
110
-
111
- it('propagates errors from validateRuntimeOptions', () => {
112
- const validateRuntimeOptionsSpy = vi.spyOn(
113
- utils,
114
- 'validateRuntimeOptions'
115
- );
116
- validateRuntimeOptionsSpy.mockImplementation(() => {
117
- throw new Error('Mock validation error');
118
- });
119
- expect(() =>
120
- flow.step(
121
- {
122
- slug: 'test_step',
123
- maxAttempts: 0,
124
- },
125
- noop
126
- )
127
- ).toThrowError('Mock validation error');
128
- validateRuntimeOptionsSpy.mockRestore();
129
- });
130
-
131
- it('stores runtime options on the step definition', () => {
132
- const newFlow = flow.step(
133
- {
134
- slug: 'test_step',
135
- maxAttempts: 3,
136
- baseDelay: 100,
137
- timeout: 30,
138
- },
139
- noop
140
- );
141
-
142
- const stepDef = newFlow.getStepDefinition('test_step');
143
- expect(stepDef.options).toEqual({
144
- maxAttempts: 3,
145
- baseDelay: 100,
146
- timeout: 30,
147
- });
148
- });
149
- });
150
-
151
- describe('step integration', () => {
152
- it('allows steps to access run input', async () => {
153
- const testFlow = new Flow<{ value: number }>({ slug: 'test_flow' }).step(
154
- { slug: 'step1' },
155
- ({ run }) => ({ doubled: run.value * 2 })
156
- );
157
-
158
- const step1Def = testFlow.getStepDefinition('step1');
159
- const result = await step1Def.handler({ run: { value: 5 } });
160
-
161
- expect(result).toEqual({ doubled: 10 });
162
- });
163
-
164
- it('allows steps to access dependencies', async () => {
165
- const testFlow = new Flow<{ value: number }>({ slug: 'test_flow' })
166
- .step({ slug: 'step1' }, ({ run }) => ({ doubled: run.value * 2 }))
167
- .step({ slug: 'step2', dependsOn: ['step1'] }, ({ step1 }) => ({
168
- quadrupled: step1.doubled * 2,
169
- }));
170
-
171
- const step1Def = testFlow.getStepDefinition('step1');
172
- const step1Result = await step1Def.handler({ run: { value: 5 } });
173
-
174
- const step2Def = testFlow.getStepDefinition('step2');
175
- const step2Result = await step2Def.handler({
176
- run: { value: 5 },
177
- step1: step1Result,
178
- });
179
-
180
- expect(step2Result).toEqual({ quadrupled: 20 });
181
- });
182
- });
183
- });
@@ -1,149 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { validateSlug, validateRuntimeOptions } from '../../src/utils.ts';
3
-
4
- describe('validateSlug', () => {
5
- it('accepts valid slugs', () => {
6
- expect(() => validateSlug('valid_slug')).not.toThrowError();
7
- expect(() => validateSlug('valid_slug_123')).not.toThrowError();
8
- expect(() => validateSlug('validSlug123')).not.toThrowError();
9
- });
10
-
11
- it('rejects slugs that start with numbers', () => {
12
- expect(() => validateSlug('1invalid')).toThrowError(
13
- 'Slug cannot start with a number'
14
- );
15
- });
16
-
17
- it('rejects slugs that start with underscores', () => {
18
- expect(() => validateSlug('_invalid')).toThrowError(
19
- 'Slug cannot start with an underscore'
20
- );
21
- });
22
-
23
- it('rejects slugs containing spaces', () => {
24
- expect(() => validateSlug('invalid slug')).toThrowError(
25
- 'Slug cannot contain spaces'
26
- );
27
- });
28
-
29
- it('rejects slugs containing special characters', () => {
30
- expect(() => validateSlug('invalid/slug')).toThrowError(
31
- 'Slug cannot contain special characters like /, :, ?, #, -'
32
- );
33
- expect(() => validateSlug('invalid:slug')).toThrowError(
34
- 'Slug cannot contain special characters like /, :, ?, #, -'
35
- );
36
- expect(() => validateSlug('invalid?slug')).toThrowError(
37
- 'Slug cannot contain special characters like /, :, ?, #, -'
38
- );
39
- expect(() => validateSlug('invalid#slug')).toThrowError(
40
- 'Slug cannot contain special characters like /, :, ?, #, -'
41
- );
42
- expect(() => validateSlug('invalid-slug')).toThrowError(
43
- 'Slug cannot contain special characters like /, :, ?, #, -'
44
- );
45
- });
46
-
47
- it('rejects slugs longer than 128 characters', () => {
48
- const longSlug = 'a'.repeat(129);
49
- expect(() => validateSlug(longSlug)).toThrowError(
50
- 'Slug cannot be longer than 128 characters'
51
- );
52
- });
53
- });
54
-
55
- describe('validateRuntimeOptions', () => {
56
- describe('when optional is false (default)', () => {
57
- it('throws when required options are missing', () => {
58
- expect(() => validateRuntimeOptions({})).toThrowError(
59
- 'maxAttempts is required'
60
- );
61
- expect(() => validateRuntimeOptions({ maxAttempts: 1 })).toThrowError(
62
- 'baseDelay is required'
63
- );
64
- expect(() =>
65
- validateRuntimeOptions({ maxAttempts: 1, baseDelay: 5 })
66
- ).toThrowError('timeout is required');
67
- });
68
-
69
- it('validates maxAttempts is >= 1', () => {
70
- expect(() =>
71
- validateRuntimeOptions({
72
- maxAttempts: 0,
73
- baseDelay: 10,
74
- timeout: 10,
75
- })
76
- ).toThrowError('maxAttempts must be greater than or equal to 1');
77
- });
78
-
79
- it('validates baseDelay is >= 1', () => {
80
- expect(() =>
81
- validateRuntimeOptions({
82
- maxAttempts: 3,
83
- baseDelay: 0,
84
- timeout: 10,
85
- })
86
- ).toThrowError('baseDelay must be greater than or equal to 1');
87
- });
88
-
89
- it('validates timeout is >= 3', () => {
90
- expect(() =>
91
- validateRuntimeOptions({
92
- maxAttempts: 3,
93
- baseDelay: 10,
94
- timeout: 2,
95
- })
96
- ).toThrowError('timeout must be greater than or equal to 3');
97
- });
98
- });
99
-
100
- describe('when optional is true', () => {
101
- it('accepts missing options', () => {
102
- expect(() =>
103
- validateRuntimeOptions({}, { optional: true })
104
- ).not.toThrowError();
105
- expect(() =>
106
- validateRuntimeOptions({ maxAttempts: 1 }, { optional: true })
107
- ).not.toThrowError();
108
- });
109
-
110
- it('still validates provided options', () => {
111
- expect(() =>
112
- validateRuntimeOptions(
113
- {
114
- maxAttempts: 0,
115
- },
116
- { optional: true }
117
- )
118
- ).toThrowError('maxAttempts must be greater than or equal to 1');
119
-
120
- expect(() =>
121
- validateRuntimeOptions(
122
- {
123
- baseDelay: 0,
124
- },
125
- { optional: true }
126
- )
127
- ).toThrowError('baseDelay must be greater than or equal to 1');
128
-
129
- expect(() =>
130
- validateRuntimeOptions(
131
- {
132
- timeout: 2,
133
- },
134
- { optional: true }
135
- )
136
- ).toThrowError('timeout must be greater than or equal to 3');
137
- });
138
- });
139
-
140
- it('accepts valid options', () => {
141
- expect(() =>
142
- validateRuntimeOptions({
143
- maxAttempts: 3,
144
- baseDelay: 10,
145
- timeout: 30,
146
- })
147
- ).not.toThrowError();
148
- });
149
- });
@@ -1,103 +0,0 @@
1
- import { Flow } from '../../src/index.ts';
2
- import { describe, it, expectTypeOf } from 'vitest';
3
-
4
- describe('Flow Type System Tests', () => {
5
- it('should properly type input argument for root steps', () => {
6
- new Flow<{ id: number; email: string }>({
7
- slug: 'test_flow',
8
- }).step({ slug: 'root_a' }, (input) => {
9
- expectTypeOf(input).toMatchTypeOf<{
10
- run: { id: number; email: string };
11
- }>();
12
- return { result: 'test-result' };
13
- });
14
- });
15
-
16
- it('should properly type input arguments for dependent steps', () => {
17
- new Flow<{ id: number; email: string }>({
18
- slug: 'test_flow',
19
- })
20
- .step({ slug: 'root_a' }, (input) => {
21
- expectTypeOf(input).toMatchTypeOf<{
22
- run: { id: number; email: string };
23
- }>();
24
- return { result: 'test-result' };
25
- })
26
- .step({ slug: 'step_a', dependsOn: ['root_a'] }, (input) => {
27
- expectTypeOf(input).toMatchTypeOf<{
28
- run: { id: number; email: string };
29
- root_a: { result: string };
30
- }>();
31
- return { count: 42 };
32
- })
33
- .step(
34
- { slug: 'final_step', dependsOn: ['root_a', 'step_a'] },
35
- (input) => {
36
- expectTypeOf(input).toMatchTypeOf<{
37
- run: { id: number; email: string };
38
- root_a: { result: string };
39
- step_a: { count: number };
40
- }>();
41
- return { flag: true };
42
- }
43
- );
44
- });
45
-
46
- describe('Flow dependency validation', () => {
47
- it('should catch non-existent steps at compile time', () => {
48
- const testFlow = new Flow<string>({ slug: 'test_flow' }).step(
49
- { slug: 'step1' },
50
- () => 5
51
- );
52
-
53
- // Type assertion to verify compile-time error
54
- type TestType = Parameters<typeof testFlow.step>[0]['dependsOn'];
55
- // @ts-expect-error - should only allow 'step1' as a valid dependency
56
- const invalidDeps: TestType = ['nonExistentStep'];
57
- });
58
-
59
- it('should not allow access to non-dependencies', () => {
60
- new Flow<string>({ slug: 'test_flow' })
61
- .step({ slug: 'step1' }, () => 1)
62
- .step({ slug: 'step2' }, () => 2)
63
- .step({ slug: 'step3', dependsOn: ['step1'] }, (payload) => {
64
- expectTypeOf(payload).toMatchTypeOf<{
65
- run: string;
66
- step1: number;
67
- }>();
68
-
69
- // Verify that step2 is not accessible
70
- expectTypeOf(payload).not.toHaveProperty('step2');
71
-
72
- return payload.step1;
73
- });
74
- });
75
- });
76
-
77
- describe('Multi-level dependencies', () => {
78
- it('should correctly type multi-level dependencies', () => {
79
- new Flow<string>({ slug: 'test_flow' })
80
- .step({ slug: 'first' }, (payload) => {
81
- expectTypeOf(payload).toMatchTypeOf<{ run: string }>();
82
- return 5;
83
- })
84
- .step({ slug: 'second', dependsOn: ['first'] }, (payload) => {
85
- expectTypeOf(payload).toMatchTypeOf<{
86
- run: string;
87
- first: number;
88
- }>();
89
-
90
- return [payload.run] as string[];
91
- })
92
- .step({ slug: 'third', dependsOn: ['first', 'second'] }, (payload) => {
93
- expectTypeOf(payload).toMatchTypeOf<{
94
- run: string;
95
- first: number;
96
- second: string[];
97
- }>();
98
-
99
- return 15;
100
- });
101
- });
102
- });
103
- });
@@ -1,76 +0,0 @@
1
- import { it, expectTypeOf } from 'vitest';
2
- import { AnalyzeWebsite } from '../../src/example-flow.ts';
3
-
4
- const websiteStepDef = AnalyzeWebsite.getStepDefinition('website');
5
- const sentimentStepDef = AnalyzeWebsite.getStepDefinition('sentiment');
6
- const summaryStepDef = AnalyzeWebsite.getStepDefinition('summary');
7
- const saveToDbStepDef = AnalyzeWebsite.getStepDefinition('saveToDb');
8
-
9
- const run = { url: 'https://example.com' };
10
- const website = { content: 'holahola' };
11
- const summary = { aiSummary: 'holahola' };
12
- const sentiment = { score: 0.5 };
13
-
14
- it('should correctly handle AnalyzeWebsite flow steps with proper types', () => {
15
- // Test website step handler type
16
- expectTypeOf(websiteStepDef.handler).toBeFunction();
17
- expectTypeOf(websiteStepDef.handler).parameters.toMatchTypeOf<
18
- [{ run: { url: string } }]
19
- >();
20
- expectTypeOf(websiteStepDef.handler).returns.toMatchTypeOf<
21
- Promise<{ content: string }> | { content: string }
22
- >();
23
-
24
- // Test sentiment step handler type
25
- expectTypeOf(sentimentStepDef.handler).toBeFunction();
26
- expectTypeOf(sentimentStepDef.handler).parameters.toMatchTypeOf<
27
- [{ run: { url: string }; website: { content: string } }]
28
- >();
29
- expectTypeOf(sentimentStepDef.handler).returns.toMatchTypeOf<
30
- Promise<{ score: number }> | { score: number }
31
- >();
32
-
33
- // Test summary step handler type
34
- expectTypeOf(summaryStepDef.handler).toBeFunction();
35
- expectTypeOf(summaryStepDef.handler).parameters.toMatchTypeOf<
36
- [{ run: { url: string }; website: { content: string } }]
37
- >();
38
- expectTypeOf(summaryStepDef.handler).returns.toMatchTypeOf<
39
- Promise<{ aiSummary: string }> | { aiSummary: string }
40
- >();
41
-
42
- // Test saveToDb step handler type
43
- expectTypeOf(saveToDbStepDef.handler).toBeFunction();
44
- expectTypeOf(saveToDbStepDef.handler).parameters.toMatchTypeOf<
45
- [
46
- {
47
- run: { url: string };
48
- sentiment: { score: number };
49
- summary: { aiSummary: string };
50
- }
51
- ]
52
- >();
53
- expectTypeOf(saveToDbStepDef.handler).returns.toMatchTypeOf<
54
- Promise<string> | string
55
- >();
56
- });
57
-
58
- it('allows to call handlers with matching inputs', () => {
59
- websiteStepDef.handler({ run });
60
- sentimentStepDef.handler({ run, website });
61
- summaryStepDef.handler({ run, website });
62
- saveToDbStepDef.handler({ run, summary, sentiment });
63
- });
64
- it('does not allow to call with additional keys', () => {
65
- // @ts-expect-error - no additional keys allowed
66
- websiteStepDef.handler({ run, newKey: true });
67
-
68
- // @ts-expect-error - no additional keys allowed
69
- sentimentStepDef.handler({ run, website, newKey: true });
70
-
71
- // @ts-expect-error - no additional keys allowed
72
- summaryStepDef.handler({ run, website, newKey: true });
73
-
74
- // @ts-expect-error - no additional keys allowed
75
- saveToDbStepDef.handler({ run, summary, sentiment, newKey: true });
76
- });