@outputai/core 0.14.0 → 0.14.1-next.51e8690.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 +14 -3
- 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
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { dirname } from 'node:path';
|
|
2
|
+
import { MissingCredentialError } from './errors.js';
|
|
3
|
+
import { deepMerge } from '#helpers/object';
|
|
4
|
+
import { getProvider } from './provider_registry.js';
|
|
5
|
+
import { Storage } from '#async_storage';
|
|
6
|
+
const getNestedValue = (obj, dotPath) => dotPath.split('.').reduce((acc, part) => acc?.[part], obj);
|
|
7
|
+
const detectEnvironment = () => {
|
|
8
|
+
const env = process.env.NODE_ENV;
|
|
9
|
+
return (env === 'production' || env === 'development') ? env : undefined;
|
|
10
|
+
};
|
|
11
|
+
const GLOBAL_CACHE_KEY = Symbol('global');
|
|
12
|
+
const cache = new Map();
|
|
13
|
+
const loadGlobal = () => {
|
|
14
|
+
if (cache.has(GLOBAL_CACHE_KEY)) {
|
|
15
|
+
return cache.get(GLOBAL_CACHE_KEY);
|
|
16
|
+
}
|
|
17
|
+
const data = getProvider().loadGlobal({ environment: detectEnvironment() });
|
|
18
|
+
cache.set(GLOBAL_CACHE_KEY, data);
|
|
19
|
+
return data;
|
|
20
|
+
};
|
|
21
|
+
const loadForWorkflow = (workflowName, workflowDir) => {
|
|
22
|
+
if (cache.has(workflowName)) {
|
|
23
|
+
return cache.get(workflowName);
|
|
24
|
+
}
|
|
25
|
+
const globalData = loadGlobal();
|
|
26
|
+
const workflowData = getProvider().loadForWorkflow({
|
|
27
|
+
workflowName,
|
|
28
|
+
workflowDir,
|
|
29
|
+
environment: detectEnvironment()
|
|
30
|
+
});
|
|
31
|
+
const merged = workflowData ? deepMerge(globalData, workflowData) : globalData;
|
|
32
|
+
cache.set(workflowName, merged);
|
|
33
|
+
return merged;
|
|
34
|
+
};
|
|
35
|
+
const getWorkflowContext = () => {
|
|
36
|
+
const ctx = Storage.load();
|
|
37
|
+
if (!ctx) {
|
|
38
|
+
return { workflowName: undefined, workflowDir: undefined };
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
workflowName: ctx.activityInfo.workflowType,
|
|
42
|
+
workflowDir: dirname(ctx.workflowFilename)
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
const load = () => {
|
|
46
|
+
const { workflowName, workflowDir } = getWorkflowContext();
|
|
47
|
+
if (!workflowName) {
|
|
48
|
+
return loadGlobal();
|
|
49
|
+
}
|
|
50
|
+
return loadForWorkflow(workflowName, workflowDir);
|
|
51
|
+
};
|
|
52
|
+
const CREDENTIAL_REF_PREFIX = 'credential:';
|
|
53
|
+
export const resolveCredentialRefs = () => {
|
|
54
|
+
const refs = Object.entries(process.env)
|
|
55
|
+
.filter(([, v]) => typeof v === 'string' && v.startsWith(CREDENTIAL_REF_PREFIX));
|
|
56
|
+
if (refs.length === 0) {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
const data = loadGlobal();
|
|
60
|
+
const resolved = [];
|
|
61
|
+
for (const [envVar, value] of refs) {
|
|
62
|
+
const credPath = value.slice(CREDENTIAL_REF_PREFIX.length);
|
|
63
|
+
const credValue = getNestedValue(data, credPath);
|
|
64
|
+
if (typeof credValue === 'string' && credValue.length > 0) {
|
|
65
|
+
process.env[envVar] = credValue;
|
|
66
|
+
resolved.push(envVar);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return resolved;
|
|
70
|
+
};
|
|
71
|
+
export const credentials = {
|
|
72
|
+
get: (path, defaultValue = undefined) => {
|
|
73
|
+
const data = load();
|
|
74
|
+
const value = getNestedValue(data, path);
|
|
75
|
+
return value !== undefined ? value : defaultValue;
|
|
76
|
+
},
|
|
77
|
+
require: (path) => {
|
|
78
|
+
const value = credentials.get(path);
|
|
79
|
+
if (value === undefined || value === null) {
|
|
80
|
+
throw new MissingCredentialError(path);
|
|
81
|
+
}
|
|
82
|
+
return value;
|
|
83
|
+
},
|
|
84
|
+
_reset: () => {
|
|
85
|
+
cache.clear();
|
|
86
|
+
}
|
|
87
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { load as parseYaml } from 'js-yaml';
|
|
3
|
+
import { decrypt } from './encryption.js';
|
|
4
|
+
import { InvalidCredentialsKeyError, MalformedCredentialsKeyError, MissingKeyError } from './errors.js';
|
|
5
|
+
import { resolveKeyEnvVar, resolveCredentialsPath, resolveKeyPath, resolveWorkflowCredentialsPath, resolveWorkflowKeyPath, resolveWorkflowKeyEnvVar } from './paths.js';
|
|
6
|
+
const resolveBaseDir = () => {
|
|
7
|
+
const arg = process.argv[2];
|
|
8
|
+
return (arg && arg.startsWith('/')) ? arg : process.cwd();
|
|
9
|
+
};
|
|
10
|
+
const resolveKey = (environment) => {
|
|
11
|
+
const envVarName = resolveKeyEnvVar(environment);
|
|
12
|
+
if (process.env[envVarName]) {
|
|
13
|
+
return process.env[envVarName];
|
|
14
|
+
}
|
|
15
|
+
const keyFilePath = resolveKeyPath(resolveBaseDir(), environment);
|
|
16
|
+
if (existsSync(keyFilePath)) {
|
|
17
|
+
return readFileSync(keyFilePath, 'utf8').trim();
|
|
18
|
+
}
|
|
19
|
+
throw new MissingKeyError(environment);
|
|
20
|
+
};
|
|
21
|
+
const resolveWorkflowKey = (workflowName, workflowDir) => {
|
|
22
|
+
const envVarName = resolveWorkflowKeyEnvVar(workflowName);
|
|
23
|
+
if (process.env[envVarName]) {
|
|
24
|
+
return process.env[envVarName];
|
|
25
|
+
}
|
|
26
|
+
const keyPath = resolveWorkflowKeyPath(workflowDir);
|
|
27
|
+
if (existsSync(keyPath)) {
|
|
28
|
+
return readFileSync(keyPath, 'utf8').trim();
|
|
29
|
+
}
|
|
30
|
+
return resolveKey(undefined);
|
|
31
|
+
};
|
|
32
|
+
const safeDecrypt = (ciphertext, key, credPath) => {
|
|
33
|
+
try {
|
|
34
|
+
return decrypt(ciphertext, key);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
if (error instanceof RangeError) {
|
|
38
|
+
throw new MalformedCredentialsKeyError(credPath, error.message);
|
|
39
|
+
}
|
|
40
|
+
if (error instanceof Error && error.message.includes('aes/gcm')) {
|
|
41
|
+
throw new InvalidCredentialsKeyError(credPath);
|
|
42
|
+
}
|
|
43
|
+
throw new InvalidCredentialsKeyError(credPath, error instanceof Error ? error.message : String(error));
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const decryptYaml = (credPath, key) => {
|
|
47
|
+
const ciphertext = readFileSync(credPath, 'utf8').trim();
|
|
48
|
+
const plaintext = safeDecrypt(ciphertext, key, credPath);
|
|
49
|
+
return parseYaml(plaintext) || {};
|
|
50
|
+
};
|
|
51
|
+
export const encryptedYamlProvider = {
|
|
52
|
+
loadGlobal: ({ environment }) => {
|
|
53
|
+
const baseDir = resolveBaseDir();
|
|
54
|
+
const credPath = resolveCredentialsPath(baseDir, environment);
|
|
55
|
+
if (!existsSync(credPath)) {
|
|
56
|
+
if (environment) {
|
|
57
|
+
const defaultPath = resolveCredentialsPath(baseDir, undefined);
|
|
58
|
+
if (existsSync(defaultPath)) {
|
|
59
|
+
return decryptYaml(defaultPath, resolveKey(undefined));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return {};
|
|
63
|
+
}
|
|
64
|
+
return decryptYaml(credPath, resolveKey(environment));
|
|
65
|
+
},
|
|
66
|
+
loadForWorkflow: ({ workflowName, workflowDir }) => {
|
|
67
|
+
if (!workflowDir) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const credPath = resolveWorkflowCredentialsPath(workflowDir);
|
|
71
|
+
if (!existsSync(credPath)) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const key = resolveWorkflowKey(workflowName, workflowDir);
|
|
75
|
+
return decryptYaml(credPath, key);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { gcm } from '@noble/ciphers/aes.js';
|
|
2
|
+
import { managedNonce, randomBytes, hexToBytes, bytesToHex } from '@noble/ciphers/utils.js';
|
|
3
|
+
const aes = managedNonce(gcm);
|
|
4
|
+
export const generateKey = () => bytesToHex(randomBytes(32));
|
|
5
|
+
export const encrypt = (plaintext, keyHex) => Buffer.from(aes(hexToBytes(keyHex)).encrypt(new TextEncoder().encode(plaintext))).toString('base64');
|
|
6
|
+
export const decrypt = (ciphertext, keyHex) => new TextDecoder().decode(aes(hexToBytes(keyHex)).decrypt(Buffer.from(ciphertext, 'base64')));
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { FatalError } from '#errors';
|
|
2
|
+
export declare class MissingKeyError extends FatalError {
|
|
3
|
+
constructor(environment?: string | null);
|
|
4
|
+
}
|
|
5
|
+
export declare class MissingCredentialError extends FatalError {
|
|
6
|
+
constructor(path: string);
|
|
7
|
+
}
|
|
8
|
+
export declare class InvalidCredentialsKeyError extends FatalError {
|
|
9
|
+
constructor(credentialsPath: string, underlyingError?: string);
|
|
10
|
+
}
|
|
11
|
+
export declare class MalformedCredentialsKeyError extends FatalError {
|
|
12
|
+
constructor(credentialsPath: string, detail: string);
|
|
13
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { FatalError } from '#errors';
|
|
2
|
+
export class MissingKeyError extends FatalError {
|
|
3
|
+
constructor(environment) {
|
|
4
|
+
const envVar = environment ?
|
|
5
|
+
`OUTPUT_CREDENTIALS_KEY_${environment.toUpperCase()}` :
|
|
6
|
+
'OUTPUT_CREDENTIALS_KEY';
|
|
7
|
+
const keyFile = environment ?
|
|
8
|
+
`config/credentials/${environment}.key` :
|
|
9
|
+
'config/credentials.key';
|
|
10
|
+
super(`No credentials key found. Set ${envVar} env var or create ${keyFile}.`);
|
|
11
|
+
this.name = 'MissingKeyError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class MissingCredentialError extends FatalError {
|
|
15
|
+
constructor(path) {
|
|
16
|
+
super(`Required credential not found: "${path}".`);
|
|
17
|
+
this.name = 'MissingCredentialError';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class InvalidCredentialsKeyError extends FatalError {
|
|
21
|
+
constructor(credentialsPath, underlyingError) {
|
|
22
|
+
const message = underlyingError ?
|
|
23
|
+
`Failed to decrypt ${credentialsPath}: ${underlyingError}. ` +
|
|
24
|
+
'The credentials key may not match the one used to encrypt this file, or the credentials file may be corrupted. ' +
|
|
25
|
+
'Check OUTPUT_CREDENTIALS_KEY env var or config/credentials.key.' :
|
|
26
|
+
`Failed to decrypt ${credentialsPath}. The credentials key does not match the one used to encrypt this file. ` +
|
|
27
|
+
'Check OUTPUT_CREDENTIALS_KEY env var or config/credentials.key.';
|
|
28
|
+
super(message);
|
|
29
|
+
this.name = 'InvalidCredentialsKeyError';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export class MalformedCredentialsKeyError extends FatalError {
|
|
33
|
+
constructor(credentialsPath, detail) {
|
|
34
|
+
super(`Credentials key for ${credentialsPath} is malformed (${detail}). ` +
|
|
35
|
+
'The key must be exactly 64 hex characters. ' +
|
|
36
|
+
'Check OUTPUT_CREDENTIALS_KEY env var or config/credentials.key for typos, whitespace, or truncation.');
|
|
37
|
+
this.name = 'MalformedCredentialsKeyError';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { credentials, resolveCredentialRefs } from './credentials.js';
|
|
2
|
+
export { setProvider } from './provider_registry.js';
|
|
3
|
+
export { encrypt, decrypt, generateKey } from './encryption.js';
|
|
4
|
+
export { InvalidCredentialsKeyError, MalformedCredentialsKeyError, MissingCredentialError, MissingKeyError } from './errors.js';
|
|
5
|
+
export { getNestedValue, resolveCredentialsPath, resolveKeyPath, resolveKeyEnvVar, resolveWorkflowCredentialsPath, resolveWorkflowKeyPath, resolveWorkflowKeyEnvVar } from './paths.js';
|
|
6
|
+
export type { CredentialsProvider } from './types.js';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { credentials, resolveCredentialRefs } from './credentials.js';
|
|
2
|
+
export { setProvider } from './provider_registry.js';
|
|
3
|
+
export { encrypt, decrypt, generateKey } from './encryption.js';
|
|
4
|
+
export { InvalidCredentialsKeyError, MalformedCredentialsKeyError, MissingCredentialError, MissingKeyError } from './errors.js';
|
|
5
|
+
export { getNestedValue, resolveCredentialsPath, resolveKeyPath, resolveKeyEnvVar, resolveWorkflowCredentialsPath, resolveWorkflowKeyPath, resolveWorkflowKeyEnvVar } from './paths.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const init: () => void;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createChildLogger } from '#logger';
|
|
2
|
+
import { resolveCredentialRefs } from './credentials.js';
|
|
3
|
+
const log = createChildLogger('Credentials');
|
|
4
|
+
export const init = () => {
|
|
5
|
+
const vars = resolveCredentialRefs();
|
|
6
|
+
log.info('Resolved credential env vars', { vars });
|
|
7
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const resolveKeyEnvVar: (environment?: string) => string;
|
|
2
|
+
export declare const resolveWorkflowKeyEnvVar: (workflowName: string) => string;
|
|
3
|
+
export declare const resolveCredentialsPath: (baseDir: string, environment?: string) => string;
|
|
4
|
+
export declare const resolveKeyPath: (baseDir: string, environment?: string) => string;
|
|
5
|
+
export declare const resolveWorkflowCredentialsPath: (workflowDir: string) => string;
|
|
6
|
+
export declare const resolveWorkflowKeyPath: (workflowDir: string) => string;
|
|
7
|
+
export declare const getNestedValue: (obj: unknown, dotPath: string) => unknown;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
export const resolveKeyEnvVar = (environment) => environment ?
|
|
3
|
+
`OUTPUT_CREDENTIALS_KEY_${environment.toUpperCase()}` :
|
|
4
|
+
'OUTPUT_CREDENTIALS_KEY';
|
|
5
|
+
export const resolveWorkflowKeyEnvVar = (workflowName) => `OUTPUT_CREDENTIALS_KEY_${workflowName.toUpperCase()}`;
|
|
6
|
+
export const resolveCredentialsPath = (baseDir, environment) => environment ?
|
|
7
|
+
resolve(baseDir, `config/credentials/${environment}.yml.enc`) :
|
|
8
|
+
resolve(baseDir, 'config/credentials.yml.enc');
|
|
9
|
+
export const resolveKeyPath = (baseDir, environment) => environment ?
|
|
10
|
+
resolve(baseDir, `config/credentials/${environment}.key`) :
|
|
11
|
+
resolve(baseDir, 'config/credentials.key');
|
|
12
|
+
export const resolveWorkflowCredentialsPath = (workflowDir) => resolve(workflowDir, 'credentials.yml.enc');
|
|
13
|
+
export const resolveWorkflowKeyPath = (workflowDir) => resolve(workflowDir, 'credentials.key');
|
|
14
|
+
export const getNestedValue = (obj, dotPath) => dotPath.split('.').reduce((acc, part) => acc && typeof acc === 'object' ? acc[part] : undefined, obj);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface GlobalContext {
|
|
2
|
+
environment: string | undefined;
|
|
3
|
+
}
|
|
4
|
+
export interface WorkflowContext {
|
|
5
|
+
workflowName: string;
|
|
6
|
+
workflowDir: string | undefined;
|
|
7
|
+
environment?: string | undefined;
|
|
8
|
+
}
|
|
9
|
+
export interface CredentialsProvider {
|
|
10
|
+
loadGlobal(context: GlobalContext): Record<string, unknown>;
|
|
11
|
+
loadForWorkflow(context: WorkflowContext): Record<string, unknown> | null;
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@outputai/core",
|
|
3
|
-
"version": "0.14.0",
|
|
3
|
+
"version": "0.14.1-next.51e8690.0",
|
|
4
4
|
"description": "The core module of the output framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -26,11 +26,18 @@
|
|
|
26
26
|
"./temporal": {
|
|
27
27
|
"types": "./src/temporal/index.d.ts",
|
|
28
28
|
"import": "./src/temporal/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./credentials": {
|
|
31
|
+
"types": "./dist/credentials/index.d.ts",
|
|
32
|
+
"import": "./dist/credentials/index.js"
|
|
29
33
|
}
|
|
30
34
|
},
|
|
31
35
|
"files": [
|
|
32
36
|
"./src",
|
|
33
|
-
"./
|
|
37
|
+
"./dist",
|
|
38
|
+
"./bin",
|
|
39
|
+
"!**/*.spec.*",
|
|
40
|
+
"!src/credentials"
|
|
34
41
|
],
|
|
35
42
|
"bin": {
|
|
36
43
|
"output-worker": "./bin/worker.sh",
|
|
@@ -45,12 +52,14 @@
|
|
|
45
52
|
"@babel/parser": "7.29.2",
|
|
46
53
|
"@babel/traverse": "7.29.0",
|
|
47
54
|
"@babel/types": "7.29.0",
|
|
55
|
+
"@noble/ciphers": "2.2.0",
|
|
48
56
|
"@temporalio/activity": "1.20.3",
|
|
49
57
|
"@temporalio/client": "1.20.3",
|
|
50
58
|
"@temporalio/common": "1.20.3",
|
|
51
59
|
"@temporalio/worker": "1.20.3",
|
|
52
60
|
"@temporalio/workflow": "1.20.3",
|
|
53
61
|
"folder-hash": "4.1.3",
|
|
62
|
+
"js-yaml": "4.3.2",
|
|
54
63
|
"json-stream-stringify": "3.1.6",
|
|
55
64
|
"redis": "5.12.1",
|
|
56
65
|
"stacktrace-parser": "0.1.11",
|
|
@@ -61,6 +70,7 @@
|
|
|
61
70
|
"zod": ">=4.3 <5"
|
|
62
71
|
},
|
|
63
72
|
"devDependencies": {
|
|
73
|
+
"@types/js-yaml": "4.0.9",
|
|
64
74
|
"zod": "4.3.6"
|
|
65
75
|
},
|
|
66
76
|
"license": "Apache-2.0",
|
|
@@ -70,6 +80,7 @@
|
|
|
70
80
|
"imports": {
|
|
71
81
|
"#bus": "./src/bus.js",
|
|
72
82
|
"#consts": "./src/consts.js",
|
|
83
|
+
"#credentials/*": "./dist/credentials/*.js",
|
|
73
84
|
"#errors": "./src/errors.js",
|
|
74
85
|
"#logger": "./src/logger/index.js",
|
|
75
86
|
"#hooks/*": "./src/hooks/*.js",
|
|
@@ -82,6 +93,6 @@
|
|
|
82
93
|
},
|
|
83
94
|
"scripts": {
|
|
84
95
|
"worker": "node ./src/worker/index.js",
|
|
85
|
-
"build": "pnpm exec tsc -p ./tsconfig.typecheck.json"
|
|
96
|
+
"build": "rm -rf ./dist && tsc && pnpm exec tsc -p ./tsconfig.typecheck.json"
|
|
86
97
|
}
|
|
87
98
|
}
|
package/src/consts.js
CHANGED
package/src/hooks/index.d.ts
CHANGED
|
@@ -185,14 +185,6 @@ export type ErrorHookPayload =
|
|
|
185
185
|
*/
|
|
186
186
|
export declare function onError( handler: ( payload: ErrorHookPayload ) => void ): void;
|
|
187
187
|
|
|
188
|
-
/**
|
|
189
|
-
* Register a handler to be invoked once, before the worker starts processing tasks.
|
|
190
|
-
* It is invoked before Worker.create().
|
|
191
|
-
*
|
|
192
|
-
* @param handler - Function called with no arguments.
|
|
193
|
-
*/
|
|
194
|
-
export declare function onBeforeWorkerStart( handler: () => void ): void;
|
|
195
|
-
|
|
196
188
|
/**
|
|
197
189
|
* Register a handler to be invoked when a workflow run starts.
|
|
198
190
|
*
|
package/src/hooks/index.js
CHANGED
|
@@ -33,8 +33,6 @@ const onError = cb => {
|
|
|
33
33
|
callHookCb( cb, { source: 'runtime', ...payload }, 'onError' ) );
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
-
const onBeforeWorkerStart = cb => mainEventBus.on( BusEventType.WORKER_BEFORE_START, () => callHookCb( cb, undefined, 'onBeforeWorkerStart' ) );
|
|
37
|
-
|
|
38
36
|
// Workflow Life-cycle
|
|
39
37
|
// --------------------------------------
|
|
40
38
|
const onWorkflowStart = cb => mainEventBus.on( BusEventType.WORKFLOW_START, payload => callHookCb( cb, payload, 'onWorkflowStart' ) );
|
|
@@ -68,7 +66,6 @@ export {
|
|
|
68
66
|
onActivityEnd,
|
|
69
67
|
onActivityError,
|
|
70
68
|
onActivityStart,
|
|
71
|
-
onBeforeWorkerStart,
|
|
72
69
|
onError,
|
|
73
70
|
onWorkflowEnd,
|
|
74
71
|
onWorkflowError,
|
package/src/worker/index.js
CHANGED
|
@@ -23,6 +23,7 @@ import { serializeError } from '#helpers/error_serializer';
|
|
|
23
23
|
import { setupTemporalLogger } from './temporal_logger.js';
|
|
24
24
|
import { WorkerRunner } from './worker_runner.js';
|
|
25
25
|
import { shutdownServices } from './shutdown.js';
|
|
26
|
+
import { init as initCredentials } from '#credentials/init';
|
|
26
27
|
|
|
27
28
|
import './log_hooks.js';
|
|
28
29
|
|
|
@@ -76,7 +77,8 @@ const execute = async () => {
|
|
|
76
77
|
log.info( 'Loading activities...', { callerDir } );
|
|
77
78
|
const { activities } = await run( () => loadActivities( callerDir, workflows ) );
|
|
78
79
|
|
|
79
|
-
|
|
80
|
+
log.info( 'Initializing credentials...' );
|
|
81
|
+
run( initCredentials );
|
|
80
82
|
|
|
81
83
|
log.info( 'Initializing tracing...' );
|
|
82
84
|
await run( initTracing );
|
package/bin/healthcheck.spec.js
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
|
|
3
|
-
const closeMock = vi.fn().mockResolvedValue( undefined );
|
|
4
|
-
const connectionMock = { close: closeMock };
|
|
5
|
-
|
|
6
|
-
const queryMock = vi.fn();
|
|
7
|
-
const getHandleMock = vi.fn().mockReturnValue( { query: queryMock } );
|
|
8
|
-
const ClientMock = vi.fn().mockImplementation( function () {
|
|
9
|
-
return { workflow: { getHandle: getHandleMock } };
|
|
10
|
-
} );
|
|
11
|
-
const connectMock = vi.fn().mockResolvedValue( connectionMock );
|
|
12
|
-
|
|
13
|
-
vi.mock( '@temporalio/client', () => ( {
|
|
14
|
-
Connection: { connect: connectMock },
|
|
15
|
-
Client: ClientMock
|
|
16
|
-
} ) );
|
|
17
|
-
|
|
18
|
-
describe( 'bin/healthcheck', () => {
|
|
19
|
-
const exitMock = vi.fn();
|
|
20
|
-
const originalExit = process.exit;
|
|
21
|
-
|
|
22
|
-
beforeEach( () => {
|
|
23
|
-
vi.clearAllMocks();
|
|
24
|
-
process.exit = exitMock;
|
|
25
|
-
process.env.TEMPORAL_ADDRESS = 'localhost:7233';
|
|
26
|
-
process.env.TEMPORAL_NAMESPACE = 'default';
|
|
27
|
-
process.env.OUTPUT_CATALOG_ID = 'test-catalog';
|
|
28
|
-
delete process.env.TEMPORAL_API_KEY;
|
|
29
|
-
} );
|
|
30
|
-
|
|
31
|
-
afterEach( () => {
|
|
32
|
-
process.exit = originalExit;
|
|
33
|
-
} );
|
|
34
|
-
|
|
35
|
-
it( 'exits 0 when catalog ping returns "pong"', async () => {
|
|
36
|
-
queryMock.mockResolvedValue( 'pong' );
|
|
37
|
-
vi.resetModules();
|
|
38
|
-
await import( './healthcheck.mjs' );
|
|
39
|
-
expect( connectMock ).toHaveBeenCalledWith( {
|
|
40
|
-
address: 'localhost:7233',
|
|
41
|
-
tls: false,
|
|
42
|
-
apiKey: undefined
|
|
43
|
-
} );
|
|
44
|
-
expect( ClientMock ).toHaveBeenCalledWith( { connection: connectionMock, namespace: 'default' } );
|
|
45
|
-
expect( getHandleMock ).toHaveBeenCalledWith( 'test-catalog' );
|
|
46
|
-
expect( queryMock ).toHaveBeenCalledWith( 'ping' );
|
|
47
|
-
expect( exitMock ).toHaveBeenCalledWith( 0 );
|
|
48
|
-
expect( closeMock ).toHaveBeenCalled();
|
|
49
|
-
} );
|
|
50
|
-
|
|
51
|
-
it( 'uses TLS and apiKey when TEMPORAL_API_KEY is set', async () => {
|
|
52
|
-
process.env.TEMPORAL_API_KEY = 'secret';
|
|
53
|
-
queryMock.mockResolvedValue( 'pong' );
|
|
54
|
-
vi.resetModules();
|
|
55
|
-
await import( './healthcheck.mjs' );
|
|
56
|
-
expect( connectMock ).toHaveBeenCalledWith( {
|
|
57
|
-
address: 'localhost:7233',
|
|
58
|
-
tls: true,
|
|
59
|
-
apiKey: 'secret'
|
|
60
|
-
} );
|
|
61
|
-
expect( exitMock ).toHaveBeenCalledWith( 0 );
|
|
62
|
-
} );
|
|
63
|
-
|
|
64
|
-
it( 'uses default namespace and catalog id when env unset', async () => {
|
|
65
|
-
delete process.env.TEMPORAL_NAMESPACE;
|
|
66
|
-
delete process.env.OUTPUT_CATALOG_ID;
|
|
67
|
-
queryMock.mockResolvedValue( 'pong' );
|
|
68
|
-
vi.resetModules();
|
|
69
|
-
await import( './healthcheck.mjs' );
|
|
70
|
-
expect( ClientMock ).toHaveBeenCalledWith( { connection: connectionMock, namespace: 'default' } );
|
|
71
|
-
expect( getHandleMock ).toHaveBeenCalledWith( 'main' );
|
|
72
|
-
expect( exitMock ).toHaveBeenCalledWith( 0 );
|
|
73
|
-
} );
|
|
74
|
-
|
|
75
|
-
it( 'exits 1 when catalog ping returns non-pong', async () => {
|
|
76
|
-
queryMock.mockResolvedValue( 'nope' );
|
|
77
|
-
vi.resetModules();
|
|
78
|
-
await import( './healthcheck.mjs' );
|
|
79
|
-
expect( exitMock ).toHaveBeenCalledWith( 1 );
|
|
80
|
-
expect( closeMock ).toHaveBeenCalled();
|
|
81
|
-
} );
|
|
82
|
-
|
|
83
|
-
it( 'exits 1 when query throws', async () => {
|
|
84
|
-
queryMock.mockRejectedValue( new Error( 'connection refused' ) );
|
|
85
|
-
vi.resetModules();
|
|
86
|
-
await import( './healthcheck.mjs' );
|
|
87
|
-
expect( exitMock ).toHaveBeenCalledWith( 1 );
|
|
88
|
-
expect( closeMock ).toHaveBeenCalled();
|
|
89
|
-
} );
|
|
90
|
-
} );
|