skedyul 1.7.6 → 1.7.7
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/.build-stamp +1 -1
- package/dist/cli/index.js +108 -0
- package/dist/config/app-config.d.ts +5 -1
- package/dist/config/define.d.ts +34 -0
- package/dist/config/index.d.ts +1 -1
- package/dist/config/types/batch-operation.d.ts +145 -0
- package/dist/config/types/index.d.ts +1 -0
- package/dist/dedicated/server.js +108 -0
- package/dist/esm/index.mjs +144 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +149 -1
- package/dist/schemas.d.ts +53 -0
- package/dist/server/index.d.ts +3 -2
- package/dist/server/route-handlers/handlers.d.ts +4 -0
- package/dist/server/route-handlers/index.d.ts +1 -1
- package/dist/server/route-handlers/types.d.ts +2 -1
- package/dist/server.js +108 -0
- package/dist/serverless/server.mjs +108 -0
- package/dist/types/batch-operation.d.ts +47 -0
- package/dist/types/index.d.ts +1 -0
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -1988,6 +1988,107 @@ async function handleMcpBatchRoute(req, ctx) {
|
|
|
1988
1988
|
}
|
|
1989
1989
|
};
|
|
1990
1990
|
}
|
|
1991
|
+
async function handleBatchOperationRoute(req, ctx) {
|
|
1992
|
+
const bodyResult = parseJsonBody(req);
|
|
1993
|
+
if (!bodyResult.success) {
|
|
1994
|
+
return bodyResult.error;
|
|
1995
|
+
}
|
|
1996
|
+
const body = bodyResult.data;
|
|
1997
|
+
const registry = ctx.batchOperationRegistry;
|
|
1998
|
+
if (!registry) {
|
|
1999
|
+
return {
|
|
2000
|
+
status: 404,
|
|
2001
|
+
body: {
|
|
2002
|
+
success: false,
|
|
2003
|
+
error: "No batch operations registered"
|
|
2004
|
+
}
|
|
2005
|
+
};
|
|
2006
|
+
}
|
|
2007
|
+
const operation = registry[body.handle];
|
|
2008
|
+
if (!operation) {
|
|
2009
|
+
return {
|
|
2010
|
+
status: 404,
|
|
2011
|
+
body: {
|
|
2012
|
+
success: false,
|
|
2013
|
+
error: `Batch operation not found: ${body.handle}`
|
|
2014
|
+
}
|
|
2015
|
+
};
|
|
2016
|
+
}
|
|
2017
|
+
const log = {
|
|
2018
|
+
info: (message, meta) => {
|
|
2019
|
+
console.log(`[batch:${body.handle}] ${message}`, meta ?? "");
|
|
2020
|
+
},
|
|
2021
|
+
warn: (message, meta) => {
|
|
2022
|
+
console.warn(`[batch:${body.handle}] ${message}`, meta ?? "");
|
|
2023
|
+
},
|
|
2024
|
+
error: (message, meta) => {
|
|
2025
|
+
console.error(`[batch:${body.handle}] ${message}`, meta ?? "");
|
|
2026
|
+
}
|
|
2027
|
+
};
|
|
2028
|
+
try {
|
|
2029
|
+
if (body.method === "setup") {
|
|
2030
|
+
if (!operation.setup) {
|
|
2031
|
+
return {
|
|
2032
|
+
status: 200,
|
|
2033
|
+
body: {
|
|
2034
|
+
success: true,
|
|
2035
|
+
result: { state: {}, total: void 0 }
|
|
2036
|
+
}
|
|
2037
|
+
};
|
|
2038
|
+
}
|
|
2039
|
+
const result = await operation.setup({
|
|
2040
|
+
workplaceId: body.workplaceId,
|
|
2041
|
+
appInstallationId: body.appInstallationId,
|
|
2042
|
+
appId: body.appId,
|
|
2043
|
+
input: body.input,
|
|
2044
|
+
log
|
|
2045
|
+
});
|
|
2046
|
+
return {
|
|
2047
|
+
status: 200,
|
|
2048
|
+
body: {
|
|
2049
|
+
success: true,
|
|
2050
|
+
result
|
|
2051
|
+
}
|
|
2052
|
+
};
|
|
2053
|
+
}
|
|
2054
|
+
if (body.method === "iterate") {
|
|
2055
|
+
const result = await operation.iterate({
|
|
2056
|
+
workplaceId: body.workplaceId,
|
|
2057
|
+
appInstallationId: body.appInstallationId,
|
|
2058
|
+
appId: body.appId,
|
|
2059
|
+
input: body.input,
|
|
2060
|
+
state: body.state,
|
|
2061
|
+
page: body.page,
|
|
2062
|
+
cursor: body.cursor,
|
|
2063
|
+
limit: body.limit,
|
|
2064
|
+
log
|
|
2065
|
+
});
|
|
2066
|
+
return {
|
|
2067
|
+
status: 200,
|
|
2068
|
+
body: {
|
|
2069
|
+
success: true,
|
|
2070
|
+
result
|
|
2071
|
+
}
|
|
2072
|
+
};
|
|
2073
|
+
}
|
|
2074
|
+
return {
|
|
2075
|
+
status: 400,
|
|
2076
|
+
body: {
|
|
2077
|
+
success: false,
|
|
2078
|
+
error: `Unknown method: ${body.method}`
|
|
2079
|
+
}
|
|
2080
|
+
};
|
|
2081
|
+
} catch (err) {
|
|
2082
|
+
log.error("Batch operation failed", { error: err });
|
|
2083
|
+
return {
|
|
2084
|
+
status: 500,
|
|
2085
|
+
body: {
|
|
2086
|
+
success: false,
|
|
2087
|
+
error: err instanceof Error ? err.message : String(err)
|
|
2088
|
+
}
|
|
2089
|
+
};
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
1991
2092
|
function createNotFoundResponse() {
|
|
1992
2093
|
return {
|
|
1993
2094
|
status: 404,
|
|
@@ -2067,6 +2168,9 @@ async function routeRequest(req, ctx) {
|
|
|
2067
2168
|
if (req.path === "/mcp/batch" && req.method === "POST") {
|
|
2068
2169
|
return handleMcpBatchRoute(req, ctx);
|
|
2069
2170
|
}
|
|
2171
|
+
if (req.path === "/batch-operation" && req.method === "POST") {
|
|
2172
|
+
return handleBatchOperationRoute(req, ctx);
|
|
2173
|
+
}
|
|
2070
2174
|
return createNotFoundResponse();
|
|
2071
2175
|
} catch (err) {
|
|
2072
2176
|
return createErrorResponse(err);
|
|
@@ -2108,11 +2212,13 @@ function createDedicatedServerInstance(config, tools, callTool, state, mcpServer
|
|
|
2108
2212
|
const defaultHeaders = getDefaultHeaders(config.cors);
|
|
2109
2213
|
const registry = config.tools;
|
|
2110
2214
|
const webhookRegistry = config.webhooks;
|
|
2215
|
+
const batchOperationRegistry = config.batchOperations;
|
|
2111
2216
|
const ctx = {
|
|
2112
2217
|
config,
|
|
2113
2218
|
tools,
|
|
2114
2219
|
registry,
|
|
2115
2220
|
webhookRegistry,
|
|
2221
|
+
batchOperationRegistry,
|
|
2116
2222
|
callTool,
|
|
2117
2223
|
state,
|
|
2118
2224
|
mcpServer,
|
|
@@ -2227,12 +2333,14 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer) {
|
|
|
2227
2333
|
const defaultHeaders = getDefaultHeaders(config.cors);
|
|
2228
2334
|
const registry = config.tools;
|
|
2229
2335
|
const webhookRegistry = config.webhooks;
|
|
2336
|
+
const batchOperationRegistry = config.batchOperations;
|
|
2230
2337
|
let hasLoggedStartup = false;
|
|
2231
2338
|
const ctx = {
|
|
2232
2339
|
config,
|
|
2233
2340
|
tools,
|
|
2234
2341
|
registry,
|
|
2235
2342
|
webhookRegistry,
|
|
2343
|
+
batchOperationRegistry,
|
|
2236
2344
|
callTool,
|
|
2237
2345
|
state,
|
|
2238
2346
|
mcpServer,
|
|
@@ -1949,6 +1949,107 @@ async function handleMcpBatchRoute(req, ctx) {
|
|
|
1949
1949
|
}
|
|
1950
1950
|
};
|
|
1951
1951
|
}
|
|
1952
|
+
async function handleBatchOperationRoute(req, ctx) {
|
|
1953
|
+
const bodyResult = parseJsonBody(req);
|
|
1954
|
+
if (!bodyResult.success) {
|
|
1955
|
+
return bodyResult.error;
|
|
1956
|
+
}
|
|
1957
|
+
const body = bodyResult.data;
|
|
1958
|
+
const registry = ctx.batchOperationRegistry;
|
|
1959
|
+
if (!registry) {
|
|
1960
|
+
return {
|
|
1961
|
+
status: 404,
|
|
1962
|
+
body: {
|
|
1963
|
+
success: false,
|
|
1964
|
+
error: "No batch operations registered"
|
|
1965
|
+
}
|
|
1966
|
+
};
|
|
1967
|
+
}
|
|
1968
|
+
const operation = registry[body.handle];
|
|
1969
|
+
if (!operation) {
|
|
1970
|
+
return {
|
|
1971
|
+
status: 404,
|
|
1972
|
+
body: {
|
|
1973
|
+
success: false,
|
|
1974
|
+
error: `Batch operation not found: ${body.handle}`
|
|
1975
|
+
}
|
|
1976
|
+
};
|
|
1977
|
+
}
|
|
1978
|
+
const log = {
|
|
1979
|
+
info: (message, meta) => {
|
|
1980
|
+
console.log(`[batch:${body.handle}] ${message}`, meta ?? "");
|
|
1981
|
+
},
|
|
1982
|
+
warn: (message, meta) => {
|
|
1983
|
+
console.warn(`[batch:${body.handle}] ${message}`, meta ?? "");
|
|
1984
|
+
},
|
|
1985
|
+
error: (message, meta) => {
|
|
1986
|
+
console.error(`[batch:${body.handle}] ${message}`, meta ?? "");
|
|
1987
|
+
}
|
|
1988
|
+
};
|
|
1989
|
+
try {
|
|
1990
|
+
if (body.method === "setup") {
|
|
1991
|
+
if (!operation.setup) {
|
|
1992
|
+
return {
|
|
1993
|
+
status: 200,
|
|
1994
|
+
body: {
|
|
1995
|
+
success: true,
|
|
1996
|
+
result: { state: {}, total: void 0 }
|
|
1997
|
+
}
|
|
1998
|
+
};
|
|
1999
|
+
}
|
|
2000
|
+
const result = await operation.setup({
|
|
2001
|
+
workplaceId: body.workplaceId,
|
|
2002
|
+
appInstallationId: body.appInstallationId,
|
|
2003
|
+
appId: body.appId,
|
|
2004
|
+
input: body.input,
|
|
2005
|
+
log
|
|
2006
|
+
});
|
|
2007
|
+
return {
|
|
2008
|
+
status: 200,
|
|
2009
|
+
body: {
|
|
2010
|
+
success: true,
|
|
2011
|
+
result
|
|
2012
|
+
}
|
|
2013
|
+
};
|
|
2014
|
+
}
|
|
2015
|
+
if (body.method === "iterate") {
|
|
2016
|
+
const result = await operation.iterate({
|
|
2017
|
+
workplaceId: body.workplaceId,
|
|
2018
|
+
appInstallationId: body.appInstallationId,
|
|
2019
|
+
appId: body.appId,
|
|
2020
|
+
input: body.input,
|
|
2021
|
+
state: body.state,
|
|
2022
|
+
page: body.page,
|
|
2023
|
+
cursor: body.cursor,
|
|
2024
|
+
limit: body.limit,
|
|
2025
|
+
log
|
|
2026
|
+
});
|
|
2027
|
+
return {
|
|
2028
|
+
status: 200,
|
|
2029
|
+
body: {
|
|
2030
|
+
success: true,
|
|
2031
|
+
result
|
|
2032
|
+
}
|
|
2033
|
+
};
|
|
2034
|
+
}
|
|
2035
|
+
return {
|
|
2036
|
+
status: 400,
|
|
2037
|
+
body: {
|
|
2038
|
+
success: false,
|
|
2039
|
+
error: `Unknown method: ${body.method}`
|
|
2040
|
+
}
|
|
2041
|
+
};
|
|
2042
|
+
} catch (err) {
|
|
2043
|
+
log.error("Batch operation failed", { error: err });
|
|
2044
|
+
return {
|
|
2045
|
+
status: 500,
|
|
2046
|
+
body: {
|
|
2047
|
+
success: false,
|
|
2048
|
+
error: err instanceof Error ? err.message : String(err)
|
|
2049
|
+
}
|
|
2050
|
+
};
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
1952
2053
|
function createNotFoundResponse() {
|
|
1953
2054
|
return {
|
|
1954
2055
|
status: 404,
|
|
@@ -2028,6 +2129,9 @@ async function routeRequest(req, ctx) {
|
|
|
2028
2129
|
if (req.path === "/mcp/batch" && req.method === "POST") {
|
|
2029
2130
|
return handleMcpBatchRoute(req, ctx);
|
|
2030
2131
|
}
|
|
2132
|
+
if (req.path === "/batch-operation" && req.method === "POST") {
|
|
2133
|
+
return handleBatchOperationRoute(req, ctx);
|
|
2134
|
+
}
|
|
2031
2135
|
return createNotFoundResponse();
|
|
2032
2136
|
} catch (err) {
|
|
2033
2137
|
return createErrorResponse(err);
|
|
@@ -2069,11 +2173,13 @@ function createDedicatedServerInstance(config, tools, callTool, state, mcpServer
|
|
|
2069
2173
|
const defaultHeaders = getDefaultHeaders(config.cors);
|
|
2070
2174
|
const registry = config.tools;
|
|
2071
2175
|
const webhookRegistry = config.webhooks;
|
|
2176
|
+
const batchOperationRegistry = config.batchOperations;
|
|
2072
2177
|
const ctx = {
|
|
2073
2178
|
config,
|
|
2074
2179
|
tools,
|
|
2075
2180
|
registry,
|
|
2076
2181
|
webhookRegistry,
|
|
2182
|
+
batchOperationRegistry,
|
|
2077
2183
|
callTool,
|
|
2078
2184
|
state,
|
|
2079
2185
|
mcpServer,
|
|
@@ -2188,12 +2294,14 @@ function createServerlessInstance(config, tools, callTool, state, mcpServer) {
|
|
|
2188
2294
|
const defaultHeaders = getDefaultHeaders(config.cors);
|
|
2189
2295
|
const registry = config.tools;
|
|
2190
2296
|
const webhookRegistry = config.webhooks;
|
|
2297
|
+
const batchOperationRegistry = config.batchOperations;
|
|
2191
2298
|
let hasLoggedStartup = false;
|
|
2192
2299
|
const ctx = {
|
|
2193
2300
|
config,
|
|
2194
2301
|
tools,
|
|
2195
2302
|
registry,
|
|
2196
2303
|
webhookRegistry,
|
|
2304
|
+
batchOperationRegistry,
|
|
2197
2305
|
callTool,
|
|
2198
2306
|
state,
|
|
2199
2307
|
mcpServer,
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Batch operation runtime types.
|
|
3
|
+
*
|
|
4
|
+
* These types define the registry and context for batch operations at runtime.
|
|
5
|
+
*/
|
|
6
|
+
import type { BatchOperationSetupFn, BatchOperationIterateFn } from '../config/types/batch-operation';
|
|
7
|
+
export type { BatchOperationContext } from '../config/types/batch-operation';
|
|
8
|
+
/**
|
|
9
|
+
* Entry in the batch operation registry.
|
|
10
|
+
* Contains both metadata and function implementations.
|
|
11
|
+
*/
|
|
12
|
+
export interface BatchOperationRegistryEntry {
|
|
13
|
+
/** Unique handle for this operation */
|
|
14
|
+
handle: string;
|
|
15
|
+
/** Human-readable label */
|
|
16
|
+
label: string;
|
|
17
|
+
/** Description of what this operation does */
|
|
18
|
+
description?: string;
|
|
19
|
+
/** Entity handle that items will be upserted to */
|
|
20
|
+
entity: string;
|
|
21
|
+
/** Setup function called once at the start */
|
|
22
|
+
setup?: BatchOperationSetupFn;
|
|
23
|
+
/** Iterate function called for each page */
|
|
24
|
+
iterate: BatchOperationIterateFn;
|
|
25
|
+
/** Maximum concurrent operations per app installation */
|
|
26
|
+
maxConcurrent?: number;
|
|
27
|
+
/** Default page size */
|
|
28
|
+
pageSize?: number;
|
|
29
|
+
/** Optional icon */
|
|
30
|
+
icon?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Registry mapping batch operation handles to their implementations.
|
|
34
|
+
*/
|
|
35
|
+
export type BatchOperationRegistry = Record<string, BatchOperationRegistryEntry>;
|
|
36
|
+
/**
|
|
37
|
+
* Metadata for a batch operation (serializable, no functions).
|
|
38
|
+
*/
|
|
39
|
+
export interface BatchOperationMetadata {
|
|
40
|
+
handle: string;
|
|
41
|
+
label: string;
|
|
42
|
+
description?: string;
|
|
43
|
+
entity: string;
|
|
44
|
+
maxConcurrent?: number;
|
|
45
|
+
pageSize?: number;
|
|
46
|
+
icon?: string;
|
|
47
|
+
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -22,3 +22,4 @@ export type { WebhookWireRequest, HandlerRawRequest, WebhookRequest, WebhookResp
|
|
|
22
22
|
export { isRuntimeWebhookContext } from './webhook';
|
|
23
23
|
export type { MCPError, MCPContentItem, MCPResult, MCPResponse, MCPRequest, } from './mcp-protocol';
|
|
24
24
|
export type { DataBlock, DataBlockLink, SpreadsheetBlock, SpreadsheetColumn, ProfileBlock, ProfileAvatar, ProfileField, FieldChangesBlock, FieldChangeItem, DateTimeBlock, } from './data-blocks';
|
|
25
|
+
export type { BatchOperationContext, BatchOperationRegistryEntry, BatchOperationRegistry, BatchOperationMetadata, } from './batch-operation';
|