timeback 0.0.0-alpha.2 → 0.1.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.
- package/README.md +378 -7
- package/dist/client/adapters/react/SignInButton.d.ts +60 -0
- package/dist/client/adapters/react/SignInButton.d.ts.map +1 -0
- package/dist/client/adapters/react/index.d.ts +43 -0
- package/dist/client/adapters/react/index.d.ts.map +1 -0
- package/dist/client/adapters/react/index.js +478 -0
- package/dist/client/adapters/react/provider.d.ts +74 -0
- package/dist/client/adapters/react/provider.d.ts.map +1 -0
- package/dist/client/adapters/solid/SignInButton.d.ts +52 -0
- package/dist/client/adapters/solid/SignInButton.d.ts.map +1 -0
- package/dist/client/adapters/solid/SignInButton.tsx +321 -0
- package/dist/client/adapters/solid/context.d.ts +73 -0
- package/dist/client/adapters/solid/context.d.ts.map +1 -0
- package/dist/client/adapters/solid/context.tsx +91 -0
- package/dist/client/adapters/solid/index.d.ts +42 -0
- package/dist/client/adapters/solid/index.d.ts.map +1 -0
- package/dist/client/adapters/solid/index.ts +46 -0
- package/dist/client/adapters/svelte/SignInButton.svelte +234 -0
- package/dist/client/adapters/svelte/SignInButton.svelte.d.ts +24 -0
- package/dist/client/adapters/svelte/index.d.ts +33 -0
- package/dist/client/adapters/svelte/index.d.ts.map +1 -0
- package/dist/client/adapters/svelte/index.ts +38 -0
- package/dist/client/adapters/svelte/stores.d.ts +62 -0
- package/dist/client/adapters/svelte/stores.d.ts.map +1 -0
- package/dist/client/adapters/svelte/stores.ts +139 -0
- package/dist/client/adapters/vue/SignInButton.vue +260 -0
- package/dist/client/adapters/vue/SignInButton.vue.d.ts +53 -0
- package/dist/client/adapters/vue/index.d.ts +43 -0
- package/dist/client/adapters/vue/index.d.ts.map +1 -0
- package/dist/client/adapters/vue/index.ts +48 -0
- package/dist/client/adapters/vue/provider.d.ts +94 -0
- package/dist/client/adapters/vue/provider.d.ts.map +1 -0
- package/dist/client/adapters/vue/provider.ts +147 -0
- package/dist/client/index.d.ts +9 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/lib/activity/activity.class.d.ts +73 -0
- package/dist/client/lib/activity/activity.class.d.ts.map +1 -0
- package/dist/client/lib/activity/activity.d.ts +16 -0
- package/dist/client/lib/activity/activity.d.ts.map +1 -0
- package/dist/client/lib/activity/index.d.ts +6 -0
- package/dist/client/lib/activity/index.d.ts.map +1 -0
- package/dist/client/lib/utils.d.ts +20 -0
- package/dist/client/lib/utils.d.ts.map +1 -0
- package/dist/client/namespaces/activity.d.ts +37 -0
- package/dist/client/namespaces/activity.d.ts.map +1 -0
- package/dist/client/namespaces/auth.d.ts +33 -0
- package/dist/client/namespaces/auth.d.ts.map +1 -0
- package/dist/client/namespaces/index.d.ts +7 -0
- package/dist/client/namespaces/index.d.ts.map +1 -0
- package/dist/client/namespaces/user.d.ts +29 -0
- package/dist/client/namespaces/user.d.ts.map +1 -0
- package/dist/client/timeback-client.class.d.ts +37 -0
- package/dist/client/timeback-client.class.d.ts.map +1 -0
- package/dist/client/timeback-client.d.ts +29 -0
- package/dist/client/timeback-client.d.ts.map +1 -0
- package/dist/client.d.ts +30 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +198 -0
- package/dist/index.d.ts +27 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1373 -11
- package/dist/server/adapters/express.d.ts +62 -0
- package/dist/server/adapters/express.d.ts.map +1 -0
- package/dist/server/adapters/express.js +565 -0
- package/dist/server/adapters/native.d.ts +45 -0
- package/dist/server/adapters/native.d.ts.map +1 -0
- package/dist/server/adapters/native.js +509 -0
- package/dist/server/adapters/nextjs.d.ts +30 -0
- package/dist/server/adapters/nextjs.d.ts.map +1 -0
- package/dist/server/adapters/nextjs.js +521 -0
- package/dist/server/adapters/nuxt.d.ts +96 -0
- package/dist/server/adapters/nuxt.d.ts.map +1 -0
- package/dist/server/adapters/nuxt.js +663 -0
- package/dist/server/adapters/solid-start.d.ts +61 -0
- package/dist/server/adapters/solid-start.d.ts.map +1 -0
- package/dist/server/adapters/solid-start.js +551 -0
- package/dist/server/adapters/svelte-kit.d.ts +82 -0
- package/dist/server/adapters/svelte-kit.d.ts.map +1 -0
- package/dist/server/adapters/svelte-kit.js +572 -0
- package/dist/server/adapters/tanstack-start.d.ts +40 -0
- package/dist/server/adapters/tanstack-start.d.ts.map +1 -0
- package/dist/server/adapters/tanstack-start.js +522 -0
- package/dist/server/adapters/types.d.ts +280 -0
- package/dist/server/adapters/types.d.ts.map +1 -0
- package/dist/server/adapters/utils.d.ts +15 -0
- package/dist/server/adapters/utils.d.ts.map +1 -0
- package/dist/server/handlers/activity.d.ts +28 -0
- package/dist/server/handlers/activity.d.ts.map +1 -0
- package/dist/server/handlers/identity.d.ts +24 -0
- package/dist/server/handlers/identity.d.ts.map +1 -0
- package/dist/server/handlers/index.d.ts +9 -0
- package/dist/server/handlers/index.d.ts.map +1 -0
- package/dist/server/handlers/user.d.ts +30 -0
- package/dist/server/handlers/user.d.ts.map +1 -0
- package/dist/server/index.d.ts +10 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/lib/index.d.ts +9 -0
- package/dist/server/lib/index.d.ts.map +1 -0
- package/dist/server/lib/logger.d.ts +21 -0
- package/dist/server/lib/logger.d.ts.map +1 -0
- package/dist/server/lib/oidc.d.ts +76 -0
- package/dist/server/lib/oidc.d.ts.map +1 -0
- package/dist/server/lib/utils.d.ts +39 -0
- package/dist/server/lib/utils.d.ts.map +1 -0
- package/dist/server/timeback.d.ts +48 -0
- package/dist/server/timeback.d.ts.map +1 -0
- package/dist/server/types.d.ts +300 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/shared/constants.d.ts +18 -0
- package/dist/shared/constants.d.ts.map +1 -0
- package/dist/shared/types.d.ts +100 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/package.json +104 -28
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Sign In with Timeback Button
|
|
3
|
+
|
|
4
|
+
A pre-styled button for Timeback SSO authentication.
|
|
5
|
+
Fully customizable via CSS variables.
|
|
6
|
+
|
|
7
|
+
@example
|
|
8
|
+
```vue
|
|
9
|
+
<script setup>
|
|
10
|
+
import { SignInButton } from 'timeback/vue'
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<SignInButton />
|
|
15
|
+
<SignInButton variant="outline">Continue with Timeback</SignInButton>
|
|
16
|
+
</template>
|
|
17
|
+
```
|
|
18
|
+
-->
|
|
19
|
+
<script setup lang="ts">
|
|
20
|
+
import { computed, onMounted, ref } from 'vue'
|
|
21
|
+
import { useTimeback } from './provider'
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Props for SignInButton component.
|
|
25
|
+
*/
|
|
26
|
+
interface Props {
|
|
27
|
+
/** Additional CSS class names */
|
|
28
|
+
class?: string
|
|
29
|
+
/** Disabled state */
|
|
30
|
+
disabled?: boolean
|
|
31
|
+
/** Show loading spinner when clicked */
|
|
32
|
+
showLoading?: boolean
|
|
33
|
+
/** Button variant */
|
|
34
|
+
variant?: 'default' | 'outline' | 'minimal'
|
|
35
|
+
/** Button size */
|
|
36
|
+
size?: 'sm' | 'md' | 'lg'
|
|
37
|
+
/** Show Timeback logo */
|
|
38
|
+
showLogo?: boolean
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
42
|
+
class: '',
|
|
43
|
+
disabled: false,
|
|
44
|
+
showLoading: true,
|
|
45
|
+
variant: 'default',
|
|
46
|
+
size: 'md',
|
|
47
|
+
showLogo: true,
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
const emit = defineEmits<{
|
|
51
|
+
(e: 'click', event: MouseEvent): void
|
|
52
|
+
}>()
|
|
53
|
+
|
|
54
|
+
const timeback = useTimeback()
|
|
55
|
+
const isLoading = ref(false)
|
|
56
|
+
|
|
57
|
+
const isReady = computed(() => !!timeback.value)
|
|
58
|
+
|
|
59
|
+
const classes = computed(() => {
|
|
60
|
+
return [
|
|
61
|
+
'timeback-signin-btn',
|
|
62
|
+
props.variant !== 'default' && `timeback-signin-btn--${props.variant}`,
|
|
63
|
+
props.size !== 'md' && `timeback-signin-btn--${props.size}`,
|
|
64
|
+
props.class,
|
|
65
|
+
]
|
|
66
|
+
.filter(Boolean)
|
|
67
|
+
.join(' ')
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
function handleClick(e: MouseEvent) {
|
|
71
|
+
emit('click', e)
|
|
72
|
+
if (e.defaultPrevented) {
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (props.showLoading) {
|
|
77
|
+
isLoading.value = true
|
|
78
|
+
}
|
|
79
|
+
timeback.value?.auth.signIn()
|
|
80
|
+
}
|
|
81
|
+
</script>
|
|
82
|
+
|
|
83
|
+
<template>
|
|
84
|
+
<button
|
|
85
|
+
type="button"
|
|
86
|
+
:class="classes"
|
|
87
|
+
:disabled="disabled || !isReady || isLoading"
|
|
88
|
+
:aria-busy="isLoading"
|
|
89
|
+
@click="handleClick"
|
|
90
|
+
>
|
|
91
|
+
<svg
|
|
92
|
+
v-if="isLoading"
|
|
93
|
+
class="timeback-signin-btn__spinner"
|
|
94
|
+
width="16"
|
|
95
|
+
height="16"
|
|
96
|
+
viewBox="0 0 24 24"
|
|
97
|
+
fill="none"
|
|
98
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
99
|
+
aria-hidden="true"
|
|
100
|
+
>
|
|
101
|
+
<circle
|
|
102
|
+
cx="12"
|
|
103
|
+
cy="12"
|
|
104
|
+
r="10"
|
|
105
|
+
stroke="currentColor"
|
|
106
|
+
stroke-width="2"
|
|
107
|
+
stroke-opacity="0.25"
|
|
108
|
+
/>
|
|
109
|
+
<path
|
|
110
|
+
d="M12 2C6.48 2 2 6.48 2 12"
|
|
111
|
+
stroke="currentColor"
|
|
112
|
+
stroke-width="2"
|
|
113
|
+
stroke-linecap="round"
|
|
114
|
+
/>
|
|
115
|
+
</svg>
|
|
116
|
+
<svg
|
|
117
|
+
v-else-if="showLogo"
|
|
118
|
+
class="timeback-signin-btn__logo"
|
|
119
|
+
width="20"
|
|
120
|
+
height="18"
|
|
121
|
+
viewBox="0 0 199 180"
|
|
122
|
+
fill="none"
|
|
123
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
124
|
+
aria-hidden="true"
|
|
125
|
+
>
|
|
126
|
+
<g clip-path="url(#tb-logo-clip-vue)">
|
|
127
|
+
<path
|
|
128
|
+
d="M121.432 179.456C110.607 177.871 101.153 173.91 92.4882 168.085C91.1274 167.17 89.4598 165.404 89.4375 164.008C89.2123 149.891 89.3002 135.77 89.3002 119.86C93.1365 123.255 95.8538 125.706 98.6224 128.099C103.151 132.012 107.437 136.28 112.314 139.703C126.466 149.635 145.037 147.25 156.045 134.448C166.919 121.803 167.226 101.374 155.695 89.6399C145.727 79.4958 134.693 70.3995 123.251 60.0438C123.251 77.8871 123.251 94.5637 123.251 112.15C121.428 110.999 120.279 110.479 119.383 109.676C110.329 101.573 101.241 93.5044 92.3634 85.2109C90.8519 83.7988 89.4363 81.3758 89.4209 79.4084C89.2249 54.4218 89.2905 29.4332 89.3061 4.44502C89.3066 3.64954 89.3061 2.22136 89.3061 1.47755C90.8061 1.47755 92.694 1.47857 94.1427 1.47755C118.131 1.46071 142.12 1.52088 166.108 1.39821C169.235 1.38222 171.33 2.18661 173.251 4.75826C180.607 14.6032 188.189 24.279 196.266 34.7705C179.79 34.7705 164.169 34.7705 148.548 34.7705C147.871 34.7705 147.366 34.7705 146.866 34.7705C147.866 35.7705 150.35 38.3018 151.61 39.4825C162.643 49.8249 174.663 59.3807 184.245 70.947C202.474 92.9508 203.539 118.134 191.204 143.046C178.598 168.508 156.61 180.302 128.298 180.295C126.154 180.295 124.011 179.778 121.432 179.456Z"
|
|
129
|
+
fill="currentColor"
|
|
130
|
+
/>
|
|
131
|
+
<circle cx="40" cy="133" r="39" fill="currentColor" />
|
|
132
|
+
<circle cx="39" cy="39" r="39" fill="currentColor" />
|
|
133
|
+
</g>
|
|
134
|
+
<defs>
|
|
135
|
+
<clipPath id="tb-logo-clip-vue">
|
|
136
|
+
<rect width="199" height="180" fill="currentColor" />
|
|
137
|
+
</clipPath>
|
|
138
|
+
</defs>
|
|
139
|
+
</svg>
|
|
140
|
+
<slot>Sign in with Timeback</slot>
|
|
141
|
+
</button>
|
|
142
|
+
</template>
|
|
143
|
+
|
|
144
|
+
<style scoped>
|
|
145
|
+
.timeback-signin-btn {
|
|
146
|
+
/* Colors */
|
|
147
|
+
--tb-btn-bg: #0f172a;
|
|
148
|
+
--tb-btn-bg-hover: #1e293b;
|
|
149
|
+
--tb-btn-text: #ffffff;
|
|
150
|
+
--tb-btn-border: transparent;
|
|
151
|
+
|
|
152
|
+
/* Outline variant */
|
|
153
|
+
--tb-btn-outline-bg: transparent;
|
|
154
|
+
--tb-btn-outline-bg-hover: #f1f5f9;
|
|
155
|
+
--tb-btn-outline-text: #0f172a;
|
|
156
|
+
--tb-btn-outline-border: #e2e8f0;
|
|
157
|
+
|
|
158
|
+
/* Minimal variant */
|
|
159
|
+
--tb-btn-minimal-bg: transparent;
|
|
160
|
+
--tb-btn-minimal-bg-hover: #f1f5f9;
|
|
161
|
+
--tb-btn-minimal-text: #0f172a;
|
|
162
|
+
|
|
163
|
+
/* Sizing */
|
|
164
|
+
--tb-btn-padding-x: 1rem;
|
|
165
|
+
--tb-btn-padding-y: 0.625rem;
|
|
166
|
+
--tb-btn-font-size: 0.875rem;
|
|
167
|
+
--tb-btn-border-radius: 0.5rem;
|
|
168
|
+
--tb-btn-gap: 0.5rem;
|
|
169
|
+
|
|
170
|
+
/* Transitions */
|
|
171
|
+
--tb-btn-transition: all 150ms ease;
|
|
172
|
+
|
|
173
|
+
/* Focus ring */
|
|
174
|
+
--tb-btn-focus-ring: #3b82f6;
|
|
175
|
+
--tb-btn-focus-ring-offset: 2px;
|
|
176
|
+
|
|
177
|
+
/* Base styles */
|
|
178
|
+
display: inline-flex;
|
|
179
|
+
align-items: center;
|
|
180
|
+
justify-content: center;
|
|
181
|
+
gap: var(--tb-btn-gap);
|
|
182
|
+
padding: var(--tb-btn-padding-y) var(--tb-btn-padding-x);
|
|
183
|
+
font-size: var(--tb-btn-font-size);
|
|
184
|
+
font-weight: 500;
|
|
185
|
+
font-family: inherit;
|
|
186
|
+
line-height: 1.5;
|
|
187
|
+
border-radius: var(--tb-btn-border-radius);
|
|
188
|
+
border: 1px solid var(--tb-btn-border);
|
|
189
|
+
background-color: var(--tb-btn-bg);
|
|
190
|
+
color: var(--tb-btn-text);
|
|
191
|
+
cursor: pointer;
|
|
192
|
+
transition: var(--tb-btn-transition);
|
|
193
|
+
text-decoration: none;
|
|
194
|
+
white-space: nowrap;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.timeback-signin-btn:hover:not(:disabled) {
|
|
198
|
+
background-color: var(--tb-btn-bg-hover);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.timeback-signin-btn:focus-visible {
|
|
202
|
+
outline: 2px solid var(--tb-btn-focus-ring);
|
|
203
|
+
outline-offset: var(--tb-btn-focus-ring-offset);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.timeback-signin-btn:disabled {
|
|
207
|
+
opacity: 0.6;
|
|
208
|
+
cursor: not-allowed;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* Outline variant */
|
|
212
|
+
.timeback-signin-btn--outline {
|
|
213
|
+
--tb-btn-bg: var(--tb-btn-outline-bg);
|
|
214
|
+
--tb-btn-bg-hover: var(--tb-btn-outline-bg-hover);
|
|
215
|
+
--tb-btn-text: var(--tb-btn-outline-text);
|
|
216
|
+
--tb-btn-border: var(--tb-btn-outline-border);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/* Minimal variant */
|
|
220
|
+
.timeback-signin-btn--minimal {
|
|
221
|
+
--tb-btn-bg: var(--tb-btn-minimal-bg);
|
|
222
|
+
--tb-btn-bg-hover: var(--tb-btn-minimal-bg-hover);
|
|
223
|
+
--tb-btn-text: var(--tb-btn-minimal-text);
|
|
224
|
+
--tb-btn-border: transparent;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/* Sizes */
|
|
228
|
+
.timeback-signin-btn--sm {
|
|
229
|
+
--tb-btn-padding-x: 0.75rem;
|
|
230
|
+
--tb-btn-padding-y: 0.375rem;
|
|
231
|
+
--tb-btn-font-size: 0.75rem;
|
|
232
|
+
--tb-btn-gap: 0.375rem;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.timeback-signin-btn--lg {
|
|
236
|
+
--tb-btn-padding-x: 1.5rem;
|
|
237
|
+
--tb-btn-padding-y: 0.75rem;
|
|
238
|
+
--tb-btn-font-size: 1rem;
|
|
239
|
+
--tb-btn-gap: 0.625rem;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/* Logo */
|
|
243
|
+
.timeback-signin-btn__logo {
|
|
244
|
+
flex-shrink: 0;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/* Loading spinner */
|
|
248
|
+
.timeback-signin-btn__spinner {
|
|
249
|
+
animation: timeback-spin 1s linear infinite;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
@keyframes timeback-spin {
|
|
253
|
+
from {
|
|
254
|
+
transform: rotate(0deg);
|
|
255
|
+
}
|
|
256
|
+
to {
|
|
257
|
+
transform: rotate(360deg);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
</style>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sign In with Timeback Button (Vue)
|
|
3
|
+
*
|
|
4
|
+
* Type declarations for SignInButton.vue component.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { DefineComponent } from 'vue'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Props for SignInButton component.
|
|
11
|
+
*/
|
|
12
|
+
export interface SignInButtonProps {
|
|
13
|
+
/** Additional CSS class names */
|
|
14
|
+
class?: string
|
|
15
|
+
/** Disabled state */
|
|
16
|
+
disabled?: boolean
|
|
17
|
+
/** Show loading spinner when clicked */
|
|
18
|
+
showLoading?: boolean
|
|
19
|
+
/** Button variant */
|
|
20
|
+
variant?: 'default' | 'outline' | 'minimal'
|
|
21
|
+
/** Button size */
|
|
22
|
+
size?: 'sm' | 'md' | 'lg'
|
|
23
|
+
/** Show Timeback logo */
|
|
24
|
+
showLogo?: boolean
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Sign In with Timeback button component.
|
|
29
|
+
*
|
|
30
|
+
* Triggers SSO authentication flow when clicked.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```vue
|
|
34
|
+
* <script setup>
|
|
35
|
+
* import { SignInButton } from 'timeback/vue'
|
|
36
|
+
* </script>
|
|
37
|
+
*
|
|
38
|
+
* <template>
|
|
39
|
+
* <!-- Basic usage -->
|
|
40
|
+
* <SignInButton />
|
|
41
|
+
*
|
|
42
|
+
* <!-- Custom text -->
|
|
43
|
+
* <SignInButton>Continue with Timeback</SignInButton>
|
|
44
|
+
*
|
|
45
|
+
* <!-- Outline variant -->
|
|
46
|
+
* <SignInButton variant="outline" />
|
|
47
|
+
* </template>
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
declare const SignInButton: DefineComponent<SignInButtonProps>
|
|
51
|
+
|
|
52
|
+
export default SignInButton
|
|
53
|
+
export { SignInButtonProps }
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vue Client Module
|
|
3
|
+
*
|
|
4
|
+
* Vue 3-specific exports for Timeback SDK.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```vue
|
|
8
|
+
* <script setup>
|
|
9
|
+
* import { TimebackProvider, useTimeback, SignInButton } from 'timeback/vue'
|
|
10
|
+
*
|
|
11
|
+
* const timeback = useTimeback()
|
|
12
|
+
*
|
|
13
|
+
* function handleSignIn() {
|
|
14
|
+
* timeback.value?.auth.signIn()
|
|
15
|
+
* }
|
|
16
|
+
*
|
|
17
|
+
* async function handleFetchProfile() {
|
|
18
|
+
* const profile = await timeback.value?.user.fetch()
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* function handleStartActivity() {
|
|
22
|
+
* const activity = timeback.value?.activity.new({
|
|
23
|
+
* id: 'lesson-1',
|
|
24
|
+
* name: 'Intro',
|
|
25
|
+
* courseCode: 'MATH'
|
|
26
|
+
* })
|
|
27
|
+
* activity?.start()
|
|
28
|
+
* }
|
|
29
|
+
* </script>
|
|
30
|
+
*
|
|
31
|
+
* <template>
|
|
32
|
+
* <TimebackProvider>
|
|
33
|
+
* <SignInButton />
|
|
34
|
+
* </TimebackProvider>
|
|
35
|
+
* </template>
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export { Activity, createClient, TimebackClient } from 'timeback/client';
|
|
39
|
+
export type { ActivityMetrics, ActivityParams, TimebackUser } from 'timeback/client';
|
|
40
|
+
export { TimebackProvider, useTimeback } from './provider';
|
|
41
|
+
export { default as SignInButton } from './SignInButton.vue';
|
|
42
|
+
export type { SignInButtonProps } from './SignInButton.vue';
|
|
43
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/vue/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAGH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACxE,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAGpF,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAG1D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vue Client Module
|
|
3
|
+
*
|
|
4
|
+
* Vue 3-specific exports for Timeback SDK.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```vue
|
|
8
|
+
* <script setup>
|
|
9
|
+
* import { TimebackProvider, useTimeback, SignInButton } from 'timeback/vue'
|
|
10
|
+
*
|
|
11
|
+
* const timeback = useTimeback()
|
|
12
|
+
*
|
|
13
|
+
* function handleSignIn() {
|
|
14
|
+
* timeback.value?.auth.signIn()
|
|
15
|
+
* }
|
|
16
|
+
*
|
|
17
|
+
* async function handleFetchProfile() {
|
|
18
|
+
* const profile = await timeback.value?.user.fetch()
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* function handleStartActivity() {
|
|
22
|
+
* const activity = timeback.value?.activity.new({
|
|
23
|
+
* id: 'lesson-1',
|
|
24
|
+
* name: 'Intro',
|
|
25
|
+
* courseCode: 'MATH'
|
|
26
|
+
* })
|
|
27
|
+
* activity?.start()
|
|
28
|
+
* }
|
|
29
|
+
* </script>
|
|
30
|
+
*
|
|
31
|
+
* <template>
|
|
32
|
+
* <TimebackProvider>
|
|
33
|
+
* <SignInButton />
|
|
34
|
+
* </TimebackProvider>
|
|
35
|
+
* </template>
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
// Re-export from timeback/client for convenience
|
|
40
|
+
export { Activity, createClient, TimebackClient } from 'timeback/client'
|
|
41
|
+
export type { ActivityMetrics, ActivityParams, TimebackUser } from 'timeback/client'
|
|
42
|
+
|
|
43
|
+
// Vue-specific
|
|
44
|
+
export { TimebackProvider, useTimeback } from './provider'
|
|
45
|
+
|
|
46
|
+
// Components
|
|
47
|
+
export { default as SignInButton } from './SignInButton.vue'
|
|
48
|
+
export type { SignInButtonProps } from './SignInButton.vue'
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { TimebackClient } from 'timeback/client';
|
|
2
|
+
import type { PropType, ShallowRef } from 'vue';
|
|
3
|
+
/**
|
|
4
|
+
* TimebackProvider component.
|
|
5
|
+
*
|
|
6
|
+
* Wraps your app to provide the Timeback client via Vue's provide/inject.
|
|
7
|
+
* Handles SSR gracefully by only initializing the client in the browser.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```vue
|
|
11
|
+
* <script setup>
|
|
12
|
+
* import { TimebackProvider } from 'timeback/vue'
|
|
13
|
+
* </script>
|
|
14
|
+
*
|
|
15
|
+
* <template>
|
|
16
|
+
* <TimebackProvider>
|
|
17
|
+
* <App />
|
|
18
|
+
* </TimebackProvider>
|
|
19
|
+
* </template>
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```vue
|
|
24
|
+
* <!-- With custom client -->
|
|
25
|
+
* <script setup>
|
|
26
|
+
* import { TimebackProvider, createClient } from 'timeback/vue'
|
|
27
|
+
*
|
|
28
|
+
* const client = createClient({ baseURL: 'https://example.com/api/timeback' })
|
|
29
|
+
* </script>
|
|
30
|
+
*
|
|
31
|
+
* <template>
|
|
32
|
+
* <TimebackProvider :client="client">
|
|
33
|
+
* <App />
|
|
34
|
+
* </TimebackProvider>
|
|
35
|
+
* </template>
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare const TimebackProvider: import("@vue/runtime-core").DefineComponent<import("@vue/runtime-core").ExtractPropTypes<{
|
|
39
|
+
/** Optional Timeback client instance. If not provided, one is created automatically. */
|
|
40
|
+
client: {
|
|
41
|
+
type: PropType<TimebackClient>;
|
|
42
|
+
default: undefined;
|
|
43
|
+
};
|
|
44
|
+
}>, () => import("@vue/runtime-core").VNode<import("@vue/runtime-core").RendererNode, import("@vue/runtime-core").RendererElement, {
|
|
45
|
+
[key: string]: any;
|
|
46
|
+
}>[] | null, {}, {}, {}, import("@vue/runtime-core").ComponentOptionsMixin, import("@vue/runtime-core").ComponentOptionsMixin, {}, string, import("@vue/runtime-core").PublicProps, Readonly<import("@vue/runtime-core").ExtractPropTypes<{
|
|
47
|
+
/** Optional Timeback client instance. If not provided, one is created automatically. */
|
|
48
|
+
client: {
|
|
49
|
+
type: PropType<TimebackClient>;
|
|
50
|
+
default: undefined;
|
|
51
|
+
};
|
|
52
|
+
}>> & Readonly<{}>, {
|
|
53
|
+
client: TimebackClient;
|
|
54
|
+
}, {}, {}, {}, string, import("@vue/runtime-core").ComponentProvideOptions, true, {}, any>;
|
|
55
|
+
/**
|
|
56
|
+
* Composable to access the Timeback client.
|
|
57
|
+
*
|
|
58
|
+
* Returns the client instance or undefined if not yet hydrated.
|
|
59
|
+
* Use this to access all Timeback functionality: auth, user, activities.
|
|
60
|
+
*
|
|
61
|
+
* @returns The Timeback client or undefined
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```vue
|
|
65
|
+
* <script setup>
|
|
66
|
+
* import { useTimeback } from 'timeback/vue'
|
|
67
|
+
*
|
|
68
|
+
* const timeback = useTimeback()
|
|
69
|
+
*
|
|
70
|
+
* function handleSignIn() {
|
|
71
|
+
* timeback.value?.auth.signIn()
|
|
72
|
+
* }
|
|
73
|
+
*
|
|
74
|
+
* async function handleFetchProfile() {
|
|
75
|
+
* const profile = await timeback.value?.user.fetch()
|
|
76
|
+
* }
|
|
77
|
+
*
|
|
78
|
+
* function handleStartActivity() {
|
|
79
|
+
* const activity = timeback.value?.activity.new({
|
|
80
|
+
* id: 'lesson-1',
|
|
81
|
+
* name: 'Intro',
|
|
82
|
+
* courseCode: 'MATH'
|
|
83
|
+
* })
|
|
84
|
+
* activity?.start()
|
|
85
|
+
* }
|
|
86
|
+
* </script>
|
|
87
|
+
*
|
|
88
|
+
* <template>
|
|
89
|
+
* <button @click="handleSignIn">Sign In</button>
|
|
90
|
+
* </template>
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export declare function useTimeback(): ShallowRef<TimebackClient | undefined>;
|
|
94
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../../src/client/adapters/vue/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAGhD,OAAO,KAAK,EAAgB,QAAQ,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAqC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,eAAO,MAAM,gBAAgB;IAG3B,wFAAwF;;;;;;;;IAAxF,wFAAwF;;;;;;;0FAoBxF,CAAA;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,WAAW,IAAI,UAAU,CAAC,cAAc,GAAG,SAAS,CAAC,CAQpE"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { TimebackClient } from 'timeback/client'
|
|
2
|
+
import { defineComponent, inject, onMounted, provide, shallowRef } from 'vue'
|
|
3
|
+
|
|
4
|
+
import type { InjectionKey, PropType, ShallowRef } from 'vue'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Vue Provider
|
|
8
|
+
*
|
|
9
|
+
* Context-based Timeback client for Vue 3.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Injection key for Timeback client.
|
|
14
|
+
*/
|
|
15
|
+
const TimebackKey: InjectionKey<ShallowRef<TimebackClient | undefined>> = Symbol('timeback')
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Check if we're running in the browser.
|
|
19
|
+
*
|
|
20
|
+
* @returns True if in browser
|
|
21
|
+
*/
|
|
22
|
+
function isBrowser(): boolean {
|
|
23
|
+
return typeof window !== 'undefined'
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Singleton client instance for browser
|
|
27
|
+
let clientInstance: TimebackClient | undefined
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get or create the singleton Timeback client.
|
|
31
|
+
*
|
|
32
|
+
* @returns TimebackClient instance
|
|
33
|
+
*/
|
|
34
|
+
function getOrCreateClient(): TimebackClient {
|
|
35
|
+
if (!clientInstance) {
|
|
36
|
+
clientInstance = new TimebackClient()
|
|
37
|
+
}
|
|
38
|
+
return clientInstance
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* TimebackProvider component.
|
|
43
|
+
*
|
|
44
|
+
* Wraps your app to provide the Timeback client via Vue's provide/inject.
|
|
45
|
+
* Handles SSR gracefully by only initializing the client in the browser.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```vue
|
|
49
|
+
* <script setup>
|
|
50
|
+
* import { TimebackProvider } from 'timeback/vue'
|
|
51
|
+
* </script>
|
|
52
|
+
*
|
|
53
|
+
* <template>
|
|
54
|
+
* <TimebackProvider>
|
|
55
|
+
* <App />
|
|
56
|
+
* </TimebackProvider>
|
|
57
|
+
* </template>
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```vue
|
|
62
|
+
* <!-- With custom client -->
|
|
63
|
+
* <script setup>
|
|
64
|
+
* import { TimebackProvider, createClient } from 'timeback/vue'
|
|
65
|
+
*
|
|
66
|
+
* const client = createClient({ baseURL: 'https://example.com/api/timeback' })
|
|
67
|
+
* </script>
|
|
68
|
+
*
|
|
69
|
+
* <template>
|
|
70
|
+
* <TimebackProvider :client="client">
|
|
71
|
+
* <App />
|
|
72
|
+
* </TimebackProvider>
|
|
73
|
+
* </template>
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export const TimebackProvider = defineComponent({
|
|
77
|
+
name: 'TimebackProvider',
|
|
78
|
+
props: {
|
|
79
|
+
/** Optional Timeback client instance. If not provided, one is created automatically. */
|
|
80
|
+
client: {
|
|
81
|
+
type: Object as PropType<TimebackClient>,
|
|
82
|
+
default: undefined,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
setup(props, { slots }) {
|
|
86
|
+
const clientRef = shallowRef<TimebackClient | undefined>(props.client)
|
|
87
|
+
|
|
88
|
+
// SSR-safe: only create client in browser if not provided
|
|
89
|
+
onMounted(() => {
|
|
90
|
+
if (!clientRef.value && isBrowser()) {
|
|
91
|
+
clientRef.value = getOrCreateClient()
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
provide(TimebackKey, clientRef)
|
|
96
|
+
|
|
97
|
+
return () => (slots.default ? slots.default() : null)
|
|
98
|
+
},
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Composable to access the Timeback client.
|
|
103
|
+
*
|
|
104
|
+
* Returns the client instance or undefined if not yet hydrated.
|
|
105
|
+
* Use this to access all Timeback functionality: auth, user, activities.
|
|
106
|
+
*
|
|
107
|
+
* @returns The Timeback client or undefined
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```vue
|
|
111
|
+
* <script setup>
|
|
112
|
+
* import { useTimeback } from 'timeback/vue'
|
|
113
|
+
*
|
|
114
|
+
* const timeback = useTimeback()
|
|
115
|
+
*
|
|
116
|
+
* function handleSignIn() {
|
|
117
|
+
* timeback.value?.auth.signIn()
|
|
118
|
+
* }
|
|
119
|
+
*
|
|
120
|
+
* async function handleFetchProfile() {
|
|
121
|
+
* const profile = await timeback.value?.user.fetch()
|
|
122
|
+
* }
|
|
123
|
+
*
|
|
124
|
+
* function handleStartActivity() {
|
|
125
|
+
* const activity = timeback.value?.activity.new({
|
|
126
|
+
* id: 'lesson-1',
|
|
127
|
+
* name: 'Intro',
|
|
128
|
+
* courseCode: 'MATH'
|
|
129
|
+
* })
|
|
130
|
+
* activity?.start()
|
|
131
|
+
* }
|
|
132
|
+
* </script>
|
|
133
|
+
*
|
|
134
|
+
* <template>
|
|
135
|
+
* <button @click="handleSignIn">Sign In</button>
|
|
136
|
+
* </template>
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
export function useTimeback(): ShallowRef<TimebackClient | undefined> {
|
|
140
|
+
const clientRef = inject(TimebackKey, undefined)
|
|
141
|
+
if (!clientRef) {
|
|
142
|
+
// Return a standalone ref if not in provider context
|
|
143
|
+
// This allows usage without provider (client won't be auto-created)
|
|
144
|
+
return shallowRef<TimebackClient | undefined>(undefined)
|
|
145
|
+
}
|
|
146
|
+
return clientRef
|
|
147
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client Module
|
|
3
|
+
*
|
|
4
|
+
* Framework-agnostic client exports.
|
|
5
|
+
*/
|
|
6
|
+
export { createClient } from './timeback-client';
|
|
7
|
+
export { TimebackClient } from './timeback-client.class';
|
|
8
|
+
export { createActivity, Activity } from './lib/activity';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAGxD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA"}
|