@clerk/electron 0.0.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 (41) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/dist/cjs/index.js +172 -0
  4. package/dist/cjs/index.js.map +1 -0
  5. package/dist/cjs/preload/index.js +39 -0
  6. package/dist/cjs/preload/index.js.map +1 -0
  7. package/dist/cjs/react/index.js +76 -0
  8. package/dist/cjs/react/index.js.map +1 -0
  9. package/dist/cjs/storage/index.js +133 -0
  10. package/dist/cjs/storage/index.js.map +1 -0
  11. package/dist/esm/chunk-WJNPPS7B.js +14 -0
  12. package/dist/esm/chunk-WJNPPS7B.js.map +1 -0
  13. package/dist/esm/index.js +157 -0
  14. package/dist/esm/index.js.map +1 -0
  15. package/dist/esm/preload/index.js +24 -0
  16. package/dist/esm/preload/index.js.map +1 -0
  17. package/dist/esm/react/index.js +68 -0
  18. package/dist/esm/react/index.js.map +1 -0
  19. package/dist/esm/storage/index.js +127 -0
  20. package/dist/esm/storage/index.js.map +1 -0
  21. package/dist/types/index.d.ts +3 -0
  22. package/dist/types/index.d.ts.map +1 -0
  23. package/dist/types/main/create-clerk-bridge.d.ts +10 -0
  24. package/dist/types/main/create-clerk-bridge.d.ts.map +1 -0
  25. package/dist/types/main/ipc-handlers.d.ts +3 -0
  26. package/dist/types/main/ipc-handlers.d.ts.map +1 -0
  27. package/dist/types/main/oauth-transport.d.ts +7 -0
  28. package/dist/types/main/oauth-transport.d.ts.map +1 -0
  29. package/dist/types/preload/index.d.ts +8 -0
  30. package/dist/types/preload/index.d.ts.map +1 -0
  31. package/dist/types/react/create-clerk-instance.d.ts +5 -0
  32. package/dist/types/react/create-clerk-instance.d.ts.map +1 -0
  33. package/dist/types/react/index.d.ts +12 -0
  34. package/dist/types/react/index.d.ts.map +1 -0
  35. package/dist/types/shared/ipc.d.ts +10 -0
  36. package/dist/types/shared/ipc.d.ts.map +1 -0
  37. package/dist/types/shared/types.d.ts +45 -0
  38. package/dist/types/shared/types.d.ts.map +1 -0
  39. package/dist/types/storage/index.d.ts +47 -0
  40. package/dist/types/storage/index.d.ts.map +1 -0
  41. package/package.json +121 -0
@@ -0,0 +1,157 @@
1
+ import { TOKEN_CACHE_CHANNELS, OAUTH_TRANSPORT_CHANNELS } from './chunk-WJNPPS7B.js';
2
+ import { protocol, ipcMain, app, shell } from 'electron';
3
+
4
+ function setupTokenCacheIpcHandlers(storage) {
5
+ ipcMain.handle(TOKEN_CACHE_CHANNELS.getToken, (_event, key) => {
6
+ return storage.getItem(key);
7
+ });
8
+ ipcMain.handle(TOKEN_CACHE_CHANNELS.saveToken, (_event, key, value) => {
9
+ return storage.setItem(key, value);
10
+ });
11
+ ipcMain.handle(TOKEN_CACHE_CHANNELS.clearToken, (_event, key) => {
12
+ return storage.removeItem(key);
13
+ });
14
+ return () => {
15
+ ipcMain.removeHandler(TOKEN_CACHE_CHANNELS.getToken);
16
+ ipcMain.removeHandler(TOKEN_CACHE_CHANNELS.saveToken);
17
+ ipcMain.removeHandler(TOKEN_CACHE_CHANNELS.clearToken);
18
+ };
19
+ }
20
+ var CALLBACK_TIMEOUT_MS = 3 * 60 * 1e3;
21
+ function buildRedirectUrl(options) {
22
+ return `${options.renderer.scheme}://${options.renderer.host}/`;
23
+ }
24
+ function isMatchingCallbackUrl(url, redirectUrl) {
25
+ try {
26
+ const callback = new URL(url);
27
+ const expected = new URL(redirectUrl);
28
+ return callback.protocol === expected.protocol && callback.host === expected.host && callback.pathname === expected.pathname;
29
+ } catch {
30
+ return false;
31
+ }
32
+ }
33
+ function assertExternalOAuthUrl(url) {
34
+ const parsedUrl = new URL(url);
35
+ if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") {
36
+ throw new TypeError(`Clerk: refusing to open unsupported OAuth URL protocol: ${parsedUrl.protocol}`);
37
+ }
38
+ }
39
+ function setupOAuthTransportIpcHandlers(options) {
40
+ const redirectUrl = buildRedirectUrl(options);
41
+ let pendingOAuthFlow = null;
42
+ const disposePendingOAuthFlow = (reason) => {
43
+ if (!pendingOAuthFlow) {
44
+ return;
45
+ }
46
+ const pending = pendingOAuthFlow;
47
+ clearTimeout(pendingOAuthFlow.timeout);
48
+ pendingOAuthFlow = null;
49
+ if (reason) {
50
+ pending.reject(reason);
51
+ }
52
+ };
53
+ const handleCallbackUrl = (url) => {
54
+ if (!pendingOAuthFlow || !isMatchingCallbackUrl(url, redirectUrl)) {
55
+ return;
56
+ }
57
+ const pending = pendingOAuthFlow;
58
+ disposePendingOAuthFlow();
59
+ pending.resolve({ callbackUrl: url });
60
+ };
61
+ const openUrlListener = (event, url) => {
62
+ if (!isMatchingCallbackUrl(url, redirectUrl)) {
63
+ return;
64
+ }
65
+ event.preventDefault();
66
+ handleCallbackUrl(url);
67
+ };
68
+ const secondInstanceListener = (_event, argv) => {
69
+ const callbackUrl = argv.find((url) => isMatchingCallbackUrl(url, redirectUrl));
70
+ if (callbackUrl) {
71
+ handleCallbackUrl(callbackUrl);
72
+ }
73
+ };
74
+ app.setAsDefaultProtocolClient(options.renderer.scheme);
75
+ app.on("open-url", openUrlListener);
76
+ app.on("second-instance", secondInstanceListener);
77
+ ipcMain.handle(OAUTH_TRANSPORT_CHANNELS.getRedirectUrl, () => {
78
+ return redirectUrl;
79
+ });
80
+ ipcMain.handle(OAUTH_TRANSPORT_CHANNELS.open, async (_event, url) => {
81
+ if (pendingOAuthFlow) {
82
+ throw new Error("Clerk: an OAuth flow is already pending.");
83
+ }
84
+ assertExternalOAuthUrl(url);
85
+ const callbackPromise = new Promise((resolve, reject) => {
86
+ const timeout = setTimeout(() => {
87
+ disposePendingOAuthFlow();
88
+ reject(new Error("Clerk: OAuth callback timed out."));
89
+ }, CALLBACK_TIMEOUT_MS);
90
+ pendingOAuthFlow = { resolve, reject, timeout };
91
+ });
92
+ try {
93
+ await shell.openExternal(url);
94
+ } catch (err) {
95
+ disposePendingOAuthFlow(err instanceof Error ? err : new Error(String(err)));
96
+ }
97
+ return callbackPromise;
98
+ });
99
+ return () => {
100
+ disposePendingOAuthFlow(new Error("Clerk: OAuth flow was cancelled."));
101
+ app.removeListener("open-url", openUrlListener);
102
+ app.removeListener("second-instance", secondInstanceListener);
103
+ ipcMain.removeHandler(OAUTH_TRANSPORT_CHANNELS.getRedirectUrl);
104
+ ipcMain.removeHandler(OAUTH_TRANSPORT_CHANNELS.open);
105
+ };
106
+ }
107
+
108
+ // src/main/create-clerk-bridge.ts
109
+ function assertValidRendererOriginConfig(renderer) {
110
+ if (renderer.scheme.includes(":") || renderer.scheme.includes("/")) {
111
+ throw new Error(
112
+ 'Clerk: renderer.scheme must be a scheme name like "my-app", not a URL or protocol like "my-app://".'
113
+ );
114
+ }
115
+ if (renderer.host.includes(":") || renderer.host.includes("/")) {
116
+ throw new Error(
117
+ 'Clerk: renderer.host must be a host name like "renderer", not a URL or origin like "my-app://renderer".'
118
+ );
119
+ }
120
+ }
121
+ function createClerkBridge(options) {
122
+ if (!options.storage) {
123
+ throw new Error(
124
+ "Clerk: createClerkBridge requires a storage adapter. Pass createClerkBridge({ storage: storage() }) from @clerk/electron/storage, or provide a custom storage adapter."
125
+ );
126
+ }
127
+ const cleanupTokenPersistence = setupTokenCacheIpcHandlers(options.storage);
128
+ let cleanupOAuthTransport;
129
+ if (options.renderer) {
130
+ assertValidRendererOriginConfig(options.renderer);
131
+ protocol.registerSchemesAsPrivileged([
132
+ {
133
+ scheme: options.renderer.scheme,
134
+ privileges: {
135
+ standard: true,
136
+ secure: true,
137
+ supportFetchAPI: true,
138
+ corsEnabled: true,
139
+ stream: true
140
+ }
141
+ }
142
+ ]);
143
+ cleanupOAuthTransport = setupOAuthTransportIpcHandlers({
144
+ renderer: options.renderer
145
+ });
146
+ }
147
+ return {
148
+ cleanup() {
149
+ cleanupTokenPersistence();
150
+ cleanupOAuthTransport == null ? void 0 : cleanupOAuthTransport();
151
+ }
152
+ };
153
+ }
154
+
155
+ export { createClerkBridge };
156
+ //# sourceMappingURL=index.js.map
157
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/main/ipc-handlers.ts","../../src/main/oauth-transport.ts","../../src/main/create-clerk-bridge.ts"],"names":["ipcMain"],"mappings":"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","file":"index.js","sourcesContent":["import { ipcMain } from 'electron';\n\nimport { TOKEN_CACHE_CHANNELS } from '../shared/ipc';\nimport type { TokenStorage } from '../shared/types';\n\nexport function setupTokenCacheIpcHandlers(storage: TokenStorage): () => void {\n ipcMain.handle(TOKEN_CACHE_CHANNELS.getToken, (_event, key: string) => {\n return storage.getItem(key);\n });\n\n ipcMain.handle(TOKEN_CACHE_CHANNELS.saveToken, (_event, key: string, value: string) => {\n return storage.setItem(key, value);\n });\n\n ipcMain.handle(TOKEN_CACHE_CHANNELS.clearToken, (_event, key: string) => {\n return storage.removeItem(key);\n });\n\n return () => {\n ipcMain.removeHandler(TOKEN_CACHE_CHANNELS.getToken);\n ipcMain.removeHandler(TOKEN_CACHE_CHANNELS.saveToken);\n ipcMain.removeHandler(TOKEN_CACHE_CHANNELS.clearToken);\n };\n}\n","import { app, ipcMain, shell } from 'electron';\n\nimport { OAUTH_TRANSPORT_CHANNELS } from '../shared/ipc';\nimport type { RendererSchemeOptions } from '../shared/types';\n\nconst CALLBACK_TIMEOUT_MS = 3 * 60 * 1000;\n\ntype PendingOAuthFlow = {\n resolve: (value: { callbackUrl: string }) => void;\n reject: (reason: Error) => void;\n timeout: NodeJS.Timeout;\n};\n\ntype OAuthTransportOptions = {\n renderer: RendererSchemeOptions;\n};\n\nfunction buildRedirectUrl(options: OAuthTransportOptions): string {\n return `${options.renderer.scheme}://${options.renderer.host}/`;\n}\n\nfunction isMatchingCallbackUrl(url: string, redirectUrl: string): boolean {\n try {\n const callback = new URL(url);\n const expected = new URL(redirectUrl);\n\n return (\n callback.protocol === expected.protocol &&\n callback.host === expected.host &&\n callback.pathname === expected.pathname\n );\n } catch {\n return false;\n }\n}\n\nfunction assertExternalOAuthUrl(url: string): void {\n const parsedUrl = new URL(url);\n\n if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {\n throw new TypeError(`Clerk: refusing to open unsupported OAuth URL protocol: ${parsedUrl.protocol}`);\n }\n}\n\nexport function setupOAuthTransportIpcHandlers(options: OAuthTransportOptions): () => void {\n const redirectUrl = buildRedirectUrl(options);\n let pendingOAuthFlow: PendingOAuthFlow | null = null;\n\n const disposePendingOAuthFlow = (reason?: Error): void => {\n if (!pendingOAuthFlow) {\n return;\n }\n\n const pending = pendingOAuthFlow;\n clearTimeout(pendingOAuthFlow.timeout);\n pendingOAuthFlow = null;\n\n if (reason) {\n pending.reject(reason);\n }\n };\n\n const handleCallbackUrl = (url: string): void => {\n if (!pendingOAuthFlow || !isMatchingCallbackUrl(url, redirectUrl)) {\n return;\n }\n\n const pending = pendingOAuthFlow;\n disposePendingOAuthFlow();\n pending.resolve({ callbackUrl: url });\n };\n\n const openUrlListener = (event: Electron.Event, url: string): void => {\n if (!isMatchingCallbackUrl(url, redirectUrl)) {\n return;\n }\n\n event.preventDefault();\n handleCallbackUrl(url);\n };\n\n const secondInstanceListener = (_event: Electron.Event, argv: string[]): void => {\n const callbackUrl = argv.find(url => isMatchingCallbackUrl(url, redirectUrl));\n\n if (callbackUrl) {\n handleCallbackUrl(callbackUrl);\n }\n };\n\n app.setAsDefaultProtocolClient(options.renderer.scheme);\n app.on('open-url', openUrlListener);\n app.on('second-instance', secondInstanceListener);\n\n ipcMain.handle(OAUTH_TRANSPORT_CHANNELS.getRedirectUrl, () => {\n return redirectUrl;\n });\n\n ipcMain.handle(OAUTH_TRANSPORT_CHANNELS.open, async (_event, url: string) => {\n if (pendingOAuthFlow) {\n throw new Error('Clerk: an OAuth flow is already pending.');\n }\n\n assertExternalOAuthUrl(url);\n\n const callbackPromise = new Promise<{ callbackUrl: string }>((resolve, reject) => {\n const timeout = setTimeout(() => {\n disposePendingOAuthFlow();\n reject(new Error('Clerk: OAuth callback timed out.'));\n }, CALLBACK_TIMEOUT_MS);\n\n pendingOAuthFlow = { resolve, reject, timeout };\n });\n\n try {\n await shell.openExternal(url);\n } catch (err) {\n disposePendingOAuthFlow(err instanceof Error ? err : new Error(String(err)));\n }\n\n return callbackPromise;\n });\n\n return () => {\n disposePendingOAuthFlow(new Error('Clerk: OAuth flow was cancelled.'));\n app.removeListener('open-url', openUrlListener);\n app.removeListener('second-instance', secondInstanceListener);\n ipcMain.removeHandler(OAUTH_TRANSPORT_CHANNELS.getRedirectUrl);\n ipcMain.removeHandler(OAUTH_TRANSPORT_CHANNELS.open);\n };\n}\n","import { protocol } from 'electron';\n\nimport type { ClerkBridge, CreateClerkBridgeOptions } from '../shared/types';\nimport { setupTokenCacheIpcHandlers } from './ipc-handlers';\nimport { setupOAuthTransportIpcHandlers } from './oauth-transport';\n\nfunction assertValidRendererOriginConfig(renderer: NonNullable<CreateClerkBridgeOptions['renderer']>): void {\n if (renderer.scheme.includes(':') || renderer.scheme.includes('/')) {\n throw new Error(\n 'Clerk: renderer.scheme must be a scheme name like \"my-app\", not a URL or protocol like \"my-app://\".',\n );\n }\n\n if (renderer.host.includes(':') || renderer.host.includes('/')) {\n throw new Error(\n 'Clerk: renderer.host must be a host name like \"renderer\", not a URL or origin like \"my-app://renderer\".',\n );\n }\n}\n\n/**\n * Creates the Clerk bridge for Electron's main process.\n *\n * The bridge owns Clerk's main-process IPC handlers, token persistence, and OAuth deep-link\n * transport. Call this before creating renderer windows, and call the returned `cleanup` method\n * when tearing down the app or test environment.\n */\nexport function createClerkBridge(options: CreateClerkBridgeOptions): ClerkBridge {\n if (!options.storage) {\n throw new Error(\n 'Clerk: createClerkBridge requires a storage adapter. Pass createClerkBridge({ storage: storage() }) from @clerk/electron/storage, or provide a custom storage adapter.',\n );\n }\n\n const cleanupTokenPersistence = setupTokenCacheIpcHandlers(options.storage);\n let cleanupOAuthTransport: (() => void) | undefined;\n\n if (options.renderer) {\n assertValidRendererOriginConfig(options.renderer);\n\n protocol.registerSchemesAsPrivileged([\n {\n scheme: options.renderer.scheme,\n privileges: {\n standard: true,\n secure: true,\n supportFetchAPI: true,\n corsEnabled: true,\n stream: true,\n },\n },\n ]);\n\n cleanupOAuthTransport = setupOAuthTransportIpcHandlers({\n renderer: options.renderer,\n });\n }\n\n return {\n cleanup() {\n cleanupTokenPersistence();\n cleanupOAuthTransport?.();\n },\n };\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import { TOKEN_CACHE_CHANNELS, OAUTH_TRANSPORT_CHANNELS } from '../chunk-WJNPPS7B.js';
2
+ import { contextBridge, ipcRenderer } from 'electron';
3
+
4
+ function exposeClerkBridge() {
5
+ const tokenCache = {
6
+ getToken: (key) => ipcRenderer.invoke(TOKEN_CACHE_CHANNELS.getToken, key),
7
+ saveToken: (key, value) => ipcRenderer.invoke(TOKEN_CACHE_CHANNELS.saveToken, key, value),
8
+ clearToken: (key) => ipcRenderer.invoke(TOKEN_CACHE_CHANNELS.clearToken, key)
9
+ };
10
+ const oauthTransport = {
11
+ getRedirectUrl: () => ipcRenderer.invoke(OAUTH_TRANSPORT_CHANNELS.getRedirectUrl),
12
+ open: (url) => ipcRenderer.invoke(OAUTH_TRANSPORT_CHANNELS.open, url)
13
+ };
14
+ const bridge = { tokenCache, oauthTransport };
15
+ if (process.contextIsolated) {
16
+ contextBridge.exposeInMainWorld("__clerk_internal_electron", bridge);
17
+ } else {
18
+ window.__clerk_internal_electron = bridge;
19
+ }
20
+ }
21
+
22
+ export { exposeClerkBridge };
23
+ //# sourceMappingURL=index.js.map
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/preload/index.ts"],"names":[],"mappings":";;;AAWO,SAAS,iBAAA,GAA0B;AACxC,EAAA,MAAM,UAAA,GAAyB;AAAA,IAC7B,UAAU,CAAA,GAAA,KAAO,WAAA,CAAY,MAAA,CAAO,oBAAA,CAAqB,UAAU,GAAG,CAAA;AAAA,IACtE,SAAA,EAAW,CAAC,GAAA,EAAK,KAAA,KAAU,YAAY,MAAA,CAAO,oBAAA,CAAqB,SAAA,EAAW,GAAA,EAAK,KAAK,CAAA;AAAA,IACxF,YAAY,CAAA,GAAA,KAAO,WAAA,CAAY,MAAA,CAAO,oBAAA,CAAqB,YAAY,GAAG;AAAA,GAC5E;AACA,EAAA,MAAM,cAAA,GAAiC;AAAA,IACrC,cAAA,EAAgB,MAAM,WAAA,CAAY,MAAA,CAAO,yBAAyB,cAAc,CAAA;AAAA,IAChF,MAAM,CAAA,GAAA,KAAO,WAAA,CAAY,MAAA,CAAO,wBAAA,CAAyB,MAAM,GAAG;AAAA,GACpE;AACA,EAAA,MAAM,MAAA,GAAS,EAAE,UAAA,EAAY,cAAA,EAAe;AAE5C,EAAA,IAAI,QAAQ,eAAA,EAAiB;AAC3B,IAAA,aAAA,CAAc,iBAAA,CAAkB,6BAA6B,MAAM,CAAA;AAAA,EACrE,CAAA,MAAO;AACL,IAAA,MAAA,CAAO,yBAAA,GAA4B,MAAA;AAAA,EACrC;AACF","file":"index.js","sourcesContent":["import { contextBridge, ipcRenderer } from 'electron';\n\nimport { OAUTH_TRANSPORT_CHANNELS, TOKEN_CACHE_CHANNELS } from '../shared/ipc';\nimport type { OAuthTransport, TokenCache } from '../shared/types';\n\n/**\n * Exposes Clerk's Electron bridge from the preload script to the renderer.\n *\n * Call this from an Electron preload script. It publishes a narrow internal bridge used by\n * `@clerk/electron/react` for token storage and OAuth transport.\n */\nexport function exposeClerkBridge(): void {\n const tokenCache: TokenCache = {\n getToken: key => ipcRenderer.invoke(TOKEN_CACHE_CHANNELS.getToken, key),\n saveToken: (key, value) => ipcRenderer.invoke(TOKEN_CACHE_CHANNELS.saveToken, key, value),\n clearToken: key => ipcRenderer.invoke(TOKEN_CACHE_CHANNELS.clearToken, key),\n };\n const oauthTransport: OAuthTransport = {\n getRedirectUrl: () => ipcRenderer.invoke(OAUTH_TRANSPORT_CHANNELS.getRedirectUrl),\n open: url => ipcRenderer.invoke(OAUTH_TRANSPORT_CHANNELS.open, url),\n };\n const bridge = { tokenCache, oauthTransport };\n\n if (process.contextIsolated) {\n contextBridge.exposeInMainWorld('__clerk_internal_electron', bridge);\n } else {\n window.__clerk_internal_electron = bridge;\n }\n}\n"]}
@@ -0,0 +1,68 @@
1
+ import { InternalClerkProvider } from '@clerk/react/internal';
2
+ import { ui } from '@clerk/ui';
3
+ import { Clerk } from '@clerk/clerk-js';
4
+ export * from '@clerk/react';
5
+ import { jsx } from 'react/jsx-runtime';
6
+
7
+ // src/react/index.tsx
8
+ var CLERK_CLIENT_JWT_KEY = "__clerk_client_jwt";
9
+ var cached = null;
10
+ function createClerkInstance(publishableKey) {
11
+ if ((cached == null ? void 0 : cached.publishableKey) === publishableKey) {
12
+ return cached.instance;
13
+ }
14
+ const clerk = new Clerk(publishableKey);
15
+ clerk.__internal_onBeforeRequest(async (request) => {
16
+ var _a, _b;
17
+ request.credentials = "omit";
18
+ (_a = request.url) == null ? void 0 : _a.searchParams.append("_is_native", "1");
19
+ const token = await ((_b = window.__clerk_internal_electron) == null ? void 0 : _b.tokenCache.getToken(CLERK_CLIENT_JWT_KEY));
20
+ if (token) {
21
+ const headers = new Headers(request.headers);
22
+ headers.set("Authorization", `Bearer ${token}`);
23
+ request.headers = headers;
24
+ }
25
+ });
26
+ clerk.__internal_onAfterResponse(async (_request, response) => {
27
+ var _a;
28
+ const authorization = response.headers.get("Authorization");
29
+ if (!authorization) {
30
+ return;
31
+ }
32
+ const token = authorization.startsWith("Bearer ") ? authorization.slice("Bearer ".length) : authorization;
33
+ await ((_a = window.__clerk_internal_electron) == null ? void 0 : _a.tokenCache.saveToken(CLERK_CLIENT_JWT_KEY, token));
34
+ });
35
+ cached = { instance: clerk, publishableKey };
36
+ return clerk;
37
+ }
38
+ function createOAuthTransport() {
39
+ var _a;
40
+ const bridge = (_a = window.__clerk_internal_electron) == null ? void 0 : _a.oauthTransport;
41
+ if (!bridge) {
42
+ return void 0;
43
+ }
44
+ return {
45
+ getRedirectUrl: () => bridge.getRedirectUrl(),
46
+ open: (url) => bridge.open(url.href)
47
+ };
48
+ }
49
+ function ClerkProvider({ children, publishableKey, ...props }) {
50
+ const clerk = createClerkInstance(publishableKey);
51
+ const oauthTransport = createOAuthTransport();
52
+ return /* @__PURE__ */ jsx(
53
+ InternalClerkProvider,
54
+ {
55
+ ...props,
56
+ Clerk: clerk,
57
+ __internal_oauthTransport: oauthTransport,
58
+ publishableKey,
59
+ standardBrowser: false,
60
+ ui,
61
+ children
62
+ }
63
+ );
64
+ }
65
+
66
+ export { ClerkProvider };
67
+ //# sourceMappingURL=index.js.map
68
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/react/create-clerk-instance.ts","../../../src/react/index.tsx"],"names":["ReactClerkProvider"],"mappings":"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","file":"index.js","sourcesContent":["import { Clerk } from '@clerk/clerk-js';\n\nconst CLERK_CLIENT_JWT_KEY = '__clerk_client_jwt';\n\ntype ClerkInstance = InstanceType<typeof Clerk>;\n\nlet cached: { instance: ClerkInstance; publishableKey: string } | null = null;\n\nexport function createClerkInstance(publishableKey: string): ClerkInstance {\n if (cached?.publishableKey === publishableKey) {\n return cached.instance;\n }\n\n const clerk = new Clerk(publishableKey);\n\n clerk.__internal_onBeforeRequest(async request => {\n request.credentials = 'omit';\n request.url?.searchParams.append('_is_native', '1');\n\n const token = await window.__clerk_internal_electron?.tokenCache.getToken(CLERK_CLIENT_JWT_KEY);\n if (token) {\n const headers = new Headers(request.headers);\n headers.set('Authorization', `Bearer ${token}`);\n request.headers = headers;\n }\n });\n\n clerk.__internal_onAfterResponse(async (_request, response) => {\n const authorization = (response as Response).headers.get('Authorization');\n if (!authorization) {\n return;\n }\n\n const token = authorization.startsWith('Bearer ') ? authorization.slice('Bearer '.length) : authorization;\n await window.__clerk_internal_electron?.tokenCache.saveToken(CLERK_CLIENT_JWT_KEY, token);\n });\n\n cached = { instance: clerk, publishableKey };\n return clerk;\n}\n","import type { ClerkProviderProps as ReactClerkProviderProps } from '@clerk/react';\nimport { InternalClerkProvider as ReactClerkProvider } from '@clerk/react/internal';\nimport { ui } from '@clerk/ui';\nimport type { ReactNode } from 'react';\n\nimport { createClerkInstance } from './create-clerk-instance';\n\ntype ClerkOAuthTransport = NonNullable<ReactClerkProviderProps['__internal_oauthTransport']>;\n\nexport type ClerkProviderProps = Omit<\n ReactClerkProviderProps,\n 'Clerk' | 'children' | 'publishableKey' | 'standardBrowser' | 'ui' | '__internal_oauthTransport'\n> & {\n children: ReactNode;\n /**\n * Your Clerk publishable key, available in the Clerk Dashboard.\n */\n publishableKey: string;\n};\n\nfunction createOAuthTransport(): ClerkOAuthTransport | undefined {\n const bridge = window.__clerk_internal_electron?.oauthTransport;\n\n if (!bridge) {\n return undefined;\n }\n\n return {\n getRedirectUrl: () => bridge.getRedirectUrl(),\n open: url => bridge.open(url.href),\n };\n}\n\nexport function ClerkProvider({ children, publishableKey, ...props }: ClerkProviderProps): JSX.Element {\n const clerk = createClerkInstance(publishableKey);\n const oauthTransport = createOAuthTransport();\n\n return (\n <ReactClerkProvider\n {...props}\n Clerk={clerk}\n __internal_oauthTransport={oauthTransport}\n publishableKey={publishableKey}\n standardBrowser={false}\n ui={ui}\n >\n {children}\n </ReactClerkProvider>\n );\n}\n\nexport * from '@clerk/react';\n"]}
@@ -0,0 +1,127 @@
1
+ import { safeStorage } from 'electron';
2
+ import Store from 'electron-store';
3
+
4
+ // src/storage/index.ts
5
+ var ENCRYPTED_PREFIX = "enc:";
6
+ var RAW_PREFIX = "raw:";
7
+ var syncCipher = {
8
+ encrypt: (value) => Promise.resolve(safeStorage.encryptString(value).toString("base64")),
9
+ decrypt: (payload) => Promise.resolve({ value: safeStorage.decryptString(Buffer.from(payload, "base64")), shouldReEncrypt: false })
10
+ };
11
+ function hasAsyncSafeStorage(storage2) {
12
+ const candidate = storage2;
13
+ return typeof candidate.encryptStringAsync === "function" && typeof candidate.decryptStringAsync === "function" && typeof candidate.isAsyncEncryptionAvailable === "function";
14
+ }
15
+ function createAsyncCipher(storage2) {
16
+ return {
17
+ encrypt: async (value) => (await storage2.encryptStringAsync(value)).toString("base64"),
18
+ decrypt: async (payload) => {
19
+ const { result, shouldReEncrypt } = await storage2.decryptStringAsync(Buffer.from(payload, "base64"));
20
+ return { value: result, shouldReEncrypt };
21
+ }
22
+ };
23
+ }
24
+ async function resolveCipher() {
25
+ if (hasAsyncSafeStorage(safeStorage)) {
26
+ try {
27
+ if (await safeStorage.isAsyncEncryptionAvailable()) {
28
+ return createAsyncCipher(safeStorage);
29
+ }
30
+ } catch {
31
+ }
32
+ }
33
+ if (typeof safeStorage.isEncryptionAvailable === "function" && safeStorage.isEncryptionAvailable()) {
34
+ return syncCipher;
35
+ }
36
+ return null;
37
+ }
38
+ function storage(options = {}) {
39
+ var _a;
40
+ const store = new Store({
41
+ name: (_a = options.name) != null ? _a : "clerk-tokens",
42
+ ...options.path ? { cwd: options.path } : {}
43
+ });
44
+ let cachedCipher = null;
45
+ let resolving = null;
46
+ const getCipher = () => {
47
+ if (cachedCipher) {
48
+ return Promise.resolve(cachedCipher);
49
+ }
50
+ resolving != null ? resolving : resolving = resolveCipher().then((resolved) => {
51
+ resolving = null;
52
+ if (resolved) {
53
+ cachedCipher = resolved;
54
+ }
55
+ return resolved;
56
+ });
57
+ return resolving;
58
+ };
59
+ let warned = false;
60
+ const warnOnce = (message) => {
61
+ if (warned) {
62
+ return;
63
+ }
64
+ warned = true;
65
+ console.warn(message);
66
+ };
67
+ return {
68
+ async getItem(key) {
69
+ const stored = store.get(key);
70
+ if (!stored) {
71
+ return null;
72
+ }
73
+ if (stored.startsWith(RAW_PREFIX)) {
74
+ return stored.slice(RAW_PREFIX.length);
75
+ }
76
+ if (stored.startsWith(ENCRYPTED_PREFIX)) {
77
+ const cipher = await getCipher();
78
+ if (!cipher) {
79
+ return null;
80
+ }
81
+ const payload = stored.slice(ENCRYPTED_PREFIX.length);
82
+ try {
83
+ const { value, shouldReEncrypt } = await cipher.decrypt(payload);
84
+ if (shouldReEncrypt) {
85
+ try {
86
+ store.set(key, ENCRYPTED_PREFIX + await cipher.encrypt(value));
87
+ } catch {
88
+ }
89
+ }
90
+ return value;
91
+ } catch {
92
+ return null;
93
+ }
94
+ }
95
+ store.delete(key);
96
+ return null;
97
+ },
98
+ async setItem(key, value) {
99
+ const cipher = await getCipher();
100
+ if (!cipher) {
101
+ if (options.unencryptedFallback) {
102
+ warnOnce(
103
+ "Clerk: OS encryption is unavailable; falling back to unencrypted storage. Session tokens are being stored unencrypted on local disk."
104
+ );
105
+ store.set(key, RAW_PREFIX + value);
106
+ } else {
107
+ warnOnce(
108
+ "Clerk: OS encryption is unavailable and unencryptedFallback is not enabled, so tokens are not being persisted. The user will be signed out on the next launch. Pass `storage({ unencryptedFallback: true })` to persist unencrypted (less secure)."
109
+ );
110
+ }
111
+ return;
112
+ }
113
+ try {
114
+ store.set(key, ENCRYPTED_PREFIX + await cipher.encrypt(value));
115
+ } catch {
116
+ warnOnce("Clerk: failed to encrypt the session token; it was not persisted.");
117
+ }
118
+ },
119
+ removeItem(key) {
120
+ store.delete(key);
121
+ }
122
+ };
123
+ }
124
+
125
+ export { storage };
126
+ //# sourceMappingURL=index.js.map
127
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/storage/index.ts"],"names":["storage"],"mappings":"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","file":"index.js","sourcesContent":["import { safeStorage } from 'electron';\nimport Store from 'electron-store';\n\nimport type { TokenStorage } from '../shared/types';\n\ntype StorageOptions = {\n /**\n * The name of the file (without extension) used to persist tokens.\n *\n * @default 'clerk-tokens'\n */\n name?: string;\n /**\n * The directory in which the token file is stored. Maps to `electron-store`'s `cwd` option.\n * When omitted, the OS default user config directory is used.\n */\n path?: string;\n /**\n * When OS-level encryption is unavailable (e.g. a Linux machine without a keyring), tokens are\n * not persisted by default, which signs the user out on the next app launch. Set this to `true`\n * to instead persist tokens **unencrypted** in that scenario, keeping the user signed in across\n * restarts at the cost of storing tokens in plaintext on disk.\n *\n * @default false\n */\n unencryptedFallback?: boolean;\n};\n\n/**\n * Marks a value that was encrypted via {@link safeStorage}; the remainder is base64 ciphertext.\n * values will be stored as: `enc:<encrypted value>`\n */\nconst ENCRYPTED_PREFIX = 'enc:';\n/**\n * Marks a value persisted unencrypted via the `unencryptedFallback` option.\n * values will be stored as: `raw:<value>`\n */\nconst RAW_PREFIX = 'raw:';\n\ntype Cipher = {\n encrypt: (value: string) => Promise<string>;\n /**\n * Decrypts a base64 payload. `shouldReEncrypt` is `true` (async backend only) when the OS key\n * has rotated and the payload should be re-encrypted with the new key.\n */\n decrypt: (payload: string) => Promise<{ value: string; shouldReEncrypt: boolean }>;\n};\n\ntype AsyncSafeStorage = {\n encryptStringAsync: (plainText: string) => Promise<Buffer>;\n decryptStringAsync: (encrypted: Buffer) => Promise<{ result: string; shouldReEncrypt: boolean }>;\n isAsyncEncryptionAvailable: () => Promise<boolean>;\n};\n\nconst syncCipher: Cipher = {\n encrypt: value => Promise.resolve(safeStorage.encryptString(value).toString('base64')),\n decrypt: payload =>\n Promise.resolve({ value: safeStorage.decryptString(Buffer.from(payload, 'base64')), shouldReEncrypt: false }),\n};\n\nfunction hasAsyncSafeStorage(storage: typeof safeStorage): storage is typeof safeStorage & AsyncSafeStorage {\n const candidate = storage as Partial<AsyncSafeStorage>;\n\n return (\n typeof candidate.encryptStringAsync === 'function' &&\n typeof candidate.decryptStringAsync === 'function' &&\n typeof candidate.isAsyncEncryptionAvailable === 'function'\n );\n}\n\nfunction createAsyncCipher(storage: AsyncSafeStorage): Cipher {\n return {\n encrypt: async value => (await storage.encryptStringAsync(value)).toString('base64'),\n decrypt: async payload => {\n const { result, shouldReEncrypt } = await storage.decryptStringAsync(Buffer.from(payload, 'base64'));\n return { value: result, shouldReEncrypt };\n },\n };\n}\n\n/**\n * Resolves the crypto backend to use, or `null` when no OS encryption is currently available.\n */\nasync function resolveCipher(): Promise<Cipher | null> {\n // Prefer the async API, but only when the full optional function surface exists.\n if (hasAsyncSafeStorage(safeStorage)) {\n try {\n if (await safeStorage.isAsyncEncryptionAvailable()) {\n return createAsyncCipher(safeStorage);\n }\n } catch {\n /* fall through to the synchronous API */\n }\n }\n\n // The synchronous API blocks the calling thread on the OS prompt during the first encrypt/decrypt,\n if (typeof safeStorage.isEncryptionAvailable === 'function' && safeStorage.isEncryptionAvailable()) {\n return syncCipher;\n }\n\n return null;\n}\n\n/**\n * Creates a secure {@link TokenStorage} adapter for the Electron main process.\n *\n * Tokens are persisted with `electron-store` and encrypted at rest using Electron's\n * {@link safeStorage} API, which is backed by the OS keystore (Keychain on macOS, DPAPI on\n * Windows, libsecret/kwallet on Linux). It uses Electron 42's async `safeStorage` API only when it\n * reports itself available (which generally requires a code-signed app) and otherwise falls back to\n * the synchronous API. Pass the result to `createClerkBridge({ storage: storage() })`.\n *\n * Behavior is secure by default: when OS encryption is unavailable the adapter does not persist\n * tokens (the user will be signed out on restart) unless {@link StorageOptions.unencryptedFallback}\n * is enabled. Undecryptable entries return `null`.\n *\n * @example\n * ```ts\n * import { createClerkBridge } from '@clerk/electron';\n * import { storage } from '@clerk/electron/storage';\n *\n * createClerkBridge({ storage: storage({ name: 'my-app-tokens' }) });\n * ```\n */\nexport function storage(options: StorageOptions = {}): TokenStorage {\n const store = new Store<Record<string, string>>({\n name: options.name ?? 'clerk-tokens',\n ...(options.path ? { cwd: options.path } : {}),\n });\n\n let cachedCipher: Cipher | null = null;\n let resolving: Promise<Cipher | null> | null = null;\n const getCipher = (): Promise<Cipher | null> => {\n if (cachedCipher) {\n return Promise.resolve(cachedCipher);\n }\n resolving ??= resolveCipher().then(resolved => {\n resolving = null;\n if (resolved) {\n cachedCipher = resolved;\n }\n return resolved;\n });\n return resolving;\n };\n\n let warned = false;\n const warnOnce = (message: string) => {\n if (warned) {\n return;\n }\n warned = true;\n console.warn(message);\n };\n\n return {\n async getItem(key) {\n const stored = store.get(key);\n\n if (!stored) {\n return null;\n }\n\n if (stored.startsWith(RAW_PREFIX)) {\n return stored.slice(RAW_PREFIX.length);\n }\n\n if (stored.startsWith(ENCRYPTED_PREFIX)) {\n const cipher = await getCipher();\n\n // No usable OS encryption, preserve entry.\n if (!cipher) {\n return null;\n }\n\n const payload = stored.slice(ENCRYPTED_PREFIX.length);\n\n try {\n const { value, shouldReEncrypt } = await cipher.decrypt(payload);\n\n if (shouldReEncrypt) {\n // OS key has rotated, persist with new value\n try {\n store.set(key, ENCRYPTED_PREFIX + (await cipher.encrypt(value)));\n } catch {\n // keep the existing payload; it still decrypts for now\n }\n }\n\n return value;\n } catch {\n // Decryption failed, preserve the entry, new write on next sign-in.\n return null;\n }\n }\n\n // Unknown or unrecognized format, drop the entry so we don't repeatedly fail on it.\n store.delete(key);\n return null;\n },\n async setItem(key, value) {\n const cipher = await getCipher();\n\n if (!cipher) {\n if (options.unencryptedFallback) {\n warnOnce(\n 'Clerk: OS encryption is unavailable; falling back to unencrypted storage. Session tokens are being stored unencrypted on local disk.',\n );\n store.set(key, RAW_PREFIX + value);\n } else {\n warnOnce(\n 'Clerk: OS encryption is unavailable and unencryptedFallback is not enabled, so tokens are not being persisted. The user will be signed out on the next launch. Pass `storage({ unencryptedFallback: true })` to persist unencrypted (less secure).',\n );\n }\n return;\n }\n\n try {\n store.set(key, ENCRYPTED_PREFIX + (await cipher.encrypt(value)));\n } catch {\n // Encryption is available but encryption failed\n warnOnce('Clerk: failed to encrypt the session token; it was not persisted.');\n }\n },\n removeItem(key) {\n store.delete(key);\n },\n };\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export { createClerkBridge } from './main/create-clerk-bridge';
2
+ export type { ClerkBridge, CreateClerkBridgeOptions } from './shared/types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,YAAY,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { ClerkBridge, CreateClerkBridgeOptions } from '../shared/types';
2
+ /**
3
+ * Creates the Clerk bridge for Electron's main process.
4
+ *
5
+ * The bridge owns Clerk's main-process IPC handlers, token persistence, and OAuth deep-link
6
+ * transport. Call this before creating renderer windows, and call the returned `cleanup` method
7
+ * when tearing down the app or test environment.
8
+ */
9
+ export declare function createClerkBridge(options: CreateClerkBridgeOptions): ClerkBridge;
10
+ //# sourceMappingURL=create-clerk-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-clerk-bridge.d.ts","sourceRoot":"","sources":["../../../src/main/create-clerk-bridge.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAkB7E;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,WAAW,CAqChF"}
@@ -0,0 +1,3 @@
1
+ import type { TokenStorage } from '../shared/types';
2
+ export declare function setupTokenCacheIpcHandlers(storage: TokenStorage): () => void;
3
+ //# sourceMappingURL=ipc-handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipc-handlers.d.ts","sourceRoot":"","sources":["../../../src/main/ipc-handlers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,IAAI,CAkB5E"}
@@ -0,0 +1,7 @@
1
+ import type { RendererSchemeOptions } from '../shared/types';
2
+ type OAuthTransportOptions = {
3
+ renderer: RendererSchemeOptions;
4
+ };
5
+ export declare function setupOAuthTransportIpcHandlers(options: OAuthTransportOptions): () => void;
6
+ export {};
7
+ //# sourceMappingURL=oauth-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-transport.d.ts","sourceRoot":"","sources":["../../../src/main/oauth-transport.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAU7D,KAAK,qBAAqB,GAAG;IAC3B,QAAQ,EAAE,qBAAqB,CAAC;CACjC,CAAC;AA6BF,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,IAAI,CAqFzF"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Exposes Clerk's Electron bridge from the preload script to the renderer.
3
+ *
4
+ * Call this from an Electron preload script. It publishes a narrow internal bridge used by
5
+ * `@clerk/electron/react` for token storage and OAuth transport.
6
+ */
7
+ export declare function exposeClerkBridge(): void;
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/preload/index.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAiBxC"}
@@ -0,0 +1,5 @@
1
+ import { Clerk } from '@clerk/clerk-js';
2
+ type ClerkInstance = InstanceType<typeof Clerk>;
3
+ export declare function createClerkInstance(publishableKey: string): ClerkInstance;
4
+ export {};
5
+ //# sourceMappingURL=create-clerk-instance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-clerk-instance.d.ts","sourceRoot":"","sources":["../../../src/react/create-clerk-instance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAIxC,KAAK,aAAa,GAAG,YAAY,CAAC,OAAO,KAAK,CAAC,CAAC;AAIhD,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,aAAa,CA+BzE"}
@@ -0,0 +1,12 @@
1
+ import type { ClerkProviderProps as ReactClerkProviderProps } from '@clerk/react';
2
+ import type { ReactNode } from 'react';
3
+ export type ClerkProviderProps = Omit<ReactClerkProviderProps, 'Clerk' | 'children' | 'publishableKey' | 'standardBrowser' | 'ui' | '__internal_oauthTransport'> & {
4
+ children: ReactNode;
5
+ /**
6
+ * Your Clerk publishable key, available in the Clerk Dashboard.
7
+ */
8
+ publishableKey: string;
9
+ };
10
+ export declare function ClerkProvider({ children, publishableKey, ...props }: ClerkProviderProps): JSX.Element;
11
+ export * from '@clerk/react';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,IAAI,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAGlF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,uBAAuB,EACvB,OAAO,GAAG,UAAU,GAAG,gBAAgB,GAAG,iBAAiB,GAAG,IAAI,GAAG,2BAA2B,CACjG,GAAG;IACF,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAeF,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,KAAK,EAAE,EAAE,kBAAkB,GAAG,GAAG,CAAC,OAAO,CAgBrG;AAED,cAAc,cAAc,CAAC"}
@@ -0,0 +1,10 @@
1
+ export declare const TOKEN_CACHE_CHANNELS: {
2
+ readonly getToken: "clerk:token-cache:get";
3
+ readonly saveToken: "clerk:token-cache:save";
4
+ readonly clearToken: "clerk:token-cache:clear";
5
+ };
6
+ export declare const OAUTH_TRANSPORT_CHANNELS: {
7
+ readonly getRedirectUrl: "clerk:oauth-transport:get-redirect-url";
8
+ readonly open: "clerk:oauth-transport:open";
9
+ };
10
+ //# sourceMappingURL=ipc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipc.d.ts","sourceRoot":"","sources":["../../../src/shared/ipc.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB;;;;CAIvB,CAAC;AAEX,eAAO,MAAM,wBAAwB;;;CAG3B,CAAC"}
@@ -0,0 +1,45 @@
1
+ type Awaitable<T> = T | Promise<T>;
2
+ export type TokenStorage = {
3
+ getItem: (key: string) => Awaitable<string | null>;
4
+ setItem: (key: string, value: string) => Awaitable<void>;
5
+ removeItem: (key: string) => Awaitable<void>;
6
+ };
7
+ export type CreateClerkBridgeOptions = {
8
+ /**
9
+ * Storage adapter used by the main process to persist Clerk tokens.
10
+ */
11
+ storage: TokenStorage;
12
+ /**
13
+ * Registers the custom scheme used to serve the Electron renderer from a stable origin.
14
+ */
15
+ renderer?: RendererSchemeOptions;
16
+ };
17
+ export type ClerkBridge = {
18
+ /**
19
+ * Removes IPC handlers and listeners registered by `createClerkBridge`.
20
+ */
21
+ cleanup: () => void;
22
+ };
23
+ export type RendererSchemeOptions = {
24
+ /**
25
+ * Custom scheme used for the renderer origin.
26
+ */
27
+ scheme: string;
28
+ /**
29
+ * Custom host used for the renderer origin.
30
+ */
31
+ host: string;
32
+ };
33
+ export type TokenCache = {
34
+ getToken: (key: string) => Promise<string | null>;
35
+ saveToken: (key: string, value: string) => Promise<void>;
36
+ clearToken: (key: string) => Promise<void>;
37
+ };
38
+ export type OAuthTransport = {
39
+ getRedirectUrl: () => Promise<string>;
40
+ open: (url: string) => Promise<{
41
+ callbackUrl: string;
42
+ }>;
43
+ };
44
+ export {};
45
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/shared/types.ts"],"names":[],"mappings":"AAAA,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAEnC,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACnD,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC;IACzD,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC;;OAEG;IACH,OAAO,EAAE,YAAY,CAAC;IACtB;;OAEG;IACH,QAAQ,CAAC,EAAE,qBAAqB,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAClD,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzD,CAAC"}