@zapier/zapier-sdk 0.13.5 → 0.13.7

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 (129) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/api/schemas.d.ts +38 -38
  3. package/dist/index.cjs +1 -1
  4. package/dist/index.d.mts +170 -177
  5. package/dist/index.mjs +1 -1
  6. package/dist/plugins/fetch/schemas.d.ts +4 -4
  7. package/dist/plugins/getAction/schemas.d.ts +2 -2
  8. package/dist/plugins/listActions/schemas.d.ts +6 -6
  9. package/dist/plugins/listApps/schemas.d.ts +6 -6
  10. package/dist/plugins/listAuthentications/schemas.d.ts +4 -4
  11. package/dist/plugins/listInputFieldChoices/schemas.d.ts +8 -8
  12. package/dist/plugins/listInputFields/schemas.d.ts +8 -8
  13. package/dist/plugins/request/schemas.d.ts +8 -8
  14. package/dist/plugins/runAction/schemas.d.ts +8 -8
  15. package/dist/schemas/Action.d.ts +2 -2
  16. package/dist/schemas/App.d.ts +8 -8
  17. package/dist/types/sdk.d.ts +2 -8
  18. package/dist/types/sdk.d.ts.map +1 -1
  19. package/package.json +8 -3
  20. package/src/api/auth.ts +0 -28
  21. package/src/api/client.ts +0 -491
  22. package/src/api/debug.test.ts +0 -76
  23. package/src/api/debug.ts +0 -154
  24. package/src/api/index.ts +0 -90
  25. package/src/api/polling.test.ts +0 -405
  26. package/src/api/polling.ts +0 -253
  27. package/src/api/schemas.ts +0 -465
  28. package/src/api/types.ts +0 -152
  29. package/src/auth.ts +0 -72
  30. package/src/constants.ts +0 -16
  31. package/src/index.ts +0 -111
  32. package/src/plugins/api/index.ts +0 -43
  33. package/src/plugins/apps/index.ts +0 -203
  34. package/src/plugins/apps/schemas.ts +0 -64
  35. package/src/plugins/eventEmission/builders.ts +0 -115
  36. package/src/plugins/eventEmission/index.test.ts +0 -169
  37. package/src/plugins/eventEmission/index.ts +0 -294
  38. package/src/plugins/eventEmission/transport.test.ts +0 -214
  39. package/src/plugins/eventEmission/transport.ts +0 -135
  40. package/src/plugins/eventEmission/types.ts +0 -58
  41. package/src/plugins/eventEmission/utils.ts +0 -121
  42. package/src/plugins/fetch/index.ts +0 -83
  43. package/src/plugins/fetch/schemas.ts +0 -37
  44. package/src/plugins/findFirstAuthentication/index.test.ts +0 -209
  45. package/src/plugins/findFirstAuthentication/index.ts +0 -68
  46. package/src/plugins/findFirstAuthentication/schemas.ts +0 -47
  47. package/src/plugins/findUniqueAuthentication/index.test.ts +0 -197
  48. package/src/plugins/findUniqueAuthentication/index.ts +0 -77
  49. package/src/plugins/findUniqueAuthentication/schemas.ts +0 -49
  50. package/src/plugins/getAction/index.test.ts +0 -239
  51. package/src/plugins/getAction/index.ts +0 -75
  52. package/src/plugins/getAction/schemas.ts +0 -41
  53. package/src/plugins/getApp/index.test.ts +0 -181
  54. package/src/plugins/getApp/index.ts +0 -60
  55. package/src/plugins/getApp/schemas.ts +0 -33
  56. package/src/plugins/getAuthentication/index.test.ts +0 -294
  57. package/src/plugins/getAuthentication/index.ts +0 -95
  58. package/src/plugins/getAuthentication/schemas.ts +0 -38
  59. package/src/plugins/getProfile/index.ts +0 -60
  60. package/src/plugins/getProfile/schemas.ts +0 -24
  61. package/src/plugins/listActions/index.test.ts +0 -526
  62. package/src/plugins/listActions/index.ts +0 -132
  63. package/src/plugins/listActions/schemas.ts +0 -55
  64. package/src/plugins/listApps/index.test.ts +0 -378
  65. package/src/plugins/listApps/index.ts +0 -159
  66. package/src/plugins/listApps/schemas.ts +0 -41
  67. package/src/plugins/listAuthentications/index.test.ts +0 -739
  68. package/src/plugins/listAuthentications/index.ts +0 -152
  69. package/src/plugins/listAuthentications/schemas.ts +0 -77
  70. package/src/plugins/listInputFieldChoices/index.test.ts +0 -653
  71. package/src/plugins/listInputFieldChoices/index.ts +0 -173
  72. package/src/plugins/listInputFieldChoices/schemas.ts +0 -125
  73. package/src/plugins/listInputFields/index.test.ts +0 -439
  74. package/src/plugins/listInputFields/index.ts +0 -294
  75. package/src/plugins/listInputFields/schemas.ts +0 -68
  76. package/src/plugins/manifest/index.test.ts +0 -776
  77. package/src/plugins/manifest/index.ts +0 -461
  78. package/src/plugins/manifest/schemas.ts +0 -60
  79. package/src/plugins/registry/index.ts +0 -160
  80. package/src/plugins/request/index.test.ts +0 -333
  81. package/src/plugins/request/index.ts +0 -105
  82. package/src/plugins/request/schemas.ts +0 -69
  83. package/src/plugins/runAction/index.test.ts +0 -388
  84. package/src/plugins/runAction/index.ts +0 -215
  85. package/src/plugins/runAction/schemas.ts +0 -60
  86. package/src/resolvers/actionKey.ts +0 -37
  87. package/src/resolvers/actionType.ts +0 -34
  88. package/src/resolvers/appKey.ts +0 -7
  89. package/src/resolvers/authenticationId.ts +0 -54
  90. package/src/resolvers/index.ts +0 -11
  91. package/src/resolvers/inputFieldKey.ts +0 -70
  92. package/src/resolvers/inputs.ts +0 -69
  93. package/src/schemas/Action.ts +0 -52
  94. package/src/schemas/App.ts +0 -45
  95. package/src/schemas/Auth.ts +0 -59
  96. package/src/schemas/Field.ts +0 -169
  97. package/src/schemas/Run.ts +0 -40
  98. package/src/schemas/UserProfile.ts +0 -60
  99. package/src/sdk.test.ts +0 -212
  100. package/src/sdk.ts +0 -178
  101. package/src/types/domain.test.ts +0 -50
  102. package/src/types/domain.ts +0 -66
  103. package/src/types/errors.ts +0 -278
  104. package/src/types/events.ts +0 -43
  105. package/src/types/functions.ts +0 -28
  106. package/src/types/optional-zapier-sdk-cli-login.d.ts +0 -37
  107. package/src/types/plugin.ts +0 -125
  108. package/src/types/properties.ts +0 -80
  109. package/src/types/sdk.ts +0 -117
  110. package/src/types/telemetry-events.ts +0 -85
  111. package/src/utils/array-utils.test.ts +0 -131
  112. package/src/utils/array-utils.ts +0 -41
  113. package/src/utils/domain-utils.test.ts +0 -433
  114. package/src/utils/domain-utils.ts +0 -267
  115. package/src/utils/file-utils.test.ts +0 -73
  116. package/src/utils/file-utils.ts +0 -94
  117. package/src/utils/function-utils.test.ts +0 -141
  118. package/src/utils/function-utils.ts +0 -245
  119. package/src/utils/pagination-utils.test.ts +0 -620
  120. package/src/utils/pagination-utils.ts +0 -242
  121. package/src/utils/schema-utils.ts +0 -207
  122. package/src/utils/string-utils.test.ts +0 -45
  123. package/src/utils/string-utils.ts +0 -54
  124. package/src/utils/validation.test.ts +0 -51
  125. package/src/utils/validation.ts +0 -44
  126. package/tsconfig.build.json +0 -18
  127. package/tsconfig.json +0 -20
  128. package/tsconfig.tsbuildinfo +0 -1
  129. package/tsup.config.ts +0 -23
@@ -1,433 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import {
3
- groupVersionedAppKeysByType,
4
- groupAppKeysByType,
5
- toAppLocator,
6
- } from "./domain-utils";
7
-
8
- describe("domain-utils", () => {
9
- describe("groupVersionedAppKeysByType", () => {
10
- it("should reject UUID app keys", () => {
11
- expect(() => {
12
- groupVersionedAppKeysByType(["61e47557-af91-4b0c-a3e0-c28606357664"]);
13
- }).toThrow(
14
- "UUID app keys are not supported. Use app slug or implementation ID instead of: 61e47557-af91-4b0c-a3e0-c28606357664",
15
- );
16
- });
17
-
18
- it("should categorize *API as selectedApi", () => {
19
- const result = groupVersionedAppKeysByType(["FormatterCLIAPI"]);
20
-
21
- expect(result).toEqual({
22
- selectedApi: ["FormatterCLIAPI"],
23
- slug: [],
24
- });
25
- });
26
-
27
- it("should categorize various API types as selectedApi", () => {
28
- const result = groupVersionedAppKeysByType([
29
- "FormatterCLIAPI",
30
- "SlackAPI",
31
- "GmailRESTAPI",
32
- "WebhookAPI",
33
- "AnythingWithUppercase",
34
- ]);
35
-
36
- expect(result).toEqual({
37
- selectedApi: [
38
- "FormatterCLIAPI",
39
- "SlackAPI",
40
- "GmailRESTAPI",
41
- "WebhookAPI",
42
- "AnythingWithUppercase",
43
- ],
44
- slug: [],
45
- });
46
- });
47
-
48
- it("should categorize lower-case strings as slugs, converting underscores to dashes", () => {
49
- const result = groupVersionedAppKeysByType([
50
- "slack",
51
- "google-sheets",
52
- "_100hires_ats",
53
- "amazon_redshift",
54
- ]);
55
-
56
- expect(result).toEqual({
57
- selectedApi: [],
58
- slug: ["slack", "google-sheets", "100hires-ats", "amazon-redshift"],
59
- });
60
- });
61
-
62
- it("should preserve version from API implementations", () => {
63
- const result = groupVersionedAppKeysByType(["FormatterCLIAPI@1.0.0"]);
64
-
65
- expect(result).toEqual({
66
- selectedApi: ["FormatterCLIAPI@1.0.0"],
67
- slug: [],
68
- });
69
- });
70
-
71
- it("should preserve version from slugs", () => {
72
- const result = groupVersionedAppKeysByType(["slack@2.1.0"]);
73
-
74
- expect(result).toEqual({
75
- selectedApi: [],
76
- slug: ["slack@2.1.0"],
77
- });
78
- });
79
-
80
- it("should handle mixed types correctly", () => {
81
- const result = groupVersionedAppKeysByType([
82
- "FormatterCLIAPI@1.0.0",
83
- "slack",
84
- "AnotherAPI",
85
- "gmail@3.0.1",
86
- ]);
87
-
88
- expect(result).toEqual({
89
- selectedApi: ["FormatterCLIAPI@1.0.0", "AnotherAPI"],
90
- slug: ["slack", "gmail@3.0.1"],
91
- });
92
- });
93
-
94
- it("should handle empty array", () => {
95
- const result = groupVersionedAppKeysByType([]);
96
-
97
- expect(result).toEqual({
98
- selectedApi: [],
99
- slug: [],
100
- });
101
- });
102
-
103
- it("should reject uppercase and lowercase UUIDs", () => {
104
- expect(() => {
105
- groupVersionedAppKeysByType(["61E47557-AF91-4B0C-A3E0-C28606357664"]);
106
- }).toThrow(
107
- "UUID app keys are not supported. Use app slug or implementation ID instead of: 61E47557-AF91-4B0C-A3E0-C28606357664",
108
- );
109
-
110
- expect(() => {
111
- groupVersionedAppKeysByType(["f47ac10b-58cc-4372-a567-0e02b2c3d479"]);
112
- }).toThrow(
113
- "UUID app keys are not supported. Use app slug or implementation ID instead of: f47ac10b-58cc-4372-a567-0e02b2c3d479",
114
- );
115
- });
116
-
117
- it("should categorize partial UUIDs as slugs", () => {
118
- const result = groupVersionedAppKeysByType([
119
- "61e47557-af91-4b0c-a3e0", // too short
120
- "61e47557-af91-4b0c-a3e0-c28606357664-extra", // too long
121
- ]);
122
-
123
- expect(result).toEqual({
124
- selectedApi: [],
125
- slug: [
126
- "61e47557-af91-4b0c-a3e0",
127
- "61e47557-af91-4b0c-a3e0-c28606357664-extra",
128
- ],
129
- });
130
- });
131
-
132
- it("should dedupe exact duplicate versioned keys", () => {
133
- const result = groupVersionedAppKeysByType([
134
- "slack@2.1.0",
135
- "FormatterCLIAPI@1.0.0",
136
- "slack@2.1.0", // exact duplicate
137
- "FormatterCLIAPI@1.0.0", // exact duplicate
138
- "slack@2.1.1",
139
- "FormatterCLIAPI@1.0.1",
140
- ]);
141
-
142
- expect(result).toEqual({
143
- selectedApi: ["FormatterCLIAPI@1.0.0", "FormatterCLIAPI@1.0.1"],
144
- slug: ["slack@2.1.0", "slack@2.1.1"],
145
- });
146
- });
147
- });
148
-
149
- describe("groupAppKeysByType", () => {
150
- it("should strip versions from API implementations", () => {
151
- const result = groupAppKeysByType(["FormatterCLIAPI@1.0.0"]);
152
-
153
- expect(result).toEqual({
154
- selectedApi: ["FormatterCLIAPI"],
155
- slug: [],
156
- });
157
- });
158
-
159
- it("should strip versions from slugs", () => {
160
- const result = groupAppKeysByType(["slack@2.1.0"]);
161
-
162
- expect(result).toEqual({
163
- selectedApi: [],
164
- slug: ["slack"],
165
- });
166
- });
167
-
168
- it("should handle mixed types and strip versions", () => {
169
- const result = groupAppKeysByType([
170
- "FormatterCLIAPI@1.0.0",
171
- "slack",
172
- "AnotherAPI@2.3.4",
173
- "gmail@3.0.1",
174
- ]);
175
-
176
- expect(result).toEqual({
177
- selectedApi: ["FormatterCLIAPI", "AnotherAPI"],
178
- slug: ["slack", "gmail"],
179
- });
180
- });
181
-
182
- it("should handle keys without versions", () => {
183
- const result = groupAppKeysByType([
184
- "FormatterCLIAPI",
185
- "slack",
186
- "AnotherAPI",
187
- ]);
188
-
189
- expect(result).toEqual({
190
- selectedApi: ["FormatterCLIAPI", "AnotherAPI"],
191
- slug: ["slack"],
192
- });
193
- });
194
-
195
- it("should reject UUID app keys (delegated to versioned function)", () => {
196
- expect(() => {
197
- groupAppKeysByType(["61e47557-af91-4b0c-a3e0-c28606357664"]);
198
- }).toThrow(
199
- "UUID app keys are not supported. Use app slug or implementation ID instead of: 61e47557-af91-4b0c-a3e0-c28606357664",
200
- );
201
- });
202
-
203
- it("should handle empty array", () => {
204
- const result = groupAppKeysByType([]);
205
-
206
- expect(result).toEqual({
207
- selectedApi: [],
208
- slug: [],
209
- });
210
- });
211
-
212
- it("should dedupe multiple versions of same base key", () => {
213
- const result = groupAppKeysByType([
214
- "slack@1.0.0",
215
- "FormatterCLIAPI@2.1.0",
216
- "slack@1.2.3", // different version of slack
217
- "FormatterCLIAPI@1.0.0", // different version of FormatterCLIAPI
218
- "gmail",
219
- ]);
220
-
221
- expect(result).toEqual({
222
- selectedApi: ["FormatterCLIAPI"], // only one instance despite multiple versions
223
- slug: ["slack", "gmail"], // only one slack despite multiple versions
224
- });
225
- });
226
-
227
- it("should dedupe exact duplicates after version stripping", () => {
228
- const result = groupAppKeysByType([
229
- "slack@1.0.0",
230
- "slack", // no version
231
- "slack@2.0.0", // different version
232
- "FormatterCLIAPI",
233
- "FormatterCLIAPI@1.5.0",
234
- ]);
235
-
236
- expect(result).toEqual({
237
- selectedApi: ["FormatterCLIAPI"],
238
- slug: ["slack"],
239
- });
240
- });
241
- });
242
-
243
- describe("toAppLocator", () => {
244
- it("should reject UUID app keys", () => {
245
- expect(() => {
246
- toAppLocator("61e47557-af91-4b0c-a3e0-c28606357664");
247
- }).toThrow(
248
- "UUID app keys are not supported. Use app slug or implementation ID instead of: 61e47557-af91-4b0c-a3e0-c28606357664",
249
- );
250
- });
251
-
252
- it("should reject UUID app keys with versions", () => {
253
- expect(() => {
254
- toAppLocator("61e47557-af91-4b0c-a3e0-c28606357664@1.0.0");
255
- }).toThrow(
256
- "UUID app keys are not supported. Use app slug or implementation ID instead of: 61e47557-af91-4b0c-a3e0-c28606357664@1.0.0",
257
- );
258
- });
259
-
260
- it("should reject uppercase UUID app keys", () => {
261
- expect(() => {
262
- toAppLocator("61E47557-AF91-4B0C-A3E0-C28606357664");
263
- }).toThrow(
264
- "UUID app keys are not supported. Use app slug or implementation ID instead of: 61E47557-AF91-4B0C-A3E0-C28606357664",
265
- );
266
- });
267
-
268
- it("should handle simple slug without version", () => {
269
- const result = toAppLocator("slack");
270
-
271
- expect(result).toEqual({
272
- lookupAppKey: "slack",
273
- slug: "slack",
274
- implementationName: undefined,
275
- version: undefined,
276
- });
277
- });
278
-
279
- it("should handle slug with version", () => {
280
- const result = toAppLocator("slack@1.0.0");
281
-
282
- expect(result).toEqual({
283
- lookupAppKey: "slack",
284
- slug: "slack",
285
- implementationName: undefined,
286
- version: "1.0.0",
287
- });
288
- });
289
-
290
- it("should handle dashified slug", () => {
291
- const result = toAppLocator("google-sheets");
292
-
293
- expect(result).toEqual({
294
- lookupAppKey: "google-sheets",
295
- slug: "google-sheets",
296
- implementationName: undefined,
297
- version: undefined,
298
- });
299
- });
300
-
301
- it("should handle dashified slug with version", () => {
302
- const result = toAppLocator("google-sheets@2.1.3");
303
-
304
- expect(result).toEqual({
305
- lookupAppKey: "google-sheets",
306
- slug: "google-sheets",
307
- implementationName: undefined,
308
- version: "2.1.3",
309
- });
310
- });
311
-
312
- it("should handle snake_cased slug and convert to dash", () => {
313
- const result = toAppLocator("google_sheets");
314
-
315
- expect(result).toEqual({
316
- lookupAppKey: "google_sheets",
317
- slug: "google-sheets",
318
- implementationName: undefined,
319
- version: undefined,
320
- });
321
- });
322
-
323
- it("should handle snake_cased slug with version and convert to dash", () => {
324
- const result = toAppLocator("google_sheets@2.1.3");
325
-
326
- expect(result).toEqual({
327
- lookupAppKey: "google_sheets",
328
- slug: "google-sheets",
329
- implementationName: undefined,
330
- version: "2.1.3",
331
- });
332
- });
333
-
334
- it("should handle leading underscore snake_cased slug", () => {
335
- const result = toAppLocator("_100hires_ats");
336
-
337
- expect(result).toEqual({
338
- lookupAppKey: "_100hires_ats",
339
- slug: "100hires-ats",
340
- implementationName: undefined,
341
- version: undefined,
342
- });
343
- });
344
-
345
- it("should handle leading underscore snake_cased slug with version", () => {
346
- const result = toAppLocator("_100hires_ats@3.0.0");
347
-
348
- expect(result).toEqual({
349
- lookupAppKey: "_100hires_ats",
350
- slug: "100hires-ats",
351
- implementationName: undefined,
352
- version: "3.0.0",
353
- });
354
- });
355
-
356
- it("should handle implementation name without version", () => {
357
- const result = toAppLocator("SlackCLIAPI");
358
-
359
- expect(result).toEqual({
360
- lookupAppKey: "SlackCLIAPI",
361
- slug: undefined,
362
- implementationName: "SlackCLIAPI",
363
- version: undefined,
364
- });
365
- });
366
-
367
- it("should handle implementation name with version", () => {
368
- const result = toAppLocator("SlackCLIAPI@1.29.0");
369
-
370
- expect(result).toEqual({
371
- lookupAppKey: "SlackCLIAPI",
372
- slug: undefined,
373
- implementationName: "SlackCLIAPI",
374
- version: "1.29.0",
375
- });
376
- });
377
-
378
- it("should handle edge cases with complex version numbers", () => {
379
- const result = toAppLocator("slack@1.2.3-beta.4+build.5");
380
-
381
- expect(result).toEqual({
382
- lookupAppKey: "slack",
383
- slug: "slack",
384
- implementationName: undefined,
385
- version: "1.2.3-beta.4+build.5",
386
- });
387
- });
388
-
389
- it("should handle single character app keys", () => {
390
- const result = toAppLocator("a");
391
-
392
- expect(result).toEqual({
393
- lookupAppKey: "a",
394
- slug: "a",
395
- implementationName: undefined,
396
- version: undefined,
397
- });
398
- });
399
-
400
- it("should handle app keys with numbers", () => {
401
- const result = toAppLocator("app123");
402
-
403
- expect(result).toEqual({
404
- lookupAppKey: "app123",
405
- slug: "app123",
406
- implementationName: undefined,
407
- version: undefined,
408
- });
409
- });
410
-
411
- it("should handle mixed case app keys that aren't implementation names", () => {
412
- const result = toAppLocator("SlackBot");
413
-
414
- expect(result).toEqual({
415
- lookupAppKey: "SlackBot",
416
- slug: undefined,
417
- implementationName: "SlackBot",
418
- version: undefined,
419
- });
420
- });
421
-
422
- it("should handle empty version (app key ending with @)", () => {
423
- const result = toAppLocator("slack@");
424
-
425
- expect(result).toEqual({
426
- lookupAppKey: "slack",
427
- slug: "slack",
428
- implementationName: undefined,
429
- version: "",
430
- });
431
- });
432
- });
433
- });
@@ -1,267 +0,0 @@
1
- /**
2
- * Domain utility functions for working with app identifiers and data normalization
3
- */
4
-
5
- import type { Action, Authentication, ImplementationMeta } from "../api/types";
6
- import type { ActionItem, AppItem, AuthenticationItem } from "../types/domain";
7
-
8
- /**
9
- * Splits a versioned key to extract the base key and version
10
- *
11
- * @param versionedKey - Versioned key in format "KeyName@version" (e.g., "SlackCLIAPI@1.21.1")
12
- * @returns Tuple of [baseKey, version] or [versionedKey, undefined] if no @ symbol
13
- *
14
- * @example
15
- * splitVersionedKey("SlackCLIAPI@1.21.1") // ["SlackCLIAPI", "1.21.1"]
16
- * splitVersionedKey("SomeAPI") // ["SomeAPI", undefined]
17
- */
18
- export function splitVersionedKey(
19
- versionedKey: string,
20
- ): [string, string | undefined] {
21
- const parts = versionedKey.split("@");
22
- if (parts.length >= 2) {
23
- const baseKey = parts[0];
24
- const version = parts.slice(1).join("@"); // Handle edge case of multiple @ symbols
25
- return [baseKey, version];
26
- }
27
- return [versionedKey, undefined];
28
- }
29
-
30
- /**
31
- * Converts a lightweight ImplementationMeta to a slimmed AppItem
32
- *
33
- * @param implementationMeta - Raw ImplementationMeta from API
34
- * @returns Normalized AppItem with essential fields only
35
- */
36
- export function normalizeImplementationMetaToAppItem(
37
- implementationMeta: ImplementationMeta,
38
- ): AppItem {
39
- const [selectedApi, appVersion] = splitVersionedKey(implementationMeta.id);
40
-
41
- const { id, name, ...restOfImplementationMeta } = implementationMeta;
42
-
43
- return {
44
- ...restOfImplementationMeta,
45
- title: name,
46
- key: selectedApi,
47
- implementation_id: id,
48
- version: appVersion,
49
- };
50
- }
51
-
52
- /**
53
- * Converts an API Authentication to an AuthenticationItem with normalized field names
54
- *
55
- * @param auth - Raw Authentication from API
56
- * @param options - Additional fields to include
57
- * @param options.app_key - selected_api from implementations endpoint
58
- * @param options.app_version - Version extracted from selected_api
59
- * @returns Normalized AuthenticationItem
60
- */
61
- export function normalizeAuthenticationItem(
62
- auth: Authentication,
63
- options: { app_key?: string; app_version?: string } = {},
64
- ): AuthenticationItem {
65
- // Extract app key and version from selected_api if not provided
66
- let appKey = options.app_key;
67
- let appVersion = options.app_version;
68
-
69
- if (auth.selected_api) {
70
- const [extractedAppKey, extractedVersion] = splitVersionedKey(
71
- auth.selected_api,
72
- );
73
-
74
- // Use extracted app key if not provided in options
75
- if (!appKey) {
76
- appKey = extractedAppKey;
77
- }
78
-
79
- // Use extracted version if not provided in options
80
- if (!appVersion) {
81
- appVersion = extractedVersion;
82
- }
83
- }
84
-
85
- const {
86
- selected_api: selectedApi,
87
- customuser_id: userId,
88
- ...restOfAuth
89
- } = auth;
90
-
91
- return {
92
- ...restOfAuth, // Pass through all other API response fields except selected_api
93
- implementation_id: selectedApi, // Rename selected_api to implementation_id
94
- title: auth.title || (auth as any).label || undefined, // Coerce title from label if missing
95
- is_expired: auth.is_stale, // Map is_stale to is_expired
96
- expired_at: auth.marked_stale_at, // Map marked_stale_at to expired_at
97
- app_key: appKey, // App key from implementations endpoint or parsed from selected_api
98
- app_version: appVersion, // Version from selected_api or provided
99
- user_id: userId, // Map customuser_id to user_id
100
- };
101
- }
102
-
103
- export function normalizeActionItem(action: Action): ActionItem {
104
- const { name, type, selected_api: selectedApi } = action;
105
-
106
- // Split version from selected_api
107
- const [appKey, appVersion] = selectedApi
108
- ? splitVersionedKey(selectedApi)
109
- : ["", undefined];
110
-
111
- return {
112
- // Only include the fields we want - explicitly list them
113
- id: action.id,
114
- key: action.key,
115
- description: action.description,
116
- is_important: action.is_important,
117
- is_hidden: action.is_hidden,
118
- // Transformed fields
119
- app_key: appKey,
120
- app_version: appVersion,
121
- action_type: type,
122
- title: name, // Map name to title
123
- type: "action",
124
- };
125
- }
126
-
127
- /**
128
- * Groups app keys by their type based on format patterns
129
- *
130
- * @param appKeys Array of app key strings to categorize
131
- * @returns Object with arrays of keys grouped by type: selectedApi (CLI APIs), slug (everything else)
132
- *
133
- * @example
134
- * groupVersionedAppKeysByType([
135
- * 'FormatterCLIAPI@1.0.0',
136
- * 'slack',
137
- * 'AnotherAPI'
138
- * ])
139
- * // Returns: {
140
- * // selectedApi: ['FormatterCLIAPI@1.0.0', 'AnotherAPI'],
141
- * // slug: ['slack']
142
- * // }
143
- */
144
- export function groupVersionedAppKeysByType(appKeys: string[]): {
145
- selectedApi: string[];
146
- slug: string[];
147
- } {
148
- const result = {
149
- selectedApi: [] as string[],
150
- slug: [] as string[],
151
- };
152
-
153
- // Use Sets to track seen keys for deduplication
154
- const seenSelectedApi = new Set<string>();
155
- const seenSlugs = new Set<string>();
156
-
157
- for (const key of appKeys) {
158
- const appLocator = toAppLocator(key);
159
-
160
- if (appLocator.slug) {
161
- // For slugs, we need to reconstruct the versioned slug
162
- const versionedSlug = appLocator.version
163
- ? `${appLocator.slug}@${appLocator.version}`
164
- : appLocator.slug;
165
- if (!seenSlugs.has(versionedSlug)) {
166
- seenSlugs.add(versionedSlug);
167
- result.slug.push(versionedSlug);
168
- }
169
- } else {
170
- // For implementation names (selectedApi)
171
- if (!seenSelectedApi.has(key)) {
172
- seenSelectedApi.add(key);
173
- result.selectedApi.push(key);
174
- }
175
- }
176
- }
177
-
178
- return result;
179
- }
180
-
181
- export function groupAppKeysByType(appKeys: string[]): {
182
- selectedApi: string[];
183
- slug: string[];
184
- } {
185
- const grouped = groupVersionedAppKeysByType(appKeys);
186
-
187
- // Extract base keys and dedupe by using Set
188
- return {
189
- selectedApi: [
190
- ...new Set(grouped.selectedApi.map((key) => key.split("@")[0])),
191
- ],
192
- slug: [...new Set(grouped.slug.map((key) => key.split("@")[0]))],
193
- };
194
- }
195
-
196
- export function isSlug(slug: string): boolean {
197
- return !!slug.match(/^[a-z0-9]+(?:-[a-z0-9]+)*$/);
198
- }
199
-
200
- export function isSnakeCasedSlug(slug: string): boolean {
201
- // Allow leading underscore for slugs starting with a number.
202
- if (slug.match(/^_[0-9]/)) {
203
- slug = slug.slice(1);
204
- }
205
-
206
- return !!slug.match(/^[a-z0-9]+(?:_[a-z0-9]+)*$/);
207
- }
208
-
209
- export function dashifySnakeCasedSlug(slug: string): string {
210
- // Only dashify if it's a valid snake_cased slug.
211
- if (!isSnakeCasedSlug(slug)) {
212
- return slug;
213
- }
214
-
215
- // Allow one leading underscore for slugs starting with a number.
216
- if (slug.startsWith("_")) {
217
- slug = slug.slice(1);
218
- }
219
-
220
- return slug.replace(/_/g, "-");
221
- }
222
-
223
- export interface AppLocator {
224
- lookupAppKey: string;
225
- slug?: string;
226
- implementationName?: string;
227
- version?: string;
228
- }
229
- export interface ResolvedAppLocator extends AppLocator {
230
- implementationName: string;
231
- }
232
-
233
- export function isUuid(appKey: string): boolean {
234
- return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
235
- appKey,
236
- );
237
- }
238
-
239
- export function toAppLocator(appKey: string): AppLocator {
240
- const [appKeyWithoutVersion, version] = splitVersionedKey(appKey);
241
- if (isUuid(appKeyWithoutVersion)) {
242
- throw new Error(
243
- `UUID app keys are not supported. Use app slug or implementation ID instead of: ${appKey}`,
244
- );
245
- }
246
- const slug = isSlug(appKeyWithoutVersion)
247
- ? appKeyWithoutVersion
248
- : isSnakeCasedSlug(appKeyWithoutVersion)
249
- ? dashifySnakeCasedSlug(appKeyWithoutVersion)
250
- : undefined;
251
- return {
252
- lookupAppKey: appKeyWithoutVersion,
253
- slug,
254
- implementationName: slug ? undefined : appKeyWithoutVersion,
255
- version,
256
- };
257
- }
258
-
259
- export function isResolvedAppLocator(
260
- appLocator: AppLocator,
261
- ): appLocator is ResolvedAppLocator {
262
- return !!appLocator.implementationName;
263
- }
264
-
265
- export function toImplementationId(appLocator: ResolvedAppLocator): string {
266
- return `${appLocator.implementationName}@${appLocator.version || "latest"}`;
267
- }