digital-tools 2.1.3 → 2.3.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 (294) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +2 -0
  3. package/dist/client.d.ts +109 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +69 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/define.d.ts +2 -2
  8. package/dist/define.d.ts.map +1 -1
  9. package/dist/define.js +21 -11
  10. package/dist/define.js.map +1 -1
  11. package/dist/function-ref.d.ts +229 -0
  12. package/dist/function-ref.d.ts.map +1 -0
  13. package/dist/function-ref.js +28 -0
  14. package/dist/function-ref.js.map +1 -0
  15. package/dist/function-sugar.d.ts +57 -0
  16. package/dist/function-sugar.d.ts.map +1 -0
  17. package/dist/function-sugar.js +79 -0
  18. package/dist/function-sugar.js.map +1 -0
  19. package/dist/index.d.ts +10 -3
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +24 -4
  22. package/dist/index.js.map +1 -1
  23. package/dist/providers/analytics/mixpanel.d.ts.map +1 -1
  24. package/dist/providers/analytics/mixpanel.js +21 -18
  25. package/dist/providers/analytics/mixpanel.js.map +1 -1
  26. package/dist/providers/calendar/cal-com.d.ts.map +1 -1
  27. package/dist/providers/calendar/cal-com.js +10 -10
  28. package/dist/providers/calendar/cal-com.js.map +1 -1
  29. package/dist/providers/calendar/google-calendar.d.ts.map +1 -1
  30. package/dist/providers/calendar/google-calendar.js +4 -4
  31. package/dist/providers/calendar/google-calendar.js.map +1 -1
  32. package/dist/providers/crm/hubspot.d.ts.map +1 -1
  33. package/dist/providers/crm/hubspot.js +107 -85
  34. package/dist/providers/crm/hubspot.js.map +1 -1
  35. package/dist/providers/development/github.d.ts.map +1 -1
  36. package/dist/providers/development/github.js +40 -43
  37. package/dist/providers/development/github.js.map +1 -1
  38. package/dist/providers/ecommerce/shopify.d.ts.map +1 -1
  39. package/dist/providers/ecommerce/shopify.js +79 -62
  40. package/dist/providers/ecommerce/shopify.js.map +1 -1
  41. package/dist/providers/email/resend.d.ts.map +1 -1
  42. package/dist/providers/email/resend.js +20 -16
  43. package/dist/providers/email/resend.js.map +1 -1
  44. package/dist/providers/email/sendgrid.d.ts.map +1 -1
  45. package/dist/providers/email/sendgrid.js +12 -9
  46. package/dist/providers/email/sendgrid.js.map +1 -1
  47. package/dist/providers/finance/stripe.d.ts.map +1 -1
  48. package/dist/providers/finance/stripe.js +44 -42
  49. package/dist/providers/finance/stripe.js.map +1 -1
  50. package/dist/providers/forms/typeform.d.ts.map +1 -1
  51. package/dist/providers/forms/typeform.js +68 -58
  52. package/dist/providers/forms/typeform.js.map +1 -1
  53. package/dist/providers/knowledge/notion.d.ts.map +1 -1
  54. package/dist/providers/knowledge/notion.js +75 -41
  55. package/dist/providers/knowledge/notion.js.map +1 -1
  56. package/dist/providers/marketing/mailchimp.d.ts.map +1 -1
  57. package/dist/providers/marketing/mailchimp.js +74 -61
  58. package/dist/providers/marketing/mailchimp.js.map +1 -1
  59. package/dist/providers/media/cloudinary.d.ts.map +1 -1
  60. package/dist/providers/media/cloudinary.js +30 -28
  61. package/dist/providers/media/cloudinary.js.map +1 -1
  62. package/dist/providers/messaging/slack.d.ts.map +1 -1
  63. package/dist/providers/messaging/slack.js +75 -58
  64. package/dist/providers/messaging/slack.js.map +1 -1
  65. package/dist/providers/messaging/twilio-sms.d.ts.map +1 -1
  66. package/dist/providers/messaging/twilio-sms.js +33 -15
  67. package/dist/providers/messaging/twilio-sms.js.map +1 -1
  68. package/dist/providers/project-management/linear.d.ts.map +1 -1
  69. package/dist/providers/project-management/linear.js +31 -27
  70. package/dist/providers/project-management/linear.js.map +1 -1
  71. package/dist/providers/spreadsheet/google-sheets.d.ts.map +1 -1
  72. package/dist/providers/spreadsheet/google-sheets.js +21 -18
  73. package/dist/providers/spreadsheet/google-sheets.js.map +1 -1
  74. package/dist/providers/spreadsheet/xlsx.d.ts.map +1 -1
  75. package/dist/providers/spreadsheet/xlsx.js +4 -4
  76. package/dist/providers/spreadsheet/xlsx.js.map +1 -1
  77. package/dist/providers/storage/index.js +1 -0
  78. package/dist/providers/storage/index.js.map +1 -1
  79. package/dist/providers/storage/s3.d.ts.map +1 -1
  80. package/dist/providers/storage/s3.js +36 -27
  81. package/dist/providers/storage/s3.js.map +1 -1
  82. package/dist/providers/support/zendesk.d.ts.map +1 -1
  83. package/dist/providers/support/zendesk.js +24 -25
  84. package/dist/providers/support/zendesk.js.map +1 -1
  85. package/dist/providers/tasks/todoist.d.ts.map +1 -1
  86. package/dist/providers/tasks/todoist.js +18 -18
  87. package/dist/providers/tasks/todoist.js.map +1 -1
  88. package/dist/providers/video-conferencing/google-meet.d.ts.map +1 -1
  89. package/dist/providers/video-conferencing/google-meet.js +11 -11
  90. package/dist/providers/video-conferencing/google-meet.js.map +1 -1
  91. package/dist/providers/video-conferencing/jitsi.js +14 -14
  92. package/dist/providers/video-conferencing/jitsi.js.map +1 -1
  93. package/dist/providers/video-conferencing/teams.d.ts.map +1 -1
  94. package/dist/providers/video-conferencing/teams.js +9 -7
  95. package/dist/providers/video-conferencing/teams.js.map +1 -1
  96. package/dist/providers/video-conferencing/zoom.d.ts.map +1 -1
  97. package/dist/providers/video-conferencing/zoom.js +26 -24
  98. package/dist/providers/video-conferencing/zoom.js.map +1 -1
  99. package/dist/tools/data.d.ts.map +1 -1
  100. package/dist/tools/data.js +5 -12
  101. package/dist/tools/data.js.map +1 -1
  102. package/dist/tools/index.d.ts +1 -0
  103. package/dist/tools/index.d.ts.map +1 -1
  104. package/dist/tools/index.js +1 -0
  105. package/dist/tools/index.js.map +1 -1
  106. package/dist/tools/system.d.ts +289 -0
  107. package/dist/tools/system.d.ts.map +1 -0
  108. package/dist/tools/system.js +752 -0
  109. package/dist/tools/system.js.map +1 -0
  110. package/dist/tools/web.d.ts.map +1 -1
  111. package/dist/tools/web.js +22 -10
  112. package/dist/tools/web.js.map +1 -1
  113. package/dist/track-record.d.ts +101 -0
  114. package/dist/track-record.d.ts.map +1 -0
  115. package/dist/track-record.js +17 -0
  116. package/dist/track-record.js.map +1 -0
  117. package/dist/types.d.ts +210 -9
  118. package/dist/types.d.ts.map +1 -1
  119. package/dist/verb-registration.d.ts +122 -0
  120. package/dist/verb-registration.d.ts.map +1 -0
  121. package/dist/verb-registration.js +176 -0
  122. package/dist/verb-registration.js.map +1 -0
  123. package/dist/worker.d.ts +93 -0
  124. package/dist/worker.d.ts.map +1 -0
  125. package/dist/worker.js +315 -0
  126. package/dist/worker.js.map +1 -0
  127. package/dist/wrap.d.ts +89 -0
  128. package/dist/wrap.d.ts.map +1 -0
  129. package/dist/wrap.js +225 -0
  130. package/dist/wrap.js.map +1 -0
  131. package/package.json +31 -14
  132. package/src/client.ts +136 -0
  133. package/src/define.ts +30 -24
  134. package/src/function-ref.ts +264 -0
  135. package/src/function-sugar.ts +134 -0
  136. package/src/index.ts +132 -10
  137. package/src/providers/analytics/mixpanel.ts +19 -18
  138. package/src/providers/calendar/cal-com.ts +29 -18
  139. package/src/providers/calendar/google-calendar.ts +20 -14
  140. package/src/providers/crm/hubspot.ts +225 -99
  141. package/src/providers/development/github.ts +206 -135
  142. package/src/providers/ecommerce/shopify.ts +250 -89
  143. package/src/providers/email/resend.ts +101 -28
  144. package/src/providers/email/sendgrid.ts +12 -9
  145. package/src/providers/finance/stripe.ts +128 -49
  146. package/src/providers/forms/typeform.ts +74 -58
  147. package/src/providers/knowledge/notion.ts +340 -88
  148. package/src/providers/marketing/mailchimp.ts +86 -70
  149. package/src/providers/media/cloudinary.ts +99 -41
  150. package/src/providers/messaging/slack.ts +283 -85
  151. package/src/providers/messaging/twilio-sms.ts +35 -15
  152. package/src/providers/project-management/linear.ts +143 -55
  153. package/src/providers/spreadsheet/google-sheets.ts +222 -56
  154. package/src/providers/spreadsheet/xlsx.ts +47 -16
  155. package/src/providers/storage/s3.ts +119 -47
  156. package/src/providers/support/zendesk.ts +196 -46
  157. package/src/providers/tasks/todoist.ts +20 -26
  158. package/src/providers/video-conferencing/google-meet.ts +17 -20
  159. package/src/providers/video-conferencing/jitsi.ts +14 -14
  160. package/src/providers/video-conferencing/teams.ts +14 -13
  161. package/src/providers/video-conferencing/zoom.ts +54 -49
  162. package/src/tools/data.ts +6 -16
  163. package/src/tools/index.ts +1 -0
  164. package/src/tools/system.ts +887 -0
  165. package/src/tools/web.ts +22 -10
  166. package/src/track-record.ts +106 -0
  167. package/src/types.ts +241 -13
  168. package/src/verb-registration.ts +197 -0
  169. package/src/worker.ts +370 -0
  170. package/src/wrap.ts +260 -0
  171. package/test/client.test.ts +146 -0
  172. package/test/communication-tools-extended.test.ts +734 -0
  173. package/test/data-tools-extended.test.ts +743 -0
  174. package/test/define-extended.test.ts +819 -0
  175. package/test/define.test.ts +150 -41
  176. package/test/entities.test.ts +623 -0
  177. package/test/extended-entities.test.ts +1228 -0
  178. package/test/provider-implementations.test.ts +725 -0
  179. package/test/provider-registry-extended.test.ts +583 -0
  180. package/test/providers/google-sheets.test.ts +851 -0
  181. package/test/providers/helpers.ts +554 -0
  182. package/test/providers/hubspot.test.ts +576 -0
  183. package/test/providers/slack.test.ts +932 -0
  184. package/test/providers/stripe.test.ts +701 -0
  185. package/test/providers.test.ts +578 -0
  186. package/test/system-tools-extended.test.ts +632 -0
  187. package/test/system.test.ts +673 -0
  188. package/test/tools.test.ts +15 -11
  189. package/test/types.test.ts +402 -0
  190. package/test/verb-registration.test.ts +395 -0
  191. package/test/web-tools.test.ts +553 -0
  192. package/test/worker-extended.test.ts +699 -0
  193. package/test/worker.test.ts +576 -0
  194. package/test/wrap.test.ts +366 -0
  195. package/tsconfig.json +3 -13
  196. package/vitest.config.ts +37 -0
  197. package/wrangler.jsonc +9 -0
  198. package/.turbo/turbo-build.log +0 -4
  199. package/LICENSE +0 -21
  200. package/dist/providers/voice/vapi.d.ts +0 -27
  201. package/dist/providers/voice/vapi.d.ts.map +0 -1
  202. package/dist/providers/voice/vapi.js +0 -440
  203. package/dist/providers/voice/vapi.js.map +0 -1
  204. package/src/define.js +0 -259
  205. package/src/entities/advertising.js +0 -999
  206. package/src/entities/ai.js +0 -756
  207. package/src/entities/analytics.js +0 -1588
  208. package/src/entities/automation.js +0 -601
  209. package/src/entities/communication.js +0 -1150
  210. package/src/entities/crm.js +0 -1386
  211. package/src/entities/design.js +0 -546
  212. package/src/entities/development.js +0 -2212
  213. package/src/entities/document.js +0 -874
  214. package/src/entities/ecommerce.js +0 -1429
  215. package/src/entities/experiment.js +0 -1039
  216. package/src/entities/finance.js +0 -3478
  217. package/src/entities/forms.js +0 -1892
  218. package/src/entities/hr.js +0 -661
  219. package/src/entities/identity.js +0 -997
  220. package/src/entities/index.js +0 -282
  221. package/src/entities/infrastructure.js +0 -1153
  222. package/src/entities/knowledge.js +0 -1438
  223. package/src/entities/marketing.js +0 -1610
  224. package/src/entities/media.js +0 -1634
  225. package/src/entities/notification.js +0 -1199
  226. package/src/entities/presentation.js +0 -1274
  227. package/src/entities/productivity.js +0 -1317
  228. package/src/entities/project-management.js +0 -1136
  229. package/src/entities/recruiting.js +0 -736
  230. package/src/entities/shipping.js +0 -509
  231. package/src/entities/signature.js +0 -1102
  232. package/src/entities/site.js +0 -222
  233. package/src/entities/spreadsheet.js +0 -1341
  234. package/src/entities/storage.js +0 -1198
  235. package/src/entities/support.js +0 -1166
  236. package/src/entities/video-conferencing.js +0 -1750
  237. package/src/entities/video.js +0 -950
  238. package/src/entities.js +0 -1663
  239. package/src/index.js +0 -74
  240. package/src/providers/analytics/index.js +0 -17
  241. package/src/providers/analytics/mixpanel.js +0 -255
  242. package/src/providers/calendar/cal-com.js +0 -303
  243. package/src/providers/calendar/google-calendar.js +0 -335
  244. package/src/providers/calendar/index.js +0 -20
  245. package/src/providers/crm/hubspot.js +0 -566
  246. package/src/providers/crm/index.js +0 -17
  247. package/src/providers/development/github.js +0 -472
  248. package/src/providers/development/index.js +0 -17
  249. package/src/providers/ecommerce/index.js +0 -17
  250. package/src/providers/ecommerce/shopify.js +0 -378
  251. package/src/providers/email/index.js +0 -20
  252. package/src/providers/email/resend.js +0 -258
  253. package/src/providers/email/sendgrid.js +0 -161
  254. package/src/providers/finance/index.js +0 -17
  255. package/src/providers/finance/stripe.js +0 -549
  256. package/src/providers/forms/index.js +0 -17
  257. package/src/providers/forms/typeform.js +0 -500
  258. package/src/providers/index.js +0 -123
  259. package/src/providers/knowledge/index.js +0 -17
  260. package/src/providers/knowledge/notion.js +0 -389
  261. package/src/providers/marketing/index.js +0 -17
  262. package/src/providers/marketing/mailchimp.js +0 -443
  263. package/src/providers/media/cloudinary.js +0 -318
  264. package/src/providers/media/index.js +0 -17
  265. package/src/providers/messaging/index.js +0 -20
  266. package/src/providers/messaging/slack.js +0 -393
  267. package/src/providers/messaging/twilio-sms.js +0 -249
  268. package/src/providers/project-management/index.js +0 -17
  269. package/src/providers/project-management/linear.js +0 -575
  270. package/src/providers/registry.js +0 -86
  271. package/src/providers/spreadsheet/google-sheets.js +0 -375
  272. package/src/providers/spreadsheet/index.js +0 -20
  273. package/src/providers/spreadsheet/xlsx.js +0 -423
  274. package/src/providers/storage/index.js +0 -24
  275. package/src/providers/storage/s3.js +0 -419
  276. package/src/providers/support/index.js +0 -17
  277. package/src/providers/support/zendesk.js +0 -373
  278. package/src/providers/tasks/index.js +0 -17
  279. package/src/providers/tasks/todoist.js +0 -286
  280. package/src/providers/types.js +0 -9
  281. package/src/providers/video-conferencing/google-meet.js +0 -286
  282. package/src/providers/video-conferencing/index.js +0 -31
  283. package/src/providers/video-conferencing/jitsi.js +0 -254
  284. package/src/providers/video-conferencing/teams.js +0 -270
  285. package/src/providers/video-conferencing/zoom.js +0 -332
  286. package/src/registry.js +0 -128
  287. package/src/tools/communication.js +0 -184
  288. package/src/tools/data.js +0 -205
  289. package/src/tools/index.js +0 -11
  290. package/src/tools/web.js +0 -137
  291. package/src/types.js +0 -10
  292. package/test/define.test.js +0 -306
  293. package/test/registry.test.js +0 -357
  294. package/test/tools.test.js +0 -363
@@ -1,575 +0,0 @@
1
- /**
2
- * Linear Project Management Provider
3
- *
4
- * Concrete implementation of ProjectManagementProvider using Linear GraphQL API.
5
- *
6
- * @packageDocumentation
7
- */
8
- import { defineProvider } from '../registry.js';
9
- const LINEAR_API_URL = 'https://api.linear.app/graphql';
10
- /**
11
- * Linear provider info
12
- */
13
- export const linearInfo = {
14
- id: 'project-management.linear',
15
- name: 'Linear',
16
- description: 'Linear issue tracking and project management',
17
- category: 'project-management',
18
- website: 'https://linear.app',
19
- docsUrl: 'https://developers.linear.app',
20
- requiredConfig: ['apiKey'],
21
- optionalConfig: [],
22
- };
23
- /**
24
- * GraphQL query helper
25
- */
26
- async function graphqlRequest(apiKey, query, variables) {
27
- const response = await fetch(LINEAR_API_URL, {
28
- method: 'POST',
29
- headers: {
30
- 'Content-Type': 'application/json',
31
- Authorization: apiKey,
32
- },
33
- body: JSON.stringify({ query, variables }),
34
- });
35
- const result = (await response.json());
36
- if (result.errors) {
37
- throw new Error(result.errors[0]?.message || 'GraphQL query failed');
38
- }
39
- return result.data;
40
- }
41
- /**
42
- * Create Linear project management provider
43
- */
44
- export function createLinearProvider(config) {
45
- let apiKey;
46
- return {
47
- info: linearInfo,
48
- async initialize(cfg) {
49
- apiKey = cfg.apiKey;
50
- if (!apiKey) {
51
- throw new Error('Linear API key is required');
52
- }
53
- },
54
- async healthCheck() {
55
- const start = Date.now();
56
- try {
57
- await graphqlRequest(apiKey, `query { viewer { id name } }`);
58
- return {
59
- healthy: true,
60
- latencyMs: Date.now() - start,
61
- message: 'Connected',
62
- checkedAt: new Date(),
63
- };
64
- }
65
- catch (error) {
66
- return {
67
- healthy: false,
68
- latencyMs: Date.now() - start,
69
- message: error instanceof Error ? error.message : 'Unknown error',
70
- checkedAt: new Date(),
71
- };
72
- }
73
- },
74
- async dispose() {
75
- // No cleanup needed
76
- },
77
- async listProjects(options) {
78
- const first = options?.limit || 50;
79
- const after = options?.cursor;
80
- const query = `
81
- query($first: Int!, $after: String) {
82
- projects(first: $first, after: $after) {
83
- nodes {
84
- id
85
- key
86
- name
87
- description
88
- lead {
89
- id
90
- }
91
- url
92
- }
93
- pageInfo {
94
- hasNextPage
95
- endCursor
96
- }
97
- }
98
- }
99
- `;
100
- const data = await graphqlRequest(apiKey, query, { first, after });
101
- return {
102
- items: data.projects.nodes.map((p) => ({
103
- id: p.id,
104
- key: p.key,
105
- name: p.name,
106
- description: p.description,
107
- lead: p.lead?.id,
108
- url: p.url,
109
- })),
110
- hasMore: data.projects.pageInfo.hasNextPage,
111
- nextCursor: data.projects.pageInfo.endCursor,
112
- };
113
- },
114
- async getProject(projectId) {
115
- const query = `
116
- query($id: String!) {
117
- project(id: $id) {
118
- id
119
- key
120
- name
121
- description
122
- lead {
123
- id
124
- }
125
- url
126
- }
127
- }
128
- `;
129
- try {
130
- const data = await graphqlRequest(apiKey, query, { id: projectId });
131
- if (!data.project) {
132
- return null;
133
- }
134
- return {
135
- id: data.project.id,
136
- key: data.project.key,
137
- name: data.project.name,
138
- description: data.project.description,
139
- lead: data.project.lead?.id,
140
- url: data.project.url,
141
- };
142
- }
143
- catch {
144
- return null;
145
- }
146
- },
147
- async createIssue(projectId, issue) {
148
- const query = `
149
- mutation($input: IssueCreateInput!) {
150
- issueCreate(input: $input) {
151
- success
152
- issue {
153
- id
154
- identifier
155
- title
156
- description
157
- state {
158
- name
159
- }
160
- priority
161
- priorityLabel
162
- labels {
163
- nodes {
164
- name
165
- }
166
- }
167
- assignee {
168
- id
169
- }
170
- creator {
171
- id
172
- }
173
- createdAt
174
- updatedAt
175
- url
176
- }
177
- }
178
- }
179
- `;
180
- const input = {
181
- projectId,
182
- title: issue.title,
183
- description: issue.description,
184
- ...(issue.type && { type: issue.type }),
185
- ...(issue.priority && { priority: parsePriority(issue.priority) }),
186
- ...(issue.assigneeId && { assigneeId: issue.assigneeId }),
187
- ...(issue.parentId && { parentId: issue.parentId }),
188
- ...(issue.estimate && { estimate: issue.estimate }),
189
- };
190
- if (issue.labels?.length) {
191
- input.labelIds = issue.labels;
192
- }
193
- const data = await graphqlRequest(apiKey, query, { input });
194
- if (!data.issueCreate.success) {
195
- throw new Error('Failed to create issue');
196
- }
197
- const created = data.issueCreate.issue;
198
- return {
199
- id: created.id,
200
- key: created.identifier,
201
- title: created.title,
202
- description: created.description,
203
- type: issue.type || 'Issue',
204
- status: created.state.name,
205
- priority: created.priorityLabel,
206
- labels: created.labels.nodes.map((l) => l.name),
207
- assigneeId: created.assignee?.id,
208
- reporterId: created.creator?.id,
209
- createdAt: new Date(created.createdAt),
210
- updatedAt: new Date(created.updatedAt),
211
- url: created.url,
212
- };
213
- },
214
- async getIssue(issueId) {
215
- const query = `
216
- query($id: String!) {
217
- issue(id: $id) {
218
- id
219
- identifier
220
- title
221
- description
222
- state {
223
- name
224
- }
225
- priority
226
- priorityLabel
227
- labels {
228
- nodes {
229
- name
230
- }
231
- }
232
- assignee {
233
- id
234
- }
235
- creator {
236
- id
237
- }
238
- createdAt
239
- updatedAt
240
- url
241
- }
242
- }
243
- `;
244
- try {
245
- const data = await graphqlRequest(apiKey, query, { id: issueId });
246
- if (!data.issue) {
247
- return null;
248
- }
249
- const issue = data.issue;
250
- return {
251
- id: issue.id,
252
- key: issue.identifier,
253
- title: issue.title,
254
- description: issue.description,
255
- type: 'Issue',
256
- status: issue.state.name,
257
- priority: issue.priorityLabel,
258
- labels: issue.labels.nodes.map((l) => l.name),
259
- assigneeId: issue.assignee?.id,
260
- reporterId: issue.creator?.id,
261
- createdAt: new Date(issue.createdAt),
262
- updatedAt: new Date(issue.updatedAt),
263
- url: issue.url,
264
- };
265
- }
266
- catch {
267
- return null;
268
- }
269
- },
270
- async updateIssue(issueId, updates) {
271
- const query = `
272
- mutation($id: String!, $input: IssueUpdateInput!) {
273
- issueUpdate(id: $id, input: $input) {
274
- success
275
- issue {
276
- id
277
- identifier
278
- title
279
- description
280
- state {
281
- name
282
- }
283
- priority
284
- priorityLabel
285
- labels {
286
- nodes {
287
- name
288
- }
289
- }
290
- assignee {
291
- id
292
- }
293
- creator {
294
- id
295
- }
296
- createdAt
297
- updatedAt
298
- url
299
- }
300
- }
301
- }
302
- `;
303
- const input = {};
304
- if (updates.title)
305
- input.title = updates.title;
306
- if (updates.description !== undefined)
307
- input.description = updates.description;
308
- if (updates.priority)
309
- input.priority = parsePriority(updates.priority);
310
- if (updates.assigneeId)
311
- input.assigneeId = updates.assigneeId;
312
- if (updates.estimate !== undefined)
313
- input.estimate = updates.estimate;
314
- const data = await graphqlRequest(apiKey, query, { id: issueId, input });
315
- if (!data.issueUpdate.success) {
316
- throw new Error('Failed to update issue');
317
- }
318
- const updated = data.issueUpdate.issue;
319
- return {
320
- id: updated.id,
321
- key: updated.identifier,
322
- title: updated.title,
323
- description: updated.description,
324
- type: 'Issue',
325
- status: updated.state.name,
326
- priority: updated.priorityLabel,
327
- labels: updated.labels.nodes.map((l) => l.name),
328
- assigneeId: updated.assignee?.id,
329
- reporterId: updated.creator?.id,
330
- createdAt: new Date(updated.createdAt),
331
- updatedAt: new Date(updated.updatedAt),
332
- url: updated.url,
333
- };
334
- },
335
- async deleteIssue(issueId) {
336
- const query = `
337
- mutation($id: String!) {
338
- issueDelete(id: $id) {
339
- success
340
- }
341
- }
342
- `;
343
- try {
344
- const data = await graphqlRequest(apiKey, query, { id: issueId });
345
- return data.issueDelete.success;
346
- }
347
- catch {
348
- return false;
349
- }
350
- },
351
- async listIssues(projectId, options) {
352
- const first = options?.limit || 50;
353
- const after = options?.cursor;
354
- // Build filter
355
- const filter = { project: { id: { eq: projectId } } };
356
- if (options?.status?.length) {
357
- filter.state = { name: { in: options.status } };
358
- }
359
- if (options?.assignee) {
360
- filter.assignee = { id: { eq: options.assignee } };
361
- }
362
- if (options?.labels?.length) {
363
- filter.labels = { name: { in: options.labels } };
364
- }
365
- const query = `
366
- query($first: Int!, $after: String, $filter: IssueFilter) {
367
- issues(first: $first, after: $after, filter: $filter) {
368
- nodes {
369
- id
370
- identifier
371
- title
372
- description
373
- state {
374
- name
375
- }
376
- priority
377
- priorityLabel
378
- labels {
379
- nodes {
380
- name
381
- }
382
- }
383
- assignee {
384
- id
385
- }
386
- creator {
387
- id
388
- }
389
- createdAt
390
- updatedAt
391
- url
392
- }
393
- pageInfo {
394
- hasNextPage
395
- endCursor
396
- }
397
- }
398
- }
399
- `;
400
- const data = await graphqlRequest(apiKey, query, { first, after, filter });
401
- return {
402
- items: data.issues.nodes.map((issue) => ({
403
- id: issue.id,
404
- key: issue.identifier,
405
- title: issue.title,
406
- description: issue.description,
407
- type: 'Issue',
408
- status: issue.state.name,
409
- priority: issue.priorityLabel,
410
- labels: issue.labels.nodes.map((l) => l.name),
411
- assigneeId: issue.assignee?.id,
412
- reporterId: issue.creator?.id,
413
- createdAt: new Date(issue.createdAt),
414
- updatedAt: new Date(issue.updatedAt),
415
- url: issue.url,
416
- })),
417
- hasMore: data.issues.pageInfo.hasNextPage,
418
- nextCursor: data.issues.pageInfo.endCursor,
419
- };
420
- },
421
- async searchIssues(query, options) {
422
- const first = options?.limit || 50;
423
- const after = options?.cursor;
424
- const graphqlQuery = `
425
- query($first: Int!, $after: String, $filter: IssueFilter) {
426
- issueSearch(first: $first, after: $after, query: $query, filter: $filter) {
427
- nodes {
428
- id
429
- identifier
430
- title
431
- description
432
- state {
433
- name
434
- }
435
- priority
436
- priorityLabel
437
- labels {
438
- nodes {
439
- name
440
- }
441
- }
442
- assignee {
443
- id
444
- }
445
- creator {
446
- id
447
- }
448
- createdAt
449
- updatedAt
450
- url
451
- }
452
- pageInfo {
453
- hasNextPage
454
- endCursor
455
- }
456
- }
457
- }
458
- `;
459
- // Build filter
460
- const filter = {};
461
- if (options?.status?.length) {
462
- filter.state = { name: { in: options.status } };
463
- }
464
- if (options?.assignee) {
465
- filter.assignee = { id: { eq: options.assignee } };
466
- }
467
- if (options?.labels?.length) {
468
- filter.labels = { name: { in: options.labels } };
469
- }
470
- const data = await graphqlRequest(apiKey, graphqlQuery, { first, after, query, filter });
471
- return {
472
- items: data.issueSearch.nodes.map((issue) => ({
473
- id: issue.id,
474
- key: issue.identifier,
475
- title: issue.title,
476
- description: issue.description,
477
- type: 'Issue',
478
- status: issue.state.name,
479
- priority: issue.priorityLabel,
480
- labels: issue.labels.nodes.map((l) => l.name),
481
- assigneeId: issue.assignee?.id,
482
- reporterId: issue.creator?.id,
483
- createdAt: new Date(issue.createdAt),
484
- updatedAt: new Date(issue.updatedAt),
485
- url: issue.url,
486
- })),
487
- hasMore: data.issueSearch.pageInfo.hasNextPage,
488
- nextCursor: data.issueSearch.pageInfo.endCursor,
489
- };
490
- },
491
- async addComment(issueId, body) {
492
- const query = `
493
- mutation($input: CommentCreateInput!) {
494
- commentCreate(input: $input) {
495
- success
496
- comment {
497
- id
498
- body
499
- user {
500
- id
501
- }
502
- createdAt
503
- }
504
- }
505
- }
506
- `;
507
- const data = await graphqlRequest(apiKey, query, {
508
- input: {
509
- issueId,
510
- body,
511
- },
512
- });
513
- if (!data.commentCreate.success) {
514
- throw new Error('Failed to create comment');
515
- }
516
- const comment = data.commentCreate.comment;
517
- return {
518
- id: comment.id,
519
- issueId,
520
- body: comment.body,
521
- authorId: comment.user.id,
522
- createdAt: new Date(comment.createdAt),
523
- };
524
- },
525
- async transition(issueId, statusId) {
526
- const query = `
527
- mutation($id: String!, $stateId: String!) {
528
- issueUpdate(id: $id, input: { stateId: $stateId }) {
529
- success
530
- }
531
- }
532
- `;
533
- try {
534
- const data = await graphqlRequest(apiKey, query, { id: issueId, stateId: statusId });
535
- return data.issueUpdate.success;
536
- }
537
- catch {
538
- return false;
539
- }
540
- },
541
- async assign(issueId, userId) {
542
- const query = `
543
- mutation($id: String!, $assigneeId: String!) {
544
- issueUpdate(id: $id, input: { assigneeId: $assigneeId }) {
545
- success
546
- }
547
- }
548
- `;
549
- try {
550
- const data = await graphqlRequest(apiKey, query, { id: issueId, assigneeId: userId });
551
- return data.issueUpdate.success;
552
- }
553
- catch {
554
- return false;
555
- }
556
- },
557
- };
558
- }
559
- /**
560
- * Parse priority string to Linear priority number
561
- */
562
- function parsePriority(priority) {
563
- const map = {
564
- urgent: 1,
565
- high: 2,
566
- medium: 3,
567
- low: 4,
568
- none: 0,
569
- };
570
- return map[priority.toLowerCase()] ?? 0;
571
- }
572
- /**
573
- * Linear provider definition
574
- */
575
- export const linearProvider = defineProvider(linearInfo, async (config) => createLinearProvider(config));
@@ -1,86 +0,0 @@
1
- /**
2
- * Provider Registry Implementation
3
- *
4
- * Central registry for discovering and instantiating providers.
5
- *
6
- * @packageDocumentation
7
- */
8
- /**
9
- * Create a new provider registry
10
- */
11
- export function createProviderRegistry() {
12
- const providers = new Map();
13
- return {
14
- register(info, factory) {
15
- if (providers.has(info.id)) {
16
- throw new Error(`Provider '${info.id}' is already registered`);
17
- }
18
- providers.set(info.id, { info, factory });
19
- },
20
- get(providerId) {
21
- return providers.get(providerId);
22
- },
23
- list(category) {
24
- const all = Array.from(providers.values());
25
- if (category) {
26
- return all.filter((p) => p.info.category === category);
27
- }
28
- return all;
29
- },
30
- async create(providerId, config) {
31
- const registered = providers.get(providerId);
32
- if (!registered) {
33
- throw new Error(`Provider '${providerId}' not found. Available: ${Array.from(providers.keys()).join(', ')}`);
34
- }
35
- // Validate required config
36
- const missing = registered.info.requiredConfig.filter((key) => !(key in config));
37
- if (missing.length > 0) {
38
- throw new Error(`Provider '${providerId}' missing required config: ${missing.join(', ')}`);
39
- }
40
- const provider = await registered.factory(config);
41
- await provider.initialize(config);
42
- return provider;
43
- },
44
- has(providerId) {
45
- return providers.has(providerId);
46
- },
47
- };
48
- }
49
- /**
50
- * Global provider registry instance
51
- */
52
- export const providerRegistry = createProviderRegistry();
53
- /**
54
- * Register a provider in the global registry
55
- */
56
- export function registerProvider(info, factory) {
57
- providerRegistry.register(info, factory);
58
- }
59
- /**
60
- * Get a provider from the global registry
61
- */
62
- export function getProvider(providerId) {
63
- return providerRegistry.get(providerId);
64
- }
65
- /**
66
- * Create a provider instance from the global registry
67
- */
68
- export async function createProvider(providerId, config) {
69
- return providerRegistry.create(providerId, config);
70
- }
71
- /**
72
- * List providers by category
73
- */
74
- export function listProviders(category) {
75
- return providerRegistry.list(category);
76
- }
77
- /**
78
- * Helper to define a provider with type safety
79
- */
80
- export function defineProvider(info, factory) {
81
- return {
82
- info,
83
- factory,
84
- register: () => registerProvider(info, factory),
85
- };
86
- }