@zapier/zapier-sdk 0.13.6 → 0.13.8

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 (155) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/api/client.d.ts.map +1 -1
  3. package/dist/api/client.js +5 -5
  4. package/dist/api/client.test.d.ts +2 -0
  5. package/dist/api/client.test.d.ts.map +1 -0
  6. package/dist/api/client.test.js +80 -0
  7. package/dist/api/index.d.ts +1 -0
  8. package/dist/api/index.d.ts.map +1 -1
  9. package/dist/api/index.js +3 -1
  10. package/dist/api/schemas.d.ts +20 -20
  11. package/dist/api/types.d.ts +2 -0
  12. package/dist/api/types.d.ts.map +1 -1
  13. package/dist/auth.d.ts +3 -0
  14. package/dist/auth.d.ts.map +1 -1
  15. package/dist/auth.test.d.ts +2 -0
  16. package/dist/auth.test.d.ts.map +1 -0
  17. package/dist/auth.test.js +102 -0
  18. package/dist/constants.d.ts +4 -4
  19. package/dist/constants.d.ts.map +1 -1
  20. package/dist/constants.js +4 -4
  21. package/dist/index.cjs +89 -21
  22. package/dist/index.d.mts +21 -1
  23. package/dist/index.d.ts +1 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +2 -0
  26. package/dist/index.mjs +88 -22
  27. package/dist/plugins/api/index.d.ts.map +1 -1
  28. package/dist/plugins/api/index.js +4 -1
  29. package/dist/plugins/eventEmission/index.d.ts +2 -0
  30. package/dist/plugins/eventEmission/index.d.ts.map +1 -1
  31. package/dist/plugins/eventEmission/index.js +35 -9
  32. package/dist/plugins/eventEmission/index.test.js +100 -0
  33. package/dist/schemas/Action.d.ts +2 -2
  34. package/dist/schemas/Auth.d.ts +4 -4
  35. package/dist/schemas/Field.d.ts +10 -10
  36. package/dist/sdk.test.js +121 -1
  37. package/dist/types/sdk.d.ts +3 -0
  38. package/dist/types/sdk.d.ts.map +1 -1
  39. package/dist/utils/url-utils.d.ts +19 -0
  40. package/dist/utils/url-utils.d.ts.map +1 -0
  41. package/dist/utils/url-utils.js +62 -0
  42. package/dist/utils/url-utils.test.d.ts +2 -0
  43. package/dist/utils/url-utils.test.d.ts.map +1 -0
  44. package/dist/utils/url-utils.test.js +103 -0
  45. package/package.json +8 -3
  46. package/src/api/auth.ts +0 -28
  47. package/src/api/client.ts +0 -491
  48. package/src/api/debug.test.ts +0 -76
  49. package/src/api/debug.ts +0 -154
  50. package/src/api/index.ts +0 -90
  51. package/src/api/polling.test.ts +0 -405
  52. package/src/api/polling.ts +0 -253
  53. package/src/api/schemas.ts +0 -465
  54. package/src/api/types.ts +0 -152
  55. package/src/auth.ts +0 -72
  56. package/src/constants.ts +0 -16
  57. package/src/index.ts +0 -111
  58. package/src/plugins/api/index.ts +0 -43
  59. package/src/plugins/apps/index.ts +0 -203
  60. package/src/plugins/apps/schemas.ts +0 -64
  61. package/src/plugins/eventEmission/builders.ts +0 -115
  62. package/src/plugins/eventEmission/index.test.ts +0 -169
  63. package/src/plugins/eventEmission/index.ts +0 -294
  64. package/src/plugins/eventEmission/transport.test.ts +0 -214
  65. package/src/plugins/eventEmission/transport.ts +0 -135
  66. package/src/plugins/eventEmission/types.ts +0 -58
  67. package/src/plugins/eventEmission/utils.ts +0 -121
  68. package/src/plugins/fetch/index.ts +0 -83
  69. package/src/plugins/fetch/schemas.ts +0 -37
  70. package/src/plugins/findFirstAuthentication/index.test.ts +0 -209
  71. package/src/plugins/findFirstAuthentication/index.ts +0 -68
  72. package/src/plugins/findFirstAuthentication/schemas.ts +0 -47
  73. package/src/plugins/findUniqueAuthentication/index.test.ts +0 -197
  74. package/src/plugins/findUniqueAuthentication/index.ts +0 -77
  75. package/src/plugins/findUniqueAuthentication/schemas.ts +0 -49
  76. package/src/plugins/getAction/index.test.ts +0 -239
  77. package/src/plugins/getAction/index.ts +0 -75
  78. package/src/plugins/getAction/schemas.ts +0 -41
  79. package/src/plugins/getApp/index.test.ts +0 -181
  80. package/src/plugins/getApp/index.ts +0 -60
  81. package/src/plugins/getApp/schemas.ts +0 -33
  82. package/src/plugins/getAuthentication/index.test.ts +0 -294
  83. package/src/plugins/getAuthentication/index.ts +0 -95
  84. package/src/plugins/getAuthentication/schemas.ts +0 -38
  85. package/src/plugins/getProfile/index.ts +0 -60
  86. package/src/plugins/getProfile/schemas.ts +0 -24
  87. package/src/plugins/listActions/index.test.ts +0 -526
  88. package/src/plugins/listActions/index.ts +0 -132
  89. package/src/plugins/listActions/schemas.ts +0 -55
  90. package/src/plugins/listApps/index.test.ts +0 -378
  91. package/src/plugins/listApps/index.ts +0 -159
  92. package/src/plugins/listApps/schemas.ts +0 -41
  93. package/src/plugins/listAuthentications/index.test.ts +0 -739
  94. package/src/plugins/listAuthentications/index.ts +0 -152
  95. package/src/plugins/listAuthentications/schemas.ts +0 -77
  96. package/src/plugins/listInputFieldChoices/index.test.ts +0 -653
  97. package/src/plugins/listInputFieldChoices/index.ts +0 -173
  98. package/src/plugins/listInputFieldChoices/schemas.ts +0 -125
  99. package/src/plugins/listInputFields/index.test.ts +0 -439
  100. package/src/plugins/listInputFields/index.ts +0 -294
  101. package/src/plugins/listInputFields/schemas.ts +0 -68
  102. package/src/plugins/manifest/index.test.ts +0 -776
  103. package/src/plugins/manifest/index.ts +0 -461
  104. package/src/plugins/manifest/schemas.ts +0 -60
  105. package/src/plugins/registry/index.ts +0 -160
  106. package/src/plugins/request/index.test.ts +0 -333
  107. package/src/plugins/request/index.ts +0 -105
  108. package/src/plugins/request/schemas.ts +0 -69
  109. package/src/plugins/runAction/index.test.ts +0 -388
  110. package/src/plugins/runAction/index.ts +0 -215
  111. package/src/plugins/runAction/schemas.ts +0 -60
  112. package/src/resolvers/actionKey.ts +0 -37
  113. package/src/resolvers/actionType.ts +0 -34
  114. package/src/resolvers/appKey.ts +0 -7
  115. package/src/resolvers/authenticationId.ts +0 -54
  116. package/src/resolvers/index.ts +0 -11
  117. package/src/resolvers/inputFieldKey.ts +0 -70
  118. package/src/resolvers/inputs.ts +0 -69
  119. package/src/schemas/Action.ts +0 -52
  120. package/src/schemas/App.ts +0 -45
  121. package/src/schemas/Auth.ts +0 -59
  122. package/src/schemas/Field.ts +0 -169
  123. package/src/schemas/Run.ts +0 -40
  124. package/src/schemas/UserProfile.ts +0 -60
  125. package/src/sdk.test.ts +0 -212
  126. package/src/sdk.ts +0 -178
  127. package/src/types/domain.test.ts +0 -50
  128. package/src/types/domain.ts +0 -66
  129. package/src/types/errors.ts +0 -278
  130. package/src/types/events.ts +0 -43
  131. package/src/types/functions.ts +0 -28
  132. package/src/types/optional-zapier-sdk-cli-login.d.ts +0 -37
  133. package/src/types/plugin.ts +0 -125
  134. package/src/types/properties.ts +0 -80
  135. package/src/types/sdk.ts +0 -111
  136. package/src/types/telemetry-events.ts +0 -85
  137. package/src/utils/array-utils.test.ts +0 -131
  138. package/src/utils/array-utils.ts +0 -41
  139. package/src/utils/domain-utils.test.ts +0 -433
  140. package/src/utils/domain-utils.ts +0 -267
  141. package/src/utils/file-utils.test.ts +0 -73
  142. package/src/utils/file-utils.ts +0 -94
  143. package/src/utils/function-utils.test.ts +0 -141
  144. package/src/utils/function-utils.ts +0 -245
  145. package/src/utils/pagination-utils.test.ts +0 -620
  146. package/src/utils/pagination-utils.ts +0 -242
  147. package/src/utils/schema-utils.ts +0 -207
  148. package/src/utils/string-utils.test.ts +0 -45
  149. package/src/utils/string-utils.ts +0 -54
  150. package/src/utils/validation.test.ts +0 -51
  151. package/src/utils/validation.ts +0 -44
  152. package/tsconfig.build.json +0 -18
  153. package/tsconfig.json +0 -20
  154. package/tsconfig.tsbuildinfo +0 -1
  155. package/tsup.config.ts +0 -23
@@ -1,85 +0,0 @@
1
- /**
2
- * Event emission types matching Avro schemas for SDK telemetry
3
- *
4
- * These interfaces correspond to the Avro schemas:
5
- * - application_lifecycle_event.avsc
6
- * - error_occurred_event.avsc
7
- */
8
-
9
- // Common fields present in all events
10
- export interface BaseEvent {
11
- event_id: string;
12
- timestamp_ms: number;
13
- release_id: string;
14
- customuser_id?: number | null;
15
- account_id?: number | null;
16
- identity_id?: number | null;
17
- visitor_id?: string | null;
18
- correlation_id?: string | null;
19
- }
20
-
21
- // Error Event - tracks SDK errors and exceptions
22
- export interface ErrorOccurredEvent extends BaseEvent {
23
- zap_id?: number | null;
24
- node_id?: number | null;
25
- selected_api?: string | null;
26
- app_id?: number | null;
27
- app_version_id?: number | null;
28
- error_message: string;
29
- error_type?: string | null;
30
- error_status_code?: number | null;
31
- error_stack_trace?: string | null;
32
- error_source_method?: string | null;
33
- error_source_file?: string | null;
34
- error_line_number?: number | null;
35
- operation_type?: string | null;
36
- operation_key?: string | null;
37
- error_severity?: string | null;
38
- is_user_facing: boolean;
39
- is_recoverable?: boolean | null;
40
- sdk_version?: string | null;
41
- error_metadata?: Record<string, string | null> | null;
42
- parent_error_id?: string | null;
43
- error_occurred_timestamp_ms?: number | null;
44
- error_code?: string | null;
45
- recovery_attempted?: boolean | null;
46
- recovery_action?: string | null;
47
- recovery_successful?: boolean | null;
48
- environment?: string | null;
49
- execution_time_before_error_ms?: number | null;
50
- }
51
-
52
- // Application Lifecycle Event - tracks SDK application lifecycle transitions
53
- export interface ApplicationLifecycleEvent extends BaseEvent {
54
- lifecycle_event_type: "startup" | "exit" | "signal_termination";
55
- selected_api?: string | null;
56
- app_id?: number | null;
57
- app_version_id?: number | null;
58
- sdk_version?: string | null;
59
- cli_version?: string | null;
60
- exit_code?: number | null;
61
- signal_name?: string | null;
62
- uptime_ms?: number | null;
63
- memory_usage_bytes?: number | null;
64
- peak_memory_usage_bytes?: number | null;
65
- cpu_time_ms?: number | null;
66
- os_platform?: string | null;
67
- os_release?: string | null;
68
- os_architecture?: string | null;
69
- platform_versions?: Record<string, string | null> | null;
70
- environment?: string | null;
71
- is_ci_environment?: boolean | null;
72
- ci_platform?: string | null;
73
- session_id?: string | null;
74
- metadata?: Record<string, string | null> | null;
75
- process_argv?: (string | null)[] | null;
76
- is_graceful_shutdown?: boolean | null;
77
- shutdown_duration_ms?: number | null;
78
- active_requests_count?: number | null;
79
- }
80
-
81
- // Union type for all telemetry events
82
- export type TelemetryEvent = ErrorOccurredEvent | ApplicationLifecycleEvent;
83
-
84
- // Event type discriminator
85
- export type TelemetryEventType = "error_occurred" | "application_lifecycle";
@@ -1,131 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { toArrayFromAsync } from "./array-utils";
3
-
4
- describe("array-utils", () => {
5
- describe("fromAsync", () => {
6
- it("should convert async generator to array", async () => {
7
- async function* generateNumbers() {
8
- yield 1;
9
- yield 2;
10
- yield 3;
11
- }
12
-
13
- const result = await toArrayFromAsync(generateNumbers());
14
- expect(result).toEqual([1, 2, 3]);
15
- });
16
-
17
- it("should handle empty async generator", async () => {
18
- async function* generateNothing() {
19
- // yield nothing
20
- }
21
-
22
- const result = await toArrayFromAsync(generateNothing());
23
- expect(result).toEqual([]);
24
- });
25
-
26
- it("should handle async generator with async operations", async () => {
27
- async function* generateWithDelay() {
28
- for (let i = 1; i <= 3; i++) {
29
- await new Promise((resolve) => setTimeout(resolve, 1)); // Small delay
30
- yield i * 10;
31
- }
32
- }
33
-
34
- const result = await toArrayFromAsync(generateWithDelay());
35
- expect(result).toEqual([10, 20, 30]);
36
- });
37
-
38
- it("should handle async generator that yields different types", async () => {
39
- async function* generateMixed() {
40
- yield "hello";
41
- yield 42;
42
- yield { name: "test" };
43
- yield [1, 2, 3];
44
- }
45
-
46
- const result = await toArrayFromAsync(generateMixed());
47
- expect(result).toEqual(["hello", 42, { name: "test" }, [1, 2, 3]]);
48
- });
49
-
50
- it("should handle async generator with error", async () => {
51
- async function* generateWithError() {
52
- yield 1;
53
- yield 2;
54
- throw new Error("Test error");
55
- }
56
-
57
- await expect(toArrayFromAsync(generateWithError())).rejects.toThrow(
58
- "Test error",
59
- );
60
- });
61
-
62
- it("should handle async iterable from array with Symbol.asyncIterator", async () => {
63
- const asyncIterable = {
64
- async *[Symbol.asyncIterator]() {
65
- for (const item of ["a", "b", "c"]) {
66
- yield item;
67
- }
68
- },
69
- };
70
-
71
- const result = await toArrayFromAsync(asyncIterable);
72
- expect(result).toEqual(["a", "b", "c"]);
73
- });
74
-
75
- it("should handle large async generator efficiently", async () => {
76
- async function* generateLargeSequence() {
77
- for (let i = 0; i < 1000; i++) {
78
- yield i;
79
- }
80
- }
81
-
82
- const result = await toArrayFromAsync(generateLargeSequence());
83
- expect(result).toHaveLength(1000);
84
- expect(result[0]).toBe(0);
85
- expect(result[999]).toBe(999);
86
- });
87
-
88
- it("should handle async generator that yields promises (promises are auto-awaited)", async () => {
89
- async function* generatePromises() {
90
- yield Promise.resolve("first");
91
- yield Promise.resolve("second");
92
- }
93
-
94
- const result = await toArrayFromAsync(generatePromises());
95
- // for await automatically awaits promises, so we get resolved values
96
- expect(result).toEqual(["first", "second"]);
97
- });
98
-
99
- it("should handle async generator that yields already resolved values", async () => {
100
- async function* generateResolvedValues() {
101
- yield await Promise.resolve("first");
102
- yield await Promise.resolve("second");
103
- }
104
-
105
- const result = await toArrayFromAsync(generateResolvedValues());
106
- // The resolved values are yielded directly
107
- expect(result).toEqual(["first", "second"]);
108
- });
109
-
110
- it("should maintain order of async generator items", async () => {
111
- async function* generateInOrder() {
112
- for (let i = 1; i <= 5; i++) {
113
- // Simulate varying delays
114
- await new Promise((resolve) =>
115
- setTimeout(resolve, Math.random() * 10),
116
- );
117
- yield `item-${i}`;
118
- }
119
- }
120
-
121
- const result = await toArrayFromAsync(generateInOrder());
122
- expect(result).toEqual([
123
- "item-1",
124
- "item-2",
125
- "item-3",
126
- "item-4",
127
- "item-5",
128
- ]);
129
- });
130
- });
131
- });
@@ -1,41 +0,0 @@
1
- /**
2
- * Array utility functions for working with async iterators and arrays
3
- */
4
-
5
- /**
6
- * Creates an array from an async iterable, similar to Array.from() but for async iterables
7
- *
8
- * @param asyncIterable - An async iterable to convert to an array
9
- * @returns Promise that resolves to an array containing all items from the async iterable
10
- *
11
- * @example
12
- * async function* generateNumbers() {
13
- * yield 1;
14
- * yield 2;
15
- * yield 3;
16
- * }
17
- *
18
- * const numbers = await fromAsync(generateNumbers()); // [1, 2, 3]
19
- *
20
- * @example
21
- * // With async generator that fetches data
22
- * async function* fetchUsers() {
23
- * for (let page = 1; page <= 3; page++) {
24
- * const users = await fetchUsersPage(page);
25
- * yield* users;
26
- * }
27
- * }
28
- *
29
- * const allUsers = await fromAsync(fetchUsers());
30
- */
31
- export async function toArrayFromAsync<T>(
32
- asyncIterable: AsyncIterable<T>,
33
- ): Promise<T[]> {
34
- const result: T[] = [];
35
-
36
- for await (const item of asyncIterable) {
37
- result.push(item);
38
- }
39
-
40
- return result;
41
- }
@@ -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
- });