@decocms/runtime 0.24.0 → 0.25.1
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/bindings/deconfig/index.d.ts +2 -2
- package/dist/bindings/deconfig/index.js +5 -5
- package/dist/bindings/index.d.ts +2 -2
- package/dist/bindings/index.js +6 -6
- package/dist/{chunk-4UQ5U73Y.js → chunk-F6XZPFWM.js} +3 -5
- package/dist/chunk-F6XZPFWM.js.map +1 -0
- package/dist/{chunk-ZRJ5SGAO.js → chunk-I2KGAHFY.js} +26 -6
- package/dist/chunk-I2KGAHFY.js.map +1 -0
- package/dist/{chunk-73FIKR3X.js → chunk-NKUMVYKI.js} +3 -3
- package/dist/chunk-NKUMVYKI.js.map +1 -0
- package/dist/{chunk-377XXI4J.js → chunk-O6IURJAY.js} +4 -4
- package/dist/{chunk-377XXI4J.js.map → chunk-O6IURJAY.js.map} +1 -1
- package/dist/{chunk-G3NWZG2F.js → chunk-QELHWEZH.js} +3 -3
- package/dist/chunk-QELHWEZH.js.map +1 -0
- package/dist/drizzle.d.ts +1 -1
- package/dist/{index-D_J_044C.d.ts → index-D8GtUDPS.d.ts} +11 -2
- package/dist/{index-BBAR4TQu.d.ts → index-SnnmAI05.d.ts} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -6
- package/dist/index.js.map +1 -1
- package/dist/mastra.d.ts +1 -1
- package/dist/mastra.js +2 -2
- package/dist/mcp-client.js +1 -1
- package/dist/proxy.js +2 -2
- package/dist/resources.d.ts +2 -33
- package/dist/resources.js +1 -1
- package/package.json +14 -1
- package/src/admin.ts +16 -0
- package/src/auth.ts +233 -0
- package/src/bindings/README.md +132 -0
- package/src/bindings/binder.ts +143 -0
- package/src/bindings/channels.ts +54 -0
- package/src/bindings/deconfig/helpers.ts +107 -0
- package/src/bindings/deconfig/index.ts +1 -0
- package/src/bindings/deconfig/resources.ts +659 -0
- package/src/bindings/deconfig/types.ts +106 -0
- package/src/bindings/index.ts +61 -0
- package/src/bindings/resources/bindings.ts +99 -0
- package/src/bindings/resources/helpers.ts +95 -0
- package/src/bindings/resources/schemas.ts +265 -0
- package/src/bindings/utils.ts +22 -0
- package/src/bindings/views.ts +14 -0
- package/src/bindings.ts +178 -0
- package/src/cf-imports.ts +1 -0
- package/src/client.ts +201 -0
- package/src/connection.ts +53 -0
- package/src/d1-store.ts +34 -0
- package/src/deprecated.ts +59 -0
- package/src/drizzle.ts +201 -0
- package/src/http-client-transport.ts +66 -0
- package/src/index.ts +409 -0
- package/src/mastra.ts +894 -0
- package/src/mcp-client.ts +119 -0
- package/src/mcp.ts +170 -0
- package/src/proxy.ts +212 -0
- package/src/resources.ts +168 -0
- package/src/state.ts +44 -0
- package/src/views.ts +26 -0
- package/src/well-known.ts +20 -0
- package/src/workflow.ts +193 -0
- package/src/wrangler.ts +146 -0
- package/dist/chunk-4UQ5U73Y.js.map +0 -1
- package/dist/chunk-73FIKR3X.js.map +0 -1
- package/dist/chunk-G3NWZG2F.js.map +0 -1
- package/dist/chunk-ZRJ5SGAO.js.map +0 -1
package/src/bindings.ts
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import type { MCPConnection } from "./connection.ts";
|
|
2
|
+
import type { DefaultEnv, RequestContext } from "./index.ts";
|
|
3
|
+
import { MCPClient } from "./mcp.ts";
|
|
4
|
+
import type {
|
|
5
|
+
BindingBase,
|
|
6
|
+
ContractBinding,
|
|
7
|
+
MCPBinding,
|
|
8
|
+
MCPIntegrationNameBinding,
|
|
9
|
+
} from "./wrangler.ts";
|
|
10
|
+
|
|
11
|
+
interface IntegrationContext {
|
|
12
|
+
integrationId: string;
|
|
13
|
+
workspace: string;
|
|
14
|
+
branch?: string;
|
|
15
|
+
decoCmsApiUrl?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const normalizeWorkspace = (workspace: string) => {
|
|
19
|
+
if (workspace.startsWith("/users")) {
|
|
20
|
+
return workspace;
|
|
21
|
+
}
|
|
22
|
+
if (workspace.startsWith("/shared")) {
|
|
23
|
+
return workspace;
|
|
24
|
+
}
|
|
25
|
+
if (workspace.includes("/")) {
|
|
26
|
+
return workspace;
|
|
27
|
+
}
|
|
28
|
+
return `/shared/${workspace}`;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Url: /apps/mcp?appName=$appName
|
|
33
|
+
*/
|
|
34
|
+
const createAppsUrl = ({
|
|
35
|
+
appName,
|
|
36
|
+
decoChatApiUrl,
|
|
37
|
+
}: {
|
|
38
|
+
appName: string;
|
|
39
|
+
decoChatApiUrl?: string;
|
|
40
|
+
}) =>
|
|
41
|
+
new URL(
|
|
42
|
+
`/apps/mcp?appName=${appName}`,
|
|
43
|
+
decoChatApiUrl ?? "https://api.decocms.com",
|
|
44
|
+
).href;
|
|
45
|
+
/**
|
|
46
|
+
* Url: /:workspace.root/:workspace.slug/:integrationId/mcp
|
|
47
|
+
*/
|
|
48
|
+
const createIntegrationsUrl = ({
|
|
49
|
+
integrationId,
|
|
50
|
+
workspace,
|
|
51
|
+
decoCmsApiUrl,
|
|
52
|
+
branch,
|
|
53
|
+
}: IntegrationContext) => {
|
|
54
|
+
const base = `${normalizeWorkspace(workspace)}/${integrationId}/mcp`;
|
|
55
|
+
const url = new URL(base, decoCmsApiUrl ?? "https://api.decocms.com");
|
|
56
|
+
branch && url.searchParams.set("branch", branch);
|
|
57
|
+
return url.href;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
type WorkspaceClientContext = Omit<
|
|
61
|
+
RequestContext,
|
|
62
|
+
"ensureAuthenticated" | "state" | "fetchIntegrationMetadata"
|
|
63
|
+
>;
|
|
64
|
+
export const workspaceClient = (
|
|
65
|
+
ctx: WorkspaceClientContext,
|
|
66
|
+
): ReturnType<(typeof MCPClient)["forWorkspace"]> => {
|
|
67
|
+
return MCPClient.forWorkspace(ctx.workspace, ctx.token);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const mcpClientForAppName = (appName: string, decoChatApiUrl?: string) => {
|
|
71
|
+
const mcpConnection: MCPConnection = {
|
|
72
|
+
type: "HTTP",
|
|
73
|
+
url: createAppsUrl({
|
|
74
|
+
appName,
|
|
75
|
+
decoChatApiUrl,
|
|
76
|
+
}),
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return MCPClient.forConnection(mcpConnection);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export const proxyConnectionForId = (
|
|
83
|
+
integrationId: string,
|
|
84
|
+
ctx: Omit<WorkspaceClientContext, "token"> & {
|
|
85
|
+
token?: string;
|
|
86
|
+
cookie?: string;
|
|
87
|
+
},
|
|
88
|
+
decoChatApiUrl?: string,
|
|
89
|
+
appName?: string,
|
|
90
|
+
): MCPConnection => {
|
|
91
|
+
let headers: Record<string, string> | undefined = appName
|
|
92
|
+
? { "x-caller-app": appName }
|
|
93
|
+
: undefined;
|
|
94
|
+
if (ctx.cookie) {
|
|
95
|
+
headers ??= {};
|
|
96
|
+
headers.cookie = ctx.cookie;
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
type: "HTTP",
|
|
100
|
+
url: createIntegrationsUrl({
|
|
101
|
+
integrationId,
|
|
102
|
+
workspace: ctx.workspace,
|
|
103
|
+
decoCmsApiUrl: decoChatApiUrl,
|
|
104
|
+
branch: ctx.branch,
|
|
105
|
+
}),
|
|
106
|
+
token: ctx.token,
|
|
107
|
+
headers,
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
const mcpClientForIntegrationId = (
|
|
111
|
+
integrationId: string,
|
|
112
|
+
ctx: WorkspaceClientContext,
|
|
113
|
+
decoChatApiUrl?: string,
|
|
114
|
+
appName?: string,
|
|
115
|
+
) => {
|
|
116
|
+
const mcpConnection = proxyConnectionForId(
|
|
117
|
+
integrationId,
|
|
118
|
+
ctx,
|
|
119
|
+
decoChatApiUrl,
|
|
120
|
+
appName,
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
// TODO(@igorbrasileiro): Switch this proxy to be a proxy that call MCP Client.toolCall from @modelcontextprotocol
|
|
124
|
+
return MCPClient.forConnection(mcpConnection);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
function mcpClientFromState(
|
|
128
|
+
binding: BindingBase | MCPIntegrationNameBinding,
|
|
129
|
+
env: DefaultEnv,
|
|
130
|
+
) {
|
|
131
|
+
const ctx = env.DECO_REQUEST_CONTEXT;
|
|
132
|
+
const bindingFromState = ctx?.state?.[binding.name];
|
|
133
|
+
const integrationId =
|
|
134
|
+
bindingFromState &&
|
|
135
|
+
typeof bindingFromState === "object" &&
|
|
136
|
+
"value" in bindingFromState
|
|
137
|
+
? bindingFromState.value
|
|
138
|
+
: undefined;
|
|
139
|
+
if (typeof integrationId !== "string" && "integration_name" in binding) {
|
|
140
|
+
// in case of a binding to an app name, we need to use the new apps/mcp endpoint which will proxy the request to the app but without any token
|
|
141
|
+
return mcpClientForAppName(binding.integration_name, env.DECO_API_URL);
|
|
142
|
+
}
|
|
143
|
+
return mcpClientForIntegrationId(
|
|
144
|
+
integrationId,
|
|
145
|
+
ctx,
|
|
146
|
+
env.DECO_API_URL,
|
|
147
|
+
env.DECO_APP_NAME,
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export const createContractBinding = (
|
|
152
|
+
binding: ContractBinding,
|
|
153
|
+
env: DefaultEnv,
|
|
154
|
+
) => {
|
|
155
|
+
return mcpClientFromState(binding, env);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
export const createIntegrationBinding = (
|
|
159
|
+
binding: MCPBinding,
|
|
160
|
+
env: DefaultEnv,
|
|
161
|
+
) => {
|
|
162
|
+
const integrationId =
|
|
163
|
+
"integration_id" in binding ? binding.integration_id : undefined;
|
|
164
|
+
if (!integrationId) {
|
|
165
|
+
return mcpClientFromState(binding, env);
|
|
166
|
+
}
|
|
167
|
+
// bindings pointed to an specific integration id are binded using the app deployment workspace
|
|
168
|
+
return mcpClientForIntegrationId(
|
|
169
|
+
integrationId,
|
|
170
|
+
{
|
|
171
|
+
workspace: env.DECO_WORKSPACE,
|
|
172
|
+
token: env.DECO_API_TOKEN,
|
|
173
|
+
branch: env.DECO_REQUEST_CONTEXT?.branch,
|
|
174
|
+
},
|
|
175
|
+
env.DECO_API_URL,
|
|
176
|
+
env.DECO_APP_NAME,
|
|
177
|
+
);
|
|
178
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DurableObject } from "cloudflare:workers";
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { toAsyncIterator } from "./bindings/deconfig/helpers.ts";
|
|
2
|
+
// Extract resource name from DECO_RESOURCE_${NAME}_READ pattern
|
|
3
|
+
type ExtractResourceName<K> = K extends `DECO_RESOURCE_${infer Name}_READ`
|
|
4
|
+
? Name
|
|
5
|
+
: never;
|
|
6
|
+
|
|
7
|
+
// Generate SUBSCRIBE method name from resource name
|
|
8
|
+
type SubscribeMethodName<Name extends string> =
|
|
9
|
+
`DECO_RESOURCE_${Name}_SUBSCRIBE`;
|
|
10
|
+
|
|
11
|
+
// Extract data type from READ method return type
|
|
12
|
+
type ExtractReadData<T> = T extends Promise<{ data: infer D }>
|
|
13
|
+
? D
|
|
14
|
+
: T extends { data: infer D }
|
|
15
|
+
? D
|
|
16
|
+
: never;
|
|
17
|
+
|
|
18
|
+
// Generate all SUBSCRIBE method names for a given type
|
|
19
|
+
type SubscribeMethods<T> = {
|
|
20
|
+
[K in keyof T as K extends `DECO_RESOURCE_${string}_READ`
|
|
21
|
+
? SubscribeMethodName<ExtractResourceName<K>>
|
|
22
|
+
: never]: K extends `DECO_RESOURCE_${string}_READ`
|
|
23
|
+
? // oxlint-disable-next-line no-explicit-any
|
|
24
|
+
T[K] extends (...args: any) => any
|
|
25
|
+
? (args: { id: string } | { uri: string }) => AsyncIterableIterator<{
|
|
26
|
+
uri: string;
|
|
27
|
+
data: ExtractReadData<Awaited<ReturnType<T[K]>>>;
|
|
28
|
+
}>
|
|
29
|
+
: never
|
|
30
|
+
: never;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type MCPClient<T> = {
|
|
34
|
+
// oxlint-disable-next-line no-explicit-any
|
|
35
|
+
[K in keyof T]: T[K] extends (...args: any) => any
|
|
36
|
+
? (
|
|
37
|
+
args: Parameters<T[K]>[0],
|
|
38
|
+
init?: CustomInit,
|
|
39
|
+
) => Promise<Awaited<ReturnType<T[K]>>>
|
|
40
|
+
: never;
|
|
41
|
+
} & SubscribeMethods<T>;
|
|
42
|
+
|
|
43
|
+
export type CustomInit = RequestInit & {
|
|
44
|
+
handleResponse?: (response: Response) => Promise<unknown>;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const DECO_MCP_CLIENT_HEADER = "X-Deco-MCP-Client";
|
|
48
|
+
|
|
49
|
+
export const DEFAULT_INIT: CustomInit = {
|
|
50
|
+
credentials: "include",
|
|
51
|
+
headers: {
|
|
52
|
+
[DECO_MCP_CLIENT_HEADER]: "true",
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Helper function to call an MCP tool via fetch
|
|
58
|
+
*/
|
|
59
|
+
async function callMCPTool<T = unknown>(
|
|
60
|
+
methodName: string,
|
|
61
|
+
args: unknown,
|
|
62
|
+
init?: CustomInit,
|
|
63
|
+
): Promise<T> {
|
|
64
|
+
const mergedInit: CustomInit = {
|
|
65
|
+
...init,
|
|
66
|
+
headers: {
|
|
67
|
+
...DEFAULT_INIT.headers,
|
|
68
|
+
...init?.headers,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const response = await fetch(`/mcp/call-tool/${methodName}`, {
|
|
73
|
+
method: "POST",
|
|
74
|
+
body: JSON.stringify(args),
|
|
75
|
+
credentials: "include",
|
|
76
|
+
...mergedInit,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
if (!response.ok) {
|
|
80
|
+
throw new Error(`Failed to call ${methodName}: ${response.statusText}`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return response.json() as Promise<T>;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Creates a subscribe method for a resource that returns an async iterator
|
|
88
|
+
* yielding {uri, data} objects as resources are updated.
|
|
89
|
+
*/
|
|
90
|
+
function createSubscribeMethod(
|
|
91
|
+
resourceName: string,
|
|
92
|
+
init?: CustomInit,
|
|
93
|
+
): (args: { id: string }) => AsyncIterableIterator<{
|
|
94
|
+
uri: string;
|
|
95
|
+
data: unknown;
|
|
96
|
+
}> {
|
|
97
|
+
return async function* (args: { id: string } | { uri: string }) {
|
|
98
|
+
// Step 1: Call DESCRIBE to get watch endpoint configuration and URI template
|
|
99
|
+
const describeMethodName = `DECO_RESOURCE_${resourceName}_DESCRIBE`;
|
|
100
|
+
const readMethodName = `DECO_RESOURCE_${resourceName}_READ`;
|
|
101
|
+
|
|
102
|
+
// Get describe information
|
|
103
|
+
const describeData = await callMCPTool<{
|
|
104
|
+
uriTemplate?: string;
|
|
105
|
+
features?: {
|
|
106
|
+
watch?: {
|
|
107
|
+
pathname?: string;
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
}>(describeMethodName, {}, init);
|
|
111
|
+
|
|
112
|
+
const watchPathname = describeData?.features?.watch?.pathname;
|
|
113
|
+
const uriTemplate = describeData?.uriTemplate;
|
|
114
|
+
|
|
115
|
+
if (!watchPathname) {
|
|
116
|
+
throw new Error(
|
|
117
|
+
`Resource ${resourceName} does not support watch functionality`,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (!uriTemplate) {
|
|
122
|
+
throw new Error(`Resource ${resourceName} does not provide uriTemplate`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Step 2: Construct URI from template by replacing * with id
|
|
126
|
+
const resourceUri =
|
|
127
|
+
"uri" in args ? args.uri : uriTemplate.replace("*", args.id);
|
|
128
|
+
|
|
129
|
+
// Step 3: Construct watch URL and create EventSource
|
|
130
|
+
const watchUrl = new URL(watchPathname, globalThis.location.origin);
|
|
131
|
+
watchUrl.searchParams.set("uri", resourceUri);
|
|
132
|
+
|
|
133
|
+
const eventSource = new EventSource(watchUrl.href);
|
|
134
|
+
|
|
135
|
+
// Step 4: Use toAsyncIterator to consume SSE events and enrich with READ data
|
|
136
|
+
const eventStream = toAsyncIterator<{ uri: string }>(
|
|
137
|
+
eventSource,
|
|
138
|
+
"message",
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
// Iterate over SSE events and enrich with full data
|
|
142
|
+
for await (const event of eventStream) {
|
|
143
|
+
const uri = event.uri;
|
|
144
|
+
|
|
145
|
+
if (uri) {
|
|
146
|
+
// Call READ to get full resource data
|
|
147
|
+
const readData = await callMCPTool<{ data: unknown }>(
|
|
148
|
+
readMethodName,
|
|
149
|
+
{ uri },
|
|
150
|
+
init,
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
yield { uri, data: readData.data };
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export const createClient = <T>(init?: CustomInit): MCPClient<T> => {
|
|
160
|
+
return new Proxy(
|
|
161
|
+
{},
|
|
162
|
+
{
|
|
163
|
+
get: (_, prop) => {
|
|
164
|
+
const propStr = String(prop);
|
|
165
|
+
|
|
166
|
+
// Check if this is a SUBSCRIBE method call
|
|
167
|
+
const subscribeMatch = propStr.match(/^DECO_RESOURCE_(.+)_SUBSCRIBE$/);
|
|
168
|
+
if (subscribeMatch) {
|
|
169
|
+
const resourceName = subscribeMatch[1];
|
|
170
|
+
return createSubscribeMethod(resourceName, init);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Regular method call
|
|
174
|
+
return async (args: unknown, innerInit?: CustomInit) => {
|
|
175
|
+
const mergedInit: CustomInit = {
|
|
176
|
+
...init,
|
|
177
|
+
...innerInit,
|
|
178
|
+
headers: {
|
|
179
|
+
...DEFAULT_INIT.headers,
|
|
180
|
+
...init?.headers,
|
|
181
|
+
...innerInit?.headers,
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const response = await fetch(`/mcp/call-tool/${String(prop)}`, {
|
|
186
|
+
method: "POST",
|
|
187
|
+
body: JSON.stringify(args),
|
|
188
|
+
credentials: "include",
|
|
189
|
+
...mergedInit,
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
if (typeof mergedInit.handleResponse === "function") {
|
|
193
|
+
return mergedInit.handleResponse(response);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return response.json();
|
|
197
|
+
};
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
) as MCPClient<T>;
|
|
201
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export type SSEConnection = {
|
|
2
|
+
type: "SSE";
|
|
3
|
+
url: string;
|
|
4
|
+
token?: string;
|
|
5
|
+
headers?: Record<string, string>;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type WebsocketConnection = {
|
|
9
|
+
type: "Websocket";
|
|
10
|
+
url: string;
|
|
11
|
+
token?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type DecoConnection = {
|
|
15
|
+
type: "Deco";
|
|
16
|
+
tenant: string;
|
|
17
|
+
token?: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type InnateConnection = {
|
|
21
|
+
type: "INNATE";
|
|
22
|
+
name: string;
|
|
23
|
+
workspace?: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type HTTPConnection = {
|
|
27
|
+
type: "HTTP";
|
|
28
|
+
url: string;
|
|
29
|
+
headers?: Record<string, string>;
|
|
30
|
+
token?: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type MCPConnection =
|
|
34
|
+
| SSEConnection
|
|
35
|
+
| WebsocketConnection
|
|
36
|
+
| InnateConnection
|
|
37
|
+
| DecoConnection
|
|
38
|
+
| HTTPConnection;
|
|
39
|
+
|
|
40
|
+
export type Integration = {
|
|
41
|
+
/** Unique identifier for the MCP */
|
|
42
|
+
id: string;
|
|
43
|
+
/** Human-readable name of the integration */
|
|
44
|
+
name: string;
|
|
45
|
+
/** Brief description of the integration's functionality */
|
|
46
|
+
description?: string;
|
|
47
|
+
/** URL to the integration's icon */
|
|
48
|
+
icon?: string;
|
|
49
|
+
/** Access level of the integration */
|
|
50
|
+
access?: string | null;
|
|
51
|
+
/** Connection configuration */
|
|
52
|
+
connection: MCPConnection;
|
|
53
|
+
};
|
package/src/d1-store.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
D1ClientConfig as MastraD1StoreConfig,
|
|
3
|
+
D1Store as MastraD1Store,
|
|
4
|
+
} from "@mastra/cloudflare-d1";
|
|
5
|
+
|
|
6
|
+
export class D1Store extends MastraD1Store {
|
|
7
|
+
constructor(private config: MastraD1StoreConfig) {
|
|
8
|
+
super(config);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
override async init() {
|
|
12
|
+
await super.init();
|
|
13
|
+
|
|
14
|
+
// Create indexes for better performance on frequently queried columns
|
|
15
|
+
const indexQueries = [
|
|
16
|
+
{
|
|
17
|
+
sql: "CREATE INDEX IF NOT EXISTS idx_mastra_workflow_snapshot_created_at ON mastra_workflow_snapshot(createdAt)",
|
|
18
|
+
params: [],
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
sql: "CREATE INDEX IF NOT EXISTS idx_mastra_messages_created_at ON mastra_messages(createdAt)",
|
|
22
|
+
params: [],
|
|
23
|
+
},
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
// Execute each index creation query
|
|
27
|
+
for (const { sql, params } of indexQueries) {
|
|
28
|
+
await this.config.client.query({
|
|
29
|
+
sql,
|
|
30
|
+
params,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { RequestContext } from "./index.ts";
|
|
2
|
+
import type { DurableObjectNamespace } from "@cloudflare/workers-types";
|
|
3
|
+
import type { WorkspaceDB } from "./index.ts";
|
|
4
|
+
import type { WorkflowDO } from "./workflow.ts";
|
|
5
|
+
import type { z } from "zod";
|
|
6
|
+
|
|
7
|
+
// oxlint-disable-next-line no-explicit-any
|
|
8
|
+
export interface DeprecatedEnv<TSchema extends z.ZodTypeAny = any> {
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated Use DECO_REQUEST_CONTEXT instead
|
|
11
|
+
*/
|
|
12
|
+
DECO_CHAT_REQUEST_CONTEXT: RequestContext<TSchema>;
|
|
13
|
+
/**
|
|
14
|
+
* @deprecated Use DECO_APP_NAME instead
|
|
15
|
+
*/
|
|
16
|
+
DECO_CHAT_APP_NAME: string;
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated Use DECO_APP_SLUG instead
|
|
19
|
+
*/
|
|
20
|
+
DECO_CHAT_APP_SLUG: string;
|
|
21
|
+
/**
|
|
22
|
+
* @deprecated Use DECO_APP_ENTRYPOINT instead
|
|
23
|
+
*/
|
|
24
|
+
DECO_CHAT_APP_ENTRYPOINT: string;
|
|
25
|
+
/**
|
|
26
|
+
* @deprecated Use DECO_API_URL instead
|
|
27
|
+
*/
|
|
28
|
+
DECO_CHAT_API_URL?: string;
|
|
29
|
+
/**
|
|
30
|
+
* @deprecated Use DECO_WORKSPACE instead
|
|
31
|
+
*/
|
|
32
|
+
DECO_CHAT_WORKSPACE: string;
|
|
33
|
+
/**
|
|
34
|
+
* @deprecated Use DECO_API_JWT_PUBLIC_KEY instead
|
|
35
|
+
*/
|
|
36
|
+
DECO_CHAT_API_JWT_PUBLIC_KEY: string;
|
|
37
|
+
/**
|
|
38
|
+
* @deprecated Use DECO_APP_DEPLOYMENT_ID instead
|
|
39
|
+
*/
|
|
40
|
+
DECO_CHAT_APP_DEPLOYMENT_ID: string;
|
|
41
|
+
/**
|
|
42
|
+
* @deprecated Use DECO_BINDINGS instead
|
|
43
|
+
*/
|
|
44
|
+
DECO_CHAT_BINDINGS: string;
|
|
45
|
+
/**
|
|
46
|
+
* @deprecated Use DECO_API_TOKEN instead
|
|
47
|
+
*/
|
|
48
|
+
DECO_CHAT_API_TOKEN: string;
|
|
49
|
+
/**
|
|
50
|
+
* @deprecated Use DECO_WORKFLOW_DO instead
|
|
51
|
+
*/
|
|
52
|
+
DECO_CHAT_WORKFLOW_DO: DurableObjectNamespace<WorkflowDO>;
|
|
53
|
+
/**
|
|
54
|
+
* @deprecated Use DECO_WORKSPACE_DB instead
|
|
55
|
+
*/
|
|
56
|
+
DECO_CHAT_WORKSPACE_DB: WorkspaceDB & {
|
|
57
|
+
forContext: (ctx: RequestContext) => WorkspaceDB;
|
|
58
|
+
};
|
|
59
|
+
}
|