@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.
Files changed (106) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +195 -0
  3. package/dist/action.d.mts +37 -0
  4. package/dist/action.d.mts.map +1 -0
  5. package/dist/action.mjs +24 -0
  6. package/dist/action.mjs.map +1 -0
  7. package/dist/agent.d.mts +21 -0
  8. package/dist/agent.d.mts.map +1 -0
  9. package/dist/agent.mjs +66 -0
  10. package/dist/agent.mjs.map +1 -0
  11. package/dist/config.d.mts +10 -0
  12. package/dist/config.d.mts.map +1 -0
  13. package/dist/config.mjs +21 -0
  14. package/dist/config.mjs.map +1 -0
  15. package/dist/connector.d.mts +27 -0
  16. package/dist/connector.d.mts.map +1 -0
  17. package/dist/connector.mjs +32 -0
  18. package/dist/connector.mjs.map +1 -0
  19. package/dist/credential.d.mts +62 -0
  20. package/dist/credential.d.mts.map +1 -0
  21. package/dist/credential.mjs +62 -0
  22. package/dist/credential.mjs.map +1 -0
  23. package/dist/error.d.mts +17 -0
  24. package/dist/error.d.mts.map +1 -0
  25. package/dist/error.mjs +22 -0
  26. package/dist/error.mjs.map +1 -0
  27. package/dist/figma/index.d.mts +48 -0
  28. package/dist/figma/index.d.mts.map +1 -0
  29. package/dist/figma/index.mjs +97 -0
  30. package/dist/figma/index.mjs.map +1 -0
  31. package/dist/google/calendar.d.mts +53 -0
  32. package/dist/google/calendar.d.mts.map +1 -0
  33. package/dist/google/calendar.mjs +111 -0
  34. package/dist/google/calendar.mjs.map +1 -0
  35. package/dist/google/gmail.d.mts +53 -0
  36. package/dist/google/gmail.d.mts.map +1 -0
  37. package/dist/google/gmail.mjs +103 -0
  38. package/dist/google/gmail.mjs.map +1 -0
  39. package/dist/google/index.d.mts +14 -0
  40. package/dist/google/index.d.mts.map +1 -0
  41. package/dist/google/index.mjs +15 -0
  42. package/dist/google/index.mjs.map +1 -0
  43. package/dist/google/oauth.d.mts +18 -0
  44. package/dist/google/oauth.d.mts.map +1 -0
  45. package/dist/google/oauth.mjs +25 -0
  46. package/dist/google/oauth.mjs.map +1 -0
  47. package/dist/google/shared.d.mts +20 -0
  48. package/dist/google/shared.d.mts.map +1 -0
  49. package/dist/google/shared.mjs +36 -0
  50. package/dist/google/shared.mjs.map +1 -0
  51. package/dist/http.d.mts +32 -0
  52. package/dist/http.d.mts.map +1 -0
  53. package/dist/http.mjs +36 -0
  54. package/dist/http.mjs.map +1 -0
  55. package/dist/index.d.mts +9 -0
  56. package/dist/index.mjs +9 -0
  57. package/dist/integration.d.mts +24 -0
  58. package/dist/integration.d.mts.map +1 -0
  59. package/dist/integration.mjs +22 -0
  60. package/dist/integration.mjs.map +1 -0
  61. package/dist/linkedin-search/index.d.mts +60 -0
  62. package/dist/linkedin-search/index.d.mts.map +1 -0
  63. package/dist/linkedin-search/index.mjs +162 -0
  64. package/dist/linkedin-search/index.mjs.map +1 -0
  65. package/dist/notion/index.d.mts +69 -0
  66. package/dist/notion/index.d.mts.map +1 -0
  67. package/dist/notion/index.mjs +169 -0
  68. package/dist/notion/index.mjs.map +1 -0
  69. package/dist/r2-storage/index.d.mts +48 -0
  70. package/dist/r2-storage/index.d.mts.map +1 -0
  71. package/dist/r2-storage/index.mjs +91 -0
  72. package/dist/r2-storage/index.mjs.map +1 -0
  73. package/dist/result.d.mts +32 -0
  74. package/dist/result.d.mts.map +1 -0
  75. package/dist/result.mjs +23 -0
  76. package/dist/result.mjs.map +1 -0
  77. package/dist/telegram/index.d.mts +34 -0
  78. package/dist/telegram/index.d.mts.map +1 -0
  79. package/dist/telegram/index.mjs +109 -0
  80. package/dist/telegram/index.mjs.map +1 -0
  81. package/dist/todoist/index.d.mts +70 -0
  82. package/dist/todoist/index.d.mts.map +1 -0
  83. package/dist/todoist/index.mjs +176 -0
  84. package/dist/todoist/index.mjs.map +1 -0
  85. package/package.json +96 -0
  86. package/src/action.ts +75 -0
  87. package/src/agent.ts +120 -0
  88. package/src/config.ts +28 -0
  89. package/src/connector.ts +62 -0
  90. package/src/credential.ts +86 -0
  91. package/src/error.ts +20 -0
  92. package/src/figma/index.ts +121 -0
  93. package/src/google/calendar.ts +145 -0
  94. package/src/google/gmail.ts +127 -0
  95. package/src/google/index.ts +46 -0
  96. package/src/google/oauth.ts +26 -0
  97. package/src/google/shared.ts +56 -0
  98. package/src/http.ts +51 -0
  99. package/src/index.ts +36 -0
  100. package/src/integration.ts +28 -0
  101. package/src/linkedin-search/index.ts +217 -0
  102. package/src/notion/index.ts +234 -0
  103. package/src/r2-storage/index.ts +118 -0
  104. package/src/result.ts +35 -0
  105. package/src/telegram/index.ts +144 -0
  106. package/src/todoist/index.ts +227 -0
package/src/result.ts ADDED
@@ -0,0 +1,35 @@
1
+ import * as Schema from 'effect/Schema'
2
+
3
+ export class ProviderFailure extends Schema.Class<ProviderFailure>('ProviderFailure')({
4
+ code: Schema.String,
5
+ message: Schema.String,
6
+ status: Schema.optional(Schema.Number),
7
+ retryAfterMs: Schema.optional(Schema.Number),
8
+ underlying: Schema.optional(Schema.Unknown)
9
+ }) {}
10
+
11
+ export type ProviderFailureInput = {
12
+ readonly code: string
13
+ readonly message: string
14
+ readonly status?: number
15
+ readonly retryAfterMs?: number
16
+ readonly underlying?: unknown
17
+ }
18
+
19
+ export type ActionResult<Output> =
20
+ | {
21
+ readonly _tag: 'Success'
22
+ readonly value: Output
23
+ }
24
+ | {
25
+ readonly _tag: 'Failure'
26
+ readonly error: ProviderFailure
27
+ }
28
+
29
+ export const ActionResult = {
30
+ success: <Output>(value: Output): ActionResult<Output> => ({ _tag: 'Success', value }),
31
+ failure: (failure: ProviderFailure | ProviderFailureInput): ActionResult<never> => ({
32
+ _tag: 'Failure',
33
+ error: failure instanceof ProviderFailure ? failure : ProviderFailure.make(failure)
34
+ })
35
+ }
@@ -0,0 +1,144 @@
1
+ import { Effect } from 'effect'
2
+ import * as Schema from 'effect/Schema'
3
+ import { defineAction } from '../action.ts'
4
+ import { requiredStringConfig } from '../config.ts'
5
+ import { defineConnector } from '../connector.ts'
6
+ import { CredentialSlot, resolveCredential } from '../credential.ts'
7
+ import { ConnectorHttpClient, ConnectorHttpRequest } from '../http.ts'
8
+ import { ActionResult, ProviderFailure } from '../result.ts'
9
+ import type { ConnectorIntegration } from '../integration.ts'
10
+
11
+ export const telegramConnectorId = 'telegram'
12
+ export const telegramBotTokenSlotId = 'telegram.bot_token'
13
+ export const telegramApiBaseUrl = 'https://api.telegram.org'
14
+
15
+ export const TelegramBotTokenSlot = CredentialSlot.make({
16
+ id: telegramBotTokenSlotId,
17
+ kind: 'api_key'
18
+ })
19
+
20
+ const resolveTelegramBotToken = (integration: ConnectorIntegration) =>
21
+ Effect.gen(function* () {
22
+ const credential = yield* resolveCredential(integration, TelegramBotTokenSlot)
23
+
24
+ switch (credential._tag) {
25
+ case 'ApiKeyCredential':
26
+ return credential.key
27
+ case 'BearerTokenCredential':
28
+ return credential.token
29
+ case 'OAuthCredential':
30
+ return credential.accessToken
31
+ }
32
+ })
33
+
34
+ const isSuccessStatus = (status: number) => status >= 200 && status < 300
35
+
36
+ const telegramProviderFailure = (input: {
37
+ readonly code: string
38
+ readonly message: string
39
+ readonly status: number
40
+ readonly body: string
41
+ }) =>
42
+ ActionResult.failure(
43
+ new ProviderFailure({
44
+ code: input.code,
45
+ message: input.message,
46
+ status: input.status,
47
+ underlying: input.body
48
+ })
49
+ )
50
+
51
+ export class TelegramSendMessageInput extends Schema.Class<TelegramSendMessageInput>(
52
+ 'TelegramSendMessageInput'
53
+ )({
54
+ message: Schema.String,
55
+ disableWebPagePreview: Schema.optional(Schema.Boolean)
56
+ }) {}
57
+
58
+ export class TelegramSendMessageOutput extends Schema.Class<TelegramSendMessageOutput>(
59
+ 'TelegramSendMessageOutput'
60
+ )({
61
+ sent: Schema.Boolean,
62
+ chatId: Schema.String
63
+ }) {}
64
+
65
+ export class TelegramValidateOutput extends Schema.Class<TelegramValidateOutput>('TelegramValidateOutput')({
66
+ ok: Schema.Boolean,
67
+ chatId: Schema.String
68
+ }) {}
69
+
70
+ export const telegramSendMessageAction = defineAction({
71
+ id: 'telegram.send_message',
72
+ description: 'Send a Telegram message to the configured chat.',
73
+ inputSchema: TelegramSendMessageInput,
74
+ outputSchema: TelegramSendMessageOutput,
75
+ execute: ({ integration, input }) =>
76
+ Effect.gen(function* () {
77
+ const botToken = yield* resolveTelegramBotToken(integration)
78
+ const chatId = yield* requiredStringConfig(integration, 'chatId')
79
+ const http = yield* ConnectorHttpClient
80
+ const response = yield* http.request(
81
+ ConnectorHttpRequest.make({
82
+ method: 'POST',
83
+ url: `${telegramApiBaseUrl}/bot${botToken}/sendMessage`,
84
+ headers: { 'content-type': 'application/json' },
85
+ body: JSON.stringify({
86
+ chat_id: chatId,
87
+ text: input.message,
88
+ disable_web_page_preview: input.disableWebPagePreview ?? true
89
+ })
90
+ })
91
+ )
92
+
93
+ if (!isSuccessStatus(response.status)) {
94
+ return telegramProviderFailure({
95
+ code: response.status === 429 ? 'telegram_rate_limited' : 'telegram_send_failed',
96
+ message: 'Telegram send message failed',
97
+ status: response.status,
98
+ body: response.body
99
+ })
100
+ }
101
+
102
+ return ActionResult.success(TelegramSendMessageOutput.make({ sent: true, chatId }))
103
+ })
104
+ })
105
+
106
+ export const telegramValidateAction = defineAction({
107
+ id: 'telegram.validate',
108
+ description: 'Validate the Telegram bot token and configured chat.',
109
+ inputSchema: Schema.Struct({}),
110
+ outputSchema: TelegramValidateOutput,
111
+ execute: ({ integration }) =>
112
+ Effect.gen(function* () {
113
+ const botToken = yield* resolveTelegramBotToken(integration)
114
+ const chatId = yield* requiredStringConfig(integration, 'chatId')
115
+ const http = yield* ConnectorHttpClient
116
+ const response = yield* http.request(
117
+ ConnectorHttpRequest.make({
118
+ method: 'POST',
119
+ url: `${telegramApiBaseUrl}/bot${botToken}/getChat`,
120
+ headers: { 'content-type': 'application/json' },
121
+ body: JSON.stringify({ chat_id: chatId })
122
+ })
123
+ )
124
+
125
+ if (!isSuccessStatus(response.status)) {
126
+ return telegramProviderFailure({
127
+ code: 'telegram_validate_failed',
128
+ message: 'Telegram validation failed',
129
+ status: response.status,
130
+ body: response.body
131
+ })
132
+ }
133
+
134
+ return ActionResult.success(TelegramValidateOutput.make({ ok: true, chatId }))
135
+ })
136
+ })
137
+
138
+ export const telegramActions = [telegramSendMessageAction, telegramValidateAction]
139
+
140
+ export const TelegramConnector = defineConnector({
141
+ id: telegramConnectorId,
142
+ description: 'Telegram bot connector actions.',
143
+ actions: telegramActions
144
+ })
@@ -0,0 +1,227 @@
1
+ import { Effect } from 'effect'
2
+ import * as Schema from 'effect/Schema'
3
+ import { defineAction } from '../action.ts'
4
+ import { defineConnector } from '../connector.ts'
5
+ import { CredentialSlot, resolveCredential } from '../credential.ts'
6
+ import { ConnectorHttpClient, ConnectorHttpRequest, decodeJsonResponse } from '../http.ts'
7
+ import { ActionResult, ProviderFailure } from '../result.ts'
8
+ import type { ConnectorIntegration } from '../integration.ts'
9
+
10
+ export const todoistConnectorId = 'todoist'
11
+ export const todoistApiTokenSlotId = 'todoist.api_token'
12
+ export const todoistApiBaseUrl = 'https://api.todoist.com/rest/v2'
13
+
14
+ export const TodoistApiTokenSlot = CredentialSlot.make({
15
+ id: todoistApiTokenSlotId,
16
+ kind: 'api_key'
17
+ })
18
+
19
+ export const todoistAuthorizationHeaders = (token: string) => ({
20
+ authorization: `Bearer ${token}`
21
+ })
22
+
23
+ const isSuccessStatus = (status: number) => status >= 200 && status < 300
24
+
25
+ const todoistProviderFailure = (input: {
26
+ readonly code: string
27
+ readonly message: string
28
+ readonly status: number
29
+ readonly body: string
30
+ }) =>
31
+ ActionResult.failure(
32
+ new ProviderFailure({
33
+ code: input.code,
34
+ message: input.message,
35
+ status: input.status,
36
+ underlying: input.body
37
+ })
38
+ )
39
+
40
+ const resolveTodoistToken = (integration: ConnectorIntegration) =>
41
+ Effect.gen(function* () {
42
+ const credential = yield* resolveCredential(integration, TodoistApiTokenSlot)
43
+
44
+ switch (credential._tag) {
45
+ case 'ApiKeyCredential':
46
+ return credential.key
47
+ case 'BearerTokenCredential':
48
+ return credential.token
49
+ case 'OAuthCredential':
50
+ return credential.accessToken
51
+ }
52
+ })
53
+
54
+ export class TodoistTask extends Schema.Class<TodoistTask>('TodoistTask')({
55
+ id: Schema.String,
56
+ content: Schema.String,
57
+ description: Schema.optional(Schema.String),
58
+ projectId: Schema.optional(Schema.String),
59
+ sectionId: Schema.optional(Schema.String),
60
+ parentId: Schema.optional(Schema.String),
61
+ labels: Schema.optional(Schema.Array(Schema.String)),
62
+ priority: Schema.optional(Schema.Number),
63
+ due: Schema.optional(Schema.Unknown),
64
+ url: Schema.optional(Schema.String)
65
+ }) {}
66
+
67
+ export class TodoistListTasksInput extends Schema.Class<TodoistListTasksInput>('TodoistListTasksInput')({
68
+ projectId: Schema.optional(Schema.String),
69
+ sectionId: Schema.optional(Schema.String),
70
+ parentId: Schema.optional(Schema.String),
71
+ label: Schema.optional(Schema.String),
72
+ filter: Schema.optional(Schema.String)
73
+ }) {}
74
+
75
+ export class TodoistListTasksOutput extends Schema.Class<TodoistListTasksOutput>('TodoistListTasksOutput')({
76
+ tasks: Schema.Array(TodoistTask)
77
+ }) {}
78
+
79
+ export class TodoistCreateTaskInput extends Schema.Class<TodoistCreateTaskInput>('TodoistCreateTaskInput')({
80
+ content: Schema.String,
81
+ description: Schema.optional(Schema.String),
82
+ projectId: Schema.optional(Schema.String),
83
+ sectionId: Schema.optional(Schema.String),
84
+ parentId: Schema.optional(Schema.String),
85
+ labels: Schema.optional(Schema.Array(Schema.String)),
86
+ priority: Schema.optional(Schema.Number),
87
+ dueString: Schema.optional(Schema.String),
88
+ dueDate: Schema.optional(Schema.String),
89
+ dueDatetime: Schema.optional(Schema.String)
90
+ }) {}
91
+
92
+ export class TodoistCloseTaskInput extends Schema.Class<TodoistCloseTaskInput>('TodoistCloseTaskInput')({
93
+ id: Schema.String
94
+ }) {}
95
+
96
+ export class TodoistCloseTaskOutput extends Schema.Class<TodoistCloseTaskOutput>('TodoistCloseTaskOutput')({
97
+ id: Schema.String,
98
+ closed: Schema.Boolean
99
+ }) {}
100
+
101
+ const appendSearchParam = (params: URLSearchParams, key: string, value: string | undefined) => {
102
+ if (value !== undefined && value.trim() !== '') {
103
+ params.set(key, value)
104
+ }
105
+ }
106
+
107
+ export const todoistListTasksAction = defineAction({
108
+ id: 'todoist.list_tasks',
109
+ description: 'List Todoist active tasks.',
110
+ inputSchema: TodoistListTasksInput,
111
+ outputSchema: TodoistListTasksOutput,
112
+ execute: ({ integration, input }) =>
113
+ Effect.gen(function* () {
114
+ const token = yield* resolveTodoistToken(integration)
115
+ const http = yield* ConnectorHttpClient
116
+ const params = new URLSearchParams()
117
+ appendSearchParam(params, 'project_id', input.projectId)
118
+ appendSearchParam(params, 'section_id', input.sectionId)
119
+ appendSearchParam(params, 'parent_id', input.parentId)
120
+ appendSearchParam(params, 'label', input.label)
121
+ appendSearchParam(params, 'filter', input.filter)
122
+ const query = params.toString()
123
+ const response = yield* http.request(
124
+ ConnectorHttpRequest.make({
125
+ method: 'GET',
126
+ url: `${todoistApiBaseUrl}/tasks${query === '' ? '' : `?${query}`}`,
127
+ headers: todoistAuthorizationHeaders(token)
128
+ })
129
+ )
130
+
131
+ if (!isSuccessStatus(response.status)) {
132
+ return todoistProviderFailure({
133
+ code: 'todoist_list_tasks_failed',
134
+ message: 'Todoist list tasks failed',
135
+ status: response.status,
136
+ body: response.body
137
+ })
138
+ }
139
+
140
+ const tasks = yield* decodeJsonResponse(Schema.Array(TodoistTask), response)
141
+ return ActionResult.success(TodoistListTasksOutput.make({ tasks }))
142
+ })
143
+ })
144
+
145
+ export const todoistCreateTaskAction = defineAction({
146
+ id: 'todoist.create_task',
147
+ description: 'Create a Todoist task.',
148
+ inputSchema: TodoistCreateTaskInput,
149
+ outputSchema: TodoistTask,
150
+ execute: ({ integration, input }) =>
151
+ Effect.gen(function* () {
152
+ const token = yield* resolveTodoistToken(integration)
153
+ const http = yield* ConnectorHttpClient
154
+ const response = yield* http.request(
155
+ ConnectorHttpRequest.make({
156
+ method: 'POST',
157
+ url: `${todoistApiBaseUrl}/tasks`,
158
+ headers: {
159
+ ...todoistAuthorizationHeaders(token),
160
+ 'content-type': 'application/json'
161
+ },
162
+ body: JSON.stringify({
163
+ content: input.content,
164
+ description: input.description,
165
+ project_id: input.projectId,
166
+ section_id: input.sectionId,
167
+ parent_id: input.parentId,
168
+ labels: input.labels,
169
+ priority: input.priority,
170
+ due_string: input.dueString,
171
+ due_date: input.dueDate,
172
+ due_datetime: input.dueDatetime
173
+ })
174
+ })
175
+ )
176
+
177
+ if (!isSuccessStatus(response.status)) {
178
+ return todoistProviderFailure({
179
+ code: 'todoist_create_task_failed',
180
+ message: 'Todoist create task failed',
181
+ status: response.status,
182
+ body: response.body
183
+ })
184
+ }
185
+
186
+ const output = yield* decodeJsonResponse(TodoistTask, response)
187
+ return ActionResult.success(output)
188
+ })
189
+ })
190
+
191
+ export const todoistCloseTaskAction = defineAction({
192
+ id: 'todoist.close_task',
193
+ description: 'Close a Todoist task.',
194
+ inputSchema: TodoistCloseTaskInput,
195
+ outputSchema: TodoistCloseTaskOutput,
196
+ execute: ({ integration, input }) =>
197
+ Effect.gen(function* () {
198
+ const token = yield* resolveTodoistToken(integration)
199
+ const http = yield* ConnectorHttpClient
200
+ const response = yield* http.request(
201
+ ConnectorHttpRequest.make({
202
+ method: 'POST',
203
+ url: `${todoistApiBaseUrl}/tasks/${encodeURIComponent(input.id)}/close`,
204
+ headers: todoistAuthorizationHeaders(token)
205
+ })
206
+ )
207
+
208
+ if (!isSuccessStatus(response.status)) {
209
+ return todoistProviderFailure({
210
+ code: 'todoist_close_task_failed',
211
+ message: 'Todoist close task failed',
212
+ status: response.status,
213
+ body: response.body
214
+ })
215
+ }
216
+
217
+ return ActionResult.success(TodoistCloseTaskOutput.make({ id: input.id, closed: true }))
218
+ })
219
+ })
220
+
221
+ export const todoistActions = [todoistListTasksAction, todoistCreateTaskAction, todoistCloseTaskAction]
222
+
223
+ export const TodoistConnector = defineConnector({
224
+ id: todoistConnectorId,
225
+ description: 'Todoist task connector actions.',
226
+ actions: todoistActions
227
+ })