latchkey 3.15.0 → 3.16.1

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 (44) hide show
  1. package/dist/src/browserStateImport.d.ts +50 -0
  2. package/dist/src/browserStateImport.d.ts.map +1 -0
  3. package/dist/src/browserStateImport.js +260 -0
  4. package/dist/src/browserStateImport.js.map +1 -0
  5. package/dist/src/cliCommands.d.ts.map +1 -1
  6. package/dist/src/cliCommands.js +37 -0
  7. package/dist/src/cliCommands.js.map +1 -1
  8. package/dist/src/index.d.ts +1 -1
  9. package/dist/src/index.d.ts.map +1 -1
  10. package/dist/src/index.js +1 -1
  11. package/dist/src/index.js.map +1 -1
  12. package/dist/src/pluginSdk.d.ts +2 -1
  13. package/dist/src/pluginSdk.d.ts.map +1 -1
  14. package/dist/src/pluginSdk.js +2 -1
  15. package/dist/src/pluginSdk.js.map +1 -1
  16. package/dist/src/services/core/base.d.ts +11 -1
  17. package/dist/src/services/core/base.d.ts.map +1 -1
  18. package/dist/src/services/core/base.js +15 -2
  19. package/dist/src/services/core/base.js.map +1 -1
  20. package/dist/src/services/index.d.ts +1 -1
  21. package/dist/src/services/index.d.ts.map +1 -1
  22. package/dist/src/services/index.js +1 -1
  23. package/dist/src/services/index.js.map +1 -1
  24. package/dist/src/services/linear.d.ts +9 -1
  25. package/dist/src/services/linear.d.ts.map +1 -1
  26. package/dist/src/services/linear.js +36 -0
  27. package/dist/src/services/linear.js.map +1 -1
  28. package/dist/src/services/zoom.d.ts +5 -4
  29. package/dist/src/services/zoom.d.ts.map +1 -1
  30. package/dist/src/services/zoom.js +7 -6
  31. package/dist/src/services/zoom.js.map +1 -1
  32. package/dist/src/version.d.ts +1 -1
  33. package/dist/src/version.js +1 -1
  34. package/dist/tests/browserStateImport.test.d.ts +2 -0
  35. package/dist/tests/browserStateImport.test.d.ts.map +1 -0
  36. package/dist/tests/browserStateImport.test.js +88 -0
  37. package/dist/tests/browserStateImport.test.js.map +1 -0
  38. package/dist/tests/cli.test.js +1 -0
  39. package/dist/tests/cli.test.js.map +1 -1
  40. package/dist/tests/followupFailureRecovery.test.d.ts +11 -0
  41. package/dist/tests/followupFailureRecovery.test.d.ts.map +1 -0
  42. package/dist/tests/followupFailureRecovery.test.js +101 -0
  43. package/dist/tests/followupFailureRecovery.test.js.map +1 -0
  44. package/package.json +2 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"followupFailureRecovery.test.d.ts","sourceRoot":"","sources":["../../tests/followupFailureRecovery.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Tests for what a browser followup session does once its automation fails:
3
+ * offer the manual credential form, unless the failure is one the user could
4
+ * not work around by hand.
5
+ *
6
+ * Browser-free: the context and page are stand-ins exposing only what the
7
+ * failure handling touches, and the spinner is disabled so the only page ever
8
+ * opened is the form's.
9
+ */
10
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
11
+ import { AuthorizationBearer } from '../src/apiCredentials/base.js';
12
+ import { BrowserFollowupServiceSession, FollowupWork, LoginFailedError, UnrecoverableLoginFailedError, } from '../src/services/core/base.js';
13
+ import { HUGGINGFACE } from '../src/services/huggingface.js';
14
+ class FailingFollowupSession extends BrowserFollowupServiceSession {
15
+ failure;
16
+ followupWork = FollowupWork.CreateApiToken;
17
+ manualCredentialForm = {
18
+ instructions: 'Create a token by hand.',
19
+ fields: [{ name: 'token', label: 'Token' }],
20
+ buildCredentials: (values) => new AuthorizationBearer(values.get('token')),
21
+ };
22
+ constructor(failure) {
23
+ super(HUGGINGFACE, 'latchkey');
24
+ this.failure = failure;
25
+ }
26
+ onResponse(_response) {
27
+ // The login phase is not exercised here.
28
+ }
29
+ isLoginComplete() {
30
+ return true;
31
+ }
32
+ performBrowserFollowup() {
33
+ return Promise.reject(this.failure);
34
+ }
35
+ finalize(context) {
36
+ return this.finalizeCredentials({}, context);
37
+ }
38
+ }
39
+ function createFakeBrowser() {
40
+ let openedPageCount = 0;
41
+ const closeListeners = [];
42
+ const page = {
43
+ isClosed: () => false,
44
+ bringToFront: () => Promise.resolve(),
45
+ exposeFunction: () => Promise.resolve(),
46
+ evaluate: () => Promise.resolve(undefined),
47
+ on: (event, listener) => {
48
+ if (event === 'close') {
49
+ closeListeners.push(listener);
50
+ }
51
+ },
52
+ };
53
+ const context = {
54
+ newPage: () => {
55
+ openedPageCount += 1;
56
+ return Promise.resolve(page);
57
+ },
58
+ on: () => undefined,
59
+ browser: () => ({ on: () => undefined }),
60
+ };
61
+ return {
62
+ context,
63
+ getOpenedPageCount: () => openedPageCount,
64
+ closeBrowser: () => {
65
+ for (const listener of closeListeners) {
66
+ listener();
67
+ }
68
+ },
69
+ };
70
+ }
71
+ describe('browser followup failure recovery', () => {
72
+ beforeEach(() => {
73
+ vi.stubEnv('LATCHKEY_DISABLE_SPINNER', '1');
74
+ vi.spyOn(console, 'error').mockImplementation(() => undefined);
75
+ });
76
+ afterEach(() => {
77
+ vi.unstubAllEnvs();
78
+ vi.restoreAllMocks();
79
+ });
80
+ it('offers the manual credential form after an ordinary failure', async () => {
81
+ const browser = createFakeBrowser();
82
+ const failure = new LoginFailedError('The token page changed.');
83
+ const session = new FailingFollowupSession(failure);
84
+ const finalization = session.finalize(browser.context);
85
+ await vi.waitFor(() => {
86
+ expect(browser.getOpenedPageCount()).toBe(1);
87
+ });
88
+ browser.closeBrowser();
89
+ await expect(finalization).rejects.toBe(failure);
90
+ expect(console.error).toHaveBeenCalledOnce();
91
+ });
92
+ it('reports an unrecoverable failure straight away, without the form', async () => {
93
+ const browser = createFakeBrowser();
94
+ const failure = new UnrecoverableLoginFailedError('Your user may not create apps.');
95
+ const session = new FailingFollowupSession(failure);
96
+ await expect(session.finalize(browser.context)).rejects.toBe(failure);
97
+ expect(browser.getOpenedPageCount()).toBe(0);
98
+ expect(console.error).not.toHaveBeenCalled();
99
+ });
100
+ });
101
+ //# sourceMappingURL=followupFailureRecovery.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"followupFailureRecovery.test.js","sourceRoot":"","sources":["../../tests/followupFailureRecovery.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "latchkey",
3
- "version": "3.15.0",
3
+ "version": "3.16.1",
4
4
  "description": "A CLI tool that injects API credentials into curl requests to third-party services",
5
5
  "author": "Imbue <hynek@imbue.com>",
6
6
  "repository": {
@@ -76,6 +76,7 @@
76
76
  "@napi-rs/keyring": "^1.2.0",
77
77
  "commander": "^12.0.0",
78
78
  "playwright": "~1.63.0",
79
+ "playwright-core": "1.63.0",
79
80
  "semver": "^7.8.5",
80
81
  "zod": "^3.22.0"
81
82
  },