runline 0.2.1 → 0.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 (203) hide show
  1. package/dist/commands/auth.d.ts +7 -0
  2. package/dist/commands/auth.js +96 -0
  3. package/dist/config/loader.d.ts +11 -0
  4. package/dist/config/loader.js +46 -0
  5. package/dist/core/engine.js +7 -1
  6. package/dist/core/oauth.d.ts +46 -0
  7. package/dist/core/oauth.js +145 -0
  8. package/dist/index.d.ts +4 -2
  9. package/dist/index.js +2 -1
  10. package/dist/main.js +28 -0
  11. package/dist/plugin/api.d.ts +7 -1
  12. package/dist/plugin/api.js +7 -0
  13. package/dist/plugin/types.d.ts +47 -0
  14. package/dist/plugins/actionNetwork/src/index.js +118 -25
  15. package/dist/plugins/activeCampaign/src/index.js +184 -38
  16. package/dist/plugins/adalo/src/index.js +40 -8
  17. package/dist/plugins/affinity/src/index.js +100 -20
  18. package/dist/plugins/agileCrm/src/index.js +115 -27
  19. package/dist/plugins/airtable/src/index.js +94 -19
  20. package/dist/plugins/airtop/src/index.js +266 -62
  21. package/dist/plugins/apiTemplateIo/src/index.js +25 -5
  22. package/dist/plugins/asana/src/index.js +195 -41
  23. package/dist/plugins/autopilot/src/index.js +39 -8
  24. package/dist/plugins/bambooHr/src/index.js +109 -22
  25. package/dist/plugins/bannerbear/src/index.js +36 -8
  26. package/dist/plugins/baserow/src/index.js +35 -7
  27. package/dist/plugins/beeminder/src/index.js +198 -40
  28. package/dist/plugins/bitly/src/index.js +46 -10
  29. package/dist/plugins/bitwarden/src/index.js +167 -36
  30. package/dist/plugins/box/src/index.js +172 -37
  31. package/dist/plugins/brandfetch/src/index.js +5 -1
  32. package/dist/plugins/brevo/src/index.js +136 -29
  33. package/dist/plugins/bubble/src/index.js +76 -17
  34. package/dist/plugins/chargebee/src/index.js +35 -7
  35. package/dist/plugins/circleci/src/index.js +50 -10
  36. package/dist/plugins/ciscoWebex/src/index.js +131 -27
  37. package/dist/plugins/clearbit/src/index.js +76 -17
  38. package/dist/plugins/clickup/src/index.js +500 -107
  39. package/dist/plugins/clockify/src/index.js +229 -47
  40. package/dist/plugins/cloudflare/src/index.js +28 -6
  41. package/dist/plugins/cockpit/src/index.js +54 -12
  42. package/dist/plugins/coda/src/index.js +81 -19
  43. package/dist/plugins/coingecko/src/index.js +157 -33
  44. package/dist/plugins/contentful/src/index.js +85 -17
  45. package/dist/plugins/convertkit/src/index.js +74 -18
  46. package/dist/plugins/copper/src/index.js +59 -11
  47. package/dist/plugins/cortex/src/index.js +55 -13
  48. package/dist/plugins/currents/src/index.js +310 -71
  49. package/dist/plugins/customerIo/src/index.js +112 -23
  50. package/dist/plugins/databricks/src/index.js +549 -115
  51. package/dist/plugins/deepl/src/index.js +26 -6
  52. package/dist/plugins/demio/src/index.js +56 -11
  53. package/dist/plugins/dhl/src/index.js +16 -3
  54. package/dist/plugins/discord/src/index.js +141 -31
  55. package/dist/plugins/discourse/src/index.js +136 -31
  56. package/dist/plugins/disqus/src/index.js +96 -20
  57. package/dist/plugins/docker/src/index.js +20 -4
  58. package/dist/plugins/drift/src/index.js +19 -5
  59. package/dist/plugins/dropbox/src/index.js +139 -30
  60. package/dist/plugins/dropcontact/src/index.js +21 -4
  61. package/dist/plugins/egoi/src/index.js +61 -15
  62. package/dist/plugins/elasticsearch/src/index.js +59 -13
  63. package/dist/plugins/emelia/src/index.js +95 -19
  64. package/dist/plugins/erpnext/src/index.js +74 -15
  65. package/dist/plugins/facebookGraph/src/index.js +52 -11
  66. package/dist/plugins/freshdesk/src/index.js +220 -48
  67. package/dist/plugins/freshservice/src/index.js +39 -9
  68. package/dist/plugins/freshworksCrm/src/index.js +58 -12
  69. package/dist/plugins/getresponse/src/index.js +87 -18
  70. package/dist/plugins/ghost/src/index.js +114 -26
  71. package/dist/plugins/github/src/index.js +483 -109
  72. package/dist/plugins/gitlab/src/index.js +193 -45
  73. package/dist/plugins/gmail/src/index.js +1075 -0
  74. package/dist/plugins/gong/src/index.js +68 -14
  75. package/dist/plugins/gotify/src/index.js +43 -9
  76. package/dist/plugins/gotowebinar/src/index.js +233 -47
  77. package/dist/plugins/grafana/src/index.js +92 -21
  78. package/dist/plugins/graphql/src/index.js +38 -8
  79. package/dist/plugins/grist/src/index.js +52 -10
  80. package/dist/plugins/hackernews/src/index.js +32 -6
  81. package/dist/plugins/halopsa/src/index.js +131 -26
  82. package/dist/plugins/harvest/src/index.js +182 -42
  83. package/dist/plugins/helpscout/src/index.js +153 -31
  84. package/dist/plugins/highlevel/src/index.js +291 -58
  85. package/dist/plugins/homeAssistant/src/index.js +124 -26
  86. package/dist/plugins/hubspot/src/index.js +163 -29
  87. package/dist/plugins/humanticAi/src/index.js +54 -5
  88. package/dist/plugins/hunter/src/index.js +21 -4
  89. package/dist/plugins/intercom/src/index.js +95 -20
  90. package/dist/plugins/iterable/src/index.js +96 -20
  91. package/dist/plugins/jenkins/src/index.js +75 -17
  92. package/dist/plugins/jira/src/index.js +193 -43
  93. package/dist/plugins/keap/src/index.js +222 -56
  94. package/dist/plugins/kobotoolbox/src/index.js +113 -25
  95. package/dist/plugins/lemlist/src/index.js +79 -18
  96. package/dist/plugins/linear/src/index.js +86 -19
  97. package/dist/plugins/lingvanex/src/index.js +38 -8
  98. package/dist/plugins/linkedin/src/index.js +37 -8
  99. package/dist/plugins/lonescale/src/index.js +41 -9
  100. package/dist/plugins/magento/src/index.js +98 -27
  101. package/dist/plugins/mailcheck/src/index.js +11 -2
  102. package/dist/plugins/mailchimp/src/index.js +193 -42
  103. package/dist/plugins/mailerlite/src/index.js +61 -12
  104. package/dist/plugins/mailgun/src/index.js +39 -7
  105. package/dist/plugins/mailjet/src/index.js +141 -30
  106. package/dist/plugins/mandrill/src/index.js +67 -14
  107. package/dist/plugins/marketstack/src/index.js +56 -10
  108. package/dist/plugins/matrix/src/index.js +97 -20
  109. package/dist/plugins/mattermost/src/index.js +124 -26
  110. package/dist/plugins/mautic/src/index.js +129 -26
  111. package/dist/plugins/medium/src/index.js +64 -13
  112. package/dist/plugins/messagebird/src/index.js +80 -15
  113. package/dist/plugins/metabase/src/index.js +57 -12
  114. package/dist/plugins/misp/src/index.js +135 -33
  115. package/dist/plugins/mocean/src/index.js +33 -7
  116. package/dist/plugins/monday/src/index.js +97 -23
  117. package/dist/plugins/monicaCrm/src/index.js +112 -23
  118. package/dist/plugins/msg91/src/index.js +11 -2
  119. package/dist/plugins/nasa/src/index.js +108 -21
  120. package/dist/plugins/netlify/src/index.js +28 -6
  121. package/dist/plugins/netscalerAdc/src/index.js +144 -29
  122. package/dist/plugins/nextcloud/src/index.js +103 -20
  123. package/dist/plugins/nocodb/src/index.js +57 -11
  124. package/dist/plugins/notion/src/index.js +148 -37
  125. package/dist/plugins/npm/src/index.js +59 -12
  126. package/dist/plugins/odoo/src/index.js +102 -20
  127. package/dist/plugins/okta/src/index.js +50 -10
  128. package/dist/plugins/oneSimpleApi/src/index.js +84 -17
  129. package/dist/plugins/onfleet/src/index.js +139 -32
  130. package/dist/plugins/openThesaurus/src/index.js +46 -9
  131. package/dist/plugins/openweathermap/src/index.js +31 -6
  132. package/dist/plugins/oura/src/index.js +36 -7
  133. package/dist/plugins/paddle/src/index.js +80 -17
  134. package/dist/plugins/pagerduty/src/index.js +53 -12
  135. package/dist/plugins/paypal/src/index.js +51 -11
  136. package/dist/plugins/peekalink/src/index.js +12 -3
  137. package/dist/plugins/phantombuster/src/index.js +39 -8
  138. package/dist/plugins/philipsHue/src/index.js +64 -13
  139. package/dist/plugins/pipedrive/src/index.js +167 -45
  140. package/dist/plugins/plivo/src/index.js +43 -8
  141. package/dist/plugins/postbin/src/index.js +9 -2
  142. package/dist/plugins/posthog/src/index.js +50 -13
  143. package/dist/plugins/profitwell/src/index.js +24 -5
  144. package/dist/plugins/pushbullet/src/index.js +45 -9
  145. package/dist/plugins/pushcut/src/index.js +31 -6
  146. package/dist/plugins/pushover/src/index.js +51 -10
  147. package/dist/plugins/quickbase/src/index.js +66 -13
  148. package/dist/plugins/quickbooks/src/index.js +86 -19
  149. package/dist/plugins/quickchart/src/index.js +35 -7
  150. package/dist/plugins/raindrop/src/index.js +54 -13
  151. package/dist/plugins/reddit/src/index.js +73 -18
  152. package/dist/plugins/rocketchat/src/index.js +47 -9
  153. package/dist/plugins/rundeck/src/index.js +26 -5
  154. package/dist/plugins/salesforce/src/index.js +161 -31
  155. package/dist/plugins/salesmate/src/index.js +75 -16
  156. package/dist/plugins/securityScorecard/src/index.js +73 -15
  157. package/dist/plugins/segment/src/index.js +21 -4
  158. package/dist/plugins/sendgrid/src/index.js +102 -24
  159. package/dist/plugins/sendy/src/index.js +54 -11
  160. package/dist/plugins/sentry/src/index.js +174 -34
  161. package/dist/plugins/servicenow/src/index.js +120 -27
  162. package/dist/plugins/shopify/src/index.js +53 -12
  163. package/dist/plugins/signl4/src/index.js +16 -3
  164. package/dist/plugins/slack/src/index.js +407 -105
  165. package/dist/plugins/sms77/src/index.js +26 -5
  166. package/dist/plugins/splunk/src/index.js +186 -45
  167. package/dist/plugins/spotify/src/index.js +265 -66
  168. package/dist/plugins/stackby/src/index.js +18 -6
  169. package/dist/plugins/storyblok/src/index.js +57 -11
  170. package/dist/plugins/strapi/src/index.js +63 -12
  171. package/dist/plugins/strava/src/index.js +58 -13
  172. package/dist/plugins/stripe/src/index.js +143 -30
  173. package/dist/plugins/supabase/src/index.js +49 -10
  174. package/dist/plugins/syncromsp/src/index.js +245 -67
  175. package/dist/plugins/tapfiliate/src/index.js +57 -14
  176. package/dist/plugins/telegram/src/index.js +202 -39
  177. package/dist/plugins/thehive/src/index.js +271 -66
  178. package/dist/plugins/thehiveProject/src/index.js +457 -89
  179. package/dist/plugins/todoist/src/index.js +326 -77
  180. package/dist/plugins/travisci/src/index.js +35 -8
  181. package/dist/plugins/trello/src/index.js +204 -46
  182. package/dist/plugins/twake/src/index.js +10 -2
  183. package/dist/plugins/twilio/src/index.js +56 -11
  184. package/dist/plugins/twist/src/index.js +241 -48
  185. package/dist/plugins/twitter/src/index.js +128 -30
  186. package/dist/plugins/unleashedSoftware/src/index.js +30 -6
  187. package/dist/plugins/uplead/src/index.js +9 -2
  188. package/dist/plugins/uproc/src/index.js +31 -6
  189. package/dist/plugins/uptimerobot/src/index.js +119 -25
  190. package/dist/plugins/urlscanio/src/index.js +25 -6
  191. package/dist/plugins/vero/src/index.js +68 -13
  192. package/dist/plugins/vonage/src/index.js +32 -6
  193. package/dist/plugins/wekan/src/index.js +297 -52
  194. package/dist/plugins/woocommerce/src/index.js +57 -12
  195. package/dist/plugins/wordpress/src/index.js +94 -18
  196. package/dist/plugins/xero/src/index.js +79 -13
  197. package/dist/plugins/yourls/src/index.js +33 -6
  198. package/dist/plugins/zammad/src/index.js +139 -36
  199. package/dist/plugins/zendesk/src/index.js +201 -48
  200. package/dist/plugins/zoho/src/index.js +88 -21
  201. package/dist/plugins/zoom/src/index.js +41 -7
  202. package/dist/plugins/zulip/src/index.js +101 -20
  203. package/package.json +3 -1
@@ -11,7 +11,13 @@ async function apiRequest(conn, method, endpoint, body, qs) {
11
11
  url.searchParams.set(k, String(v));
12
12
  }
13
13
  }
14
- const init = { method, headers: { Authorization: `Bearer ${conn.token}`, "Content-Type": "application/json" } };
14
+ const init = {
15
+ method,
16
+ headers: {
17
+ Authorization: `Bearer ${conn.token}`,
18
+ "Content-Type": "application/json",
19
+ },
20
+ };
15
21
  if (body && Object.keys(body).length > 0)
16
22
  init.body = JSON.stringify(body);
17
23
  const res = await fetch(url.toString(), init);
@@ -23,7 +29,10 @@ async function apiRequest(conn, method, endpoint, body, qs) {
23
29
  function registerCrud(rl, resource, basePath, idField, extraCreateFields) {
24
30
  rl.registerAction(`${resource}.get`, {
25
31
  description: `Get a ${resource} by ${idField}`,
26
- inputSchema: { [idField]: { type: "string", required: true }, org: { type: "string", required: true, description: "Organization slug" } },
32
+ inputSchema: {
33
+ [idField]: { type: "string", required: true },
34
+ org: { type: "string", required: true, description: "Organization slug" },
35
+ },
27
36
  async execute(input, ctx) {
28
37
  const p = input;
29
38
  return apiRequest(getConn(ctx), "GET", `${basePath(p)}${p[idField]}/`);
@@ -31,7 +40,19 @@ function registerCrud(rl, resource, basePath, idField, extraCreateFields) {
31
40
  });
32
41
  rl.registerAction(`${resource}.list`, {
33
42
  description: `List ${resource}s`,
34
- inputSchema: { org: { type: "string", required: true }, limit: { type: "number", required: false }, ...(resource === "event" || resource === "issue" ? { project: { type: "string", required: true, description: "Project slug" } } : {}) },
43
+ inputSchema: {
44
+ org: { type: "string", required: true },
45
+ limit: { type: "number", required: false },
46
+ ...(resource === "event" || resource === "issue"
47
+ ? {
48
+ project: {
49
+ type: "string",
50
+ required: true,
51
+ description: "Project slug",
52
+ },
53
+ }
54
+ : {}),
55
+ },
35
56
  async execute(input, ctx) {
36
57
  const p = (input ?? {});
37
58
  const qs = {};
@@ -43,7 +64,10 @@ function registerCrud(rl, resource, basePath, idField, extraCreateFields) {
43
64
  });
44
65
  rl.registerAction(`${resource}.delete`, {
45
66
  description: `Delete a ${resource}`,
46
- inputSchema: { [idField]: { type: "string", required: true }, org: { type: "string", required: true } },
67
+ inputSchema: {
68
+ [idField]: { type: "string", required: true },
69
+ org: { type: "string", required: true },
70
+ },
47
71
  async execute(input, ctx) {
48
72
  const p = input;
49
73
  await apiRequest(getConn(ctx), "DELETE", `${basePath(p)}${p[idField]}/`);
@@ -55,13 +79,27 @@ export default function sentry(rl) {
55
79
  rl.setName("sentry");
56
80
  rl.setVersion("0.1.0");
57
81
  rl.setConnectionSchema({
58
- token: { type: "string", required: true, description: "Sentry auth token (Bearer)", env: "SENTRY_TOKEN" },
59
- url: { type: "string", required: false, description: "Sentry base URL (default https://sentry.io)", env: "SENTRY_URL" },
82
+ token: {
83
+ type: "string",
84
+ required: true,
85
+ description: "Sentry auth token (Bearer)",
86
+ env: "SENTRY_TOKEN",
87
+ },
88
+ url: {
89
+ type: "string",
90
+ required: false,
91
+ description: "Sentry base URL (default https://sentry.io)",
92
+ env: "SENTRY_URL",
93
+ },
60
94
  });
61
95
  // ── Event ───────────────────────────────────────────
62
96
  rl.registerAction("event.get", {
63
97
  description: "Get a project event by ID",
64
- inputSchema: { org: { type: "string", required: true }, project: { type: "string", required: true }, eventId: { type: "string", required: true } },
98
+ inputSchema: {
99
+ org: { type: "string", required: true },
100
+ project: { type: "string", required: true },
101
+ eventId: { type: "string", required: true },
102
+ },
65
103
  async execute(input, ctx) {
66
104
  const p = input;
67
105
  return apiRequest(getConn(ctx), "GET", `/api/0/projects/${p.org}/${p.project}/events/${p.eventId}/`);
@@ -69,7 +107,12 @@ export default function sentry(rl) {
69
107
  });
70
108
  rl.registerAction("event.list", {
71
109
  description: "List project events",
72
- inputSchema: { org: { type: "string", required: true }, project: { type: "string", required: true }, full: { type: "boolean", required: false }, limit: { type: "number", required: false } },
110
+ inputSchema: {
111
+ org: { type: "string", required: true },
112
+ project: { type: "string", required: true },
113
+ full: { type: "boolean", required: false },
114
+ limit: { type: "number", required: false },
115
+ },
73
116
  async execute(input, ctx) {
74
117
  const p = (input ?? {});
75
118
  const qs = {};
@@ -84,11 +127,18 @@ export default function sentry(rl) {
84
127
  rl.registerAction("issue.get", {
85
128
  description: "Get an issue by ID",
86
129
  inputSchema: { issueId: { type: "string", required: true } },
87
- async execute(input, ctx) { return apiRequest(getConn(ctx), "GET", `/api/0/issues/${input.issueId}/`); },
130
+ async execute(input, ctx) {
131
+ return apiRequest(getConn(ctx), "GET", `/api/0/issues/${input.issueId}/`);
132
+ },
88
133
  });
89
134
  rl.registerAction("issue.list", {
90
135
  description: "List issues for a project",
91
- inputSchema: { org: { type: "string", required: true }, project: { type: "string", required: true }, query: { type: "string", required: false }, limit: { type: "number", required: false } },
136
+ inputSchema: {
137
+ org: { type: "string", required: true },
138
+ project: { type: "string", required: true },
139
+ query: { type: "string", required: false },
140
+ limit: { type: "number", required: false },
141
+ },
92
142
  async execute(input, ctx) {
93
143
  const p = (input ?? {});
94
144
  const qs = {};
@@ -101,7 +151,13 @@ export default function sentry(rl) {
101
151
  });
102
152
  rl.registerAction("issue.update", {
103
153
  description: "Update an issue",
104
- inputSchema: { issueId: { type: "string", required: true }, status: { type: "string", required: false }, assignedTo: { type: "string", required: false }, hasSeen: { type: "boolean", required: false }, isBookmarked: { type: "boolean", required: false } },
154
+ inputSchema: {
155
+ issueId: { type: "string", required: true },
156
+ status: { type: "string", required: false },
157
+ assignedTo: { type: "string", required: false },
158
+ hasSeen: { type: "boolean", required: false },
159
+ isBookmarked: { type: "boolean", required: false },
160
+ },
105
161
  async execute(input, ctx) {
106
162
  const { issueId, ...fields } = input;
107
163
  return apiRequest(getConn(ctx), "PUT", `/api/0/issues/${issueId}/`, fields);
@@ -110,13 +166,18 @@ export default function sentry(rl) {
110
166
  rl.registerAction("issue.delete", {
111
167
  description: "Delete an issue",
112
168
  inputSchema: { issueId: { type: "string", required: true } },
113
- async execute(input, ctx) { await apiRequest(getConn(ctx), "DELETE", `/api/0/issues/${input.issueId}/`); return { success: true }; },
169
+ async execute(input, ctx) {
170
+ await apiRequest(getConn(ctx), "DELETE", `/api/0/issues/${input.issueId}/`);
171
+ return { success: true };
172
+ },
114
173
  });
115
174
  // ── Organization ────────────────────────────────────
116
175
  rl.registerAction("organization.get", {
117
176
  description: "Get an organization",
118
177
  inputSchema: { org: { type: "string", required: true } },
119
- async execute(input, ctx) { return apiRequest(getConn(ctx), "GET", `/api/0/organizations/${input.org}/`); },
178
+ async execute(input, ctx) {
179
+ return apiRequest(getConn(ctx), "GET", `/api/0/organizations/${input.org}/`);
180
+ },
120
181
  });
121
182
  rl.registerAction("organization.list", {
122
183
  description: "List organizations",
@@ -130,26 +191,49 @@ export default function sentry(rl) {
130
191
  });
131
192
  rl.registerAction("organization.create", {
132
193
  description: "Create an organization",
133
- inputSchema: { name: { type: "string", required: true }, slug: { type: "string", required: false } },
194
+ inputSchema: {
195
+ name: { type: "string", required: true },
196
+ slug: { type: "string", required: false },
197
+ },
134
198
  async execute(input, ctx) {
135
199
  const p = input;
136
- return apiRequest(getConn(ctx), "POST", "/api/0/organizations/", { name: p.name, agreeTerms: true, slug: p.slug });
200
+ return apiRequest(getConn(ctx), "POST", "/api/0/organizations/", {
201
+ name: p.name,
202
+ agreeTerms: true,
203
+ slug: p.slug,
204
+ });
137
205
  },
138
206
  });
139
207
  // ── Project ─────────────────────────────────────────
140
208
  rl.registerAction("project.get", {
141
209
  description: "Get a project",
142
- inputSchema: { org: { type: "string", required: true }, project: { type: "string", required: true } },
143
- async execute(input, ctx) { const p = input; return apiRequest(getConn(ctx), "GET", `/api/0/projects/${p.org}/${p.project}/`); },
210
+ inputSchema: {
211
+ org: { type: "string", required: true },
212
+ project: { type: "string", required: true },
213
+ },
214
+ async execute(input, ctx) {
215
+ const p = input;
216
+ return apiRequest(getConn(ctx), "GET", `/api/0/projects/${p.org}/${p.project}/`);
217
+ },
144
218
  });
145
219
  rl.registerAction("project.list", {
146
220
  description: "List all projects",
147
221
  inputSchema: { limit: { type: "number", required: false } },
148
- async execute(input, ctx) { return apiRequest(getConn(ctx), "GET", "/api/0/projects/", undefined, input?.limit ? { limit: input.limit } : undefined); },
222
+ async execute(input, ctx) {
223
+ return apiRequest(getConn(ctx), "GET", "/api/0/projects/", undefined, input?.limit
224
+ ? { limit: input.limit }
225
+ : undefined);
226
+ },
149
227
  });
150
228
  rl.registerAction("project.create", {
151
229
  description: "Create a project",
152
- inputSchema: { org: { type: "string", required: true }, team: { type: "string", required: true }, name: { type: "string", required: true }, slug: { type: "string", required: false }, platform: { type: "string", required: false } },
230
+ inputSchema: {
231
+ org: { type: "string", required: true },
232
+ team: { type: "string", required: true },
233
+ name: { type: "string", required: true },
234
+ slug: { type: "string", required: false },
235
+ platform: { type: "string", required: false },
236
+ },
153
237
  async execute(input, ctx) {
154
238
  const p = input;
155
239
  const body = { name: p.name };
@@ -162,18 +246,35 @@ export default function sentry(rl) {
162
246
  });
163
247
  rl.registerAction("project.delete", {
164
248
  description: "Delete a project",
165
- inputSchema: { org: { type: "string", required: true }, project: { type: "string", required: true } },
166
- async execute(input, ctx) { const p = input; await apiRequest(getConn(ctx), "DELETE", `/api/0/projects/${p.org}/${p.project}/`); return { success: true }; },
249
+ inputSchema: {
250
+ org: { type: "string", required: true },
251
+ project: { type: "string", required: true },
252
+ },
253
+ async execute(input, ctx) {
254
+ const p = input;
255
+ await apiRequest(getConn(ctx), "DELETE", `/api/0/projects/${p.org}/${p.project}/`);
256
+ return { success: true };
257
+ },
167
258
  });
168
259
  // ── Release ─────────────────────────────────────────
169
260
  rl.registerAction("release.get", {
170
261
  description: "Get a release",
171
- inputSchema: { org: { type: "string", required: true }, version: { type: "string", required: true } },
172
- async execute(input, ctx) { const p = input; return apiRequest(getConn(ctx), "GET", `/api/0/organizations/${p.org}/releases/${encodeURIComponent(p.version)}/`); },
262
+ inputSchema: {
263
+ org: { type: "string", required: true },
264
+ version: { type: "string", required: true },
265
+ },
266
+ async execute(input, ctx) {
267
+ const p = input;
268
+ return apiRequest(getConn(ctx), "GET", `/api/0/organizations/${p.org}/releases/${encodeURIComponent(p.version)}/`);
269
+ },
173
270
  });
174
271
  rl.registerAction("release.list", {
175
272
  description: "List releases",
176
- inputSchema: { org: { type: "string", required: true }, query: { type: "string", required: false }, limit: { type: "number", required: false } },
273
+ inputSchema: {
274
+ org: { type: "string", required: true },
275
+ query: { type: "string", required: false },
276
+ limit: { type: "number", required: false },
277
+ },
177
278
  async execute(input, ctx) {
178
279
  const p = (input ?? {});
179
280
  const qs = {};
@@ -186,10 +287,22 @@ export default function sentry(rl) {
186
287
  });
187
288
  rl.registerAction("release.create", {
188
289
  description: "Create a release",
189
- inputSchema: { org: { type: "string", required: true }, version: { type: "string", required: true }, projects: { type: "object", required: true, description: "Array of project slugs" }, url: { type: "string", required: false } },
290
+ inputSchema: {
291
+ org: { type: "string", required: true },
292
+ version: { type: "string", required: true },
293
+ projects: {
294
+ type: "object",
295
+ required: true,
296
+ description: "Array of project slugs",
297
+ },
298
+ url: { type: "string", required: false },
299
+ },
190
300
  async execute(input, ctx) {
191
301
  const p = input;
192
- const body = { version: p.version, projects: p.projects };
302
+ const body = {
303
+ version: p.version,
304
+ projects: p.projects,
305
+ };
193
306
  if (p.url)
194
307
  body.url = p.url;
195
308
  return apiRequest(getConn(ctx), "POST", `/api/0/organizations/${p.org}/releases/`, body);
@@ -197,18 +310,34 @@ export default function sentry(rl) {
197
310
  });
198
311
  rl.registerAction("release.delete", {
199
312
  description: "Delete a release",
200
- inputSchema: { org: { type: "string", required: true }, version: { type: "string", required: true } },
201
- async execute(input, ctx) { const p = input; await apiRequest(getConn(ctx), "DELETE", `/api/0/organizations/${p.org}/releases/${encodeURIComponent(p.version)}/`); return { success: true }; },
313
+ inputSchema: {
314
+ org: { type: "string", required: true },
315
+ version: { type: "string", required: true },
316
+ },
317
+ async execute(input, ctx) {
318
+ const p = input;
319
+ await apiRequest(getConn(ctx), "DELETE", `/api/0/organizations/${p.org}/releases/${encodeURIComponent(p.version)}/`);
320
+ return { success: true };
321
+ },
202
322
  });
203
323
  // ── Team ────────────────────────────────────────────
204
324
  rl.registerAction("team.get", {
205
325
  description: "Get a team",
206
- inputSchema: { org: { type: "string", required: true }, team: { type: "string", required: true } },
207
- async execute(input, ctx) { const p = input; return apiRequest(getConn(ctx), "GET", `/api/0/teams/${p.org}/${p.team}/`); },
326
+ inputSchema: {
327
+ org: { type: "string", required: true },
328
+ team: { type: "string", required: true },
329
+ },
330
+ async execute(input, ctx) {
331
+ const p = input;
332
+ return apiRequest(getConn(ctx), "GET", `/api/0/teams/${p.org}/${p.team}/`);
333
+ },
208
334
  });
209
335
  rl.registerAction("team.list", {
210
336
  description: "List teams in an organization",
211
- inputSchema: { org: { type: "string", required: true }, limit: { type: "number", required: false } },
337
+ inputSchema: {
338
+ org: { type: "string", required: true },
339
+ limit: { type: "number", required: false },
340
+ },
212
341
  async execute(input, ctx) {
213
342
  const p = (input ?? {});
214
343
  return apiRequest(getConn(ctx), "GET", `/api/0/organizations/${p.org}/teams/`, undefined, p.limit ? { limit: p.limit } : undefined);
@@ -216,7 +345,11 @@ export default function sentry(rl) {
216
345
  });
217
346
  rl.registerAction("team.create", {
218
347
  description: "Create a team",
219
- inputSchema: { org: { type: "string", required: true }, name: { type: "string", required: true }, slug: { type: "string", required: false } },
348
+ inputSchema: {
349
+ org: { type: "string", required: true },
350
+ name: { type: "string", required: true },
351
+ slug: { type: "string", required: false },
352
+ },
220
353
  async execute(input, ctx) {
221
354
  const p = input;
222
355
  const body = { name: p.name };
@@ -227,7 +360,14 @@ export default function sentry(rl) {
227
360
  });
228
361
  rl.registerAction("team.delete", {
229
362
  description: "Delete a team",
230
- inputSchema: { org: { type: "string", required: true }, team: { type: "string", required: true } },
231
- async execute(input, ctx) { const p = input; await apiRequest(getConn(ctx), "DELETE", `/api/0/teams/${p.org}/${p.team}/`); return { success: true }; },
363
+ inputSchema: {
364
+ org: { type: "string", required: true },
365
+ team: { type: "string", required: true },
366
+ },
367
+ async execute(input, ctx) {
368
+ const p = input;
369
+ await apiRequest(getConn(ctx), "DELETE", `/api/0/teams/${p.org}/${p.team}/`);
370
+ return { success: true };
371
+ },
232
372
  });
233
373
  }
@@ -1,6 +1,10 @@
1
1
  function getConn(ctx) {
2
2
  const c = ctx.connection.config;
3
- return { subdomain: c.subdomain, username: c.username, password: c.password };
3
+ return {
4
+ subdomain: c.subdomain,
5
+ username: c.username,
6
+ password: c.password,
7
+ };
4
8
  }
5
9
  async function api(conn, method, endpoint, body, qs) {
6
10
  const url = new URL(`https://${conn.subdomain}.service-now.com/api${endpoint}`);
@@ -10,7 +14,14 @@ async function api(conn, method, endpoint, body, qs) {
10
14
  url.searchParams.set(k, String(v));
11
15
  }
12
16
  }
13
- const init = { method, headers: { Authorization: `Basic ${btoa(`${conn.username}:${conn.password}`)}`, "Content-Type": "application/json", Accept: "application/json" } };
17
+ const init = {
18
+ method,
19
+ headers: {
20
+ Authorization: `Basic ${btoa(`${conn.username}:${conn.password}`)}`,
21
+ "Content-Type": "application/json",
22
+ Accept: "application/json",
23
+ },
24
+ };
14
25
  if (body && Object.keys(body).length > 0)
15
26
  init.body = JSON.stringify(body);
16
27
  const res = await fetch(url.toString(), init);
@@ -19,21 +30,46 @@ async function api(conn, method, endpoint, body, qs) {
19
30
  return res.json();
20
31
  }
21
32
  const TABLES = {
22
- incident: "incident", user: "sys_user", userGroup: "sys_user_group", userRole: "sys_user_role",
23
- businessService: "cmdb_ci_service", configurationItem: "cmdb_ci", department: "cmn_department",
33
+ incident: "incident",
34
+ user: "sys_user",
35
+ userGroup: "sys_user_group",
36
+ userRole: "sys_user_role",
37
+ businessService: "cmdb_ci_service",
38
+ configurationItem: "cmdb_ci",
39
+ department: "cmn_department",
24
40
  };
25
41
  function registerTableResource(rl, resource, table, conn) {
26
- rl.registerAction(`${resource}.create`, { description: `Create a ${resource}`, inputSchema: { data: { type: "object", required: true } },
42
+ rl.registerAction(`${resource}.create`, {
43
+ description: `Create a ${resource}`,
44
+ inputSchema: { data: { type: "object", required: true } },
27
45
  async execute(input, ctx) {
28
46
  const data = (await api(conn(ctx), "POST", `/now/table/${table}`, input.data));
29
47
  return data.result;
30
- } });
31
- rl.registerAction(`${resource}.get`, { description: `Get a ${resource} by sys_id`, inputSchema: { sysId: { type: "string", required: true } },
48
+ },
49
+ });
50
+ rl.registerAction(`${resource}.get`, {
51
+ description: `Get a ${resource} by sys_id`,
52
+ inputSchema: { sysId: { type: "string", required: true } },
32
53
  async execute(input, ctx) {
33
54
  const data = (await api(conn(ctx), "GET", `/now/table/${table}/${input.sysId}`));
34
55
  return data.result;
35
- } });
36
- rl.registerAction(`${resource}.list`, { description: `List ${resource}s`, inputSchema: { limit: { type: "number", required: false }, query: { type: "string", required: false, description: "Encoded query string" }, fields: { type: "string", required: false, description: "Comma-separated fields" } },
56
+ },
57
+ });
58
+ rl.registerAction(`${resource}.list`, {
59
+ description: `List ${resource}s`,
60
+ inputSchema: {
61
+ limit: { type: "number", required: false },
62
+ query: {
63
+ type: "string",
64
+ required: false,
65
+ description: "Encoded query string",
66
+ },
67
+ fields: {
68
+ type: "string",
69
+ required: false,
70
+ description: "Comma-separated fields",
71
+ },
72
+ },
37
73
  async execute(input, ctx) {
38
74
  const p = (input ?? {});
39
75
  const qs = {};
@@ -45,44 +81,87 @@ function registerTableResource(rl, resource, table, conn) {
45
81
  qs.sysparm_fields = p.fields;
46
82
  const data = (await api(conn(ctx), "GET", `/now/table/${table}`, undefined, qs));
47
83
  return data.result;
48
- } });
49
- rl.registerAction(`${resource}.update`, { description: `Update a ${resource}`, inputSchema: { sysId: { type: "string", required: true }, data: { type: "object", required: true } },
84
+ },
85
+ });
86
+ rl.registerAction(`${resource}.update`, {
87
+ description: `Update a ${resource}`,
88
+ inputSchema: {
89
+ sysId: { type: "string", required: true },
90
+ data: { type: "object", required: true },
91
+ },
50
92
  async execute(input, ctx) {
51
93
  const p = input;
52
94
  const data = (await api(conn(ctx), "PATCH", `/now/table/${table}/${p.sysId}`, p.data));
53
95
  return data.result;
54
- } });
55
- rl.registerAction(`${resource}.delete`, { description: `Delete a ${resource}`, inputSchema: { sysId: { type: "string", required: true } },
96
+ },
97
+ });
98
+ rl.registerAction(`${resource}.delete`, {
99
+ description: `Delete a ${resource}`,
100
+ inputSchema: { sysId: { type: "string", required: true } },
56
101
  async execute(input, ctx) {
57
102
  await api(conn(ctx), "DELETE", `/now/table/${table}/${input.sysId}`);
58
103
  return { success: true };
59
- } });
104
+ },
105
+ });
60
106
  }
61
107
  export default function servicenow(rl) {
62
108
  rl.setName("servicenow");
63
109
  rl.setVersion("0.1.0");
64
110
  rl.setConnectionSchema({
65
- subdomain: { type: "string", required: true, description: "ServiceNow instance subdomain", env: "SERVICENOW_SUBDOMAIN" },
66
- username: { type: "string", required: true, description: "ServiceNow username", env: "SERVICENOW_USERNAME" },
67
- password: { type: "string", required: true, description: "ServiceNow password", env: "SERVICENOW_PASSWORD" },
111
+ subdomain: {
112
+ type: "string",
113
+ required: true,
114
+ description: "ServiceNow instance subdomain",
115
+ env: "SERVICENOW_SUBDOMAIN",
116
+ },
117
+ username: {
118
+ type: "string",
119
+ required: true,
120
+ description: "ServiceNow username",
121
+ env: "SERVICENOW_USERNAME",
122
+ },
123
+ password: {
124
+ type: "string",
125
+ required: true,
126
+ description: "ServiceNow password",
127
+ env: "SERVICENOW_PASSWORD",
128
+ },
68
129
  });
69
130
  for (const [resource, table] of Object.entries(TABLES)) {
70
131
  registerTableResource(rl, resource, table, getConn);
71
132
  }
72
133
  // ── Generic Table Record ────────────────────────────
73
- rl.registerAction("tableRecord.create", { description: "Create a record in any table", inputSchema: { tableName: { type: "string", required: true }, data: { type: "object", required: true } },
134
+ rl.registerAction("tableRecord.create", {
135
+ description: "Create a record in any table",
136
+ inputSchema: {
137
+ tableName: { type: "string", required: true },
138
+ data: { type: "object", required: true },
139
+ },
74
140
  async execute(input, ctx) {
75
141
  const p = input;
76
142
  const data = (await api(getConn(ctx), "POST", `/now/table/${p.tableName}`, p.data));
77
143
  return data.result;
78
- } });
79
- rl.registerAction("tableRecord.get", { description: "Get a record from any table", inputSchema: { tableName: { type: "string", required: true }, sysId: { type: "string", required: true } },
144
+ },
145
+ });
146
+ rl.registerAction("tableRecord.get", {
147
+ description: "Get a record from any table",
148
+ inputSchema: {
149
+ tableName: { type: "string", required: true },
150
+ sysId: { type: "string", required: true },
151
+ },
80
152
  async execute(input, ctx) {
81
153
  const p = input;
82
154
  const data = (await api(getConn(ctx), "GET", `/now/table/${p.tableName}/${p.sysId}`));
83
155
  return data.result;
84
- } });
85
- rl.registerAction("tableRecord.list", { description: "List records from any table", inputSchema: { tableName: { type: "string", required: true }, limit: { type: "number", required: false }, query: { type: "string", required: false } },
156
+ },
157
+ });
158
+ rl.registerAction("tableRecord.list", {
159
+ description: "List records from any table",
160
+ inputSchema: {
161
+ tableName: { type: "string", required: true },
162
+ limit: { type: "number", required: false },
163
+ query: { type: "string", required: false },
164
+ },
86
165
  async execute(input, ctx) {
87
166
  const p = input;
88
167
  const qs = {};
@@ -92,17 +171,31 @@ export default function servicenow(rl) {
92
171
  qs.sysparm_query = p.query;
93
172
  const data = (await api(getConn(ctx), "GET", `/now/table/${p.tableName}`, undefined, qs));
94
173
  return data.result;
95
- } });
96
- rl.registerAction("tableRecord.update", { description: "Update a record in any table", inputSchema: { tableName: { type: "string", required: true }, sysId: { type: "string", required: true }, data: { type: "object", required: true } },
174
+ },
175
+ });
176
+ rl.registerAction("tableRecord.update", {
177
+ description: "Update a record in any table",
178
+ inputSchema: {
179
+ tableName: { type: "string", required: true },
180
+ sysId: { type: "string", required: true },
181
+ data: { type: "object", required: true },
182
+ },
97
183
  async execute(input, ctx) {
98
184
  const p = input;
99
185
  const data = (await api(getConn(ctx), "PATCH", `/now/table/${p.tableName}/${p.sysId}`, p.data));
100
186
  return data.result;
101
- } });
102
- rl.registerAction("tableRecord.delete", { description: "Delete a record from any table", inputSchema: { tableName: { type: "string", required: true }, sysId: { type: "string", required: true } },
187
+ },
188
+ });
189
+ rl.registerAction("tableRecord.delete", {
190
+ description: "Delete a record from any table",
191
+ inputSchema: {
192
+ tableName: { type: "string", required: true },
193
+ sysId: { type: "string", required: true },
194
+ },
103
195
  async execute(input, ctx) {
104
196
  const p = input;
105
197
  await api(getConn(ctx), "DELETE", `/now/table/${p.tableName}/${p.sysId}`);
106
198
  return { success: true };
107
- } });
199
+ },
200
+ });
108
201
  }