@yolk-sdk/connectors 0.0.1-canary.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/LICENSE +21 -0
- package/README.md +195 -0
- package/dist/action.d.mts +37 -0
- package/dist/action.d.mts.map +1 -0
- package/dist/action.mjs +24 -0
- package/dist/action.mjs.map +1 -0
- package/dist/agent.d.mts +21 -0
- package/dist/agent.d.mts.map +1 -0
- package/dist/agent.mjs +66 -0
- package/dist/agent.mjs.map +1 -0
- package/dist/config.d.mts +10 -0
- package/dist/config.d.mts.map +1 -0
- package/dist/config.mjs +21 -0
- package/dist/config.mjs.map +1 -0
- package/dist/connector.d.mts +27 -0
- package/dist/connector.d.mts.map +1 -0
- package/dist/connector.mjs +32 -0
- package/dist/connector.mjs.map +1 -0
- package/dist/credential.d.mts +62 -0
- package/dist/credential.d.mts.map +1 -0
- package/dist/credential.mjs +62 -0
- package/dist/credential.mjs.map +1 -0
- package/dist/error.d.mts +17 -0
- package/dist/error.d.mts.map +1 -0
- package/dist/error.mjs +22 -0
- package/dist/error.mjs.map +1 -0
- package/dist/figma/index.d.mts +48 -0
- package/dist/figma/index.d.mts.map +1 -0
- package/dist/figma/index.mjs +97 -0
- package/dist/figma/index.mjs.map +1 -0
- package/dist/google/calendar.d.mts +53 -0
- package/dist/google/calendar.d.mts.map +1 -0
- package/dist/google/calendar.mjs +111 -0
- package/dist/google/calendar.mjs.map +1 -0
- package/dist/google/gmail.d.mts +53 -0
- package/dist/google/gmail.d.mts.map +1 -0
- package/dist/google/gmail.mjs +103 -0
- package/dist/google/gmail.mjs.map +1 -0
- package/dist/google/index.d.mts +14 -0
- package/dist/google/index.d.mts.map +1 -0
- package/dist/google/index.mjs +15 -0
- package/dist/google/index.mjs.map +1 -0
- package/dist/google/oauth.d.mts +18 -0
- package/dist/google/oauth.d.mts.map +1 -0
- package/dist/google/oauth.mjs +25 -0
- package/dist/google/oauth.mjs.map +1 -0
- package/dist/google/shared.d.mts +20 -0
- package/dist/google/shared.d.mts.map +1 -0
- package/dist/google/shared.mjs +36 -0
- package/dist/google/shared.mjs.map +1 -0
- package/dist/http.d.mts +32 -0
- package/dist/http.d.mts.map +1 -0
- package/dist/http.mjs +36 -0
- package/dist/http.mjs.map +1 -0
- package/dist/index.d.mts +9 -0
- package/dist/index.mjs +9 -0
- package/dist/integration.d.mts +24 -0
- package/dist/integration.d.mts.map +1 -0
- package/dist/integration.mjs +22 -0
- package/dist/integration.mjs.map +1 -0
- package/dist/linkedin-search/index.d.mts +60 -0
- package/dist/linkedin-search/index.d.mts.map +1 -0
- package/dist/linkedin-search/index.mjs +162 -0
- package/dist/linkedin-search/index.mjs.map +1 -0
- package/dist/notion/index.d.mts +69 -0
- package/dist/notion/index.d.mts.map +1 -0
- package/dist/notion/index.mjs +169 -0
- package/dist/notion/index.mjs.map +1 -0
- package/dist/r2-storage/index.d.mts +48 -0
- package/dist/r2-storage/index.d.mts.map +1 -0
- package/dist/r2-storage/index.mjs +91 -0
- package/dist/r2-storage/index.mjs.map +1 -0
- package/dist/result.d.mts +32 -0
- package/dist/result.d.mts.map +1 -0
- package/dist/result.mjs +23 -0
- package/dist/result.mjs.map +1 -0
- package/dist/telegram/index.d.mts +34 -0
- package/dist/telegram/index.d.mts.map +1 -0
- package/dist/telegram/index.mjs +109 -0
- package/dist/telegram/index.mjs.map +1 -0
- package/dist/todoist/index.d.mts +70 -0
- package/dist/todoist/index.d.mts.map +1 -0
- package/dist/todoist/index.mjs +176 -0
- package/dist/todoist/index.mjs.map +1 -0
- package/package.json +96 -0
- package/src/action.ts +75 -0
- package/src/agent.ts +120 -0
- package/src/config.ts +28 -0
- package/src/connector.ts +62 -0
- package/src/credential.ts +86 -0
- package/src/error.ts +20 -0
- package/src/figma/index.ts +121 -0
- package/src/google/calendar.ts +145 -0
- package/src/google/gmail.ts +127 -0
- package/src/google/index.ts +46 -0
- package/src/google/oauth.ts +26 -0
- package/src/google/shared.ts +56 -0
- package/src/http.ts +51 -0
- package/src/index.ts +36 -0
- package/src/integration.ts +28 -0
- package/src/linkedin-search/index.ts +217 -0
- package/src/notion/index.ts +234 -0
- package/src/r2-storage/index.ts +118 -0
- package/src/result.ts +35 -0
- package/src/telegram/index.ts +144 -0
- package/src/todoist/index.ts +227 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Yolk SDK contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# @yolk-sdk/connectors
|
|
2
|
+
|
|
3
|
+
Effect-native connector primitives for hosts that bring their own auth, storage, and policy.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @yolk-sdk/connectors@canary effect
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Canary APIs are unstable. Keep all `@yolk-sdk/*` packages on the same version.
|
|
12
|
+
|
|
13
|
+
## Subpaths
|
|
14
|
+
|
|
15
|
+
| Subpath | Purpose |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| `@yolk-sdk/connectors` | Core connector/action/integration/credential primitives |
|
|
18
|
+
| `@yolk-sdk/connectors/agent` | Adapter from connector actions to `@yolk-sdk/agent/tools` modules |
|
|
19
|
+
| `@yolk-sdk/connectors/figma` | Figma remote MCP auth action and OAuth constants |
|
|
20
|
+
| `@yolk-sdk/connectors/google` | Gmail/Calendar actions and Google OAuth slot constants |
|
|
21
|
+
| `@yolk-sdk/connectors/linkedin-search` | Exa people search and Enrich Layer profile/email actions |
|
|
22
|
+
| `@yolk-sdk/connectors/notion` | Notion search/page actions and API token slot constants |
|
|
23
|
+
| `@yolk-sdk/connectors/r2-storage` | Cloudflare R2 upload URL action with host-provided presigner |
|
|
24
|
+
| `@yolk-sdk/connectors/telegram` | Telegram bot send/validate actions |
|
|
25
|
+
| `@yolk-sdk/connectors/todoist` | Todoist task actions and API token slot constants |
|
|
26
|
+
|
|
27
|
+
## Imports
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { defineConnector, makeIntegration } from '@yolk-sdk/connectors'
|
|
31
|
+
import { makeConnectorToolModule } from '@yolk-sdk/connectors/agent'
|
|
32
|
+
import { GoogleConnector } from '@yolk-sdk/connectors/google'
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Model
|
|
36
|
+
|
|
37
|
+
- **Connector**: reusable provider logic.
|
|
38
|
+
- **Integration**: host-owned config that makes a connector invokable.
|
|
39
|
+
- **Action**: typed operation exposed by a connector.
|
|
40
|
+
- **CredentialSlot**: credential requirement declared by connector code.
|
|
41
|
+
- **CredentialBinding**: integration slot-to-host-credential-ref mapping.
|
|
42
|
+
- **CredentialResolver**: host Effect service that resolves refs at runtime.
|
|
43
|
+
- **ConnectorHttpClient**: host-provided HTTP port used by provider actions.
|
|
44
|
+
|
|
45
|
+
## HTTP port
|
|
46
|
+
|
|
47
|
+
`src/http.ts` is connector infrastructure, not a connector. It defines the typed HTTP request/response model, the `ConnectorHttpClient` Effect service, and JSON response decoding helpers.
|
|
48
|
+
|
|
49
|
+
Provider connectors build `ConnectorHttpRequest` values; hosts execute them by providing a `ConnectorHttpClient` layer. This keeps connector packages portable and avoids bundling `fetch`, Node HTTP clients, or app-specific networking policy.
|
|
50
|
+
|
|
51
|
+
Host adapters must preserve connector headers and body content type. Several provider actions send JSON and rely on `content-type: application/json` reaching the upstream API unchanged.
|
|
52
|
+
|
|
53
|
+
## Example
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import { Effect, Layer, Schema } from 'effect'
|
|
57
|
+
import {
|
|
58
|
+
ActionResult,
|
|
59
|
+
ApiKeyCredential,
|
|
60
|
+
CredentialResolver,
|
|
61
|
+
CredentialSlot,
|
|
62
|
+
defineAction,
|
|
63
|
+
defineConnector,
|
|
64
|
+
makeCredentialBinding,
|
|
65
|
+
makeIntegration,
|
|
66
|
+
resolveCredential
|
|
67
|
+
} from '@yolk-sdk/connectors'
|
|
68
|
+
|
|
69
|
+
const ApiToken = CredentialSlot.make({
|
|
70
|
+
id: 'todoist.api_token',
|
|
71
|
+
kind: 'api_key'
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
const ListTasksInput = Schema.Struct({ projectId: Schema.optional(Schema.String) })
|
|
75
|
+
const ListTasksOutput = Schema.Struct({ tasks: Schema.Array(Schema.String) })
|
|
76
|
+
|
|
77
|
+
const listTasks = defineAction({
|
|
78
|
+
id: 'todoist.list_tasks',
|
|
79
|
+
description: 'List Todoist tasks',
|
|
80
|
+
inputSchema: ListTasksInput,
|
|
81
|
+
outputSchema: ListTasksOutput,
|
|
82
|
+
execute: input =>
|
|
83
|
+
Effect.gen(function* () {
|
|
84
|
+
const credential = yield* resolveCredential(input.integration, ApiToken)
|
|
85
|
+
|
|
86
|
+
if (credential._tag !== 'ApiKeyCredential') {
|
|
87
|
+
return ActionResult.failure({ code: 'invalid_credential', message: 'Expected API key' })
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return ActionResult.success({ tasks: [] })
|
|
91
|
+
})
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
const Todoist = defineConnector({
|
|
95
|
+
id: 'todoist',
|
|
96
|
+
actions: [listTasks]
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
const integration = makeIntegration({
|
|
100
|
+
connectorId: 'todoist',
|
|
101
|
+
credentialBindings: [
|
|
102
|
+
makeCredentialBinding({ slotId: ApiToken.id, credentialRef: 'host-credential-id' })
|
|
103
|
+
]
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
const CredentialResolverLive = Layer.succeed(
|
|
107
|
+
CredentialResolver,
|
|
108
|
+
CredentialResolver.of({
|
|
109
|
+
resolve: () =>
|
|
110
|
+
Effect.succeed(
|
|
111
|
+
ApiKeyCredential.make({
|
|
112
|
+
_tag: 'ApiKeyCredential',
|
|
113
|
+
key: 'runtime-secret-from-host'
|
|
114
|
+
})
|
|
115
|
+
)
|
|
116
|
+
})
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
const program = Todoist.invoke({
|
|
120
|
+
integration,
|
|
121
|
+
action: 'todoist.list_tasks',
|
|
122
|
+
input: {}
|
|
123
|
+
}).pipe(Effect.provide(CredentialResolverLive))
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Google connector
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import { Effect } from 'effect'
|
|
130
|
+
import {
|
|
131
|
+
makeCredentialBinding,
|
|
132
|
+
makeIntegration
|
|
133
|
+
} from '@yolk-sdk/connectors'
|
|
134
|
+
import { GoogleConnector, GoogleOAuthCredentialSlot } from '@yolk-sdk/connectors/google'
|
|
135
|
+
|
|
136
|
+
const integration = makeIntegration({
|
|
137
|
+
connectorId: 'google',
|
|
138
|
+
credentialBindings: [
|
|
139
|
+
makeCredentialBinding({
|
|
140
|
+
slotId: GoogleOAuthCredentialSlot.id,
|
|
141
|
+
credentialRef: 'google-oauth-credential'
|
|
142
|
+
})
|
|
143
|
+
]
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
const result = GoogleConnector.invoke({
|
|
147
|
+
integration,
|
|
148
|
+
action: 'gmail.search',
|
|
149
|
+
input: { query: 'from:alice@example.com', maxResults: 10 }
|
|
150
|
+
})
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Provide `CredentialResolver` and `ConnectorHttpClient` layers from host code. Hosts own OAuth refresh before returning `OAuthCredential`. If using Effect HTTP, adapt `effect/unstable/http` in host code rather than importing a Yolk wrapper. Preserve connector request headers and body content type when adapting HTTP; provider connectors may rely on `content-type: application/json` for request parsing.
|
|
154
|
+
|
|
155
|
+
## Provider actions
|
|
156
|
+
|
|
157
|
+
| Subpath | Actions |
|
|
158
|
+
| --- | --- |
|
|
159
|
+
| `@yolk-sdk/connectors/figma` | `figma.mcp_auth` |
|
|
160
|
+
| `@yolk-sdk/connectors/google` | `gmail.search`, `gmail.get_message`, `calendar.list_events`, `calendar.create_event` |
|
|
161
|
+
| `@yolk-sdk/connectors/linkedin-search` | `linkedin_search.search`, `linkedin_search.profile`, `linkedin_search.email` |
|
|
162
|
+
| `@yolk-sdk/connectors/notion` | `notion.search`, `notion.get_page`, `notion.create_page` |
|
|
163
|
+
| `@yolk-sdk/connectors/r2-storage` | `r2_storage.upload_url` |
|
|
164
|
+
| `@yolk-sdk/connectors/telegram` | `telegram.send_message`, `telegram.validate` |
|
|
165
|
+
| `@yolk-sdk/connectors/todoist` | `todoist.list_tasks`, `todoist.create_task`, `todoist.close_task` |
|
|
166
|
+
|
|
167
|
+
R2 presigning is host-provided through `R2Presigner`; no AWS SDK dependency is bundled.
|
|
168
|
+
|
|
169
|
+
## Agent adapter
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
import { makeConnectorToolModule } from '@yolk-sdk/connectors/agent'
|
|
173
|
+
import { GoogleConnector } from '@yolk-sdk/connectors/google'
|
|
174
|
+
|
|
175
|
+
const toolModule = makeConnectorToolModule(GoogleConnector, {
|
|
176
|
+
integration,
|
|
177
|
+
layer: HostConnectorLayer,
|
|
178
|
+
access: action => action.includes('create') ? 'write' : 'read'
|
|
179
|
+
})
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
`HostConnectorLayer` should provide `CredentialResolver`, `ConnectorHttpClient`, and any other connector dependencies.
|
|
183
|
+
|
|
184
|
+
## Host responsibilities
|
|
185
|
+
|
|
186
|
+
- Store, encrypt, refresh, revoke, and audit credentials.
|
|
187
|
+
- Own OAuth routes, callbacks, state, and token persistence.
|
|
188
|
+
- Map integrations to users, workspaces, agents, or projects outside this package.
|
|
189
|
+
- Authorize action execution before invoking connectors.
|
|
190
|
+
|
|
191
|
+
## Boundaries
|
|
192
|
+
|
|
193
|
+
- No DB, framework, UI, app auth, or product lifecycle code.
|
|
194
|
+
- No Promise facade; use Effect directly.
|
|
195
|
+
- Integrations contain credential refs only, never raw secrets.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ConnectorError } from "./error.mjs";
|
|
2
|
+
import { ActionResult } from "./result.mjs";
|
|
3
|
+
import { ConnectorIntegration } from "./integration.mjs";
|
|
4
|
+
import { Effect } from "effect";
|
|
5
|
+
import * as Schema from "effect/Schema";
|
|
6
|
+
|
|
7
|
+
//#region src/action.d.ts
|
|
8
|
+
type ActionInputSchema = Schema.Schema<unknown> & {
|
|
9
|
+
readonly DecodingServices: never;
|
|
10
|
+
};
|
|
11
|
+
type ActionOutputSchema = Schema.Schema<unknown>;
|
|
12
|
+
type ActionExecutionInput<Input> = {
|
|
13
|
+
readonly integration: ConnectorIntegration;
|
|
14
|
+
readonly input: Input;
|
|
15
|
+
};
|
|
16
|
+
type UnknownActionExecutionInput = {
|
|
17
|
+
readonly integration: ConnectorIntegration;
|
|
18
|
+
readonly input: unknown;
|
|
19
|
+
};
|
|
20
|
+
type ConnectorAction<Env = never, Error = never> = {
|
|
21
|
+
readonly id: string;
|
|
22
|
+
readonly description?: string;
|
|
23
|
+
readonly inputSchema: ActionInputSchema;
|
|
24
|
+
readonly outputSchema: ActionOutputSchema;
|
|
25
|
+
readonly execute: (input: UnknownActionExecutionInput) => Effect.Effect<ActionResult<unknown>, Error | ConnectorError, Env>;
|
|
26
|
+
};
|
|
27
|
+
type DefineActionOptions<InputSchema extends ActionInputSchema, Output, Env, Error> = {
|
|
28
|
+
readonly id: string;
|
|
29
|
+
readonly description?: string;
|
|
30
|
+
readonly inputSchema: InputSchema;
|
|
31
|
+
readonly outputSchema: Schema.Schema<Output>;
|
|
32
|
+
readonly execute: (input: ActionExecutionInput<InputSchema['Type']>) => Effect.Effect<ActionResult<Output>, Error | ConnectorError, Env>;
|
|
33
|
+
};
|
|
34
|
+
declare const defineAction: <InputSchema extends ActionInputSchema, Output, Env = never, Error = never>(options: DefineActionOptions<InputSchema, Output, Env, Error>) => ConnectorAction<Env, Error>;
|
|
35
|
+
//#endregion
|
|
36
|
+
export { ActionExecutionInput, ConnectorAction, DefineActionOptions, UnknownActionExecutionInput, defineAction };
|
|
37
|
+
//# sourceMappingURL=action.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action.d.mts","names":[],"sources":["../src/action.ts"],"mappings":";;;;;;;KAMK,iBAAA,GAAoB,MAAA,CAAO,MAAM;EAAA,SAAuB,gBAAA;AAAA;AAAA,KACxD,kBAAA,GAAqB,MAAA,CAAO,MAAM;AAAA,KAE3B,oBAAA;EAAA,SACD,WAAA,EAAa,oBAAA;EAAA,SACb,KAAA,EAAO,KAAK;AAAA;AAAA,KAGX,2BAAA;EAAA,SACD,WAAA,EAAa,oBAAoB;EAAA,SACjC,KAAA;AAAA;AAAA,KAGC,eAAA;EAAA,SACD,EAAA;EAAA,SACA,WAAA;EAAA,SACA,WAAA,EAAa,iBAAA;EAAA,SACb,YAAA,EAAc,kBAAA;EAAA,SACd,OAAA,GACP,KAAA,EAAO,2BAAA,KACJ,MAAA,CAAO,MAAA,CAAO,YAAA,WAAuB,KAAA,GAAQ,cAAA,EAAgB,GAAA;AAAA;AAAA,KAGxD,mBAAA,qBACU,iBAAA;EAAA,SAKX,EAAA;EAAA,SACA,WAAA;EAAA,SACA,WAAA,EAAa,WAAA;EAAA,SACb,YAAA,EAAc,MAAA,CAAO,MAAA,CAAO,MAAA;EAAA,SAC5B,OAAA,GACP,KAAA,EAAO,oBAAA,CAAqB,WAAA,cACzB,MAAA,CAAO,MAAA,CAAO,YAAA,CAAa,MAAA,GAAS,KAAA,GAAQ,cAAA,EAAgB,GAAA;AAAA;AAAA,cAWtD,YAAA,uBACS,iBAAA,sCAKpB,OAAA,EAAS,mBAAA,CAAoB,WAAA,EAAa,MAAA,EAAQ,GAAA,EAAK,KAAA,MACtD,eAAA,CAAgB,GAAA,EAAK,KAAA"}
|
package/dist/action.mjs
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ConnectorError } from "./error.mjs";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
import * as Schema from "effect/Schema";
|
|
4
|
+
//#region src/action.ts
|
|
5
|
+
const validationError = (actionId, error) => new ConnectorError({
|
|
6
|
+
cause: "validation_failed",
|
|
7
|
+
message: `Invalid input for action: ${actionId}`,
|
|
8
|
+
actionId,
|
|
9
|
+
underlying: error
|
|
10
|
+
});
|
|
11
|
+
const defineAction = (options) => ({
|
|
12
|
+
id: options.id,
|
|
13
|
+
description: options.description,
|
|
14
|
+
inputSchema: options.inputSchema,
|
|
15
|
+
outputSchema: options.outputSchema,
|
|
16
|
+
execute: (input) => Schema.decodeUnknownEffect(options.inputSchema)(input.input).pipe(Effect.mapError((error) => validationError(options.id, error)), Effect.flatMap((params) => options.execute({
|
|
17
|
+
integration: input.integration,
|
|
18
|
+
input: params
|
|
19
|
+
})))
|
|
20
|
+
});
|
|
21
|
+
//#endregion
|
|
22
|
+
export { defineAction };
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=action.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action.mjs","names":[],"sources":["../src/action.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { ConnectorError } from './error.ts'\nimport type { ActionResult } from './result.ts'\nimport type { ConnectorIntegration } from './integration.ts'\n\ntype ActionInputSchema = Schema.Schema<unknown> & { readonly DecodingServices: never }\ntype ActionOutputSchema = Schema.Schema<unknown>\n\nexport type ActionExecutionInput<Input> = {\n readonly integration: ConnectorIntegration\n readonly input: Input\n}\n\nexport type UnknownActionExecutionInput = {\n readonly integration: ConnectorIntegration\n readonly input: unknown\n}\n\nexport type ConnectorAction<Env = never, Error = never> = {\n readonly id: string\n readonly description?: string\n readonly inputSchema: ActionInputSchema\n readonly outputSchema: ActionOutputSchema\n readonly execute: (\n input: UnknownActionExecutionInput\n ) => Effect.Effect<ActionResult<unknown>, Error | ConnectorError, Env>\n}\n\nexport type DefineActionOptions<\n InputSchema extends ActionInputSchema,\n Output,\n Env,\n Error\n> = {\n readonly id: string\n readonly description?: string\n readonly inputSchema: InputSchema\n readonly outputSchema: Schema.Schema<Output>\n readonly execute: (\n input: ActionExecutionInput<InputSchema['Type']>\n ) => Effect.Effect<ActionResult<Output>, Error | ConnectorError, Env>\n}\n\nconst validationError = (actionId: string, error: unknown) =>\n new ConnectorError({\n cause: 'validation_failed',\n message: `Invalid input for action: ${actionId}`,\n actionId,\n underlying: error\n })\n\nexport const defineAction = <\n InputSchema extends ActionInputSchema,\n Output,\n Env = never,\n Error = never\n>(\n options: DefineActionOptions<InputSchema, Output, Env, Error>\n): ConnectorAction<Env, Error> => ({\n id: options.id,\n description: options.description,\n inputSchema: options.inputSchema,\n outputSchema: options.outputSchema,\n execute: input =>\n Schema.decodeUnknownEffect(options.inputSchema)(input.input).pipe(\n Effect.mapError(error => validationError(options.id, error)),\n Effect.flatMap(params =>\n options.execute({\n integration: input.integration,\n input: params\n })\n )\n )\n})\n"],"mappings":";;;;AA4CA,MAAM,mBAAmB,UAAkB,UACzC,IAAI,eAAe;CACjB,OAAO;CACP,SAAS,6BAA6B;CACtC;CACA,YAAY;AACd,CAAC;AAEH,MAAa,gBAMX,aACiC;CACjC,IAAI,QAAQ;CACZ,aAAa,QAAQ;CACrB,aAAa,QAAQ;CACrB,cAAc,QAAQ;CACtB,UAAS,UACP,OAAO,oBAAoB,QAAQ,WAAW,EAAE,MAAM,KAAK,EAAE,KAC3D,OAAO,UAAS,UAAS,gBAAgB,QAAQ,IAAI,KAAK,CAAC,GAC3D,OAAO,SAAQ,WACb,QAAQ,QAAQ;EACd,aAAa,MAAM;EACnB,OAAO;CACT,CAAC,CACH,CACF;AACJ"}
|
package/dist/agent.d.mts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ConnectorIntegration } from "./integration.mjs";
|
|
2
|
+
import { Connector } from "./connector.mjs";
|
|
3
|
+
import { Effect, Layer } from "effect";
|
|
4
|
+
import { ToolError } from "@yolk-sdk/agent/loop";
|
|
5
|
+
import { ToolAccess, ToolModule, ToolRegistration } from "@yolk-sdk/agent/tools";
|
|
6
|
+
|
|
7
|
+
//#region src/agent.d.ts
|
|
8
|
+
type ConnectorIntegrationResolver<Context> = ConnectorIntegration | ((context: Context) => Effect.Effect<ConnectorIntegration, ToolError>);
|
|
9
|
+
type ConnectorToolAccessResolver = ToolAccess | ((actionId: string) => ToolAccess);
|
|
10
|
+
type MakeConnectorToolModuleOptions<Context, Env> = {
|
|
11
|
+
readonly integration: ConnectorIntegrationResolver<Context>;
|
|
12
|
+
readonly layer: Layer.Layer<Env>;
|
|
13
|
+
readonly moduleId?: string;
|
|
14
|
+
readonly namePrefix?: string;
|
|
15
|
+
readonly access?: ConnectorToolAccessResolver;
|
|
16
|
+
};
|
|
17
|
+
declare const makeConnectorToolRegistration: <Context, Env = never, Error = never>(connector: Connector<Env, Error>, actionId: string, options: MakeConnectorToolModuleOptions<Context, Env>) => ToolRegistration<Context>;
|
|
18
|
+
declare const makeConnectorToolModule: <Context, Env = never, Error = never>(connector: Connector<Env, Error>, options: MakeConnectorToolModuleOptions<Context, Env>) => ToolModule<Context>;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { ConnectorIntegrationResolver, ConnectorToolAccessResolver, MakeConnectorToolModuleOptions, makeConnectorToolModule, makeConnectorToolRegistration };
|
|
21
|
+
//# sourceMappingURL=agent.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.mts","names":[],"sources":["../src/agent.ts"],"mappings":";;;;;;;KAUY,4BAAA,YACR,oBAAA,KACE,OAAA,EAAS,OAAA,KAAY,MAAA,CAAO,MAAA,CAAO,oBAAA,EAAsB,SAAA;AAAA,KAEnD,2BAAA,GAA8B,UAAA,KAAe,QAAA,aAAqB,UAAU;AAAA,KAE5E,8BAAA;EAAA,SACD,WAAA,EAAa,4BAAA,CAA6B,OAAA;EAAA,SAC1C,KAAA,EAAO,KAAA,CAAM,KAAA,CAAM,GAAA;EAAA,SACnB,QAAA;EAAA,SACA,UAAA;EAAA,SACA,MAAA,GAAS,2BAAA;AAAA;AAAA,cAwCP,6BAAA,wCACX,SAAA,EAAW,SAAA,CAAU,GAAA,EAAK,KAAA,GAC1B,QAAA,UACA,OAAA,EAAS,8BAAA,CAA+B,OAAA,EAAS,GAAA,MAChD,gBAAA,CAAiB,OAAA;AAAA,cAgDP,uBAAA,wCACX,SAAA,EAAW,SAAA,CAAU,GAAA,EAAK,KAAA,GAC1B,OAAA,EAAS,8BAAA,CAA+B,OAAA,EAAS,GAAA,MAChD,UAAA,CAAW,OAAA"}
|
package/dist/agent.mjs
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import { ToolError } from "@yolk-sdk/agent/loop";
|
|
4
|
+
import { makeTool } from "@yolk-sdk/agent/tools";
|
|
5
|
+
import { ToolResult } from "@yolk-sdk/agent/protocol";
|
|
6
|
+
//#region src/agent.ts
|
|
7
|
+
const resolveIntegration = (resolver, context) => {
|
|
8
|
+
if (typeof resolver === "function") return resolver(context);
|
|
9
|
+
return Effect.succeed(resolver);
|
|
10
|
+
};
|
|
11
|
+
const resolveAccess = (resolver, actionId) => {
|
|
12
|
+
if (typeof resolver === "function") return resolver(actionId);
|
|
13
|
+
return resolver ?? "read";
|
|
14
|
+
};
|
|
15
|
+
const unknownToMessage = (error) => {
|
|
16
|
+
if (error instanceof Error) return error.message;
|
|
17
|
+
return String(error);
|
|
18
|
+
};
|
|
19
|
+
const failureContent = (failure) => `${failure.code}: ${failure.message}`;
|
|
20
|
+
const successContent = (value) => {
|
|
21
|
+
if (typeof value === "string") return value;
|
|
22
|
+
return JSON.stringify(value);
|
|
23
|
+
};
|
|
24
|
+
const toolName = (prefix, actionId) => prefix === void 0 ? actionId : `${prefix}.${actionId}`;
|
|
25
|
+
const makeConnectorToolRegistration = (connector, actionId, options) => {
|
|
26
|
+
const action = connector.actions.find((item) => item.id === actionId);
|
|
27
|
+
const name = toolName(options.namePrefix, actionId);
|
|
28
|
+
return makeTool({
|
|
29
|
+
name,
|
|
30
|
+
description: action?.description ?? `Invoke connector action ${actionId}.`,
|
|
31
|
+
parameters: action?.inputSchema ?? Schema.Unknown,
|
|
32
|
+
access: resolveAccess(options.access, actionId),
|
|
33
|
+
invalidParamsMessage: (error) => `Invalid ${name} arguments: ${unknownToMessage(error)}`,
|
|
34
|
+
execute: ({ call, context, params }) => resolveIntegration(options.integration, context).pipe(Effect.flatMap((integration) => connector.invoke({
|
|
35
|
+
integration,
|
|
36
|
+
action: actionId,
|
|
37
|
+
input: params
|
|
38
|
+
}).pipe(Effect.provide(options.layer))), Effect.map((result) => {
|
|
39
|
+
switch (result._tag) {
|
|
40
|
+
case "Success": return ToolResult.make({
|
|
41
|
+
toolCallId: call.id,
|
|
42
|
+
content: successContent(result.value),
|
|
43
|
+
structuredContent: result.value
|
|
44
|
+
});
|
|
45
|
+
case "Failure": return ToolResult.make({
|
|
46
|
+
toolCallId: call.id,
|
|
47
|
+
content: failureContent(result.error),
|
|
48
|
+
isError: true,
|
|
49
|
+
structuredContent: result.error
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}), Effect.mapError((error) => new ToolError({
|
|
53
|
+
tool: name,
|
|
54
|
+
message: unknownToMessage(error),
|
|
55
|
+
cause: "execution"
|
|
56
|
+
})))
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
const makeConnectorToolModule = (connector, options) => ({
|
|
60
|
+
id: options.moduleId ?? connector.id,
|
|
61
|
+
tools: connector.actions.map((action) => makeConnectorToolRegistration(connector, action.id, options))
|
|
62
|
+
});
|
|
63
|
+
//#endregion
|
|
64
|
+
export { makeConnectorToolModule, makeConnectorToolRegistration };
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=agent.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.mjs","names":[],"sources":["../src/agent.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport type { Layer } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { ToolError } from '@yolk-sdk/agent/loop'\nimport { makeTool, type ToolAccess, type ToolModule, type ToolRegistration } from '@yolk-sdk/agent/tools'\nimport { ToolResult } from '@yolk-sdk/agent/protocol'\nimport type { Connector } from './connector.ts'\nimport type { ConnectorIntegration } from './integration.ts'\nimport type { ProviderFailure } from './result.ts'\n\nexport type ConnectorIntegrationResolver<Context> =\n | ConnectorIntegration\n | ((context: Context) => Effect.Effect<ConnectorIntegration, ToolError>)\n\nexport type ConnectorToolAccessResolver = ToolAccess | ((actionId: string) => ToolAccess)\n\nexport type MakeConnectorToolModuleOptions<Context, Env> = {\n readonly integration: ConnectorIntegrationResolver<Context>\n readonly layer: Layer.Layer<Env>\n readonly moduleId?: string\n readonly namePrefix?: string\n readonly access?: ConnectorToolAccessResolver\n}\n\nconst resolveIntegration = <Context>(resolver: ConnectorIntegrationResolver<Context>, context: Context) => {\n if (typeof resolver === 'function') {\n return resolver(context)\n }\n\n return Effect.succeed(resolver)\n}\n\nconst resolveAccess = (resolver: ConnectorToolAccessResolver | undefined, actionId: string): ToolAccess => {\n if (typeof resolver === 'function') {\n return resolver(actionId)\n }\n\n return resolver ?? 'read'\n}\n\nconst unknownToMessage = (error: unknown) => {\n if (error instanceof Error) {\n return error.message\n }\n\n return String(error)\n}\n\nconst failureContent = (failure: ProviderFailure) => `${failure.code}: ${failure.message}`\n\nconst successContent = (value: unknown) => {\n if (typeof value === 'string') {\n return value\n }\n\n return JSON.stringify(value)\n}\n\nconst toolName = (prefix: string | undefined, actionId: string) =>\n prefix === undefined ? actionId : `${prefix}.${actionId}`\n\nexport const makeConnectorToolRegistration = <Context, Env = never, Error = never>(\n connector: Connector<Env, Error>,\n actionId: string,\n options: MakeConnectorToolModuleOptions<Context, Env>\n): ToolRegistration<Context> => {\n const action = connector.actions.find(item => item.id === actionId)\n const name = toolName(options.namePrefix, actionId)\n\n return makeTool({\n name,\n description: action?.description ?? `Invoke connector action ${actionId}.`,\n parameters: action?.inputSchema ?? Schema.Unknown,\n access: resolveAccess(options.access, actionId),\n invalidParamsMessage: error => `Invalid ${name} arguments: ${unknownToMessage(error)}`,\n execute: ({ call, context, params }) =>\n resolveIntegration(options.integration, context).pipe(\n Effect.flatMap(integration =>\n connector.invoke({\n integration,\n action: actionId,\n input: params\n }).pipe(Effect.provide(options.layer))\n ),\n Effect.map(result => {\n switch (result._tag) {\n case 'Success':\n return ToolResult.make({\n toolCallId: call.id,\n content: successContent(result.value),\n structuredContent: result.value\n })\n case 'Failure':\n return ToolResult.make({\n toolCallId: call.id,\n content: failureContent(result.error),\n isError: true,\n structuredContent: result.error\n })\n }\n }),\n Effect.mapError(\n error =>\n new ToolError({\n tool: name,\n message: unknownToMessage(error),\n cause: 'execution'\n })\n )\n )\n })\n}\n\nexport const makeConnectorToolModule = <Context, Env = never, Error = never>(\n connector: Connector<Env, Error>,\n options: MakeConnectorToolModuleOptions<Context, Env>\n): ToolModule<Context> => ({\n id: options.moduleId ?? connector.id,\n tools: connector.actions.map(action => makeConnectorToolRegistration(connector, action.id, options))\n})\n"],"mappings":";;;;;;AAwBA,MAAM,sBAA+B,UAAiD,YAAqB;CACzG,IAAI,OAAO,aAAa,YACtB,OAAO,SAAS,OAAO;CAGzB,OAAO,OAAO,QAAQ,QAAQ;AAChC;AAEA,MAAM,iBAAiB,UAAmD,aAAiC;CACzG,IAAI,OAAO,aAAa,YACtB,OAAO,SAAS,QAAQ;CAG1B,OAAO,YAAY;AACrB;AAEA,MAAM,oBAAoB,UAAmB;CAC3C,IAAI,iBAAiB,OACnB,OAAO,MAAM;CAGf,OAAO,OAAO,KAAK;AACrB;AAEA,MAAM,kBAAkB,YAA6B,GAAG,QAAQ,KAAK,IAAI,QAAQ;AAEjF,MAAM,kBAAkB,UAAmB;CACzC,IAAI,OAAO,UAAU,UACnB,OAAO;CAGT,OAAO,KAAK,UAAU,KAAK;AAC7B;AAEA,MAAM,YAAY,QAA4B,aAC5C,WAAW,KAAA,IAAY,WAAW,GAAG,OAAO,GAAG;AAEjD,MAAa,iCACX,WACA,UACA,YAC8B;CAC9B,MAAM,SAAS,UAAU,QAAQ,MAAK,SAAQ,KAAK,OAAO,QAAQ;CAClE,MAAM,OAAO,SAAS,QAAQ,YAAY,QAAQ;CAElD,OAAO,SAAS;EACd;EACA,aAAa,QAAQ,eAAe,2BAA2B,SAAS;EACxE,YAAY,QAAQ,eAAe,OAAO;EAC1C,QAAQ,cAAc,QAAQ,QAAQ,QAAQ;EAC9C,uBAAsB,UAAS,WAAW,KAAK,cAAc,iBAAiB,KAAK;EACnF,UAAU,EAAE,MAAM,SAAS,aACzB,mBAAmB,QAAQ,aAAa,OAAO,EAAE,KAC/C,OAAO,SAAQ,gBACb,UAAU,OAAO;GACf;GACA,QAAQ;GACR,OAAO;EACT,CAAC,EAAE,KAAK,OAAO,QAAQ,QAAQ,KAAK,CAAC,CACvC,GACA,OAAO,KAAI,WAAU;GACnB,QAAQ,OAAO,MAAf;IACE,KAAK,WACH,OAAO,WAAW,KAAK;KACrB,YAAY,KAAK;KACjB,SAAS,eAAe,OAAO,KAAK;KACpC,mBAAmB,OAAO;IAC5B,CAAC;IACH,KAAK,WACH,OAAO,WAAW,KAAK;KACrB,YAAY,KAAK;KACjB,SAAS,eAAe,OAAO,KAAK;KACpC,SAAS;KACT,mBAAmB,OAAO;IAC5B,CAAC;GACL;EACF,CAAC,GACD,OAAO,UACL,UACE,IAAI,UAAU;GACZ,MAAM;GACN,SAAS,iBAAiB,KAAK;GAC/B,OAAO;EACT,CAAC,CACL,CACF;CACJ,CAAC;AACH;AAEA,MAAa,2BACX,WACA,aACyB;CACzB,IAAI,QAAQ,YAAY,UAAU;CAClC,OAAO,UAAU,QAAQ,KAAI,WAAU,8BAA8B,WAAW,OAAO,IAAI,OAAO,CAAC;AACrG"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ConnectorError } from "./error.mjs";
|
|
2
|
+
import { ConnectorIntegration } from "./integration.mjs";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/config.d.ts
|
|
6
|
+
declare const requiredStringConfig: (integration: ConnectorIntegration, key: string) => Effect.Effect<string, never, never> | Effect.Effect<never, ConnectorError, never>;
|
|
7
|
+
declare const optionalStringConfig: (integration: ConnectorIntegration, key: string) => string | undefined;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { optionalStringConfig, requiredStringConfig };
|
|
10
|
+
//# sourceMappingURL=config.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.mts","names":[],"sources":["../src/config.ts"],"mappings":";;;;;cAOa,oBAAA,GAAwB,WAAA,EAAa,oBAAA,EAAsB,GAAA,aAAW,MAAA,CAAA,MAAA,yBAAA,MAAA,CAAA,MAAA,QAAA,cAAA;AAAA,cAgBtE,oBAAA,GAAwB,WAAA,EAAa,oBAAoB,EAAE,GAAA"}
|
package/dist/config.mjs
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ConnectorError } from "./error.mjs";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
//#region src/config.ts
|
|
4
|
+
const configValue = (integration, key) => Object.getOwnPropertyDescriptor(integration.config, key)?.value;
|
|
5
|
+
const requiredStringConfig = (integration, key) => {
|
|
6
|
+
const value = configValue(integration, key);
|
|
7
|
+
if (typeof value === "string" && value.trim() !== "") return Effect.succeed(value);
|
|
8
|
+
return Effect.fail(new ConnectorError({
|
|
9
|
+
cause: "validation_failed",
|
|
10
|
+
message: `Missing integration config: ${key}`,
|
|
11
|
+
connectorId: integration.connectorId
|
|
12
|
+
}));
|
|
13
|
+
};
|
|
14
|
+
const optionalStringConfig = (integration, key) => {
|
|
15
|
+
const value = configValue(integration, key);
|
|
16
|
+
return typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
17
|
+
};
|
|
18
|
+
//#endregion
|
|
19
|
+
export { optionalStringConfig, requiredStringConfig };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=config.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.mjs","names":[],"sources":["../src/config.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport { ConnectorError } from './error.ts'\nimport type { ConnectorIntegration } from './integration.ts'\n\nconst configValue = (integration: ConnectorIntegration, key: string) =>\n Object.getOwnPropertyDescriptor(integration.config, key)?.value\n\nexport const requiredStringConfig = (integration: ConnectorIntegration, key: string) => {\n const value = configValue(integration, key)\n\n if (typeof value === 'string' && value.trim() !== '') {\n return Effect.succeed(value)\n }\n\n return Effect.fail(\n new ConnectorError({\n cause: 'validation_failed',\n message: `Missing integration config: ${key}`,\n connectorId: integration.connectorId\n })\n )\n}\n\nexport const optionalStringConfig = (integration: ConnectorIntegration, key: string) => {\n const value = configValue(integration, key)\n\n return typeof value === 'string' && value.trim() !== '' ? value : undefined\n}\n"],"mappings":";;;AAIA,MAAM,eAAe,aAAmC,QACtD,OAAO,yBAAyB,YAAY,QAAQ,GAAG,GAAG;AAE5D,MAAa,wBAAwB,aAAmC,QAAgB;CACtF,MAAM,QAAQ,YAAY,aAAa,GAAG;CAE1C,IAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAChD,OAAO,OAAO,QAAQ,KAAK;CAG7B,OAAO,OAAO,KACZ,IAAI,eAAe;EACjB,OAAO;EACP,SAAS,+BAA+B;EACxC,aAAa,YAAY;CAC3B,CAAC,CACH;AACF;AAEA,MAAa,wBAAwB,aAAmC,QAAgB;CACtF,MAAM,QAAQ,YAAY,aAAa,GAAG;CAE1C,OAAO,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,KAAK,QAAQ,KAAA;AACpE"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ConnectorError } from "./error.mjs";
|
|
2
|
+
import { ActionResult } from "./result.mjs";
|
|
3
|
+
import { ConnectorIntegration } from "./integration.mjs";
|
|
4
|
+
import { ConnectorAction } from "./action.mjs";
|
|
5
|
+
import { Effect } from "effect";
|
|
6
|
+
|
|
7
|
+
//#region src/connector.d.ts
|
|
8
|
+
type ConnectorInvokeInput = {
|
|
9
|
+
readonly integration: ConnectorIntegration;
|
|
10
|
+
readonly action: string;
|
|
11
|
+
readonly input: unknown;
|
|
12
|
+
};
|
|
13
|
+
type Connector<Env = never, Error = never> = {
|
|
14
|
+
readonly id: string;
|
|
15
|
+
readonly description?: string;
|
|
16
|
+
readonly actions: ReadonlyArray<ConnectorAction<Env, Error>>;
|
|
17
|
+
readonly invoke: (input: ConnectorInvokeInput) => Effect.Effect<ActionResult<unknown>, Error | ConnectorError, Env>;
|
|
18
|
+
};
|
|
19
|
+
type DefineConnectorOptions<Env, Error> = {
|
|
20
|
+
readonly id: string;
|
|
21
|
+
readonly description?: string;
|
|
22
|
+
readonly actions: ReadonlyArray<ConnectorAction<Env, Error>>;
|
|
23
|
+
};
|
|
24
|
+
declare const defineConnector: <Env = never, Error = never>(options: DefineConnectorOptions<Env, Error>) => Connector<Env, Error>;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { Connector, ConnectorInvokeInput, DefineConnectorOptions, defineConnector };
|
|
27
|
+
//# sourceMappingURL=connector.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector.d.mts","names":[],"sources":["../src/connector.ts"],"mappings":";;;;;;;KAMY,oBAAA;EAAA,SACD,WAAA,EAAa,oBAAoB;EAAA,SACjC,MAAA;EAAA,SACA,KAAA;AAAA;AAAA,KAGC,SAAA;EAAA,SACD,EAAA;EAAA,SACA,WAAA;EAAA,SACA,OAAA,EAAS,aAAA,CAAc,eAAA,CAAgB,GAAA,EAAK,KAAA;EAAA,SAC5C,MAAA,GACP,KAAA,EAAO,oBAAA,KACJ,MAAA,CAAO,MAAA,CAAO,YAAA,WAAuB,KAAA,GAAQ,cAAA,EAAgB,GAAA;AAAA;AAAA,KAGxD,sBAAA;EAAA,SACD,EAAA;EAAA,SACA,WAAA;EAAA,SACA,OAAA,EAAS,aAAA,CAAc,eAAA,CAAgB,GAAA,EAAK,KAAA;AAAA;AAAA,cAkB1C,eAAA,+BACX,OAAA,EAAS,sBAAA,CAAuB,GAAA,EAAK,KAAA,MACpC,SAAA,CAAU,GAAA,EAAK,KAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ConnectorError } from "./error.mjs";
|
|
2
|
+
import { Effect, Option } from "effect";
|
|
3
|
+
//#region src/connector.ts
|
|
4
|
+
const connectorMismatchError = (connectorId, integration) => new ConnectorError({
|
|
5
|
+
cause: "connector_mismatch",
|
|
6
|
+
message: `Integration belongs to ${integration.connectorId}, not ${connectorId}`,
|
|
7
|
+
connectorId
|
|
8
|
+
});
|
|
9
|
+
const missingActionError = (connectorId, actionId) => new ConnectorError({
|
|
10
|
+
cause: "action_not_found",
|
|
11
|
+
message: `Connector action is not configured: ${actionId}`,
|
|
12
|
+
connectorId,
|
|
13
|
+
actionId
|
|
14
|
+
});
|
|
15
|
+
const defineConnector = (options) => ({
|
|
16
|
+
id: options.id,
|
|
17
|
+
description: options.description,
|
|
18
|
+
actions: options.actions,
|
|
19
|
+
invoke: (input) => {
|
|
20
|
+
if (input.integration.connectorId !== options.id) return Effect.fail(connectorMismatchError(options.id, input.integration));
|
|
21
|
+
const action = Option.fromNullishOr(options.actions.find((item) => item.id === input.action));
|
|
22
|
+
if (Option.isNone(action)) return Effect.fail(missingActionError(options.id, input.action));
|
|
23
|
+
return action.value.execute({
|
|
24
|
+
integration: input.integration,
|
|
25
|
+
input: input.input
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
//#endregion
|
|
30
|
+
export { defineConnector };
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=connector.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector.mjs","names":[],"sources":["../src/connector.ts"],"sourcesContent":["import { Effect, Option } from 'effect'\nimport type { ConnectorAction } from './action.ts'\nimport { ConnectorError } from './error.ts'\nimport type { ActionResult } from './result.ts'\nimport type { ConnectorIntegration } from './integration.ts'\n\nexport type ConnectorInvokeInput = {\n readonly integration: ConnectorIntegration\n readonly action: string\n readonly input: unknown\n}\n\nexport type Connector<Env = never, Error = never> = {\n readonly id: string\n readonly description?: string\n readonly actions: ReadonlyArray<ConnectorAction<Env, Error>>\n readonly invoke: (\n input: ConnectorInvokeInput\n ) => Effect.Effect<ActionResult<unknown>, Error | ConnectorError, Env>\n}\n\nexport type DefineConnectorOptions<Env, Error> = {\n readonly id: string\n readonly description?: string\n readonly actions: ReadonlyArray<ConnectorAction<Env, Error>>\n}\n\nconst connectorMismatchError = (connectorId: string, integration: ConnectorIntegration) =>\n new ConnectorError({\n cause: 'connector_mismatch',\n message: `Integration belongs to ${integration.connectorId}, not ${connectorId}`,\n connectorId\n })\n\nconst missingActionError = (connectorId: string, actionId: string) =>\n new ConnectorError({\n cause: 'action_not_found',\n message: `Connector action is not configured: ${actionId}`,\n connectorId,\n actionId\n })\n\nexport const defineConnector = <Env = never, Error = never>(\n options: DefineConnectorOptions<Env, Error>\n): Connector<Env, Error> => ({\n id: options.id,\n description: options.description,\n actions: options.actions,\n invoke: input => {\n if (input.integration.connectorId !== options.id) {\n return Effect.fail(connectorMismatchError(options.id, input.integration))\n }\n\n const action = Option.fromNullishOr(options.actions.find(item => item.id === input.action))\n\n if (Option.isNone(action)) {\n return Effect.fail(missingActionError(options.id, input.action))\n }\n\n return action.value.execute({ integration: input.integration, input: input.input })\n }\n})\n"],"mappings":";;;AA2BA,MAAM,0BAA0B,aAAqB,gBACnD,IAAI,eAAe;CACjB,OAAO;CACP,SAAS,0BAA0B,YAAY,YAAY,QAAQ;CACnE;AACF,CAAC;AAEH,MAAM,sBAAsB,aAAqB,aAC/C,IAAI,eAAe;CACjB,OAAO;CACP,SAAS,uCAAuC;CAChD;CACA;AACF,CAAC;AAEH,MAAa,mBACX,aAC2B;CAC3B,IAAI,QAAQ;CACZ,aAAa,QAAQ;CACrB,SAAS,QAAQ;CACjB,SAAQ,UAAS;EACf,IAAI,MAAM,YAAY,gBAAgB,QAAQ,IAC5C,OAAO,OAAO,KAAK,uBAAuB,QAAQ,IAAI,MAAM,WAAW,CAAC;EAG1E,MAAM,SAAS,OAAO,cAAc,QAAQ,QAAQ,MAAK,SAAQ,KAAK,OAAO,MAAM,MAAM,CAAC;EAE1F,IAAI,OAAO,OAAO,MAAM,GACtB,OAAO,OAAO,KAAK,mBAAmB,QAAQ,IAAI,MAAM,MAAM,CAAC;EAGjE,OAAO,OAAO,MAAM,QAAQ;GAAE,aAAa,MAAM;GAAa,OAAO,MAAM;EAAM,CAAC;CACpF;AACF"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ConnectorError } from "./error.mjs";
|
|
2
|
+
import { ConnectorIntegration } from "./integration.mjs";
|
|
3
|
+
import { Context, Effect, Option } from "effect";
|
|
4
|
+
import * as Schema from "effect/Schema";
|
|
5
|
+
|
|
6
|
+
//#region src/credential.d.ts
|
|
7
|
+
declare const CredentialKind: Schema.Literals<readonly ["api_key", "bearer_token", "oauth"]>;
|
|
8
|
+
type CredentialKind = typeof CredentialKind.Type;
|
|
9
|
+
declare const CredentialSlot_base: Schema.Class<CredentialSlot, Schema.Struct<{
|
|
10
|
+
readonly id: Schema.String;
|
|
11
|
+
readonly kind: Schema.Literals<readonly ["api_key", "bearer_token", "oauth"]>;
|
|
12
|
+
readonly requiredScopes: Schema.optional<Schema.$Array<Schema.String>>;
|
|
13
|
+
}>, {}>;
|
|
14
|
+
declare class CredentialSlot extends CredentialSlot_base {}
|
|
15
|
+
declare const CredentialBinding_base: Schema.Class<CredentialBinding, Schema.Struct<{
|
|
16
|
+
readonly slotId: Schema.String;
|
|
17
|
+
readonly credentialRef: Schema.String;
|
|
18
|
+
readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
|
|
19
|
+
}>, {}>;
|
|
20
|
+
declare class CredentialBinding extends CredentialBinding_base {}
|
|
21
|
+
declare const ApiKeyCredential_base: Schema.Class<ApiKeyCredential, Schema.Struct<{
|
|
22
|
+
readonly _tag: Schema.Literal<"ApiKeyCredential">;
|
|
23
|
+
readonly key: Schema.String;
|
|
24
|
+
}>, {}>;
|
|
25
|
+
declare class ApiKeyCredential extends ApiKeyCredential_base {}
|
|
26
|
+
declare const BearerTokenCredential_base: Schema.Class<BearerTokenCredential, Schema.Struct<{
|
|
27
|
+
readonly _tag: Schema.Literal<"BearerTokenCredential">;
|
|
28
|
+
readonly token: Schema.String;
|
|
29
|
+
readonly expiresAt: Schema.optional<Schema.Number>;
|
|
30
|
+
}>, {}>;
|
|
31
|
+
declare class BearerTokenCredential extends BearerTokenCredential_base {}
|
|
32
|
+
declare const OAuthCredential_base: Schema.Class<OAuthCredential, Schema.Struct<{
|
|
33
|
+
readonly _tag: Schema.Literal<"OAuthCredential">;
|
|
34
|
+
readonly provider: Schema.String;
|
|
35
|
+
readonly accessToken: Schema.String;
|
|
36
|
+
readonly expiresAt: Schema.Number;
|
|
37
|
+
readonly accountId: Schema.optional<Schema.String>;
|
|
38
|
+
readonly scopes: Schema.optional<Schema.$Array<Schema.String>>;
|
|
39
|
+
}>, {}>;
|
|
40
|
+
declare class OAuthCredential extends OAuthCredential_base {}
|
|
41
|
+
declare const RuntimeCredential: Schema.Union<readonly [typeof ApiKeyCredential, typeof BearerTokenCredential, typeof OAuthCredential]>;
|
|
42
|
+
type RuntimeCredential = typeof RuntimeCredential.Type;
|
|
43
|
+
type CredentialResolveRequest = {
|
|
44
|
+
readonly integration: ConnectorIntegration;
|
|
45
|
+
readonly slot: CredentialSlot;
|
|
46
|
+
readonly binding: CredentialBinding;
|
|
47
|
+
};
|
|
48
|
+
type CredentialResolverApi = {
|
|
49
|
+
readonly resolve: (request: CredentialResolveRequest) => Effect.Effect<RuntimeCredential, ConnectorError>;
|
|
50
|
+
};
|
|
51
|
+
declare const CredentialResolver_base: Context.ServiceClass<CredentialResolver, "@yolk-sdk/connectors/CredentialResolver", CredentialResolverApi>;
|
|
52
|
+
declare class CredentialResolver extends CredentialResolver_base {}
|
|
53
|
+
declare const makeCredentialBinding: (input: {
|
|
54
|
+
readonly slotId: string;
|
|
55
|
+
readonly credentialRef: string;
|
|
56
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
57
|
+
}) => CredentialBinding;
|
|
58
|
+
declare const findCredentialBinding: (integration: ConnectorIntegration, slot: CredentialSlot) => Option.Option<CredentialBinding>;
|
|
59
|
+
declare const resolveCredential: (integration: ConnectorIntegration, slot: CredentialSlot) => Effect.Effect<ApiKeyCredential | BearerTokenCredential | OAuthCredential, ConnectorError, CredentialResolver>;
|
|
60
|
+
//#endregion
|
|
61
|
+
export { ApiKeyCredential, BearerTokenCredential, CredentialBinding, CredentialKind, CredentialResolveRequest, CredentialResolver, CredentialResolverApi, CredentialSlot, OAuthCredential, RuntimeCredential, findCredentialBinding, makeCredentialBinding, resolveCredential };
|
|
62
|
+
//# sourceMappingURL=credential.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential.d.mts","names":[],"sources":["../src/credential.ts"],"mappings":";;;;;;cAKa,cAAA,EAAc,MAAA,CAAA,QAAA;AAAA,KACf,cAAA,UAAwB,cAAA,CAAe,IAAI;AAAA,cAAA,mBAAA;;;;;cAE1C,cAAA,SAAuB,mBAIlC;AAAA,cAAG,sBAAA;;;;;cAEQ,iBAAA,SAA0B,sBAIrC;AAAA,cAAG,qBAAA;;;;cAEQ,gBAAA,SAAyB,qBAGpC;AAAA,cAAG,0BAAA;;;;;cAEQ,qBAAA,SAA8B,0BAIzC;AAAA,cAAG,oBAAA;;;;;;;;cAEQ,eAAA,SAAwB,oBAOnC;AAAA,cAEW,iBAAA,EAAiB,MAAA,CAAA,KAAA,kBAAA,gBAAA,SAAA,qBAAA,SAAA,eAAA;AAAA,KAClB,iBAAA,UAA2B,iBAAA,CAAkB,IAAI;AAAA,KAEjD,wBAAA;EAAA,SACD,WAAA,EAAa,oBAAA;EAAA,SACb,IAAA,EAAM,cAAA;EAAA,SACN,OAAA,EAAS,iBAAA;AAAA;AAAA,KAGR,qBAAA;EAAA,SACD,OAAA,GACP,OAAA,EAAS,wBAAA,KACN,MAAA,CAAO,MAAA,CAAO,iBAAA,EAAmB,cAAA;AAAA;AAAA,cACvC,uBAAA;cAEY,kBAAA,SAA2B,uBAEvC;AAAA,cAEY,qBAAA,GAAyB,KAAA;EAAA,SAC3B,MAAA;EAAA,SACA,aAAA;EAAA,SACA,QAAA,GAAW,QAAA,CAAS,MAAA;AAAA,MAC9B,iBAAA;AAAA,cAEY,qBAAA,GAAyB,WAAA,EAAa,oBAAA,EAAsB,IAAA,EAAM,cAAA,KAAc,MAAA,CAAA,MAAA,CAAA,iBAAA;AAAA,cAGhF,iBAAA,GAAqB,WAAA,EAAa,oBAAA,EAAsB,IAAA,EAAM,cAAA,KAAc,MAAA,CAAA,MAAA,CAAA,gBAAA,GAAA,qBAAA,GAAA,eAAA,EAAA,cAAA,EAAA,kBAAA"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ConnectorError } from "./error.mjs";
|
|
2
|
+
import { Context, Effect, Option } from "effect";
|
|
3
|
+
import * as Schema from "effect/Schema";
|
|
4
|
+
//#region src/credential.ts
|
|
5
|
+
const CredentialKind = Schema.Literals([
|
|
6
|
+
"api_key",
|
|
7
|
+
"bearer_token",
|
|
8
|
+
"oauth"
|
|
9
|
+
]);
|
|
10
|
+
var CredentialSlot = class extends Schema.Class("CredentialSlot")({
|
|
11
|
+
id: Schema.String,
|
|
12
|
+
kind: CredentialKind,
|
|
13
|
+
requiredScopes: Schema.optional(Schema.Array(Schema.String))
|
|
14
|
+
}) {};
|
|
15
|
+
var CredentialBinding = class extends Schema.Class("CredentialBinding")({
|
|
16
|
+
slotId: Schema.String,
|
|
17
|
+
credentialRef: Schema.String,
|
|
18
|
+
metadata: Schema.optional(Schema.Record(Schema.String, Schema.Unknown))
|
|
19
|
+
}) {};
|
|
20
|
+
var ApiKeyCredential = class extends Schema.Class("ApiKeyCredential")({
|
|
21
|
+
_tag: Schema.Literal("ApiKeyCredential"),
|
|
22
|
+
key: Schema.String
|
|
23
|
+
}) {};
|
|
24
|
+
var BearerTokenCredential = class extends Schema.Class("BearerTokenCredential")({
|
|
25
|
+
_tag: Schema.Literal("BearerTokenCredential"),
|
|
26
|
+
token: Schema.String,
|
|
27
|
+
expiresAt: Schema.optional(Schema.Number)
|
|
28
|
+
}) {};
|
|
29
|
+
var OAuthCredential = class extends Schema.Class("OAuthCredential")({
|
|
30
|
+
_tag: Schema.Literal("OAuthCredential"),
|
|
31
|
+
provider: Schema.String,
|
|
32
|
+
accessToken: Schema.String,
|
|
33
|
+
expiresAt: Schema.Number,
|
|
34
|
+
accountId: Schema.optional(Schema.String),
|
|
35
|
+
scopes: Schema.optional(Schema.Array(Schema.String))
|
|
36
|
+
}) {};
|
|
37
|
+
const RuntimeCredential = Schema.Union([
|
|
38
|
+
ApiKeyCredential,
|
|
39
|
+
BearerTokenCredential,
|
|
40
|
+
OAuthCredential
|
|
41
|
+
]);
|
|
42
|
+
var CredentialResolver = class extends Context.Service()("@yolk-sdk/connectors/CredentialResolver") {};
|
|
43
|
+
const makeCredentialBinding = (input) => CredentialBinding.make(input);
|
|
44
|
+
const findCredentialBinding = (integration, slot) => Option.fromNullishOr(integration.credentialBindings.find((binding) => binding.slotId === slot.id));
|
|
45
|
+
const resolveCredential = (integration, slot) => Effect.gen(function* () {
|
|
46
|
+
const binding = findCredentialBinding(integration, slot);
|
|
47
|
+
if (Option.isNone(binding)) return yield* Effect.fail(new ConnectorError({
|
|
48
|
+
cause: "credential_binding_missing",
|
|
49
|
+
message: `Missing credential binding for slot: ${slot.id}`,
|
|
50
|
+
connectorId: integration.connectorId,
|
|
51
|
+
slotId: slot.id
|
|
52
|
+
}));
|
|
53
|
+
return yield* (yield* CredentialResolver).resolve({
|
|
54
|
+
integration,
|
|
55
|
+
slot,
|
|
56
|
+
binding: binding.value
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
//#endregion
|
|
60
|
+
export { ApiKeyCredential, BearerTokenCredential, CredentialBinding, CredentialKind, CredentialResolver, CredentialSlot, OAuthCredential, RuntimeCredential, findCredentialBinding, makeCredentialBinding, resolveCredential };
|
|
61
|
+
|
|
62
|
+
//# sourceMappingURL=credential.mjs.map
|