@mondaydotcomorg/atp-server 0.17.14
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/README.md +489 -0
- package/dist/aggregator/index.d.ts +59 -0
- package/dist/aggregator/index.d.ts.map +1 -0
- package/dist/aggregator/index.js +171 -0
- package/dist/aggregator/index.js.map +1 -0
- package/dist/callback/index.d.ts +98 -0
- package/dist/callback/index.d.ts.map +1 -0
- package/dist/callback/index.js +136 -0
- package/dist/callback/index.js.map +1 -0
- package/dist/client-sessions.d.ts +82 -0
- package/dist/client-sessions.d.ts.map +1 -0
- package/dist/client-sessions.js +174 -0
- package/dist/client-sessions.js.map +1 -0
- package/dist/controllers/definitions.controller.d.ts +4 -0
- package/dist/controllers/definitions.controller.d.ts.map +1 -0
- package/dist/controllers/definitions.controller.js +11 -0
- package/dist/controllers/definitions.controller.js.map +1 -0
- package/dist/controllers/execute.controller.d.ts +18 -0
- package/dist/controllers/execute.controller.d.ts.map +1 -0
- package/dist/controllers/execute.controller.js +122 -0
- package/dist/controllers/execute.controller.js.map +1 -0
- package/dist/controllers/info.controller.d.ts +3 -0
- package/dist/controllers/info.controller.d.ts.map +1 -0
- package/dist/controllers/info.controller.js +13 -0
- package/dist/controllers/info.controller.js.map +1 -0
- package/dist/controllers/resume.controller.d.ts +11 -0
- package/dist/controllers/resume.controller.d.ts.map +1 -0
- package/dist/controllers/resume.controller.js +61 -0
- package/dist/controllers/resume.controller.js.map +1 -0
- package/dist/controllers/search.controller.d.ts +4 -0
- package/dist/controllers/search.controller.d.ts.map +1 -0
- package/dist/controllers/search.controller.js +7 -0
- package/dist/controllers/search.controller.js.map +1 -0
- package/dist/controllers/stream.controller.d.ts +19 -0
- package/dist/controllers/stream.controller.d.ts.map +1 -0
- package/dist/controllers/stream.controller.js +141 -0
- package/dist/controllers/stream.controller.js.map +1 -0
- package/dist/core/config.d.ts +161 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +7 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/http.d.ts +4 -0
- package/dist/core/http.d.ts.map +1 -0
- package/dist/core/http.js +17 -0
- package/dist/core/http.js.map +1 -0
- package/dist/create-server.d.ts +120 -0
- package/dist/create-server.d.ts.map +1 -0
- package/dist/create-server.js +423 -0
- package/dist/create-server.js.map +1 -0
- package/dist/execution-state/index.d.ts +95 -0
- package/dist/execution-state/index.d.ts.map +1 -0
- package/dist/execution-state/index.js +128 -0
- package/dist/execution-state/index.js.map +1 -0
- package/dist/executor/ast-provenance-bridge.d.ts +12 -0
- package/dist/executor/ast-provenance-bridge.d.ts.map +1 -0
- package/dist/executor/ast-provenance-bridge.js +66 -0
- package/dist/executor/ast-provenance-bridge.js.map +1 -0
- package/dist/executor/ast-tracking-runtime.d.ts +7 -0
- package/dist/executor/ast-tracking-runtime.d.ts.map +1 -0
- package/dist/executor/ast-tracking-runtime.js +559 -0
- package/dist/executor/ast-tracking-runtime.js.map +1 -0
- package/dist/executor/bootstrap-generated.d.ts +32 -0
- package/dist/executor/bootstrap-generated.d.ts.map +1 -0
- package/dist/executor/bootstrap-generated.js +90 -0
- package/dist/executor/bootstrap-generated.js.map +1 -0
- package/dist/executor/compiler-config.d.ts +32 -0
- package/dist/executor/compiler-config.d.ts.map +1 -0
- package/dist/executor/compiler-config.js +99 -0
- package/dist/executor/compiler-config.js.map +1 -0
- package/dist/executor/constants.d.ts +4 -0
- package/dist/executor/constants.d.ts.map +1 -0
- package/dist/executor/constants.js +4 -0
- package/dist/executor/constants.js.map +1 -0
- package/dist/executor/error-handler.d.ts +9 -0
- package/dist/executor/error-handler.d.ts.map +1 -0
- package/dist/executor/error-handler.js +95 -0
- package/dist/executor/error-handler.js.map +1 -0
- package/dist/executor/execution-error-handler.d.ts +7 -0
- package/dist/executor/execution-error-handler.d.ts.map +1 -0
- package/dist/executor/execution-error-handler.js +136 -0
- package/dist/executor/execution-error-handler.js.map +1 -0
- package/dist/executor/executor.d.ts +20 -0
- package/dist/executor/executor.d.ts.map +1 -0
- package/dist/executor/executor.js +452 -0
- package/dist/executor/executor.js.map +1 -0
- package/dist/executor/index.d.ts +4 -0
- package/dist/executor/index.d.ts.map +1 -0
- package/dist/executor/index.js +3 -0
- package/dist/executor/index.js.map +1 -0
- package/dist/executor/resume-handler.d.ts +9 -0
- package/dist/executor/resume-handler.d.ts.map +1 -0
- package/dist/executor/resume-handler.js +22 -0
- package/dist/executor/resume-handler.js.map +1 -0
- package/dist/executor/sandbox-builder.d.ts +29 -0
- package/dist/executor/sandbox-builder.d.ts.map +1 -0
- package/dist/executor/sandbox-builder.js +538 -0
- package/dist/executor/sandbox-builder.js.map +1 -0
- package/dist/executor/sandbox-injector.d.ts +7 -0
- package/dist/executor/sandbox-injector.d.ts.map +1 -0
- package/dist/executor/sandbox-injector.js +293 -0
- package/dist/executor/sandbox-injector.js.map +1 -0
- package/dist/executor/types.d.ts +21 -0
- package/dist/executor/types.d.ts.map +1 -0
- package/dist/executor/types.js +2 -0
- package/dist/executor/types.js.map +1 -0
- package/dist/explorer/index.d.ts +69 -0
- package/dist/explorer/index.d.ts.map +1 -0
- package/dist/explorer/index.js +228 -0
- package/dist/explorer/index.js.map +1 -0
- package/dist/handlers/definitions.handler.d.ts +3 -0
- package/dist/handlers/definitions.handler.d.ts.map +1 -0
- package/dist/handlers/definitions.handler.js +11 -0
- package/dist/handlers/definitions.handler.js.map +1 -0
- package/dist/handlers/execute.handler.d.ts +7 -0
- package/dist/handlers/execute.handler.d.ts.map +1 -0
- package/dist/handlers/execute.handler.js +225 -0
- package/dist/handlers/execute.handler.js.map +1 -0
- package/dist/handlers/explorer.handler.d.ts +4 -0
- package/dist/handlers/explorer.handler.d.ts.map +1 -0
- package/dist/handlers/explorer.handler.js +10 -0
- package/dist/handlers/explorer.handler.js.map +1 -0
- package/dist/handlers/init.handler.d.ts +5 -0
- package/dist/handlers/init.handler.d.ts.map +1 -0
- package/dist/handlers/init.handler.js +41 -0
- package/dist/handlers/init.handler.js.map +1 -0
- package/dist/handlers/resume.handler.d.ts +6 -0
- package/dist/handlers/resume.handler.d.ts.map +1 -0
- package/dist/handlers/resume.handler.js +256 -0
- package/dist/handlers/resume.handler.js.map +1 -0
- package/dist/handlers/search.handler.d.ts +5 -0
- package/dist/handlers/search.handler.d.ts.map +1 -0
- package/dist/handlers/search.handler.js +11 -0
- package/dist/handlers/search.handler.js.map +1 -0
- package/dist/http/request-handler.d.ts +15 -0
- package/dist/http/request-handler.d.ts.map +1 -0
- package/dist/http/request-handler.js +94 -0
- package/dist/http/request-handler.js.map +1 -0
- package/dist/http/router.d.ts +4 -0
- package/dist/http/router.d.ts.map +1 -0
- package/dist/http/router.js +32 -0
- package/dist/http/router.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/instrumentation/index.d.ts +5 -0
- package/dist/instrumentation/index.d.ts.map +1 -0
- package/dist/instrumentation/index.js +5 -0
- package/dist/instrumentation/index.js.map +1 -0
- package/dist/instrumentation/serializer.d.ts +61 -0
- package/dist/instrumentation/serializer.d.ts.map +1 -0
- package/dist/instrumentation/serializer.js +334 -0
- package/dist/instrumentation/serializer.js.map +1 -0
- package/dist/instrumentation/state-manager.d.ts +61 -0
- package/dist/instrumentation/state-manager.d.ts.map +1 -0
- package/dist/instrumentation/state-manager.js +205 -0
- package/dist/instrumentation/state-manager.js.map +1 -0
- package/dist/instrumentation/transformer.d.ts +9 -0
- package/dist/instrumentation/transformer.d.ts.map +1 -0
- package/dist/instrumentation/transformer.js +70 -0
- package/dist/instrumentation/transformer.js.map +1 -0
- package/dist/instrumentation/types.d.ts +59 -0
- package/dist/instrumentation/types.d.ts.map +1 -0
- package/dist/instrumentation/types.js +5 -0
- package/dist/instrumentation/types.js.map +1 -0
- package/dist/middleware/audit.d.ts +18 -0
- package/dist/middleware/audit.d.ts.map +1 -0
- package/dist/middleware/audit.js +76 -0
- package/dist/middleware/audit.js.map +1 -0
- package/dist/openapi/index.d.ts +133 -0
- package/dist/openapi/index.d.ts.map +1 -0
- package/dist/openapi/index.js +235 -0
- package/dist/openapi/index.js.map +1 -0
- package/dist/openapi-loader.d.ts +87 -0
- package/dist/openapi-loader.d.ts.map +1 -0
- package/dist/openapi-loader.js +491 -0
- package/dist/openapi-loader.js.map +1 -0
- package/dist/routes/index.d.ts +21 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +47 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/search/index.d.ts +48 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +156 -0
- package/dist/search/index.js.map +1 -0
- package/dist/security/index.d.ts +2 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +2 -0
- package/dist/security/index.js.map +1 -0
- package/dist/shutdown.d.ts +19 -0
- package/dist/shutdown.d.ts.map +1 -0
- package/dist/shutdown.js +87 -0
- package/dist/shutdown.js.map +1 -0
- package/dist/utils/banner.d.ts +12 -0
- package/dist/utils/banner.d.ts.map +1 -0
- package/dist/utils/banner.js +18 -0
- package/dist/utils/banner.js.map +1 -0
- package/dist/utils/context.d.ts +16 -0
- package/dist/utils/context.d.ts.map +1 -0
- package/dist/utils/context.js +44 -0
- package/dist/utils/context.js.map +1 -0
- package/dist/utils/error.d.ts +8 -0
- package/dist/utils/error.d.ts.map +1 -0
- package/dist/utils/error.js +17 -0
- package/dist/utils/error.js.map +1 -0
- package/dist/utils/hint-based-instrumentation.d.ts +14 -0
- package/dist/utils/hint-based-instrumentation.d.ts.map +1 -0
- package/dist/utils/hint-based-instrumentation.js +84 -0
- package/dist/utils/hint-based-instrumentation.js.map +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/info.d.ts +20 -0
- package/dist/utils/info.d.ts.map +1 -0
- package/dist/utils/info.js +15 -0
- package/dist/utils/info.js.map +1 -0
- package/dist/utils/provenance-reattachment.d.ts +32 -0
- package/dist/utils/provenance-reattachment.d.ts.map +1 -0
- package/dist/utils/provenance-reattachment.js +115 -0
- package/dist/utils/provenance-reattachment.js.map +1 -0
- package/dist/utils/request.d.ts +21 -0
- package/dist/utils/request.d.ts.map +1 -0
- package/dist/utils/request.js +44 -0
- package/dist/utils/request.js.map +1 -0
- package/dist/utils/response.d.ts +30 -0
- package/dist/utils/response.d.ts.map +1 -0
- package/dist/utils/response.js +53 -0
- package/dist/utils/response.js.map +1 -0
- package/dist/utils/runtime-types.d.ts +6 -0
- package/dist/utils/runtime-types.d.ts.map +1 -0
- package/dist/utils/runtime-types.js +14 -0
- package/dist/utils/runtime-types.js.map +1 -0
- package/dist/utils/schema.d.ts +9 -0
- package/dist/utils/schema.d.ts.map +1 -0
- package/dist/utils/schema.js +13 -0
- package/dist/utils/schema.js.map +1 -0
- package/dist/utils/token-emitter.d.ts +21 -0
- package/dist/utils/token-emitter.d.ts.map +1 -0
- package/dist/utils/token-emitter.js +129 -0
- package/dist/utils/token-emitter.js.map +1 -0
- package/dist/validator/index.d.ts +36 -0
- package/dist/validator/index.d.ts.map +1 -0
- package/dist/validator/index.js +224 -0
- package/dist/validator/index.js.map +1 -0
- package/package.json +68 -0
- package/src/aggregator/index.ts +207 -0
- package/src/callback/index.ts +191 -0
- package/src/client-sessions.ts +234 -0
- package/src/controllers/definitions.controller.ts +19 -0
- package/src/controllers/execute.controller.ts +166 -0
- package/src/controllers/info.controller.ts +14 -0
- package/src/controllers/resume.controller.ts +92 -0
- package/src/controllers/search.controller.ts +16 -0
- package/src/controllers/stream.controller.ts +190 -0
- package/src/core/config.ts +180 -0
- package/src/core/http.ts +21 -0
- package/src/create-server.ts +536 -0
- package/src/execution-state/index.ts +204 -0
- package/src/executor/ast-provenance-bridge.ts +80 -0
- package/src/executor/ast-tracking-runtime.ts +558 -0
- package/src/executor/bootstrap-generated.ts +90 -0
- package/src/executor/compiler-config.ts +146 -0
- package/src/executor/constants.ts +5 -0
- package/src/executor/error-handler.ts +118 -0
- package/src/executor/execution-error-handler.ts +178 -0
- package/src/executor/executor.ts +631 -0
- package/src/executor/index.ts +3 -0
- package/src/executor/resume-handler.ts +39 -0
- package/src/executor/sandbox-builder.ts +684 -0
- package/src/executor/sandbox-injector.ts +345 -0
- package/src/executor/types.ts +22 -0
- package/src/explorer/index.ts +297 -0
- package/src/handlers/definitions.handler.ts +13 -0
- package/src/handlers/execute.handler.ts +286 -0
- package/src/handlers/explorer.handler.ts +18 -0
- package/src/handlers/init.handler.ts +53 -0
- package/src/handlers/resume.handler.ts +316 -0
- package/src/handlers/search.handler.ts +32 -0
- package/src/http/request-handler.ts +117 -0
- package/src/http/router.ts +29 -0
- package/src/index.ts +60 -0
- package/src/instrumentation/index.ts +4 -0
- package/src/instrumentation/serializer.ts +421 -0
- package/src/instrumentation/state-manager.ts +237 -0
- package/src/instrumentation/transformer.ts +84 -0
- package/src/instrumentation/types.ts +76 -0
- package/src/middleware/audit.ts +101 -0
- package/src/openapi/index.ts +378 -0
- package/src/openapi-loader.ts +744 -0
- package/src/routes/index.ts +93 -0
- package/src/search/index.ts +216 -0
- package/src/security/index.ts +1 -0
- package/src/shutdown.ts +108 -0
- package/src/utils/banner.ts +25 -0
- package/src/utils/context.ts +58 -0
- package/src/utils/error.ts +25 -0
- package/src/utils/hint-based-instrumentation.ts +99 -0
- package/src/utils/index.ts +15 -0
- package/src/utils/info.ts +31 -0
- package/src/utils/provenance-reattachment.ts +144 -0
- package/src/utils/request.ts +53 -0
- package/src/utils/response.ts +69 -0
- package/src/utils/runtime-types.ts +14 -0
- package/src/utils/schema.ts +18 -0
- package/src/utils/token-emitter.ts +182 -0
- package/src/validator/index.ts +253 -0
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import ivm from 'isolated-vm';
|
|
2
|
+
import type { Logger } from '@mondaydotcomorg/atp-runtime';
|
|
3
|
+
import { isPauseError, runInExecutionContext } from '@mondaydotcomorg/atp-runtime';
|
|
4
|
+
import { isBatchPauseError } from '@mondaydotcomorg/atp-compiler';
|
|
5
|
+
import { PAUSE_EXECUTION_MARKER } from './constants.js';
|
|
6
|
+
|
|
7
|
+
export async function injectTimerPolyfills(ivmContext: ivm.Context): Promise<void> {
|
|
8
|
+
await ivmContext.eval(`
|
|
9
|
+
globalThis._timerCounter = 1;
|
|
10
|
+
globalThis._activeTimers = new Map();
|
|
11
|
+
|
|
12
|
+
globalThis.setTimeout = function(callback, delay) {
|
|
13
|
+
const timerId = globalThis._timerCounter++;
|
|
14
|
+
const startTime = Date.now();
|
|
15
|
+
|
|
16
|
+
const pollTimer = () => {
|
|
17
|
+
if (!globalThis._activeTimers.has(timerId)) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (Date.now() - startTime >= delay) {
|
|
22
|
+
globalThis._activeTimers.delete(timerId);
|
|
23
|
+
callback();
|
|
24
|
+
} else {
|
|
25
|
+
Promise.resolve().then(pollTimer);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
globalThis._activeTimers.set(timerId, true);
|
|
30
|
+
Promise.resolve().then(pollTimer);
|
|
31
|
+
return timerId;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
globalThis.clearTimeout = function(timerId) {
|
|
35
|
+
globalThis._activeTimers.delete(timerId);
|
|
36
|
+
};
|
|
37
|
+
`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function injectSandbox(
|
|
41
|
+
ivmContext: ivm.Context,
|
|
42
|
+
jail: ivm.Reference<Record<string, unknown>>,
|
|
43
|
+
sandbox: Record<string, unknown>,
|
|
44
|
+
executionLogger: Logger,
|
|
45
|
+
onPauseError: (error: unknown) => void,
|
|
46
|
+
executionId?: string,
|
|
47
|
+
provenanceMode?: string,
|
|
48
|
+
hintMetadata?: Map<string, any>
|
|
49
|
+
): Promise<void> {
|
|
50
|
+
const injectFunctions = async (obj: unknown, prefix: string): Promise<void> => {
|
|
51
|
+
if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
56
|
+
if (typeof value === 'function') {
|
|
57
|
+
const boundFunc = value.bind(obj);
|
|
58
|
+
|
|
59
|
+
const isVoidFunction =
|
|
60
|
+
prefix === 'atp_log' || prefix === 'atp_progress' || prefix === 'atp_output';
|
|
61
|
+
|
|
62
|
+
if (isVoidFunction) {
|
|
63
|
+
await jail.set(
|
|
64
|
+
`__${prefix}_${key}`,
|
|
65
|
+
new ivm.Reference((...args: unknown[]) => {
|
|
66
|
+
try {
|
|
67
|
+
boundFunc(...args);
|
|
68
|
+
} catch (error) {
|
|
69
|
+
executionLogger.error('Error in void function', { prefix, key, error });
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
);
|
|
73
|
+
} else {
|
|
74
|
+
await jail.set(
|
|
75
|
+
`__${prefix}_${key}`,
|
|
76
|
+
new ivm.Reference(async (...args: unknown[]) => {
|
|
77
|
+
try {
|
|
78
|
+
const result = await boundFunc(...args);
|
|
79
|
+
return new ivm.ExternalCopy(result).copyInto();
|
|
80
|
+
} catch (error) {
|
|
81
|
+
const err = error as Error;
|
|
82
|
+
if (isPauseError(error) || err.message === PAUSE_EXECUTION_MARKER) {
|
|
83
|
+
if (isPauseError(error)) {
|
|
84
|
+
onPauseError(error);
|
|
85
|
+
}
|
|
86
|
+
throw new Error(PAUSE_EXECUTION_MARKER);
|
|
87
|
+
}
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
} else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
94
|
+
await injectFunctions(value, `${prefix}_${key}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const injectAPIFunctions = async (obj: unknown, pathPrefix: string): Promise<void> => {
|
|
100
|
+
if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
105
|
+
const newPath = pathPrefix ? `${pathPrefix}_${key}` : key;
|
|
106
|
+
|
|
107
|
+
if (typeof value === 'function') {
|
|
108
|
+
const boundFunc = value.bind(obj);
|
|
109
|
+
const safeName = newPath.replace(/-/g, '_').replace(/\//g, '_').replace(/\./g, '_');
|
|
110
|
+
|
|
111
|
+
await jail.set(
|
|
112
|
+
`__api_${safeName}`,
|
|
113
|
+
new ivm.Reference(async (...args: unknown[]) => {
|
|
114
|
+
try {
|
|
115
|
+
const result = await boundFunc(...args);
|
|
116
|
+
// In AST mode, tag result with provenance ID before copying so tag survives
|
|
117
|
+
if (isASTMode && result && typeof result === 'object') {
|
|
118
|
+
try {
|
|
119
|
+
// Generate unique ID for this API result
|
|
120
|
+
const provId = `tracked_${Date.now()}_${Math.random().toString(36).substring(7)}`;
|
|
121
|
+
Object.defineProperty(result, '__prov_id__', {
|
|
122
|
+
value: provId,
|
|
123
|
+
writable: false,
|
|
124
|
+
enumerable: true,
|
|
125
|
+
configurable: true,
|
|
126
|
+
});
|
|
127
|
+
} catch (e) {
|
|
128
|
+
// If can't define property, that's ok
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return new ivm.ExternalCopy(result).copyInto();
|
|
132
|
+
} catch (error) {
|
|
133
|
+
const err = error as Error;
|
|
134
|
+
if (isPauseError(error) || err.message === PAUSE_EXECUTION_MARKER) {
|
|
135
|
+
if (isPauseError(error)) {
|
|
136
|
+
onPauseError(error);
|
|
137
|
+
}
|
|
138
|
+
throw new Error(PAUSE_EXECUTION_MARKER);
|
|
139
|
+
}
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
);
|
|
144
|
+
} else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
145
|
+
await injectAPIFunctions(value, newPath);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const isASTMode = provenanceMode === 'ast';
|
|
151
|
+
if (isASTMode) {
|
|
152
|
+
if (hintMetadata && hintMetadata.size > 0) {
|
|
153
|
+
const hintsArray = Array.from(hintMetadata.entries());
|
|
154
|
+
await jail.set('__provenance_hints', new ivm.ExternalCopy(hintsArray).copyInto());
|
|
155
|
+
const valueMap = (hintMetadata as any).__valueMap;
|
|
156
|
+
if (valueMap && valueMap.size > 0) {
|
|
157
|
+
const valueMapArray = Array.from(valueMap.entries());
|
|
158
|
+
await jail.set('__provenance_hint_values', new ivm.ExternalCopy(valueMapArray).copyInto());
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
const { AST_TRACKING_RUNTIME } = await import('./ast-tracking-runtime.js');
|
|
162
|
+
await ivmContext.eval(AST_TRACKING_RUNTIME);
|
|
163
|
+
executionLogger.info('AST tracking runtime injected into isolate');
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const hasASTTracking = isASTMode;
|
|
167
|
+
|
|
168
|
+
for (const [namespace, value] of Object.entries(sandbox)) {
|
|
169
|
+
if (
|
|
170
|
+
hasASTTracking &&
|
|
171
|
+
(namespace.startsWith('__track') ||
|
|
172
|
+
namespace.startsWith('__get_provenance') ||
|
|
173
|
+
namespace.startsWith('__mark_tainted'))
|
|
174
|
+
) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (namespace === '__runtime' && typeof value === 'object' && value !== null) {
|
|
179
|
+
for (const [key, fn] of Object.entries(value)) {
|
|
180
|
+
if (typeof fn === 'function') {
|
|
181
|
+
await jail.set(
|
|
182
|
+
`__runtime_${key}_impl`,
|
|
183
|
+
new ivm.Reference(async (...args: unknown[]) => {
|
|
184
|
+
try {
|
|
185
|
+
const execute = async () => {
|
|
186
|
+
const result = await fn(...args);
|
|
187
|
+
return new ivm.ExternalCopy(result).copyInto();
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
if (executionId) {
|
|
191
|
+
return await runInExecutionContext(executionId, execute);
|
|
192
|
+
} else {
|
|
193
|
+
return await execute();
|
|
194
|
+
}
|
|
195
|
+
} catch (error) {
|
|
196
|
+
const err = error as Error;
|
|
197
|
+
if (isBatchPauseError(error)) {
|
|
198
|
+
onPauseError(error);
|
|
199
|
+
throw new Error(PAUSE_EXECUTION_MARKER);
|
|
200
|
+
}
|
|
201
|
+
if (isPauseError(error) || err.message === PAUSE_EXECUTION_MARKER) {
|
|
202
|
+
if (isPauseError(error)) {
|
|
203
|
+
onPauseError(error);
|
|
204
|
+
}
|
|
205
|
+
throw new Error(PAUSE_EXECUTION_MARKER);
|
|
206
|
+
}
|
|
207
|
+
throw error;
|
|
208
|
+
}
|
|
209
|
+
})
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
} else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
214
|
+
if (namespace === 'api') {
|
|
215
|
+
await injectAPIFunctions(value, '');
|
|
216
|
+
} else {
|
|
217
|
+
await injectFunctions(value, namespace);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export async function setupRuntimeNamespace(
|
|
224
|
+
ivmContext: ivm.Context,
|
|
225
|
+
sandbox: Record<string, unknown>
|
|
226
|
+
): Promise<void> {
|
|
227
|
+
const runtimeObject = sandbox.__runtime as Record<string, unknown>;
|
|
228
|
+
if (!runtimeObject || typeof runtimeObject !== 'object') {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const runtimeKeys = Object.keys(runtimeObject).filter(
|
|
233
|
+
(k) => typeof runtimeObject[k] === 'function'
|
|
234
|
+
);
|
|
235
|
+
if (runtimeKeys.length === 0) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
let runtimeSetup = 'globalThis.__runtime = {\n';
|
|
240
|
+
runtimeSetup += runtimeKeys
|
|
241
|
+
.map(
|
|
242
|
+
(key) =>
|
|
243
|
+
`\t${key}: async (...args) => {\n\t\treturn await __runtime_${key}_impl.apply(undefined, args, { arguments: { copy: true }, result: { promise: true } });\n\t}`
|
|
244
|
+
)
|
|
245
|
+
.join(',\n');
|
|
246
|
+
runtimeSetup += '\n};';
|
|
247
|
+
|
|
248
|
+
await ivmContext.eval(runtimeSetup);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export async function setupAPINamespace(
|
|
252
|
+
ivmContext: ivm.Context,
|
|
253
|
+
sandbox: Record<string, unknown>,
|
|
254
|
+
provenanceMode?: string
|
|
255
|
+
): Promise<void> {
|
|
256
|
+
const apiObject = sandbox.api as Record<string, unknown>;
|
|
257
|
+
if (!apiObject || typeof apiObject !== 'object') {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const apiGroupNames = Object.keys(apiObject);
|
|
262
|
+
if (apiGroupNames.length === 0) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const isASTMode = provenanceMode === 'ast';
|
|
267
|
+
let apiSetup = 'globalThis.api = {};';
|
|
268
|
+
|
|
269
|
+
function setupNestedAPI(
|
|
270
|
+
obj: Record<string, unknown>,
|
|
271
|
+
pathPrefix: string,
|
|
272
|
+
accessPath: string
|
|
273
|
+
): void {
|
|
274
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
275
|
+
const newPath = pathPrefix ? `${pathPrefix}_${key}` : key;
|
|
276
|
+
const safeKey = JSON.stringify(key);
|
|
277
|
+
const newAccessPath = `${accessPath}[${safeKey}]`;
|
|
278
|
+
|
|
279
|
+
if (typeof value === 'function') {
|
|
280
|
+
const safeName = newPath.replace(/-/g, '_').replace(/\//g, '_').replace(/\./g, '_');
|
|
281
|
+
|
|
282
|
+
if (isASTMode) {
|
|
283
|
+
const toolNameEscaped = newPath.replace(/'/g, "\\'");
|
|
284
|
+
apiSetup += `
|
|
285
|
+
${newAccessPath} = async function(...args) {
|
|
286
|
+
// In AST mode, recursively wrap arguments to preserve tainted primitive provenance
|
|
287
|
+
function wrapTaintedValues(obj, visited = new WeakSet()) {
|
|
288
|
+
if (obj === null || obj === undefined) return obj;
|
|
289
|
+
|
|
290
|
+
// If this is already a wrapped tainted value, don't wrap it again!
|
|
291
|
+
if (typeof obj === 'object' && '__tainted_value' in obj && '__prov_meta' in obj) {
|
|
292
|
+
return obj; // Return as-is, already wrapped
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Check if this value itself has provenance (primitive or object)
|
|
296
|
+
if (typeof globalThis.__check_provenance === 'function') {
|
|
297
|
+
const prov = globalThis.__check_provenance(obj);
|
|
298
|
+
if (prov && (typeof obj === 'string' || typeof obj === 'number')) {
|
|
299
|
+
// Wrap tainted primitive
|
|
300
|
+
return { __tainted_value: obj, __prov_meta: prov };
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// For objects/arrays, recursively wrap their contents
|
|
305
|
+
if (typeof obj === 'object') {
|
|
306
|
+
if (visited.has(obj)) return obj; // Avoid circular refs
|
|
307
|
+
visited.add(obj);
|
|
308
|
+
|
|
309
|
+
if (Array.isArray(obj)) {
|
|
310
|
+
return obj.map(item => wrapTaintedValues(item, visited));
|
|
311
|
+
} else {
|
|
312
|
+
const wrapped = {};
|
|
313
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
314
|
+
wrapped[key] = wrapTaintedValues(val, visited);
|
|
315
|
+
}
|
|
316
|
+
return wrapped;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return obj;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const wrappedArgs = args.map(arg => wrapTaintedValues(arg));
|
|
324
|
+
const result = await __api_${safeName}.apply(undefined, wrappedArgs, { arguments: { copy: true }, result: { promise: true } });
|
|
325
|
+
if (typeof globalThis.__track === 'function' && result !== null && result !== undefined) {
|
|
326
|
+
return globalThis.__track(result, { type: 'tool', tool: '${toolNameEscaped}', operation: 'read' }, []);
|
|
327
|
+
}
|
|
328
|
+
return result;
|
|
329
|
+
};`;
|
|
330
|
+
} else {
|
|
331
|
+
apiSetup += `
|
|
332
|
+
${newAccessPath} = async function(...args) {
|
|
333
|
+
return await __api_${safeName}.apply(undefined, args, { arguments: { copy: true }, result: { promise: true } });
|
|
334
|
+
};`;
|
|
335
|
+
}
|
|
336
|
+
} else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
337
|
+
apiSetup += `\n${newAccessPath} = {};`;
|
|
338
|
+
setupNestedAPI(value as Record<string, unknown>, newPath, newAccessPath);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
setupNestedAPI(apiObject, '', 'globalThis.api');
|
|
344
|
+
await ivmContext.eval(apiSetup);
|
|
345
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CacheProvider } from '@mondaydotcomorg/atp-protocol';
|
|
2
|
+
|
|
3
|
+
export interface RuntimeContext {
|
|
4
|
+
llmCallCount: number;
|
|
5
|
+
approvalCallCount: number;
|
|
6
|
+
logs: string[];
|
|
7
|
+
startTime: number;
|
|
8
|
+
maxLLMCalls: number;
|
|
9
|
+
executionId: string;
|
|
10
|
+
clientId?: string;
|
|
11
|
+
hintMetadata?: Map<string, any>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ExecutorConfig {
|
|
15
|
+
defaultTimeout: number;
|
|
16
|
+
maxTimeout: number;
|
|
17
|
+
defaultMemoryLimit: number;
|
|
18
|
+
maxMemoryLimit: number;
|
|
19
|
+
defaultLLMCallLimit: number;
|
|
20
|
+
maxLLMCallLimit: number;
|
|
21
|
+
cacheProvider?: CacheProvider;
|
|
22
|
+
}
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import type { APIGroupConfig, CustomFunctionDef } from '@mondaydotcomorg/atp-protocol';
|
|
2
|
+
|
|
3
|
+
interface TreeNode {
|
|
4
|
+
type: 'directory' | 'function';
|
|
5
|
+
name: string;
|
|
6
|
+
children?: Map<string, TreeNode>;
|
|
7
|
+
functionDef?: {
|
|
8
|
+
func: CustomFunctionDef;
|
|
9
|
+
group: string;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface ExploreDirectoryResult {
|
|
14
|
+
type: 'directory';
|
|
15
|
+
path: string;
|
|
16
|
+
items: Array<{ name: string; type: 'directory' | 'function' }>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface ExploreFunctionResult {
|
|
20
|
+
type: 'function';
|
|
21
|
+
path: string;
|
|
22
|
+
name: string;
|
|
23
|
+
description: string;
|
|
24
|
+
definition: string;
|
|
25
|
+
group: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type ExploreResult = ExploreDirectoryResult | ExploreFunctionResult;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* ExplorerService provides filesystem-like navigation of API groups.
|
|
32
|
+
* Enables progressive discovery of APIs by allowing agents to explore
|
|
33
|
+
* tool hierarchies on-demand rather than loading everything upfront.
|
|
34
|
+
*/
|
|
35
|
+
export class ExplorerService {
|
|
36
|
+
private root: TreeNode;
|
|
37
|
+
|
|
38
|
+
constructor(apiGroups: APIGroupConfig[]) {
|
|
39
|
+
this.root = { type: 'directory', name: '/', children: new Map() };
|
|
40
|
+
this.buildTree(apiGroups);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Builds the virtual filesystem tree from API groups
|
|
45
|
+
*/
|
|
46
|
+
private buildTree(apiGroups: APIGroupConfig[]): void {
|
|
47
|
+
for (const group of apiGroups) {
|
|
48
|
+
if (!group.functions || group.functions.length === 0) continue;
|
|
49
|
+
|
|
50
|
+
const typeFolder = this.ensureDirectory(this.root, group.type);
|
|
51
|
+
const groupFolder = this.ensureDirectory(typeFolder, group.name);
|
|
52
|
+
|
|
53
|
+
for (const func of group.functions) {
|
|
54
|
+
const segments = this.extractSegments(func, group);
|
|
55
|
+
|
|
56
|
+
if (segments.length > 1) {
|
|
57
|
+
let current = groupFolder;
|
|
58
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
59
|
+
current = this.ensureDirectory(current, segments[i]!);
|
|
60
|
+
}
|
|
61
|
+
this.addFunction(current, segments[segments.length - 1]!, func, group.name);
|
|
62
|
+
} else {
|
|
63
|
+
this.addFunction(groupFolder, func.name, func, group.name);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Extract path segments for organizing functions
|
|
71
|
+
*/
|
|
72
|
+
private extractSegments(func: CustomFunctionDef, group: APIGroupConfig): string[] {
|
|
73
|
+
if (group.type === 'openapi') {
|
|
74
|
+
const name = func.name;
|
|
75
|
+
|
|
76
|
+
const camelSplit = name.match(/[A-Z]?[a-z]+|[A-Z]+(?=[A-Z][a-z]|\b)/g);
|
|
77
|
+
if (camelSplit && camelSplit.length > 2) {
|
|
78
|
+
const verb = camelSplit[0].toLowerCase();
|
|
79
|
+
const isVerb = [
|
|
80
|
+
'get',
|
|
81
|
+
'list',
|
|
82
|
+
'create',
|
|
83
|
+
'update',
|
|
84
|
+
'delete',
|
|
85
|
+
'post',
|
|
86
|
+
'put',
|
|
87
|
+
'patch',
|
|
88
|
+
].includes(verb);
|
|
89
|
+
|
|
90
|
+
if (isVerb) {
|
|
91
|
+
const resource = camelSplit.slice(1).join('_').toLowerCase();
|
|
92
|
+
return [resource, name];
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (name.includes('_')) {
|
|
97
|
+
const parts = name.split('_');
|
|
98
|
+
if (parts.length > 1 && parts[0]) {
|
|
99
|
+
return [parts[0], name];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (name.includes('-')) {
|
|
104
|
+
const parts = name.split('-');
|
|
105
|
+
if (parts.length > 1 && parts[0]) {
|
|
106
|
+
return [parts[0], name];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return [func.name];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Ensures a directory exists at the given path
|
|
116
|
+
*/
|
|
117
|
+
private ensureDirectory(parent: TreeNode, name: string): TreeNode {
|
|
118
|
+
if (!parent.children) {
|
|
119
|
+
parent.children = new Map();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
let child = parent.children.get(name);
|
|
123
|
+
if (!child) {
|
|
124
|
+
child = { type: 'directory', name, children: new Map() };
|
|
125
|
+
parent.children.set(name, child);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return child;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Adds a function to the tree
|
|
133
|
+
*/
|
|
134
|
+
private addFunction(
|
|
135
|
+
parent: TreeNode,
|
|
136
|
+
name: string,
|
|
137
|
+
func: CustomFunctionDef,
|
|
138
|
+
group: string
|
|
139
|
+
): void {
|
|
140
|
+
if (!parent.children) {
|
|
141
|
+
parent.children = new Map();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
parent.children.set(name, {
|
|
145
|
+
type: 'function',
|
|
146
|
+
name,
|
|
147
|
+
functionDef: { func, group },
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Explores the filesystem at the given path
|
|
153
|
+
*/
|
|
154
|
+
explore(path: string): ExploreResult | null {
|
|
155
|
+
const normalizedPath = this.normalizePath(path);
|
|
156
|
+
const segments = normalizedPath === '/' ? [] : normalizedPath.split('/').filter((s) => s);
|
|
157
|
+
|
|
158
|
+
let current = this.root;
|
|
159
|
+
let currentPath = '/';
|
|
160
|
+
|
|
161
|
+
for (const segment of segments) {
|
|
162
|
+
if (!current.children || !current.children.has(segment)) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
current = current.children.get(segment)!;
|
|
166
|
+
currentPath = currentPath === '/' ? `/${segment}` : `${currentPath}/${segment}`;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (current.type === 'directory') {
|
|
170
|
+
const items: Array<{ name: string; type: 'directory' | 'function' }> = [];
|
|
171
|
+
if (current.children) {
|
|
172
|
+
for (const [name, node] of current.children) {
|
|
173
|
+
items.push({ name, type: node.type });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
items.sort((a, b) => {
|
|
177
|
+
if (a.type === b.type) {
|
|
178
|
+
return a.name.localeCompare(b.name);
|
|
179
|
+
}
|
|
180
|
+
return a.type === 'directory' ? -1 : 1;
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
type: 'directory',
|
|
185
|
+
path: currentPath,
|
|
186
|
+
items,
|
|
187
|
+
};
|
|
188
|
+
} else {
|
|
189
|
+
if (!current.functionDef) {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const { func, group } = current.functionDef;
|
|
194
|
+
const definition = this.generateFunctionDefinition(func);
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
type: 'function',
|
|
198
|
+
path: currentPath,
|
|
199
|
+
name: func.name,
|
|
200
|
+
description: func.description,
|
|
201
|
+
definition,
|
|
202
|
+
group,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Normalizes a path (removes trailing slashes, ensures leading slash)
|
|
209
|
+
*/
|
|
210
|
+
private normalizePath(path: string): string {
|
|
211
|
+
if (!path || path === '') return '/';
|
|
212
|
+
|
|
213
|
+
if (!path.startsWith('/')) {
|
|
214
|
+
path = '/' + path;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (path !== '/' && path.endsWith('/')) {
|
|
218
|
+
path = path.slice(0, -1);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return path;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Generates TypeScript function signature
|
|
226
|
+
*/
|
|
227
|
+
private generateFunctionDefinition(func: CustomFunctionDef): string {
|
|
228
|
+
const inputType = this.generateInputType(func.inputSchema);
|
|
229
|
+
const outputType = func.outputSchema ? this.generateOutputType(func.outputSchema) : 'unknown';
|
|
230
|
+
|
|
231
|
+
return `async function ${func.name}(params: ${inputType}): Promise<${outputType}>`;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Generates TypeScript type from JSON schema
|
|
236
|
+
*/
|
|
237
|
+
private generateInputType(schema?: {
|
|
238
|
+
properties?: Record<string, any>;
|
|
239
|
+
required?: string[];
|
|
240
|
+
}): string {
|
|
241
|
+
if (!schema || !schema.properties) {
|
|
242
|
+
return '{}';
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const props: string[] = [];
|
|
246
|
+
const required = schema.required || [];
|
|
247
|
+
|
|
248
|
+
for (const [key, value] of Object.entries(schema.properties)) {
|
|
249
|
+
const isRequired = required.includes(key);
|
|
250
|
+
const prop = value as { type?: string; description?: string };
|
|
251
|
+
const tsType = this.jsonSchemaTypeToTS(prop.type ?? 'any');
|
|
252
|
+
const optional = isRequired ? '' : '?';
|
|
253
|
+
props.push(`${key}${optional}: ${tsType}`);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return `{ ${props.join('; ')} }`;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Generates output type from JSON schema
|
|
261
|
+
*/
|
|
262
|
+
private generateOutputType(schema: { properties?: Record<string, any> }): string {
|
|
263
|
+
if (!schema.properties) {
|
|
264
|
+
return 'unknown';
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const props: string[] = [];
|
|
268
|
+
for (const [key, value] of Object.entries(schema.properties)) {
|
|
269
|
+
const prop = value as { type?: string };
|
|
270
|
+
const tsType = this.jsonSchemaTypeToTS(prop.type ?? 'any');
|
|
271
|
+
props.push(`${key}: ${tsType}`);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return `{ ${props.join('; ')} }`;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Converts JSON Schema type to TypeScript type
|
|
279
|
+
*/
|
|
280
|
+
private jsonSchemaTypeToTS(type: string): string {
|
|
281
|
+
switch (type) {
|
|
282
|
+
case 'string':
|
|
283
|
+
return 'string';
|
|
284
|
+
case 'number':
|
|
285
|
+
case 'integer':
|
|
286
|
+
return 'number';
|
|
287
|
+
case 'boolean':
|
|
288
|
+
return 'boolean';
|
|
289
|
+
case 'array':
|
|
290
|
+
return 'any[]';
|
|
291
|
+
case 'object':
|
|
292
|
+
return 'Record<string, any>';
|
|
293
|
+
default:
|
|
294
|
+
return 'any';
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { APIGroupConfig } from '@mondaydotcomorg/atp-protocol';
|
|
2
|
+
import { APIAggregator } from '../aggregator/index.js';
|
|
3
|
+
|
|
4
|
+
export async function getDefinitions(apiGroups: APIGroupConfig[]): Promise<unknown> {
|
|
5
|
+
const aggregator = new APIAggregator(apiGroups);
|
|
6
|
+
const typescript = await aggregator.generateTypeScript();
|
|
7
|
+
|
|
8
|
+
return {
|
|
9
|
+
typescript,
|
|
10
|
+
apiGroups: apiGroups.map((g) => g.name),
|
|
11
|
+
version: '1.0.0',
|
|
12
|
+
};
|
|
13
|
+
}
|