@frak-labs/core-sdk 0.1.0-beta.8d103039 → 0.1.0-beta.b0bd1f8a

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 (90) hide show
  1. package/cdn/bundle.iife.js +14 -0
  2. package/dist/actions-CEEObPYc.js +1 -0
  3. package/dist/actions-DbQhWYx8.cjs +1 -0
  4. package/dist/actions.cjs +1 -1
  5. package/dist/actions.d.cts +3 -1481
  6. package/dist/actions.d.ts +3 -1481
  7. package/dist/actions.js +1 -1
  8. package/dist/bundle.cjs +1 -13
  9. package/dist/bundle.d.cts +6 -2087
  10. package/dist/bundle.d.ts +6 -2087
  11. package/dist/bundle.js +1 -13
  12. package/dist/index-7OZ39x1U.d.ts +195 -0
  13. package/dist/index-C6FxkWPC.d.cts +511 -0
  14. package/dist/index-UFX7xCg3.d.ts +351 -0
  15. package/dist/index-d8xS4ryI.d.ts +511 -0
  16. package/dist/index-p4FqSp8z.d.cts +351 -0
  17. package/dist/index-zDq-VlKx.d.cts +195 -0
  18. package/dist/index.cjs +1 -13
  19. package/dist/index.d.cts +4 -1387
  20. package/dist/index.d.ts +4 -1387
  21. package/dist/index.js +1 -13
  22. package/dist/interaction-DMJ3ZfaF.d.cts +45 -0
  23. package/dist/interaction-KX1h9a7V.d.ts +45 -0
  24. package/dist/interactions-DnfM3oe0.js +1 -0
  25. package/dist/interactions-EIXhNLf6.cjs +1 -0
  26. package/dist/interactions.cjs +1 -1
  27. package/dist/interactions.d.cts +2 -182
  28. package/dist/interactions.d.ts +2 -182
  29. package/dist/interactions.js +1 -1
  30. package/dist/openSso-D--Airj6.d.cts +1018 -0
  31. package/dist/openSso-DsKJ4y0j.d.ts +1018 -0
  32. package/dist/productTypes-BUkXJKZ7.cjs +1 -0
  33. package/dist/productTypes-CGb1MmBF.js +1 -0
  34. package/dist/src-B_xO0AR6.cjs +13 -0
  35. package/dist/src-D2d52OZa.js +13 -0
  36. package/dist/trackEvent-CHnYa85W.js +1 -0
  37. package/dist/trackEvent-GuQm_1Nm.cjs +1 -0
  38. package/package.json +21 -17
  39. package/src/actions/displayEmbeddedWallet.test.ts +194 -0
  40. package/src/actions/displayModal.test.ts +387 -0
  41. package/src/actions/getProductInformation.test.ts +133 -0
  42. package/src/actions/index.ts +19 -19
  43. package/src/actions/openSso.test.ts +407 -0
  44. package/src/actions/prepareSso.test.ts +223 -0
  45. package/src/actions/referral/processReferral.ts +1 -1
  46. package/src/actions/referral/referralInteraction.ts +1 -1
  47. package/src/actions/sendInteraction.test.ts +219 -0
  48. package/src/actions/trackPurchaseStatus.test.ts +287 -0
  49. package/src/actions/watchWalletStatus.test.ts +372 -0
  50. package/src/bundle.ts +1 -1
  51. package/src/clients/createIFrameFrakClient.ts +2 -2
  52. package/src/clients/index.ts +1 -1
  53. package/src/clients/setupClient.test.ts +343 -0
  54. package/src/clients/setupClient.ts +3 -1
  55. package/src/clients/transports/iframeLifecycleManager.test.ts +399 -0
  56. package/src/clients/transports/iframeLifecycleManager.ts +3 -1
  57. package/src/index.ts +72 -74
  58. package/src/interactions/index.ts +2 -2
  59. package/src/interactions/pressEncoder.test.ts +215 -0
  60. package/src/interactions/pressEncoder.ts +1 -1
  61. package/src/interactions/purchaseEncoder.test.ts +291 -0
  62. package/src/interactions/purchaseEncoder.ts +8 -3
  63. package/src/interactions/referralEncoder.test.ts +170 -0
  64. package/src/interactions/retailEncoder.test.ts +107 -0
  65. package/src/interactions/retailEncoder.ts +1 -1
  66. package/src/interactions/webshopEncoder.test.ts +56 -0
  67. package/src/types/index.ts +51 -50
  68. package/src/types/lifecycle/index.ts +1 -1
  69. package/src/types/rpc/embedded/loggedIn.ts +1 -1
  70. package/src/types/rpc/embedded/loggedOut.ts +1 -1
  71. package/src/types/rpc/modal/index.ts +11 -11
  72. package/src/utils/FrakContext.test.ts +407 -0
  73. package/src/utils/FrakContext.ts +8 -2
  74. package/src/utils/compression/b64.test.ts +181 -0
  75. package/src/utils/compression/compress.test.ts +123 -0
  76. package/src/utils/compression/decompress.test.ts +145 -0
  77. package/src/utils/compression/index.ts +1 -1
  78. package/src/utils/computeProductId.test.ts +80 -0
  79. package/src/utils/constants.test.ts +23 -0
  80. package/src/utils/formatAmount.test.ts +113 -0
  81. package/src/utils/getCurrencyAmountKey.test.ts +44 -0
  82. package/src/utils/getSupportedCurrency.test.ts +51 -0
  83. package/src/utils/getSupportedLocale.test.ts +64 -0
  84. package/src/utils/iframeHelper.test.ts +450 -0
  85. package/src/utils/iframeHelper.ts +4 -3
  86. package/src/utils/index.ts +12 -12
  87. package/src/utils/sso.test.ts +361 -0
  88. package/src/utils/trackEvent.test.ts +162 -0
  89. package/cdn/bundle.js +0 -19
  90. package/cdn/bundle.js.LICENSE.txt +0 -10
@@ -0,0 +1,407 @@
1
+ /**
2
+ * Tests for openSso action
3
+ * Tests SSO flows in both redirect and popup modes
4
+ */
5
+
6
+ import { vi } from "vitest";
7
+
8
+ // Mock utilities before imports
9
+ vi.mock("../utils/sso", () => ({
10
+ generateSsoUrl: vi.fn((walletUrl, _args, productId, name, _css) => {
11
+ return `${walletUrl}/sso?name=${name}&productId=${productId}`;
12
+ }),
13
+ }));
14
+
15
+ vi.mock("../utils/computeProductId", () => ({
16
+ computeProductId: vi.fn(
17
+ () =>
18
+ "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
19
+ ),
20
+ }));
21
+
22
+ import {
23
+ afterEach,
24
+ beforeEach,
25
+ describe,
26
+ expect,
27
+ it,
28
+ } from "../../tests/vitest-fixtures";
29
+ import type {
30
+ FrakClient,
31
+ OpenSsoParamsType,
32
+ OpenSsoReturnType,
33
+ } from "../types";
34
+ import { openSso, ssoPopupFeatures, ssoPopupName } from "./openSso";
35
+
36
+ describe("openSso", () => {
37
+ describe("constants", () => {
38
+ it("should have correct popup features", () => {
39
+ expect(ssoPopupFeatures).toBe(
40
+ "menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800"
41
+ );
42
+ });
43
+
44
+ it("should have correct popup name", () => {
45
+ expect(ssoPopupName).toBe("frak-sso");
46
+ });
47
+ });
48
+
49
+ describe("redirect mode", () => {
50
+ it("should use redirect mode when openInSameWindow is true", async () => {
51
+ const mockResponse: OpenSsoReturnType = {
52
+ wallet: "0x1234567890123456789012345678901234567890",
53
+ };
54
+
55
+ const mockClient = {
56
+ config: {
57
+ metadata: { name: "Test App" },
58
+ },
59
+ request: vi.fn().mockResolvedValue(mockResponse),
60
+ } as unknown as FrakClient;
61
+
62
+ const params: OpenSsoParamsType = {
63
+ openInSameWindow: true,
64
+ metadata: {
65
+ logoUrl: "https://example.com/logo.png",
66
+ },
67
+ };
68
+
69
+ const result = await openSso(mockClient, params);
70
+
71
+ expect(mockClient.request).toHaveBeenCalledWith({
72
+ method: "frak_openSso",
73
+ params: [params, "Test App", undefined],
74
+ });
75
+ expect(result).toEqual(mockResponse);
76
+ });
77
+
78
+ it("should use redirect mode when redirectUrl is provided", async () => {
79
+ const mockResponse: OpenSsoReturnType = {
80
+ wallet: "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd",
81
+ };
82
+
83
+ const mockClient = {
84
+ config: {
85
+ metadata: { name: "Test App" },
86
+ },
87
+ request: vi.fn().mockResolvedValue(mockResponse),
88
+ } as unknown as FrakClient;
89
+
90
+ const params: OpenSsoParamsType = {
91
+ redirectUrl: "https://example.com/callback",
92
+ metadata: {
93
+ logoUrl: "https://example.com/logo.png",
94
+ },
95
+ };
96
+
97
+ const result = await openSso(mockClient, params);
98
+
99
+ expect(mockClient.request).toHaveBeenCalledWith({
100
+ method: "frak_openSso",
101
+ params: [params, "Test App", undefined],
102
+ });
103
+ expect(result).toEqual(mockResponse);
104
+ });
105
+
106
+ it("should pass custom CSS in redirect mode", async () => {
107
+ const mockResponse: OpenSsoReturnType = {};
108
+
109
+ const mockClient = {
110
+ config: {
111
+ metadata: { name: "Test App" },
112
+ customizations: {
113
+ css: ":root { --primary: blue; }",
114
+ },
115
+ },
116
+ request: vi.fn().mockResolvedValue(mockResponse),
117
+ } as unknown as FrakClient;
118
+
119
+ const params: OpenSsoParamsType = {
120
+ openInSameWindow: true,
121
+ metadata: {
122
+ logoUrl: "https://example.com/logo.png",
123
+ },
124
+ };
125
+
126
+ await openSso(mockClient, params);
127
+
128
+ expect(mockClient.request).toHaveBeenCalledWith({
129
+ method: "frak_openSso",
130
+ params: [params, "Test App", ":root { --primary: blue; }"],
131
+ });
132
+ });
133
+ });
134
+
135
+ describe("popup mode", () => {
136
+ let windowOpenSpy: any;
137
+ let mockPopup: {
138
+ focus: ReturnType<typeof vi.fn>;
139
+ };
140
+
141
+ beforeEach(() => {
142
+ mockPopup = {
143
+ focus: vi.fn(),
144
+ };
145
+ windowOpenSpy = vi
146
+ .spyOn(window, "open")
147
+ .mockReturnValue(mockPopup as unknown as Window);
148
+ });
149
+
150
+ afterEach(() => {
151
+ windowOpenSpy.mockRestore();
152
+ });
153
+
154
+ it("should open popup with generated URL", async () => {
155
+ const mockResponse: OpenSsoReturnType = {
156
+ wallet: "0x1234567890123456789012345678901234567890",
157
+ };
158
+
159
+ const mockClient = {
160
+ config: {
161
+ metadata: { name: "Test App" },
162
+ walletUrl: "https://wallet.frak.id",
163
+ },
164
+ request: vi.fn().mockResolvedValue(mockResponse),
165
+ } as unknown as FrakClient;
166
+
167
+ const params: OpenSsoParamsType = {
168
+ metadata: {
169
+ logoUrl: "https://example.com/logo.png",
170
+ },
171
+ };
172
+
173
+ await openSso(mockClient, params);
174
+
175
+ expect(window.open).toHaveBeenCalledWith(
176
+ expect.stringContaining("https://wallet.frak.id/sso"),
177
+ "frak-sso",
178
+ "menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800"
179
+ );
180
+ });
181
+
182
+ it("should use custom ssoPopupUrl when provided", async () => {
183
+ const mockResponse: OpenSsoReturnType = {};
184
+
185
+ const mockClient = {
186
+ config: {
187
+ metadata: { name: "Test App" },
188
+ },
189
+ request: vi.fn().mockResolvedValue(mockResponse),
190
+ } as unknown as FrakClient;
191
+
192
+ const params: OpenSsoParamsType = {
193
+ ssoPopupUrl: "https://custom-wallet.com/sso?custom=param",
194
+ metadata: {
195
+ logoUrl: "https://example.com/logo.png",
196
+ },
197
+ };
198
+
199
+ await openSso(mockClient, params);
200
+
201
+ expect(window.open).toHaveBeenCalledWith(
202
+ "https://custom-wallet.com/sso?custom=param",
203
+ "frak-sso",
204
+ "menubar=no,status=no,scrollbars=no,fullscreen=no,width=500, height=800"
205
+ );
206
+ });
207
+
208
+ it("should focus popup after opening", async () => {
209
+ const mockResponse: OpenSsoReturnType = {};
210
+
211
+ const mockClient = {
212
+ config: {
213
+ metadata: { name: "Test App" },
214
+ },
215
+ request: vi.fn().mockResolvedValue(mockResponse),
216
+ } as unknown as FrakClient;
217
+
218
+ const params: OpenSsoParamsType = {
219
+ metadata: {
220
+ logoUrl: "https://example.com/logo.png",
221
+ },
222
+ };
223
+
224
+ await openSso(mockClient, params);
225
+
226
+ expect(mockPopup.focus).toHaveBeenCalled();
227
+ });
228
+
229
+ it("should wait for SSO completion via client.request", async () => {
230
+ const mockResponse: OpenSsoReturnType = {
231
+ wallet: "0x1234567890123456789012345678901234567890",
232
+ };
233
+
234
+ const mockClient = {
235
+ config: {
236
+ metadata: { name: "Test App" },
237
+ },
238
+ request: vi.fn().mockResolvedValue(mockResponse),
239
+ } as unknown as FrakClient;
240
+
241
+ const params: OpenSsoParamsType = {
242
+ metadata: {
243
+ logoUrl: "https://example.com/logo.png",
244
+ },
245
+ };
246
+
247
+ const result = await openSso(mockClient, params);
248
+
249
+ expect(mockClient.request).toHaveBeenCalledWith({
250
+ method: "frak_openSso",
251
+ params: [params, "Test App", undefined],
252
+ });
253
+ expect(result).toEqual(mockResponse);
254
+ });
255
+
256
+ it("should return empty object when result is null", async () => {
257
+ const mockClient = {
258
+ config: {
259
+ metadata: { name: "Test App" },
260
+ },
261
+ request: vi.fn().mockResolvedValue(null),
262
+ } as unknown as FrakClient;
263
+
264
+ const params: OpenSsoParamsType = {
265
+ metadata: {
266
+ logoUrl: "https://example.com/logo.png",
267
+ },
268
+ };
269
+
270
+ const result = await openSso(mockClient, params);
271
+
272
+ expect(result).toEqual({});
273
+ });
274
+
275
+ it("should use default wallet URL when not configured", async () => {
276
+ const mockResponse: OpenSsoReturnType = {};
277
+
278
+ const mockClient = {
279
+ config: {
280
+ metadata: { name: "Test App" },
281
+ },
282
+ request: vi.fn().mockResolvedValue(mockResponse),
283
+ } as unknown as FrakClient;
284
+
285
+ const params: OpenSsoParamsType = {
286
+ metadata: {
287
+ logoUrl: "https://example.com/logo.png",
288
+ },
289
+ };
290
+
291
+ await openSso(mockClient, params);
292
+
293
+ expect(window.open).toHaveBeenCalledWith(
294
+ expect.stringContaining("https://wallet.frak.id/sso"),
295
+ expect.any(String),
296
+ expect.any(String)
297
+ );
298
+ });
299
+ });
300
+
301
+ describe("popup blocker", () => {
302
+ it("should throw error when popup is blocked", async () => {
303
+ vi.spyOn(window, "open").mockReturnValue(null);
304
+
305
+ const mockClient = {
306
+ config: {
307
+ metadata: { name: "Test App" },
308
+ },
309
+ request: vi.fn(),
310
+ } as unknown as FrakClient;
311
+
312
+ const params: OpenSsoParamsType = {
313
+ metadata: {
314
+ logoUrl: "https://example.com/logo.png",
315
+ },
316
+ };
317
+
318
+ await expect(openSso(mockClient, params)).rejects.toThrow(
319
+ "Popup was blocked. Please allow popups for this site."
320
+ );
321
+ });
322
+
323
+ it("should not call client.request when popup is blocked", async () => {
324
+ vi.spyOn(window, "open").mockReturnValue(null);
325
+
326
+ const mockClient = {
327
+ config: {
328
+ metadata: { name: "Test App" },
329
+ },
330
+ request: vi.fn(),
331
+ } as unknown as FrakClient;
332
+
333
+ const params: OpenSsoParamsType = {
334
+ metadata: {
335
+ logoUrl: "https://example.com/logo.png",
336
+ },
337
+ };
338
+
339
+ try {
340
+ await openSso(mockClient, params);
341
+ } catch {
342
+ // Expected error
343
+ }
344
+
345
+ expect(mockClient.request).not.toHaveBeenCalled();
346
+ });
347
+ });
348
+
349
+ describe("mode detection", () => {
350
+ it("should prefer openInSameWindow over redirectUrl", async () => {
351
+ const mockResponse: OpenSsoReturnType = {};
352
+
353
+ const mockClient = {
354
+ config: {
355
+ metadata: { name: "Test App" },
356
+ },
357
+ request: vi.fn().mockResolvedValue(mockResponse),
358
+ } as unknown as FrakClient;
359
+
360
+ const params: OpenSsoParamsType = {
361
+ openInSameWindow: false,
362
+ redirectUrl: "https://example.com/callback",
363
+ metadata: {
364
+ logoUrl: "https://example.com/logo.png",
365
+ },
366
+ };
367
+
368
+ const windowOpenSpy = vi.spyOn(window, "open").mockReturnValue({
369
+ focus: vi.fn(),
370
+ } as unknown as Window);
371
+
372
+ await openSso(mockClient, params);
373
+
374
+ // Should use popup mode because openInSameWindow=false
375
+ expect(window.open).toHaveBeenCalled();
376
+
377
+ windowOpenSpy.mockRestore();
378
+ });
379
+
380
+ it("should use popup mode when neither flag is set", async () => {
381
+ const mockResponse: OpenSsoReturnType = {};
382
+
383
+ const mockClient = {
384
+ config: {
385
+ metadata: { name: "Test App" },
386
+ },
387
+ request: vi.fn().mockResolvedValue(mockResponse),
388
+ } as unknown as FrakClient;
389
+
390
+ const params: OpenSsoParamsType = {
391
+ metadata: {
392
+ logoUrl: "https://example.com/logo.png",
393
+ },
394
+ };
395
+
396
+ const windowOpenSpy = vi.spyOn(window, "open").mockReturnValue({
397
+ focus: vi.fn(),
398
+ } as unknown as Window);
399
+
400
+ await openSso(mockClient, params);
401
+
402
+ expect(window.open).toHaveBeenCalled();
403
+
404
+ windowOpenSpy.mockRestore();
405
+ });
406
+ });
407
+ });
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Tests for prepareSso action
3
+ * Tests SSO URL generation via RPC
4
+ */
5
+
6
+ import { describe, expect, it, vi } from "../../tests/vitest-fixtures";
7
+ import type {
8
+ FrakClient,
9
+ PrepareSsoParamsType,
10
+ PrepareSsoReturnType,
11
+ } from "../types";
12
+ import { prepareSso } from "./prepareSso";
13
+
14
+ describe("prepareSso", () => {
15
+ describe("success cases", () => {
16
+ it("should call client.request with correct method and params", async () => {
17
+ const mockResponse: PrepareSsoReturnType = {
18
+ ssoUrl: "https://wallet.frak.id/sso?params=xyz",
19
+ };
20
+
21
+ const mockClient = {
22
+ config: {
23
+ metadata: {
24
+ name: "Test App",
25
+ },
26
+ },
27
+ request: vi.fn().mockResolvedValue(mockResponse),
28
+ } as unknown as FrakClient;
29
+
30
+ const params: PrepareSsoParamsType = {
31
+ directExit: true,
32
+ };
33
+
34
+ await prepareSso(mockClient, params);
35
+
36
+ expect(mockClient.request).toHaveBeenCalledWith({
37
+ method: "frak_prepareSso",
38
+ params: [params, "Test App", undefined],
39
+ });
40
+ });
41
+
42
+ it("should return SSO URL", async () => {
43
+ const mockResponse: PrepareSsoReturnType = {
44
+ ssoUrl: "https://wallet.frak.id/sso?params=abc123",
45
+ };
46
+
47
+ const mockClient = {
48
+ config: {
49
+ metadata: {
50
+ name: "Test App",
51
+ },
52
+ },
53
+ request: vi.fn().mockResolvedValue(mockResponse),
54
+ } as unknown as FrakClient;
55
+
56
+ const params: PrepareSsoParamsType = {
57
+ directExit: false,
58
+ };
59
+
60
+ const result = await prepareSso(mockClient, params);
61
+
62
+ expect(result).toEqual(mockResponse);
63
+ expect(result.ssoUrl).toBe(
64
+ "https://wallet.frak.id/sso?params=abc123"
65
+ );
66
+ });
67
+
68
+ it("should include custom CSS when provided", async () => {
69
+ const mockResponse: PrepareSsoReturnType = {
70
+ ssoUrl: "https://wallet.frak.id/sso?params=custom",
71
+ };
72
+
73
+ const mockClient = {
74
+ config: {
75
+ metadata: {
76
+ name: "Styled App",
77
+ },
78
+ customizations: {
79
+ css: "body { background: red; }",
80
+ },
81
+ },
82
+ request: vi.fn().mockResolvedValue(mockResponse),
83
+ } as unknown as FrakClient;
84
+
85
+ const params: PrepareSsoParamsType = {
86
+ directExit: true,
87
+ };
88
+
89
+ await prepareSso(mockClient, params);
90
+
91
+ expect(mockClient.request).toHaveBeenCalledWith({
92
+ method: "frak_prepareSso",
93
+ params: [params, "Styled App", "body { background: red; }"],
94
+ });
95
+ });
96
+
97
+ it("should handle params with redirectUrl", async () => {
98
+ const mockResponse: PrepareSsoReturnType = {
99
+ ssoUrl: "https://wallet.frak.id/sso?redirect=https://example.com",
100
+ };
101
+
102
+ const mockClient = {
103
+ config: {
104
+ metadata: {
105
+ name: "Test App",
106
+ },
107
+ },
108
+ request: vi.fn().mockResolvedValue(mockResponse),
109
+ } as unknown as FrakClient;
110
+
111
+ const params: PrepareSsoParamsType = {
112
+ redirectUrl: "https://example.com/callback",
113
+ directExit: false,
114
+ };
115
+
116
+ await prepareSso(mockClient, params);
117
+
118
+ expect(mockClient.request).toHaveBeenCalledWith({
119
+ method: "frak_prepareSso",
120
+ params: [params, "Test App", undefined],
121
+ });
122
+ });
123
+
124
+ it("should handle params with metadata", async () => {
125
+ const mockResponse: PrepareSsoReturnType = {
126
+ ssoUrl: "https://wallet.frak.id/sso?metadata=xyz",
127
+ };
128
+
129
+ const mockClient = {
130
+ config: {
131
+ metadata: {
132
+ name: "App with Metadata",
133
+ logoUrl: "https://example.com/logo.png",
134
+ },
135
+ },
136
+ request: vi.fn().mockResolvedValue(mockResponse),
137
+ } as unknown as FrakClient;
138
+
139
+ const params: PrepareSsoParamsType = {
140
+ metadata: {
141
+ logoUrl: "https://custom.com/logo.png",
142
+ homepageLink: "https://custom.com",
143
+ },
144
+ directExit: true,
145
+ };
146
+
147
+ await prepareSso(mockClient, params);
148
+
149
+ expect(mockClient.request).toHaveBeenCalledWith({
150
+ method: "frak_prepareSso",
151
+ params: [params, "App with Metadata", undefined],
152
+ });
153
+ });
154
+
155
+ it("should pass client metadata name to request", async () => {
156
+ const mockResponse: PrepareSsoReturnType = {
157
+ ssoUrl: "https://wallet.frak.id/sso?name=MyApp",
158
+ };
159
+
160
+ const mockClient = {
161
+ config: {
162
+ metadata: {
163
+ name: "MyApp",
164
+ logoUrl: "https://example.com/logo.png",
165
+ },
166
+ customizations: {
167
+ css: "body { color: blue; }",
168
+ },
169
+ },
170
+ request: vi.fn().mockResolvedValue(mockResponse),
171
+ } as unknown as FrakClient;
172
+
173
+ const params: PrepareSsoParamsType = {};
174
+
175
+ await prepareSso(mockClient, params);
176
+
177
+ expect(mockClient.request).toHaveBeenCalledWith({
178
+ method: "frak_prepareSso",
179
+ params: [params, "MyApp", "body { color: blue; }"],
180
+ });
181
+ });
182
+ });
183
+
184
+ describe("error handling", () => {
185
+ it("should propagate errors from client.request", async () => {
186
+ const error = new Error("SSO preparation failed");
187
+ const mockClient = {
188
+ config: {
189
+ metadata: {
190
+ name: "Test App",
191
+ },
192
+ },
193
+ request: vi.fn().mockRejectedValue(error),
194
+ } as unknown as FrakClient;
195
+
196
+ const params: PrepareSsoParamsType = {
197
+ directExit: true,
198
+ };
199
+
200
+ await expect(prepareSso(mockClient, params)).rejects.toThrow(
201
+ "SSO preparation failed"
202
+ );
203
+ });
204
+
205
+ it("should handle network errors", async () => {
206
+ const error = new Error("Network timeout");
207
+ const mockClient = {
208
+ config: {
209
+ metadata: {
210
+ name: "Test App",
211
+ },
212
+ },
213
+ request: vi.fn().mockRejectedValue(error),
214
+ } as unknown as FrakClient;
215
+
216
+ const params: PrepareSsoParamsType = {};
217
+
218
+ await expect(prepareSso(mockClient, params)).rejects.toThrow(
219
+ "Network timeout"
220
+ );
221
+ });
222
+ });
223
+ });
@@ -61,7 +61,7 @@ export type ProcessReferralOptions = {
61
61
  * @see {@link displayModal} for more details about the displayed modal
62
62
  * @see {@link sendInteraction} for more details on the interaction submission part
63
63
  * @see {@link ReferralInteractionEncoder} for more details about the referred interaction
64
- * @see {@link ModalStepTypes} for more details on each modal steps types
64
+ * @see {@link @frak-labs/core-sdk!ModalStepTypes} for more details on each modal steps types
65
65
  */
66
66
  export async function processReferral(
67
67
  client: FrakClient,
@@ -20,7 +20,7 @@ import {
20
20
  * @description This function will automatically handle the referral interaction process
21
21
  *
22
22
  * @see {@link processReferral} for more details on the automatic referral handling process
23
- * @see {@link ModalStepTypes} for more details on each modal steps types
23
+ * @see {@link @frak-labs/core-sdk!ModalStepTypes} for more details on each modal steps types
24
24
  */
25
25
  export async function referralInteraction(
26
26
  client: FrakClient,