runline 0.2.1 → 0.2.2

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 (189) hide show
  1. package/dist/plugins/actionNetwork/src/index.js +118 -25
  2. package/dist/plugins/activeCampaign/src/index.js +184 -38
  3. package/dist/plugins/adalo/src/index.js +40 -8
  4. package/dist/plugins/affinity/src/index.js +100 -20
  5. package/dist/plugins/agileCrm/src/index.js +115 -27
  6. package/dist/plugins/airtable/src/index.js +94 -19
  7. package/dist/plugins/airtop/src/index.js +266 -62
  8. package/dist/plugins/apiTemplateIo/src/index.js +25 -5
  9. package/dist/plugins/asana/src/index.js +195 -41
  10. package/dist/plugins/autopilot/src/index.js +39 -8
  11. package/dist/plugins/bambooHr/src/index.js +109 -22
  12. package/dist/plugins/bannerbear/src/index.js +36 -8
  13. package/dist/plugins/baserow/src/index.js +35 -7
  14. package/dist/plugins/beeminder/src/index.js +198 -40
  15. package/dist/plugins/bitly/src/index.js +46 -10
  16. package/dist/plugins/bitwarden/src/index.js +167 -36
  17. package/dist/plugins/box/src/index.js +172 -37
  18. package/dist/plugins/brandfetch/src/index.js +5 -1
  19. package/dist/plugins/brevo/src/index.js +136 -29
  20. package/dist/plugins/bubble/src/index.js +76 -17
  21. package/dist/plugins/chargebee/src/index.js +35 -7
  22. package/dist/plugins/circleci/src/index.js +50 -10
  23. package/dist/plugins/ciscoWebex/src/index.js +131 -27
  24. package/dist/plugins/clearbit/src/index.js +76 -17
  25. package/dist/plugins/clickup/src/index.js +500 -107
  26. package/dist/plugins/clockify/src/index.js +229 -47
  27. package/dist/plugins/cloudflare/src/index.js +28 -6
  28. package/dist/plugins/cockpit/src/index.js +54 -12
  29. package/dist/plugins/coda/src/index.js +81 -19
  30. package/dist/plugins/coingecko/src/index.js +157 -33
  31. package/dist/plugins/contentful/src/index.js +85 -17
  32. package/dist/plugins/convertkit/src/index.js +74 -18
  33. package/dist/plugins/copper/src/index.js +59 -11
  34. package/dist/plugins/cortex/src/index.js +55 -13
  35. package/dist/plugins/currents/src/index.js +310 -71
  36. package/dist/plugins/customerIo/src/index.js +112 -23
  37. package/dist/plugins/databricks/src/index.js +549 -115
  38. package/dist/plugins/deepl/src/index.js +26 -6
  39. package/dist/plugins/demio/src/index.js +56 -11
  40. package/dist/plugins/dhl/src/index.js +16 -3
  41. package/dist/plugins/discord/src/index.js +141 -31
  42. package/dist/plugins/discourse/src/index.js +136 -31
  43. package/dist/plugins/disqus/src/index.js +96 -20
  44. package/dist/plugins/docker/src/index.js +20 -4
  45. package/dist/plugins/drift/src/index.js +19 -5
  46. package/dist/plugins/dropbox/src/index.js +139 -30
  47. package/dist/plugins/dropcontact/src/index.js +21 -4
  48. package/dist/plugins/egoi/src/index.js +61 -15
  49. package/dist/plugins/elasticsearch/src/index.js +59 -13
  50. package/dist/plugins/emelia/src/index.js +95 -19
  51. package/dist/plugins/erpnext/src/index.js +74 -15
  52. package/dist/plugins/facebookGraph/src/index.js +52 -11
  53. package/dist/plugins/freshdesk/src/index.js +220 -48
  54. package/dist/plugins/freshservice/src/index.js +39 -9
  55. package/dist/plugins/freshworksCrm/src/index.js +58 -12
  56. package/dist/plugins/getresponse/src/index.js +87 -18
  57. package/dist/plugins/ghost/src/index.js +114 -26
  58. package/dist/plugins/github/src/index.js +483 -109
  59. package/dist/plugins/gitlab/src/index.js +193 -45
  60. package/dist/plugins/gong/src/index.js +68 -14
  61. package/dist/plugins/gotify/src/index.js +43 -9
  62. package/dist/plugins/gotowebinar/src/index.js +233 -47
  63. package/dist/plugins/grafana/src/index.js +92 -21
  64. package/dist/plugins/graphql/src/index.js +38 -8
  65. package/dist/plugins/grist/src/index.js +52 -10
  66. package/dist/plugins/hackernews/src/index.js +32 -6
  67. package/dist/plugins/halopsa/src/index.js +131 -26
  68. package/dist/plugins/harvest/src/index.js +182 -42
  69. package/dist/plugins/helpscout/src/index.js +153 -31
  70. package/dist/plugins/highlevel/src/index.js +291 -58
  71. package/dist/plugins/homeAssistant/src/index.js +124 -26
  72. package/dist/plugins/hubspot/src/index.js +163 -29
  73. package/dist/plugins/humanticAi/src/index.js +54 -5
  74. package/dist/plugins/hunter/src/index.js +21 -4
  75. package/dist/plugins/intercom/src/index.js +95 -20
  76. package/dist/plugins/iterable/src/index.js +96 -20
  77. package/dist/plugins/jenkins/src/index.js +75 -17
  78. package/dist/plugins/jira/src/index.js +193 -43
  79. package/dist/plugins/keap/src/index.js +222 -56
  80. package/dist/plugins/kobotoolbox/src/index.js +113 -25
  81. package/dist/plugins/lemlist/src/index.js +79 -18
  82. package/dist/plugins/linear/src/index.js +86 -19
  83. package/dist/plugins/lingvanex/src/index.js +38 -8
  84. package/dist/plugins/linkedin/src/index.js +37 -8
  85. package/dist/plugins/lonescale/src/index.js +41 -9
  86. package/dist/plugins/magento/src/index.js +98 -27
  87. package/dist/plugins/mailcheck/src/index.js +11 -2
  88. package/dist/plugins/mailchimp/src/index.js +193 -42
  89. package/dist/plugins/mailerlite/src/index.js +61 -12
  90. package/dist/plugins/mailgun/src/index.js +39 -7
  91. package/dist/plugins/mailjet/src/index.js +141 -30
  92. package/dist/plugins/mandrill/src/index.js +67 -14
  93. package/dist/plugins/marketstack/src/index.js +56 -10
  94. package/dist/plugins/matrix/src/index.js +97 -20
  95. package/dist/plugins/mattermost/src/index.js +124 -26
  96. package/dist/plugins/mautic/src/index.js +129 -26
  97. package/dist/plugins/medium/src/index.js +64 -13
  98. package/dist/plugins/messagebird/src/index.js +80 -15
  99. package/dist/plugins/metabase/src/index.js +57 -12
  100. package/dist/plugins/misp/src/index.js +135 -33
  101. package/dist/plugins/mocean/src/index.js +33 -7
  102. package/dist/plugins/monday/src/index.js +97 -23
  103. package/dist/plugins/monicaCrm/src/index.js +112 -23
  104. package/dist/plugins/msg91/src/index.js +11 -2
  105. package/dist/plugins/nasa/src/index.js +108 -21
  106. package/dist/plugins/netlify/src/index.js +28 -6
  107. package/dist/plugins/netscalerAdc/src/index.js +144 -29
  108. package/dist/plugins/nextcloud/src/index.js +103 -20
  109. package/dist/plugins/nocodb/src/index.js +57 -11
  110. package/dist/plugins/notion/src/index.js +148 -37
  111. package/dist/plugins/npm/src/index.js +59 -12
  112. package/dist/plugins/odoo/src/index.js +102 -20
  113. package/dist/plugins/okta/src/index.js +50 -10
  114. package/dist/plugins/oneSimpleApi/src/index.js +84 -17
  115. package/dist/plugins/onfleet/src/index.js +139 -32
  116. package/dist/plugins/openThesaurus/src/index.js +46 -9
  117. package/dist/plugins/openweathermap/src/index.js +31 -6
  118. package/dist/plugins/oura/src/index.js +36 -7
  119. package/dist/plugins/paddle/src/index.js +80 -17
  120. package/dist/plugins/pagerduty/src/index.js +53 -12
  121. package/dist/plugins/paypal/src/index.js +51 -11
  122. package/dist/plugins/peekalink/src/index.js +12 -3
  123. package/dist/plugins/phantombuster/src/index.js +39 -8
  124. package/dist/plugins/philipsHue/src/index.js +64 -13
  125. package/dist/plugins/pipedrive/src/index.js +167 -45
  126. package/dist/plugins/plivo/src/index.js +43 -8
  127. package/dist/plugins/postbin/src/index.js +9 -2
  128. package/dist/plugins/posthog/src/index.js +50 -13
  129. package/dist/plugins/profitwell/src/index.js +24 -5
  130. package/dist/plugins/pushbullet/src/index.js +45 -9
  131. package/dist/plugins/pushcut/src/index.js +31 -6
  132. package/dist/plugins/pushover/src/index.js +51 -10
  133. package/dist/plugins/quickbase/src/index.js +66 -13
  134. package/dist/plugins/quickbooks/src/index.js +86 -19
  135. package/dist/plugins/quickchart/src/index.js +35 -7
  136. package/dist/plugins/raindrop/src/index.js +54 -13
  137. package/dist/plugins/reddit/src/index.js +73 -18
  138. package/dist/plugins/rocketchat/src/index.js +47 -9
  139. package/dist/plugins/rundeck/src/index.js +26 -5
  140. package/dist/plugins/salesforce/src/index.js +161 -31
  141. package/dist/plugins/salesmate/src/index.js +75 -16
  142. package/dist/plugins/securityScorecard/src/index.js +73 -15
  143. package/dist/plugins/segment/src/index.js +21 -4
  144. package/dist/plugins/sendgrid/src/index.js +102 -24
  145. package/dist/plugins/sendy/src/index.js +54 -11
  146. package/dist/plugins/sentry/src/index.js +174 -34
  147. package/dist/plugins/servicenow/src/index.js +120 -27
  148. package/dist/plugins/shopify/src/index.js +53 -12
  149. package/dist/plugins/signl4/src/index.js +16 -3
  150. package/dist/plugins/slack/src/index.js +407 -105
  151. package/dist/plugins/sms77/src/index.js +26 -5
  152. package/dist/plugins/splunk/src/index.js +186 -45
  153. package/dist/plugins/spotify/src/index.js +265 -66
  154. package/dist/plugins/stackby/src/index.js +18 -6
  155. package/dist/plugins/storyblok/src/index.js +57 -11
  156. package/dist/plugins/strapi/src/index.js +63 -12
  157. package/dist/plugins/strava/src/index.js +58 -13
  158. package/dist/plugins/stripe/src/index.js +143 -30
  159. package/dist/plugins/supabase/src/index.js +49 -10
  160. package/dist/plugins/syncromsp/src/index.js +245 -67
  161. package/dist/plugins/tapfiliate/src/index.js +57 -14
  162. package/dist/plugins/telegram/src/index.js +202 -39
  163. package/dist/plugins/thehive/src/index.js +271 -66
  164. package/dist/plugins/thehiveProject/src/index.js +457 -89
  165. package/dist/plugins/todoist/src/index.js +326 -77
  166. package/dist/plugins/travisci/src/index.js +35 -8
  167. package/dist/plugins/trello/src/index.js +204 -46
  168. package/dist/plugins/twake/src/index.js +10 -2
  169. package/dist/plugins/twilio/src/index.js +56 -11
  170. package/dist/plugins/twist/src/index.js +241 -48
  171. package/dist/plugins/twitter/src/index.js +128 -30
  172. package/dist/plugins/unleashedSoftware/src/index.js +30 -6
  173. package/dist/plugins/uplead/src/index.js +9 -2
  174. package/dist/plugins/uproc/src/index.js +31 -6
  175. package/dist/plugins/uptimerobot/src/index.js +119 -25
  176. package/dist/plugins/urlscanio/src/index.js +25 -6
  177. package/dist/plugins/vero/src/index.js +68 -13
  178. package/dist/plugins/vonage/src/index.js +32 -6
  179. package/dist/plugins/wekan/src/index.js +297 -52
  180. package/dist/plugins/woocommerce/src/index.js +57 -12
  181. package/dist/plugins/wordpress/src/index.js +94 -18
  182. package/dist/plugins/xero/src/index.js +79 -13
  183. package/dist/plugins/yourls/src/index.js +33 -6
  184. package/dist/plugins/zammad/src/index.js +139 -36
  185. package/dist/plugins/zendesk/src/index.js +201 -48
  186. package/dist/plugins/zoho/src/index.js +88 -21
  187. package/dist/plugins/zoom/src/index.js +41 -7
  188. package/dist/plugins/zulip/src/index.js +101 -20
  189. package/package.json +1 -1
@@ -7,7 +7,13 @@ async function api(token, method, endpoint, body, qs) {
7
7
  url.searchParams.set(k, String(v));
8
8
  }
9
9
  }
10
- const init = { method, headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" } };
10
+ const init = {
11
+ method,
12
+ headers: {
13
+ Authorization: `Bearer ${token}`,
14
+ "Content-Type": "application/json",
15
+ },
16
+ };
11
17
  if (body && Object.keys(body).length > 0)
12
18
  init.body = JSON.stringify(body);
13
19
  const res = await fetch(url.toString(), init);
@@ -18,41 +24,119 @@ async function api(token, method, endpoint, body, qs) {
18
24
  const text = await res.text();
19
25
  return text ? JSON.parse(text) : { success: true };
20
26
  }
21
- function stripUri(uri, prefix) { return uri.replace(prefix, ""); }
27
+ function stripUri(uri, prefix) {
28
+ return uri.replace(prefix, "");
29
+ }
22
30
  export default function spotify(rl) {
23
31
  rl.setName("spotify");
24
32
  rl.setVersion("0.1.0");
25
- rl.setConnectionSchema({ accessToken: { type: "string", required: true, description: "Spotify OAuth2 access token", env: "SPOTIFY_ACCESS_TOKEN" } });
33
+ rl.setConnectionSchema({
34
+ accessToken: {
35
+ type: "string",
36
+ required: true,
37
+ description: "Spotify OAuth2 access token",
38
+ env: "SPOTIFY_ACCESS_TOKEN",
39
+ },
40
+ });
26
41
  const t = (ctx) => ctx.connection.config.accessToken;
27
42
  // ── Player ──────────────────────────────────────────
28
- rl.registerAction("player.pause", { description: "Pause playback", inputSchema: {},
29
- async execute(_i, ctx) { return api(t(ctx), "PUT", "/me/player/pause"); } });
30
- rl.registerAction("player.resume", { description: "Resume playback", inputSchema: {},
31
- async execute(_i, ctx) { return api(t(ctx), "PUT", "/me/player/play"); } });
32
- rl.registerAction("player.next", { description: "Skip to next track", inputSchema: {},
33
- async execute(_i, ctx) { return api(t(ctx), "POST", "/me/player/next"); } });
34
- rl.registerAction("player.previous", { description: "Skip to previous track", inputSchema: {},
35
- async execute(_i, ctx) { return api(t(ctx), "POST", "/me/player/previous"); } });
36
- rl.registerAction("player.currentlyPlaying", { description: "Get currently playing track", inputSchema: {},
37
- async execute(_i, ctx) { return api(t(ctx), "GET", "/me/player/currently-playing"); } });
38
- rl.registerAction("player.recentlyPlayed", { description: "Get recently played tracks", inputSchema: { limit: { type: "number", required: false } },
43
+ rl.registerAction("player.pause", {
44
+ description: "Pause playback",
45
+ inputSchema: {},
46
+ async execute(_i, ctx) {
47
+ return api(t(ctx), "PUT", "/me/player/pause");
48
+ },
49
+ });
50
+ rl.registerAction("player.resume", {
51
+ description: "Resume playback",
52
+ inputSchema: {},
53
+ async execute(_i, ctx) {
54
+ return api(t(ctx), "PUT", "/me/player/play");
55
+ },
56
+ });
57
+ rl.registerAction("player.next", {
58
+ description: "Skip to next track",
59
+ inputSchema: {},
60
+ async execute(_i, ctx) {
61
+ return api(t(ctx), "POST", "/me/player/next");
62
+ },
63
+ });
64
+ rl.registerAction("player.previous", {
65
+ description: "Skip to previous track",
66
+ inputSchema: {},
67
+ async execute(_i, ctx) {
68
+ return api(t(ctx), "POST", "/me/player/previous");
69
+ },
70
+ });
71
+ rl.registerAction("player.currentlyPlaying", {
72
+ description: "Get currently playing track",
73
+ inputSchema: {},
74
+ async execute(_i, ctx) {
75
+ return api(t(ctx), "GET", "/me/player/currently-playing");
76
+ },
77
+ });
78
+ rl.registerAction("player.recentlyPlayed", {
79
+ description: "Get recently played tracks",
80
+ inputSchema: { limit: { type: "number", required: false } },
39
81
  async execute(input, ctx) {
40
82
  const qs = {};
41
83
  if (input?.limit)
42
84
  qs.limit = input.limit;
43
85
  const data = (await api(t(ctx), "GET", "/me/player/recently-played", undefined, qs));
44
86
  return data.items;
45
- } });
46
- rl.registerAction("player.addToQueue", { description: "Add a track to the queue", inputSchema: { uri: { type: "string", required: true, description: "Track URI or ID" } },
47
- async execute(input, ctx) { return api(t(ctx), "POST", "/me/player/queue", undefined, { uri: input.uri }); } });
48
- rl.registerAction("player.setVolume", { description: "Set playback volume", inputSchema: { volumePercent: { type: "number", required: true, description: "0-100" } },
49
- async execute(input, ctx) { return api(t(ctx), "PUT", "/me/player/volume", undefined, { volume_percent: input.volumePercent }); } });
50
- rl.registerAction("player.startMusic", { description: "Start playing an album, artist, or playlist", inputSchema: { contextUri: { type: "string", required: true, description: "Spotify URI (e.g. spotify:album:...)" } },
51
- async execute(input, ctx) { return api(t(ctx), "PUT", "/me/player/play", { context_uri: input.contextUri }); } });
87
+ },
88
+ });
89
+ rl.registerAction("player.addToQueue", {
90
+ description: "Add a track to the queue",
91
+ inputSchema: {
92
+ uri: { type: "string", required: true, description: "Track URI or ID" },
93
+ },
94
+ async execute(input, ctx) {
95
+ return api(t(ctx), "POST", "/me/player/queue", undefined, {
96
+ uri: input.uri,
97
+ });
98
+ },
99
+ });
100
+ rl.registerAction("player.setVolume", {
101
+ description: "Set playback volume",
102
+ inputSchema: {
103
+ volumePercent: { type: "number", required: true, description: "0-100" },
104
+ },
105
+ async execute(input, ctx) {
106
+ return api(t(ctx), "PUT", "/me/player/volume", undefined, {
107
+ volume_percent: input.volumePercent,
108
+ });
109
+ },
110
+ });
111
+ rl.registerAction("player.startMusic", {
112
+ description: "Start playing an album, artist, or playlist",
113
+ inputSchema: {
114
+ contextUri: {
115
+ type: "string",
116
+ required: true,
117
+ description: "Spotify URI (e.g. spotify:album:...)",
118
+ },
119
+ },
120
+ async execute(input, ctx) {
121
+ return api(t(ctx), "PUT", "/me/player/play", {
122
+ context_uri: input.contextUri,
123
+ });
124
+ },
125
+ });
52
126
  // ── Album ───────────────────────────────────────────
53
- rl.registerAction("album.get", { description: "Get an album", inputSchema: { id: { type: "string", required: true } },
54
- async execute(input, ctx) { return api(t(ctx), "GET", `/albums/${stripUri(input.id, "spotify:album:")}`); } });
55
- rl.registerAction("album.getTracks", { description: "Get an album's tracks", inputSchema: { id: { type: "string", required: true }, limit: { type: "number", required: false } },
127
+ rl.registerAction("album.get", {
128
+ description: "Get an album",
129
+ inputSchema: { id: { type: "string", required: true } },
130
+ async execute(input, ctx) {
131
+ return api(t(ctx), "GET", `/albums/${stripUri(input.id, "spotify:album:")}`);
132
+ },
133
+ });
134
+ rl.registerAction("album.getTracks", {
135
+ description: "Get an album's tracks",
136
+ inputSchema: {
137
+ id: { type: "string", required: true },
138
+ limit: { type: "number", required: false },
139
+ },
56
140
  async execute(input, ctx) {
57
141
  const p = input;
58
142
  const qs = {};
@@ -60,8 +144,14 @@ export default function spotify(rl) {
60
144
  qs.limit = p.limit;
61
145
  const data = (await api(t(ctx), "GET", `/albums/${stripUri(p.id, "spotify:album:")}/tracks`, undefined, qs));
62
146
  return data.items;
63
- } });
64
- rl.registerAction("album.getNewReleases", { description: "Get new album releases", inputSchema: { limit: { type: "number", required: false }, country: { type: "string", required: false } },
147
+ },
148
+ });
149
+ rl.registerAction("album.getNewReleases", {
150
+ description: "Get new album releases",
151
+ inputSchema: {
152
+ limit: { type: "number", required: false },
153
+ country: { type: "string", required: false },
154
+ },
65
155
  async execute(input, ctx) {
66
156
  const p = (input ?? {});
67
157
  const qs = {};
@@ -71,8 +161,14 @@ export default function spotify(rl) {
71
161
  qs.country = p.country;
72
162
  const data = (await api(t(ctx), "GET", "/browse/new-releases", undefined, qs));
73
163
  return data.albums.items;
74
- } });
75
- rl.registerAction("album.search", { description: "Search albums", inputSchema: { query: { type: "string", required: true }, limit: { type: "number", required: false } },
164
+ },
165
+ });
166
+ rl.registerAction("album.search", {
167
+ description: "Search albums",
168
+ inputSchema: {
169
+ query: { type: "string", required: true },
170
+ limit: { type: "number", required: false },
171
+ },
76
172
  async execute(input, ctx) {
77
173
  const p = input;
78
174
  const qs = { q: p.query, type: "album" };
@@ -82,11 +178,22 @@ export default function spotify(rl) {
82
178
  qs.limit = 50;
83
179
  const data = (await api(t(ctx), "GET", "/search", undefined, qs));
84
180
  return data.albums.items;
85
- } });
181
+ },
182
+ });
86
183
  // ── Artist ──────────────────────────────────────────
87
- rl.registerAction("artist.get", { description: "Get an artist", inputSchema: { id: { type: "string", required: true } },
88
- async execute(input, ctx) { return api(t(ctx), "GET", `/artists/${stripUri(input.id, "spotify:artist:")}`); } });
89
- rl.registerAction("artist.getAlbums", { description: "Get an artist's albums", inputSchema: { id: { type: "string", required: true }, limit: { type: "number", required: false } },
184
+ rl.registerAction("artist.get", {
185
+ description: "Get an artist",
186
+ inputSchema: { id: { type: "string", required: true } },
187
+ async execute(input, ctx) {
188
+ return api(t(ctx), "GET", `/artists/${stripUri(input.id, "spotify:artist:")}`);
189
+ },
190
+ });
191
+ rl.registerAction("artist.getAlbums", {
192
+ description: "Get an artist's albums",
193
+ inputSchema: {
194
+ id: { type: "string", required: true },
195
+ limit: { type: "number", required: false },
196
+ },
90
197
  async execute(input, ctx) {
91
198
  const p = input;
92
199
  const qs = {};
@@ -94,29 +201,59 @@ export default function spotify(rl) {
94
201
  qs.limit = p.limit;
95
202
  const data = (await api(t(ctx), "GET", `/artists/${stripUri(p.id, "spotify:artist:")}/albums`, undefined, qs));
96
203
  return data.items;
97
- } });
98
- rl.registerAction("artist.getRelatedArtists", { description: "Get related artists", inputSchema: { id: { type: "string", required: true } },
204
+ },
205
+ });
206
+ rl.registerAction("artist.getRelatedArtists", {
207
+ description: "Get related artists",
208
+ inputSchema: { id: { type: "string", required: true } },
99
209
  async execute(input, ctx) {
100
210
  const data = (await api(t(ctx), "GET", `/artists/${stripUri(input.id, "spotify:artist:")}/related-artists`));
101
211
  return data.artists;
102
- } });
103
- rl.registerAction("artist.getTopTracks", { description: "Get an artist's top tracks", inputSchema: { id: { type: "string", required: true }, country: { type: "string", required: true } },
212
+ },
213
+ });
214
+ rl.registerAction("artist.getTopTracks", {
215
+ description: "Get an artist's top tracks",
216
+ inputSchema: {
217
+ id: { type: "string", required: true },
218
+ country: { type: "string", required: true },
219
+ },
104
220
  async execute(input, ctx) {
105
221
  const p = input;
106
222
  const data = (await api(t(ctx), "GET", `/artists/${stripUri(p.id, "spotify:artist:")}/top-tracks`, undefined, { country: p.country }));
107
223
  return data.tracks;
108
- } });
109
- rl.registerAction("artist.search", { description: "Search artists", inputSchema: { query: { type: "string", required: true }, limit: { type: "number", required: false } },
224
+ },
225
+ });
226
+ rl.registerAction("artist.search", {
227
+ description: "Search artists",
228
+ inputSchema: {
229
+ query: { type: "string", required: true },
230
+ limit: { type: "number", required: false },
231
+ },
110
232
  async execute(input, ctx) {
111
233
  const p = input;
112
- const qs = { q: p.query, type: "artist", limit: p.limit ?? 50 };
234
+ const qs = {
235
+ q: p.query,
236
+ type: "artist",
237
+ limit: p.limit ?? 50,
238
+ };
113
239
  const data = (await api(t(ctx), "GET", "/search", undefined, qs));
114
240
  return data.artists.items;
115
- } });
241
+ },
242
+ });
116
243
  // ── Playlist ────────────────────────────────────────
117
- rl.registerAction("playlist.get", { description: "Get a playlist", inputSchema: { id: { type: "string", required: true } },
118
- async execute(input, ctx) { return api(t(ctx), "GET", `/playlists/${stripUri(input.id, "spotify:playlist:")}`); } });
119
- rl.registerAction("playlist.getTracks", { description: "Get a playlist's tracks", inputSchema: { id: { type: "string", required: true }, limit: { type: "number", required: false } },
244
+ rl.registerAction("playlist.get", {
245
+ description: "Get a playlist",
246
+ inputSchema: { id: { type: "string", required: true } },
247
+ async execute(input, ctx) {
248
+ return api(t(ctx), "GET", `/playlists/${stripUri(input.id, "spotify:playlist:")}`);
249
+ },
250
+ });
251
+ rl.registerAction("playlist.getTracks", {
252
+ description: "Get a playlist's tracks",
253
+ inputSchema: {
254
+ id: { type: "string", required: true },
255
+ limit: { type: "number", required: false },
256
+ },
120
257
  async execute(input, ctx) {
121
258
  const p = input;
122
259
  const qs = {};
@@ -124,65 +261,127 @@ export default function spotify(rl) {
124
261
  qs.limit = p.limit;
125
262
  const data = (await api(t(ctx), "GET", `/playlists/${stripUri(p.id, "spotify:playlist:")}/tracks`, undefined, qs));
126
263
  return data.items;
127
- } });
128
- rl.registerAction("playlist.create", { description: "Create a playlist", inputSchema: { name: { type: "string", required: true }, description: { type: "string", required: false }, public: { type: "boolean", required: false } },
129
- async execute(input, ctx) { return api(t(ctx), "POST", "/me/playlists", input); } });
130
- rl.registerAction("playlist.addTrack", { description: "Add a track to a playlist", inputSchema: { id: { type: "string", required: true }, trackUri: { type: "string", required: true }, position: { type: "number", required: false } },
264
+ },
265
+ });
266
+ rl.registerAction("playlist.create", {
267
+ description: "Create a playlist",
268
+ inputSchema: {
269
+ name: { type: "string", required: true },
270
+ description: { type: "string", required: false },
271
+ public: { type: "boolean", required: false },
272
+ },
273
+ async execute(input, ctx) {
274
+ return api(t(ctx), "POST", "/me/playlists", input);
275
+ },
276
+ });
277
+ rl.registerAction("playlist.addTrack", {
278
+ description: "Add a track to a playlist",
279
+ inputSchema: {
280
+ id: { type: "string", required: true },
281
+ trackUri: { type: "string", required: true },
282
+ position: { type: "number", required: false },
283
+ },
131
284
  async execute(input, ctx) {
132
285
  const p = input;
133
286
  const qs = { uris: p.trackUri };
134
287
  if (p.position !== undefined)
135
288
  qs.position = p.position;
136
289
  return api(t(ctx), "POST", `/playlists/${stripUri(p.id, "spotify:playlist:")}/tracks`, {}, qs);
137
- } });
138
- rl.registerAction("playlist.removeTrack", { description: "Remove a track from a playlist", inputSchema: { id: { type: "string", required: true }, trackUri: { type: "string", required: true } },
290
+ },
291
+ });
292
+ rl.registerAction("playlist.removeTrack", {
293
+ description: "Remove a track from a playlist",
294
+ inputSchema: {
295
+ id: { type: "string", required: true },
296
+ trackUri: { type: "string", required: true },
297
+ },
139
298
  async execute(input, ctx) {
140
299
  const p = input;
141
300
  return api(t(ctx), "DELETE", `/playlists/${stripUri(p.id, "spotify:playlist:")}/tracks`, { tracks: [{ uri: p.trackUri }] });
142
- } });
143
- rl.registerAction("playlist.listMine", { description: "Get the current user's playlists", inputSchema: { limit: { type: "number", required: false } },
301
+ },
302
+ });
303
+ rl.registerAction("playlist.listMine", {
304
+ description: "Get the current user's playlists",
305
+ inputSchema: { limit: { type: "number", required: false } },
144
306
  async execute(input, ctx) {
145
307
  const qs = {};
146
308
  if (input?.limit)
147
309
  qs.limit = input.limit;
148
310
  const data = (await api(t(ctx), "GET", "/me/playlists", undefined, qs));
149
311
  return data.items;
150
- } });
151
- rl.registerAction("playlist.search", { description: "Search playlists", inputSchema: { query: { type: "string", required: true }, limit: { type: "number", required: false } },
312
+ },
313
+ });
314
+ rl.registerAction("playlist.search", {
315
+ description: "Search playlists",
316
+ inputSchema: {
317
+ query: { type: "string", required: true },
318
+ limit: { type: "number", required: false },
319
+ },
152
320
  async execute(input, ctx) {
153
321
  const p = input;
154
- const qs = { q: p.query, type: "playlist", limit: p.limit ?? 50 };
322
+ const qs = {
323
+ q: p.query,
324
+ type: "playlist",
325
+ limit: p.limit ?? 50,
326
+ };
155
327
  const data = (await api(t(ctx), "GET", "/search", undefined, qs));
156
328
  return data.playlists.items;
157
- } });
329
+ },
330
+ });
158
331
  // ── Track ───────────────────────────────────────────
159
- rl.registerAction("track.get", { description: "Get a track", inputSchema: { id: { type: "string", required: true } },
160
- async execute(input, ctx) { return api(t(ctx), "GET", `/tracks/${stripUri(input.id, "spotify:track:")}`); } });
161
- rl.registerAction("track.getAudioFeatures", { description: "Get audio features for a track", inputSchema: { id: { type: "string", required: true } },
162
- async execute(input, ctx) { return api(t(ctx), "GET", `/audio-features/${stripUri(input.id, "spotify:track:")}`); } });
163
- rl.registerAction("track.search", { description: "Search tracks", inputSchema: { query: { type: "string", required: true }, limit: { type: "number", required: false } },
332
+ rl.registerAction("track.get", {
333
+ description: "Get a track",
334
+ inputSchema: { id: { type: "string", required: true } },
335
+ async execute(input, ctx) {
336
+ return api(t(ctx), "GET", `/tracks/${stripUri(input.id, "spotify:track:")}`);
337
+ },
338
+ });
339
+ rl.registerAction("track.getAudioFeatures", {
340
+ description: "Get audio features for a track",
341
+ inputSchema: { id: { type: "string", required: true } },
342
+ async execute(input, ctx) {
343
+ return api(t(ctx), "GET", `/audio-features/${stripUri(input.id, "spotify:track:")}`);
344
+ },
345
+ });
346
+ rl.registerAction("track.search", {
347
+ description: "Search tracks",
348
+ inputSchema: {
349
+ query: { type: "string", required: true },
350
+ limit: { type: "number", required: false },
351
+ },
164
352
  async execute(input, ctx) {
165
353
  const p = input;
166
- const qs = { q: p.query, type: "track", limit: p.limit ?? 50 };
354
+ const qs = {
355
+ q: p.query,
356
+ type: "track",
357
+ limit: p.limit ?? 50,
358
+ };
167
359
  const data = (await api(t(ctx), "GET", "/search", undefined, qs));
168
360
  return data.tracks.items;
169
- } });
361
+ },
362
+ });
170
363
  // ── Library ─────────────────────────────────────────
171
- rl.registerAction("library.getLikedTracks", { description: "Get liked tracks", inputSchema: { limit: { type: "number", required: false } },
364
+ rl.registerAction("library.getLikedTracks", {
365
+ description: "Get liked tracks",
366
+ inputSchema: { limit: { type: "number", required: false } },
172
367
  async execute(input, ctx) {
173
368
  const qs = {};
174
369
  if (input?.limit)
175
370
  qs.limit = input.limit;
176
371
  const data = (await api(t(ctx), "GET", "/me/tracks", undefined, qs));
177
372
  return data.items;
178
- } });
373
+ },
374
+ });
179
375
  // ── My Data ─────────────────────────────────────────
180
- rl.registerAction("myData.getFollowingArtists", { description: "Get followed artists", inputSchema: { limit: { type: "number", required: false } },
376
+ rl.registerAction("myData.getFollowingArtists", {
377
+ description: "Get followed artists",
378
+ inputSchema: { limit: { type: "number", required: false } },
181
379
  async execute(input, ctx) {
182
380
  const qs = { type: "artist" };
183
381
  if (input?.limit)
184
382
  qs.limit = input.limit;
185
383
  const data = (await api(t(ctx), "GET", "/me/following", undefined, qs));
186
384
  return data.artists.items;
187
- } });
385
+ },
386
+ });
188
387
  }
@@ -7,7 +7,10 @@ async function apiRequest(apiKey, method, endpoint, body, qs) {
7
7
  url.searchParams.set(k, String(v));
8
8
  }
9
9
  }
10
- const init = { method, headers: { "api-key": apiKey, "Content-Type": "application/json" } };
10
+ const init = {
11
+ method,
12
+ headers: { "api-key": apiKey, "Content-Type": "application/json" },
13
+ };
11
14
  if (body !== undefined)
12
15
  init.body = JSON.stringify(body);
13
16
  const res = await fetch(url.toString(), init);
@@ -19,7 +22,12 @@ export default function stackby(rl) {
19
22
  rl.setName("stackby");
20
23
  rl.setVersion("0.1.0");
21
24
  rl.setConnectionSchema({
22
- apiKey: { type: "string", required: true, description: "Stackby API key", env: "STACKBY_API_KEY" },
25
+ apiKey: {
26
+ type: "string",
27
+ required: true,
28
+ description: "Stackby API key",
29
+ env: "STACKBY_API_KEY",
30
+ },
23
31
  });
24
32
  const key = (ctx) => ctx.connection.config.apiKey;
25
33
  rl.registerAction("row.read", {
@@ -32,7 +40,7 @@ export default function stackby(rl) {
32
40
  async execute(input, ctx) {
33
41
  const p = input;
34
42
  const data = (await apiRequest(key(ctx), "GET", `/rowlist/${p.stackId}/${encodeURIComponent(p.table)}`, undefined, { rowIds: p.rowId }));
35
- return data.map(d => d.field);
43
+ return data.map((d) => d.field);
36
44
  },
37
45
  });
38
46
  rl.registerAction("row.list", {
@@ -51,7 +59,7 @@ export default function stackby(rl) {
51
59
  if (p.limit)
52
60
  qs.maxrecord = p.limit;
53
61
  const data = (await apiRequest(key(ctx), "GET", `/rowlist/${p.stackId}/${encodeURIComponent(p.table)}`, undefined, qs));
54
- return data.map(d => d.field);
62
+ return data.map((d) => d.field);
55
63
  },
56
64
  });
57
65
  rl.registerAction("row.append", {
@@ -59,12 +67,16 @@ export default function stackby(rl) {
59
67
  inputSchema: {
60
68
  stackId: { type: "string", required: true },
61
69
  table: { type: "string", required: true },
62
- records: { type: "object", required: true, description: "Array of objects [{field: {col1: val1, col2: val2}}]" },
70
+ records: {
71
+ type: "object",
72
+ required: true,
73
+ description: "Array of objects [{field: {col1: val1, col2: val2}}]",
74
+ },
63
75
  },
64
76
  async execute(input, ctx) {
65
77
  const p = input;
66
78
  const data = (await apiRequest(key(ctx), "POST", `/rowcreate/${p.stackId}/${encodeURIComponent(p.table)}`, { records: p.records }));
67
- return data.map(d => d.field);
79
+ return data.map((d) => d.field);
68
80
  },
69
81
  });
70
82
  rl.registerAction("row.delete", {
@@ -1,6 +1,9 @@
1
1
  function getConn(ctx) {
2
2
  const c = ctx.connection.config;
3
- return { contentToken: c.contentToken, managementToken: c.managementToken };
3
+ return {
4
+ contentToken: c.contentToken,
5
+ managementToken: c.managementToken,
6
+ };
4
7
  }
5
8
  async function contentApi(token, endpoint, qs) {
6
9
  const url = new URL(`https://api.storyblok.com${endpoint}`);
@@ -24,7 +27,10 @@ async function managementApi(token, method, endpoint, body, qs) {
24
27
  url.searchParams.set(k, String(v));
25
28
  }
26
29
  }
27
- const init = { method, headers: { Authorization: token, "Content-Type": "application/json" } };
30
+ const init = {
31
+ method,
32
+ headers: { Authorization: token, "Content-Type": "application/json" },
33
+ };
28
34
  if (body && Object.keys(body).length > 0)
29
35
  init.body = JSON.stringify(body);
30
36
  const res = await fetch(url.toString(), init);
@@ -37,13 +43,29 @@ export default function storyblok(rl) {
37
43
  rl.setName("storyblok");
38
44
  rl.setVersion("0.1.0");
39
45
  rl.setConnectionSchema({
40
- contentToken: { type: "string", required: false, description: "Storyblok Content Delivery API token (for reading published content)", env: "STORYBLOK_CONTENT_TOKEN" },
41
- managementToken: { type: "string", required: false, description: "Storyblok Management API personal access token", env: "STORYBLOK_MANAGEMENT_TOKEN" },
46
+ contentToken: {
47
+ type: "string",
48
+ required: false,
49
+ description: "Storyblok Content Delivery API token (for reading published content)",
50
+ env: "STORYBLOK_CONTENT_TOKEN",
51
+ },
52
+ managementToken: {
53
+ type: "string",
54
+ required: false,
55
+ description: "Storyblok Management API personal access token",
56
+ env: "STORYBLOK_MANAGEMENT_TOKEN",
57
+ },
42
58
  });
43
59
  // ── Content API ─────────────────────────────────────
44
60
  rl.registerAction("content.story.get", {
45
61
  description: "Get a published story by slug or ID (Content API)",
46
- inputSchema: { identifier: { type: "string", required: true, description: "Story slug or numeric ID" } },
62
+ inputSchema: {
63
+ identifier: {
64
+ type: "string",
65
+ required: true,
66
+ description: "Story slug or numeric ID",
67
+ },
68
+ },
47
69
  async execute(input, ctx) {
48
70
  const conn = getConn(ctx);
49
71
  if (!conn.contentToken)
@@ -54,7 +76,14 @@ export default function storyblok(rl) {
54
76
  });
55
77
  rl.registerAction("content.story.list", {
56
78
  description: "List published stories (Content API)",
57
- inputSchema: { limit: { type: "number", required: false }, startsWith: { type: "string", required: false, description: "Filter by slug prefix" } },
79
+ inputSchema: {
80
+ limit: { type: "number", required: false },
81
+ startsWith: {
82
+ type: "string",
83
+ required: false,
84
+ description: "Filter by slug prefix",
85
+ },
86
+ },
58
87
  async execute(input, ctx) {
59
88
  const conn = getConn(ctx);
60
89
  if (!conn.contentToken)
@@ -72,7 +101,10 @@ export default function storyblok(rl) {
72
101
  // ── Management API ──────────────────────────────────
73
102
  rl.registerAction("management.story.get", {
74
103
  description: "Get a story by ID (Management API)",
75
- inputSchema: { spaceId: { type: "string", required: true }, storyId: { type: "string", required: true } },
104
+ inputSchema: {
105
+ spaceId: { type: "string", required: true },
106
+ storyId: { type: "string", required: true },
107
+ },
76
108
  async execute(input, ctx) {
77
109
  const conn = getConn(ctx);
78
110
  if (!conn.managementToken)
@@ -84,7 +116,10 @@ export default function storyblok(rl) {
84
116
  });
85
117
  rl.registerAction("management.story.list", {
86
118
  description: "List stories in a space (Management API)",
87
- inputSchema: { spaceId: { type: "string", required: true }, limit: { type: "number", required: false } },
119
+ inputSchema: {
120
+ spaceId: { type: "string", required: true },
121
+ limit: { type: "number", required: false },
122
+ },
88
123
  async execute(input, ctx) {
89
124
  const conn = getConn(ctx);
90
125
  if (!conn.managementToken)
@@ -99,7 +134,10 @@ export default function storyblok(rl) {
99
134
  });
100
135
  rl.registerAction("management.story.delete", {
101
136
  description: "Delete a story (Management API)",
102
- inputSchema: { spaceId: { type: "string", required: true }, storyId: { type: "string", required: true } },
137
+ inputSchema: {
138
+ spaceId: { type: "string", required: true },
139
+ storyId: { type: "string", required: true },
140
+ },
103
141
  async execute(input, ctx) {
104
142
  const conn = getConn(ctx);
105
143
  if (!conn.managementToken)
@@ -111,7 +149,12 @@ export default function storyblok(rl) {
111
149
  });
112
150
  rl.registerAction("management.story.publish", {
113
151
  description: "Publish a story (Management API)",
114
- inputSchema: { spaceId: { type: "string", required: true }, storyId: { type: "string", required: true }, releaseId: { type: "string", required: false }, language: { type: "string", required: false } },
152
+ inputSchema: {
153
+ spaceId: { type: "string", required: true },
154
+ storyId: { type: "string", required: true },
155
+ releaseId: { type: "string", required: false },
156
+ language: { type: "string", required: false },
157
+ },
115
158
  async execute(input, ctx) {
116
159
  const conn = getConn(ctx);
117
160
  if (!conn.managementToken)
@@ -128,7 +171,10 @@ export default function storyblok(rl) {
128
171
  });
129
172
  rl.registerAction("management.story.unpublish", {
130
173
  description: "Unpublish a story (Management API)",
131
- inputSchema: { spaceId: { type: "string", required: true }, storyId: { type: "string", required: true } },
174
+ inputSchema: {
175
+ spaceId: { type: "string", required: true },
176
+ storyId: { type: "string", required: true },
177
+ },
132
178
  async execute(input, ctx) {
133
179
  const conn = getConn(ctx);
134
180
  if (!conn.managementToken)