@outputai/core 0.14.0 → 0.14.1-next.1ec4416.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/dist/credentials/credentials.d.ts +6 -0
- package/dist/credentials/credentials.js +87 -0
- package/dist/credentials/encrypted_yaml_provider.d.ts +2 -0
- package/dist/credentials/encrypted_yaml_provider.js +77 -0
- package/dist/credentials/encryption.d.ts +3 -0
- package/dist/credentials/encryption.js +6 -0
- package/dist/credentials/errors.d.ts +13 -0
- package/dist/credentials/errors.js +39 -0
- package/dist/credentials/index.d.ts +6 -0
- package/dist/credentials/index.js +5 -0
- package/dist/credentials/init.d.ts +1 -0
- package/dist/credentials/init.js +7 -0
- package/dist/credentials/paths.d.ts +7 -0
- package/dist/credentials/paths.js +14 -0
- package/dist/credentials/provider_registry.d.ts +3 -0
- package/dist/credentials/provider_registry.js +6 -0
- package/dist/credentials/types.d.ts +12 -0
- package/dist/credentials/types.js +1 -0
- package/package.json +25 -14
- package/src/async_storage.d.ts +4 -0
- package/src/consts.js +0 -2
- package/src/helpers/object.d.ts +2 -0
- package/src/hooks/index.d.ts +0 -8
- package/src/hooks/index.js +0 -3
- package/src/logger/index.d.ts +4 -0
- package/src/worker/index.js +3 -1
- package/bin/healthcheck.spec.js +0 -90
- package/src/bus.spec.js +0 -196
- package/src/errors.spec.js +0 -19
- package/src/helpers/activity_options.spec.js +0 -55
- package/src/helpers/component.spec.js +0 -54
- package/src/helpers/error_serializer.spec.js +0 -479
- package/src/helpers/errors.spec.js +0 -189
- package/src/helpers/fetch.spec.js +0 -292
- package/src/helpers/function.spec.js +0 -24
- package/src/helpers/object.spec.js +0 -425
- package/src/helpers/promise.spec.js +0 -62
- package/src/helpers/redact.spec.js +0 -66
- package/src/helpers/string.spec.js +0 -99
- package/src/helpers/temporal_context.spec.ts +0 -83
- package/src/helpers/trace_info.spec.js +0 -45
- package/src/helpers/workflow_context.spec.js +0 -46
- package/src/hooks/index.spec.js +0 -265
- package/src/hooks/pending_hooks.spec.js +0 -62
- package/src/interface/evaluator.spec.js +0 -685
- package/src/interface/logger.spec.js +0 -172
- package/src/interface/step.spec.js +0 -128
- package/src/interface/validations/index.spec.js +0 -197
- package/src/interface/validations/schemas.spec.js +0 -229
- package/src/interface/webhook.spec.js +0 -170
- package/src/interface/workflow.spec.js +0 -710
- package/src/interface/workflow_utils.spec.js +0 -271
- package/src/interface/zod_integration.spec.js +0 -646
- package/src/internal_activities/index.spec.js +0 -186
- package/src/logger/development.spec.js +0 -87
- package/src/logger/index.spec.js +0 -27
- package/src/logger/production.spec.js +0 -71
- package/src/sdk/helpers/component_metadata.spec.js +0 -30
- package/src/sdk/helpers/objects.spec.js +0 -16
- package/src/sdk/helpers/path.spec.js +0 -102
- package/src/sdk/runtime/context.spec.js +0 -37
- package/src/sdk/runtime/events.spec.js +0 -40
- package/src/temporal/client.spec.js +0 -124
- package/src/tracing/processors/local/index.spec.js +0 -204
- package/src/tracing/processors/s3/configs.spec.js +0 -64
- package/src/tracing/processors/s3/index.spec.js +0 -185
- package/src/tracing/processors/s3/redis_client.spec.js +0 -179
- package/src/tracing/processors/s3/s3_client.spec.js +0 -68
- package/src/tracing/tools/build_trace_tree.spec.js +0 -216
- package/src/tracing/trace_engine.spec.js +0 -299
- package/src/worker/bundle.spec.js +0 -53
- package/src/worker/bundler_options.spec.js +0 -62
- package/src/worker/catalog_workflow/catalog_publisher.spec.js +0 -317
- package/src/worker/catalog_workflow/index.spec.js +0 -222
- package/src/worker/configs.spec.js +0 -213
- package/src/worker/configs_tuner_schema.spec.js +0 -127
- package/src/worker/connection_monitor.spec.js +0 -328
- package/src/worker/global_functions.spec.js +0 -55
- package/src/worker/index.spec.js +0 -526
- package/src/worker/interceptors/activity.spec.js +0 -369
- package/src/worker/interceptors/headers.spec.js +0 -73
- package/src/worker/interceptors/workflow.spec.js +0 -357
- package/src/worker/interruption.spec.js +0 -177
- package/src/worker/loader/activities.spec.js +0 -212
- package/src/worker/loader/hooks.spec.js +0 -64
- package/src/worker/loader/matchers.spec.js +0 -140
- package/src/worker/loader/tools.spec.js +0 -595
- package/src/worker/loader/workflows.spec.js +0 -287
- package/src/worker/log_hooks.spec.js +0 -303
- package/src/worker/shutdown.spec.js +0 -197
- package/src/worker/sinks.spec.js +0 -220
- package/src/worker/telemetry.spec.js +0 -80
- package/src/worker/temporal_logger.spec.js +0 -90
- package/src/worker/webpack_loaders/tools.spec.js +0 -314
- package/src/worker/webpack_loaders/workflow_rewriter/collect_target_imports.spec.js +0 -134
- package/src/worker/webpack_loaders/workflow_rewriter/index.spec.js +0 -154
- package/src/worker/webpack_loaders/workflow_rewriter/rewrite_activity_calls.spec.js +0 -165
- package/src/worker/webpack_loaders/workflow_validator/index.spec.js +0 -202
- package/src/worker/webpack_loaders/workflow_validator/npm_workflow_export_resolve.spec.js +0 -374
- package/src/worker/worker_runner.spec.js +0 -220
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import generatorModule from '@babel/generator';
|
|
3
|
-
import { parse } from '../tools.js';
|
|
4
|
-
import rewriteActivityCalls from './rewrite_activity_calls.js';
|
|
5
|
-
|
|
6
|
-
const { invokeActivitySymbolKey } = vi.hoisted( () => ( {
|
|
7
|
-
invokeActivitySymbolKey: 'test:invoke_activity'
|
|
8
|
-
} ) );
|
|
9
|
-
|
|
10
|
-
vi.mock( '#consts', async importOriginal => ( {
|
|
11
|
-
...await importOriginal(),
|
|
12
|
-
INVOKE_ACTIVITY_SYMBOL: Symbol.for( invokeActivitySymbolKey )
|
|
13
|
-
} ) );
|
|
14
|
-
|
|
15
|
-
const generate = generatorModule.default ?? generatorModule;
|
|
16
|
-
const escapeRegExp = value => value.replace( /[.*+?^${}()|[\]\\]/g, '\\$&' );
|
|
17
|
-
const invokeActivityPattern = activityName =>
|
|
18
|
-
new RegExp( `globalThis\\[globalThis\\.Symbol\\.for\\(([\"'])${escapeRegExp( invokeActivitySymbolKey )}\\1\\)\\]\\(([\"'])${activityName}\\2` );
|
|
19
|
-
|
|
20
|
-
describe( 'rewrite_activity_calls', () => {
|
|
21
|
-
it( 'rewrites step calls inside functions without changing function shape', () => {
|
|
22
|
-
const src = `
|
|
23
|
-
const obj = {
|
|
24
|
-
fn: async x => {
|
|
25
|
-
StepA( 1 );
|
|
26
|
-
FlowB( 2 );
|
|
27
|
-
}
|
|
28
|
-
}`;
|
|
29
|
-
const ast = parse( src, 'file.js' );
|
|
30
|
-
const activityImports = [ { localName: 'StepA', activityName: 'step.a' } ];
|
|
31
|
-
|
|
32
|
-
const rewrote = rewriteActivityCalls( { ast, activityImports } );
|
|
33
|
-
expect( rewrote ).toBe( true );
|
|
34
|
-
|
|
35
|
-
const { code } = generate( ast, { quotes: 'single' } );
|
|
36
|
-
expect( code ).not.toMatch( /@outputai\/core\/invoker/ );
|
|
37
|
-
expect( code ).toMatch( /fn:\s*async x =>/ );
|
|
38
|
-
expect( code ).toMatch( invokeActivityPattern( 'step\\.a' ) );
|
|
39
|
-
expect( code ).toMatch( /,\s*1\)/ );
|
|
40
|
-
expect( code ).toMatch( /FlowB\(2\)/ );
|
|
41
|
-
} );
|
|
42
|
-
|
|
43
|
-
it( 'rewrites evaluator calls to the global activity dispatcher', () => {
|
|
44
|
-
const src = `
|
|
45
|
-
const obj = {
|
|
46
|
-
fn: async x => {
|
|
47
|
-
EvalA(3);
|
|
48
|
-
}
|
|
49
|
-
};`;
|
|
50
|
-
const ast = parse( src, 'file.js' );
|
|
51
|
-
const activityImports = [ { localName: 'EvalA', activityName: 'eval.a' } ];
|
|
52
|
-
const rewrote = rewriteActivityCalls( { ast, activityImports } );
|
|
53
|
-
expect( rewrote ).toBe( true );
|
|
54
|
-
const { code } = generate( ast, { quotes: 'single' } );
|
|
55
|
-
expect( code ).toMatch( invokeActivityPattern( 'eval\\.a' ) );
|
|
56
|
-
expect( code ).toMatch( /,\s*3\)/ );
|
|
57
|
-
} );
|
|
58
|
-
|
|
59
|
-
it( 'does nothing when no matching calls are present', () => {
|
|
60
|
-
const src = [ 'const obj = { fn: function() { other(); } }' ].join( '\n' );
|
|
61
|
-
const ast = parse( src, 'file.js' );
|
|
62
|
-
const rewrote = rewriteActivityCalls( { ast, activityImports: [] } );
|
|
63
|
-
expect( rewrote ).toBe( false );
|
|
64
|
-
} );
|
|
65
|
-
|
|
66
|
-
it( 'rewrites imported activity calls in any function body', () => {
|
|
67
|
-
const src = `
|
|
68
|
-
const foo = async () => {
|
|
69
|
-
StepA( 1 );
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
function bar( x ) {
|
|
73
|
-
EvalA( x );
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const obj = {
|
|
77
|
-
fn: async x => {
|
|
78
|
-
foo();
|
|
79
|
-
bar( 2 );
|
|
80
|
-
}
|
|
81
|
-
}`;
|
|
82
|
-
|
|
83
|
-
const ast = parse( src, 'file.js' );
|
|
84
|
-
const activityImports = [
|
|
85
|
-
{ localName: 'StepA', activityName: 'step.a' },
|
|
86
|
-
{ localName: 'EvalA', activityName: 'eval.a' }
|
|
87
|
-
];
|
|
88
|
-
|
|
89
|
-
const rewrote = rewriteActivityCalls( { ast, activityImports } );
|
|
90
|
-
expect( rewrote ).toBe( true );
|
|
91
|
-
|
|
92
|
-
const { code } = generate( ast, { quotes: 'single' } );
|
|
93
|
-
|
|
94
|
-
expect( code ).toMatch( invokeActivityPattern( 'step\\.a' ) );
|
|
95
|
-
expect( code ).toMatch( invokeActivityPattern( 'eval\\.a' ) );
|
|
96
|
-
expect( code ).toMatch( /,\s*1\)/ );
|
|
97
|
-
expect( code ).toMatch( /,\s*x\)/ );
|
|
98
|
-
expect( code ).toMatch( /foo\(\)/ );
|
|
99
|
-
expect( code ).toMatch( /bar\(2\)/ );
|
|
100
|
-
expect( code ).toMatch( /const foo = async \(\) =>/ );
|
|
101
|
-
} );
|
|
102
|
-
|
|
103
|
-
it( 'does not rewrite top-level calls', () => {
|
|
104
|
-
const src = `
|
|
105
|
-
StepA( 1 );
|
|
106
|
-
function helper() {
|
|
107
|
-
StepA( 2 );
|
|
108
|
-
}`;
|
|
109
|
-
|
|
110
|
-
const ast = parse( src, 'file.js' );
|
|
111
|
-
const activityImports = [ { localName: 'StepA', activityName: 'step.a' } ];
|
|
112
|
-
const rewrote = rewriteActivityCalls( { ast, activityImports } );
|
|
113
|
-
expect( rewrote ).toBe( true );
|
|
114
|
-
|
|
115
|
-
const { code } = generate( ast, { quotes: 'single' } );
|
|
116
|
-
expect( code ).toMatch( /StepA\(1\)/ );
|
|
117
|
-
expect( code ).toMatch( invokeActivityPattern( 'step\\.a' ) );
|
|
118
|
-
expect( code ).toMatch( /,\s*2\)/ );
|
|
119
|
-
} );
|
|
120
|
-
|
|
121
|
-
it( 'ignores local invoke activity names because globalThis is explicit', () => {
|
|
122
|
-
const src = `
|
|
123
|
-
const __invokeActivity = () => 'local';
|
|
124
|
-
const _invokeActivity = () => 'local';
|
|
125
|
-
function helper() {
|
|
126
|
-
StepA();
|
|
127
|
-
}`;
|
|
128
|
-
const ast = parse( src, 'file.js' );
|
|
129
|
-
const activityImports = [ { localName: 'StepA', activityName: 'step.a' } ];
|
|
130
|
-
const rewrote = rewriteActivityCalls( { ast, activityImports } );
|
|
131
|
-
expect( rewrote ).toBe( true );
|
|
132
|
-
|
|
133
|
-
const { code } = generate( ast, { quotes: 'single' } );
|
|
134
|
-
expect( code ).not.toMatch( /@outputai\/core\/invoker/ );
|
|
135
|
-
expect( code ).toMatch( /const __invokeActivity = \(\) => 'local'/ );
|
|
136
|
-
expect( code ).toMatch( /const _invokeActivity = \(\) => 'local'/ );
|
|
137
|
-
expect( code ).toMatch( invokeActivityPattern( 'step\\.a' ) );
|
|
138
|
-
} );
|
|
139
|
-
|
|
140
|
-
it( 'reads Symbol through globalThis so local Symbol bindings are safe', () => {
|
|
141
|
-
const src = `
|
|
142
|
-
function helper( Symbol ) {
|
|
143
|
-
StepA();
|
|
144
|
-
}`;
|
|
145
|
-
const ast = parse( src, 'file.js' );
|
|
146
|
-
const activityImports = [ { localName: 'StepA', activityName: 'step.a' } ];
|
|
147
|
-
const rewrote = rewriteActivityCalls( { ast, activityImports } );
|
|
148
|
-
expect( rewrote ).toBe( true );
|
|
149
|
-
|
|
150
|
-
const { code } = generate( ast, { quotes: 'single' } );
|
|
151
|
-
expect( code ).toMatch( /function helper\(Symbol\)/ );
|
|
152
|
-
expect( code ).toMatch( invokeActivityPattern( 'step\\.a' ) );
|
|
153
|
-
} );
|
|
154
|
-
|
|
155
|
-
it( 'throws when globalThis is shadowed at an activity call site', () => {
|
|
156
|
-
const src = `
|
|
157
|
-
function helper( globalThis ) {
|
|
158
|
-
StepA();
|
|
159
|
-
}`;
|
|
160
|
-
const ast = parse( src, 'file.js' );
|
|
161
|
-
const activityImports = [ { localName: 'StepA', activityName: 'step.a' } ];
|
|
162
|
-
|
|
163
|
-
expect( () => rewriteActivityCalls( { ast, activityImports } ) ).toThrow( /globalThis.*shadowed/ );
|
|
164
|
-
} );
|
|
165
|
-
} );
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { mkdtempSync, writeFileSync, rmSync, mkdirSync } from 'node:fs';
|
|
3
|
-
import { tmpdir } from 'node:os';
|
|
4
|
-
import { join } from 'node:path';
|
|
5
|
-
import validatorLoader from './index.mjs';
|
|
6
|
-
|
|
7
|
-
const writeMockGrowthxlabsCatalog = ( dir, workflowName ) => {
|
|
8
|
-
const pkgRoot = join( dir, 'node_modules', '@growthxlabs', 'workflows_catalog' );
|
|
9
|
-
const srcDir = join( pkgRoot, 'src' );
|
|
10
|
-
mkdirSync( join( srcDir, 'workflows', 'wf' ), { recursive: true } );
|
|
11
|
-
writeFileSync( join( pkgRoot, 'package.json' ), JSON.stringify( {
|
|
12
|
-
name: '@growthxlabs/workflows_catalog',
|
|
13
|
-
type: 'module',
|
|
14
|
-
main: './src/index.js',
|
|
15
|
-
dependencies: { '@outputai/core': '1.0.0' }
|
|
16
|
-
} ) );
|
|
17
|
-
writeFileSync( join( srcDir, 'index.js' ), 'export { default as sumNumbers } from \'./workflows/wf/workflow.js\';\n' );
|
|
18
|
-
writeFileSync(
|
|
19
|
-
join( srcDir, 'workflows', 'wf', 'workflow.js' ),
|
|
20
|
-
`export default workflow({ name: '${workflowName}' });\n`
|
|
21
|
-
);
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
function runLoader( filename, source ) {
|
|
25
|
-
return new Promise( ( resolve, reject ) => {
|
|
26
|
-
const warnings = [];
|
|
27
|
-
const ctx = {
|
|
28
|
-
resourcePath: filename,
|
|
29
|
-
cacheable: () => {},
|
|
30
|
-
emitWarning: err => warnings.push( err ),
|
|
31
|
-
async: () => ( err, code, map ) => ( err ? reject( err ) : resolve( { code, map, warnings } ) ),
|
|
32
|
-
callback: ( err, code, map ) => ( err ? reject( err ) : resolve( { code, map, warnings } ) )
|
|
33
|
-
};
|
|
34
|
-
validatorLoader.call( ctx, source, null );
|
|
35
|
-
} );
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
describe( 'workflow_validator loader', () => {
|
|
39
|
-
it( 'allows supported workflow imports and arbitrary non-component imports', async () => {
|
|
40
|
-
const dir = mkdtempSync( join( tmpdir(), 'wf-imports-allow-' ) );
|
|
41
|
-
writeFileSync( join( dir, 'steps.js' ), 'export const S = step({ name: "s" })\n' );
|
|
42
|
-
writeFileSync( join( dir, 'evaluators.js' ), 'export const E = evaluator({ name: "e" })\n' );
|
|
43
|
-
writeFileSync( join( dir, 'workflow.js' ), 'export const W = workflow({ name: "w" })\n' );
|
|
44
|
-
mkdirSync( join( dir, 'utils' ) );
|
|
45
|
-
writeFileSync( join( dir, 'utils', 'helper.js' ), 'export const helper = () => 1;\n' );
|
|
46
|
-
|
|
47
|
-
const source = [
|
|
48
|
-
'import { S } from "./steps.js";',
|
|
49
|
-
'import { E } from "./evaluators.js";',
|
|
50
|
-
'import { W } from "./workflow.js";',
|
|
51
|
-
'import { helper } from "./utils/helper.js";',
|
|
52
|
-
'const x = 1;'
|
|
53
|
-
].join( '\n' );
|
|
54
|
-
|
|
55
|
-
await expect( runLoader( join( dir, 'workflow.js' ), source ) ).resolves.toBeTruthy();
|
|
56
|
-
rmSync( dir, { recursive: true, force: true } );
|
|
57
|
-
} );
|
|
58
|
-
|
|
59
|
-
it( 'allows cross-component imports and requires in activity files', async () => {
|
|
60
|
-
const dir = mkdtempSync( join( tmpdir(), 'activity-cross-imports-' ) );
|
|
61
|
-
const stepsResult = await runLoader( join( dir, 'steps.js' ), [
|
|
62
|
-
'import { E } from "./evaluators.js";',
|
|
63
|
-
'const W = require("./workflow.js");'
|
|
64
|
-
].join( '\n' ) );
|
|
65
|
-
const evaluatorResult = await runLoader( join( dir, 'evaluators.js' ), [
|
|
66
|
-
'import { S } from "./steps.js";',
|
|
67
|
-
'const util = require("./util.js");'
|
|
68
|
-
].join( '\n' ) );
|
|
69
|
-
|
|
70
|
-
expect( stepsResult.warnings ).toHaveLength( 0 );
|
|
71
|
-
expect( evaluatorResult.warnings ).toHaveLength( 0 );
|
|
72
|
-
rmSync( dir, { recursive: true, force: true } );
|
|
73
|
-
} );
|
|
74
|
-
|
|
75
|
-
it( 'rejects default and namespace imports from activity files', async () => {
|
|
76
|
-
const dir = mkdtempSync( join( tmpdir(), 'activity-import-shape-' ) );
|
|
77
|
-
|
|
78
|
-
await expect( runLoader( join( dir, 'workflow.js' ), 'import StepA from "./steps.js";' ) )
|
|
79
|
-
.rejects.toThrow( /Invalid activity import.*named imports only/ );
|
|
80
|
-
await expect( runLoader( join( dir, 'workflow.js' ), 'import * as steps from "./steps.js";' ) )
|
|
81
|
-
.rejects.toThrow( /Invalid activity import.*named imports only/ );
|
|
82
|
-
await expect( runLoader( join( dir, 'workflow.js' ), 'import EvalA, { EvalB } from "./evaluators.js";' ) )
|
|
83
|
-
.rejects.toThrow( /Invalid activity import.*named imports only/ );
|
|
84
|
-
|
|
85
|
-
rmSync( dir, { recursive: true, force: true } );
|
|
86
|
-
} );
|
|
87
|
-
|
|
88
|
-
it( 'rejects non-destructured requires from activity files', async () => {
|
|
89
|
-
const dir = mkdtempSync( join( tmpdir(), 'activity-require-shape-' ) );
|
|
90
|
-
|
|
91
|
-
await expect( runLoader( join( dir, 'workflow.js' ), 'const steps = require("./steps.js");' ) )
|
|
92
|
-
.rejects.toThrow( /Invalid activity require.*destructured requires only/ );
|
|
93
|
-
await expect( runLoader( join( dir, 'workflow.js' ), 'const evaluators = require("./evaluators.js");' ) )
|
|
94
|
-
.rejects.toThrow( /Invalid activity require.*destructured requires only/ );
|
|
95
|
-
|
|
96
|
-
rmSync( dir, { recursive: true, force: true } );
|
|
97
|
-
} );
|
|
98
|
-
|
|
99
|
-
it( 'rejects non-named exports from activity files', async () => {
|
|
100
|
-
const dir = mkdtempSync( join( tmpdir(), 'activity-export-shape-' ) );
|
|
101
|
-
|
|
102
|
-
await expect( runLoader( join( dir, 'steps.js' ), 'export default step({ name: "a" });' ) )
|
|
103
|
-
.rejects.toThrow( /Invalid activity export.*named exports only/ );
|
|
104
|
-
await expect( runLoader( join( dir, 'evaluators.js' ), 'export * from "./other_evaluators.js";' ) )
|
|
105
|
-
.rejects.toThrow( /Invalid activity export.*named exports only/ );
|
|
106
|
-
await expect( runLoader( join( dir, 'steps.js' ), 'export const A = step({ name: "a" });' ) )
|
|
107
|
-
.resolves.toBeTruthy();
|
|
108
|
-
|
|
109
|
-
rmSync( dir, { recursive: true, force: true } );
|
|
110
|
-
} );
|
|
111
|
-
|
|
112
|
-
it( 'rejects top-level activity calls but allows calls inside helper functions', async () => {
|
|
113
|
-
const dir = mkdtempSync( join( tmpdir(), 'top-level-activity-calls-' ) );
|
|
114
|
-
|
|
115
|
-
await expect( runLoader( join( dir, 'steps.js' ), 'const A = step({ name: "a" });\nA();' ) )
|
|
116
|
-
.rejects.toThrow( /Invalid top-level step call 'A'/ );
|
|
117
|
-
await expect( runLoader( join( dir, 'evaluators.js' ), 'const E = evaluator({ name: "e" });\nE();' ) )
|
|
118
|
-
.rejects.toThrow( /Invalid top-level evaluator call 'E'/ );
|
|
119
|
-
await expect( runLoader( join( dir, 'steps.js' ), 'const A = step({ name: "a" });\nfunction helper() { return A(); }' ) )
|
|
120
|
-
.resolves.toBeTruthy();
|
|
121
|
-
|
|
122
|
-
rmSync( dir, { recursive: true, force: true } );
|
|
123
|
-
} );
|
|
124
|
-
|
|
125
|
-
it( 'warns when activity fn bodies call activities or workflows', async () => {
|
|
126
|
-
const dir = mkdtempSync( join( tmpdir(), 'activity-fn-call-warnings-' ) );
|
|
127
|
-
writeMockGrowthxlabsCatalog( dir, 'cat.warn' );
|
|
128
|
-
|
|
129
|
-
const stepResult = await runLoader( join( dir, 'steps.js' ), [
|
|
130
|
-
'const A = step({ name: "a" });',
|
|
131
|
-
'const B = step({ name: "b" });',
|
|
132
|
-
'const obj = { fn: function() { B(); } };'
|
|
133
|
-
].join( '\n' ) );
|
|
134
|
-
const evaluatorResult = await runLoader( join( dir, 'evaluators.js' ), [
|
|
135
|
-
'import { sumNumbers } from "@growthxlabs/workflows_catalog";',
|
|
136
|
-
'const E = evaluator({ name: "e", fn: async () => ({ value: 1 }) });',
|
|
137
|
-
'const obj = { fn: function() { sumNumbers(); } };'
|
|
138
|
-
].join( '\n' ) );
|
|
139
|
-
|
|
140
|
-
expect( stepResult.warnings ).toHaveLength( 1 );
|
|
141
|
-
expect( stepResult.warnings[0].message ).toMatch( /Invalid call in .*steps\.js fn: calling a step/ );
|
|
142
|
-
expect( evaluatorResult.warnings ).toHaveLength( 1 );
|
|
143
|
-
expect( evaluatorResult.warnings[0].message ).toMatch( /Invalid call in .*evaluators\.js fn: calling a workflow/ );
|
|
144
|
-
rmSync( dir, { recursive: true, force: true } );
|
|
145
|
-
} );
|
|
146
|
-
|
|
147
|
-
it( 'allows component instantiation in matching files', async () => {
|
|
148
|
-
const dir = mkdtempSync( join( tmpdir(), 'instantiation-allowed-' ) );
|
|
149
|
-
mkdirSync( join( dir, 'steps' ) );
|
|
150
|
-
mkdirSync( join( dir, 'evaluators' ) );
|
|
151
|
-
|
|
152
|
-
await expect( runLoader(
|
|
153
|
-
join( dir, 'steps', 'fetch_data.js' ),
|
|
154
|
-
'export const fetchData = step({ name: "fetch_data", fn: async () => ({}) });'
|
|
155
|
-
) ).resolves.toBeTruthy();
|
|
156
|
-
await expect( runLoader(
|
|
157
|
-
join( dir, 'evaluators', 'quality.js' ),
|
|
158
|
-
'export const quality = evaluator({ name: "quality", fn: async () => ({ value: 1 }) });'
|
|
159
|
-
) ).resolves.toBeTruthy();
|
|
160
|
-
await expect( runLoader(
|
|
161
|
-
join( dir, 'workflow.js' ),
|
|
162
|
-
'export default workflow({ name: "wf", fn: async () => ({}) });'
|
|
163
|
-
) ).resolves.toBeTruthy();
|
|
164
|
-
|
|
165
|
-
rmSync( dir, { recursive: true, force: true } );
|
|
166
|
-
} );
|
|
167
|
-
|
|
168
|
-
it( 'rejects component instantiation in mismatched files', async () => {
|
|
169
|
-
const dir = mkdtempSync( join( tmpdir(), 'instantiation-rejected-' ) );
|
|
170
|
-
mkdirSync( join( dir, 'shared' ) );
|
|
171
|
-
|
|
172
|
-
await expect( runLoader(
|
|
173
|
-
join( dir, 'utils.js' ),
|
|
174
|
-
'export const badStep = step({ name: "bad", fn: async () => ({}) });'
|
|
175
|
-
) ).rejects.toThrow( /Invalid instantiation location.*step\(\).*steps/ );
|
|
176
|
-
await expect( runLoader(
|
|
177
|
-
join( dir, 'steps.js' ),
|
|
178
|
-
'export const badEval = evaluator({ name: "bad", fn: async () => ({ value: 1 }) });'
|
|
179
|
-
) ).rejects.toThrow( /Invalid instantiation location.*evaluator\(\).*evaluators/ );
|
|
180
|
-
await expect( runLoader(
|
|
181
|
-
join( dir, 'shared', 'common.js' ),
|
|
182
|
-
'export const badWf = workflow({ name: "bad", fn: async () => ({}) });'
|
|
183
|
-
) ).rejects.toThrow( /Invalid instantiation location.*workflow\(\).*workflow/ );
|
|
184
|
-
|
|
185
|
-
rmSync( dir, { recursive: true, force: true } );
|
|
186
|
-
} );
|
|
187
|
-
|
|
188
|
-
it( 'resolves bare npm workflows for require warnings in activity fn bodies', async () => {
|
|
189
|
-
const dir = mkdtempSync( join( tmpdir(), 'bare-require-workflow-warning-' ) );
|
|
190
|
-
writeMockGrowthxlabsCatalog( dir, 'cat.warn.req' );
|
|
191
|
-
|
|
192
|
-
const result = await runLoader( join( dir, 'evaluators.js' ), [
|
|
193
|
-
'const { sumNumbers } = require("@growthxlabs/workflows_catalog");',
|
|
194
|
-
'const E = evaluator({ name: "e", fn: async () => ({ value: 1 }) });',
|
|
195
|
-
'const obj = { fn: function() { sumNumbers(); } };'
|
|
196
|
-
].join( '\n' ) );
|
|
197
|
-
|
|
198
|
-
expect( result.warnings ).toHaveLength( 1 );
|
|
199
|
-
expect( result.warnings[0].message ).toMatch( /Invalid call in .*evaluators\.js fn: calling a workflow/ );
|
|
200
|
-
rmSync( dir, { recursive: true, force: true } );
|
|
201
|
-
} );
|
|
202
|
-
} );
|