forked from clerk/javascript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplugin.ts
More file actions
90 lines (78 loc) · 2.85 KB
/
Copy pathplugin.ts
File metadata and controls
90 lines (78 loc) · 2.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { inBrowser } from '@clerk/shared/browser';
import { deriveState } from '@clerk/shared/deriveState';
import { loadClerkJsScript, type LoadClerkJsScriptOptions } from '@clerk/shared/loadClerkJsScript';
import type { Clerk, ClientResource, Resources } from '@clerk/types';
import type { Plugin } from 'vue';
import { computed, ref, shallowRef, triggerRef } from 'vue';
import { ClerkInjectionKey } from './keys';
export type PluginOptions = LoadClerkJsScriptOptions;
/**
* Vue plugin for integrating Clerk.
*
* @example
* Basic usage in main.ts:
*
* ```ts
* import { createApp } from 'vue'
* import { clerkPlugin } from '@clerk/vue'
* import App from './App.vue'
*
* const app = createApp(App)
*
* app.use(clerkPlugin, {
* publishableKey: 'pk_'
* })
*
* app.mount('#app')
* ```
*/
export const clerkPlugin: Plugin = {
install(app, options: PluginOptions) {
// @ts-expect-error: Internal property for SSR frameworks like Nuxt
const { __internal_clerk_initial_state } = options;
const loaded = shallowRef(false);
const clerk = shallowRef<Clerk | null>(null);
const resources = ref<Resources>({
client: {} as ClientResource,
session: undefined,
user: undefined,
organization: undefined,
});
// We need this check for SSR apps like Nuxt as it will try to run this code on the server
// and loadClerkJsScript contains browser-specific code
if (inBrowser()) {
void loadClerkJsScript(options).then(async () => {
if (!window.Clerk) {
throw new Error('Failed to download latest ClerkJS. Contact support@clerk.com.');
}
clerk.value = window.Clerk;
await window.Clerk.load(options);
loaded.value = true;
clerk.value.addListener(payload => {
resources.value = payload;
});
// When Clerk updates its state internally, Vue's reactivity system doesn't detect
// the change since it's an external object being mutated. triggerRef() forces Vue
// to re-evaluate all dependencies regardless of how the value was changed.
triggerRef(clerk);
});
}
const derivedState = computed(() => deriveState(loaded.value, resources.value, __internal_clerk_initial_state));
const authCtx = computed(() => {
const { sessionId, userId, orgId, actor, orgRole, orgSlug, orgPermissions } = derivedState.value;
return { sessionId, userId, actor, orgId, orgRole, orgSlug, orgPermissions };
});
const clientCtx = computed(() => resources.value.client);
const userCtx = computed(() => derivedState.value.user);
const sessionCtx = computed(() => derivedState.value.session);
const organizationCtx = computed(() => derivedState.value.organization);
app.provide(ClerkInjectionKey, {
clerk,
authCtx,
clientCtx,
sessionCtx,
userCtx,
organizationCtx,
});
},
};