timeback 0.1.2 → 0.1.4
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 +34 -422
- package/dist/cli/src/config.d.ts +8 -0
- package/dist/cli.js +111089 -0
- package/dist/types/src/config.d.ts +106 -0
- package/dist/types/src/index.d.ts +5 -0
- package/dist/types/src/primitives.d.ts +53 -0
- package/package.json +27 -82
- package/schema.json +222 -0
- package/dist/client/adapters/react/SignInButton.d.ts +0 -60
- package/dist/client/adapters/react/SignInButton.d.ts.map +0 -1
- package/dist/client/adapters/react/index.d.ts +0 -43
- package/dist/client/adapters/react/index.d.ts.map +0 -1
- package/dist/client/adapters/react/index.js +0 -478
- package/dist/client/adapters/react/provider.d.ts +0 -74
- package/dist/client/adapters/react/provider.d.ts.map +0 -1
- package/dist/client/adapters/solid/SignInButton.d.ts +0 -52
- package/dist/client/adapters/solid/SignInButton.d.ts.map +0 -1
- package/dist/client/adapters/solid/SignInButton.tsx +0 -321
- package/dist/client/adapters/solid/context.d.ts +0 -73
- package/dist/client/adapters/solid/context.d.ts.map +0 -1
- package/dist/client/adapters/solid/context.tsx +0 -91
- package/dist/client/adapters/solid/index.d.ts +0 -42
- package/dist/client/adapters/solid/index.d.ts.map +0 -1
- package/dist/client/adapters/solid/index.ts +0 -46
- package/dist/client/adapters/svelte/SignInButton.svelte +0 -234
- package/dist/client/adapters/svelte/SignInButton.svelte.d.ts +0 -24
- package/dist/client/adapters/svelte/index.d.ts +0 -33
- package/dist/client/adapters/svelte/index.d.ts.map +0 -1
- package/dist/client/adapters/svelte/index.ts +0 -38
- package/dist/client/adapters/svelte/stores.d.ts +0 -62
- package/dist/client/adapters/svelte/stores.d.ts.map +0 -1
- package/dist/client/adapters/svelte/stores.ts +0 -139
- package/dist/client/adapters/vue/SignInButton.vue +0 -260
- package/dist/client/adapters/vue/SignInButton.vue.d.ts +0 -53
- package/dist/client/adapters/vue/index.d.ts +0 -43
- package/dist/client/adapters/vue/index.d.ts.map +0 -1
- package/dist/client/adapters/vue/index.ts +0 -48
- package/dist/client/adapters/vue/provider.d.ts +0 -94
- package/dist/client/adapters/vue/provider.d.ts.map +0 -1
- package/dist/client/adapters/vue/provider.ts +0 -147
- package/dist/client/index.d.ts +0 -9
- package/dist/client/index.d.ts.map +0 -1
- package/dist/client/lib/activity/activity.class.d.ts +0 -73
- package/dist/client/lib/activity/activity.class.d.ts.map +0 -1
- package/dist/client/lib/activity/activity.d.ts +0 -16
- package/dist/client/lib/activity/activity.d.ts.map +0 -1
- package/dist/client/lib/activity/index.d.ts +0 -6
- package/dist/client/lib/activity/index.d.ts.map +0 -1
- package/dist/client/lib/utils.d.ts +0 -20
- package/dist/client/lib/utils.d.ts.map +0 -1
- package/dist/client/namespaces/activity.d.ts +0 -37
- package/dist/client/namespaces/activity.d.ts.map +0 -1
- package/dist/client/namespaces/auth.d.ts +0 -33
- package/dist/client/namespaces/auth.d.ts.map +0 -1
- package/dist/client/namespaces/index.d.ts +0 -7
- package/dist/client/namespaces/index.d.ts.map +0 -1
- package/dist/client/namespaces/user.d.ts +0 -29
- package/dist/client/namespaces/user.d.ts.map +0 -1
- package/dist/client/timeback-client.class.d.ts +0 -37
- package/dist/client/timeback-client.class.d.ts.map +0 -1
- package/dist/client/timeback-client.d.ts +0 -29
- package/dist/client/timeback-client.d.ts.map +0 -1
- package/dist/client.d.ts +0 -30
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -198
- package/dist/index.d.ts +0 -47
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -1392
- package/dist/server/adapters/express.d.ts +0 -66
- package/dist/server/adapters/express.d.ts.map +0 -1
- package/dist/server/adapters/express.js +0 -581
- package/dist/server/adapters/native.d.ts +0 -47
- package/dist/server/adapters/native.d.ts.map +0 -1
- package/dist/server/adapters/native.js +0 -517
- package/dist/server/adapters/nextjs.d.ts +0 -32
- package/dist/server/adapters/nextjs.d.ts.map +0 -1
- package/dist/server/adapters/nextjs.js +0 -529
- package/dist/server/adapters/nuxt.d.ts +0 -98
- package/dist/server/adapters/nuxt.d.ts.map +0 -1
- package/dist/server/adapters/nuxt.js +0 -673
- package/dist/server/adapters/solid-start.d.ts +0 -63
- package/dist/server/adapters/solid-start.d.ts.map +0 -1
- package/dist/server/adapters/solid-start.js +0 -561
- package/dist/server/adapters/svelte-kit.d.ts +0 -84
- package/dist/server/adapters/svelte-kit.d.ts.map +0 -1
- package/dist/server/adapters/svelte-kit.js +0 -582
- package/dist/server/adapters/tanstack-start.d.ts +0 -42
- package/dist/server/adapters/tanstack-start.d.ts.map +0 -1
- package/dist/server/adapters/tanstack-start.js +0 -530
- package/dist/server/adapters/types.d.ts +0 -294
- package/dist/server/adapters/types.d.ts.map +0 -1
- package/dist/server/adapters/utils.d.ts +0 -34
- package/dist/server/adapters/utils.d.ts.map +0 -1
- package/dist/server/handlers/activity.d.ts +0 -28
- package/dist/server/handlers/activity.d.ts.map +0 -1
- package/dist/server/handlers/identity.d.ts +0 -24
- package/dist/server/handlers/identity.d.ts.map +0 -1
- package/dist/server/handlers/index.d.ts +0 -9
- package/dist/server/handlers/index.d.ts.map +0 -1
- package/dist/server/handlers/user.d.ts +0 -30
- package/dist/server/handlers/user.d.ts.map +0 -1
- package/dist/server/index.d.ts +0 -10
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/lib/index.d.ts +0 -9
- package/dist/server/lib/index.d.ts.map +0 -1
- package/dist/server/lib/logger.d.ts +0 -21
- package/dist/server/lib/logger.d.ts.map +0 -1
- package/dist/server/lib/oidc.d.ts +0 -76
- package/dist/server/lib/oidc.d.ts.map +0 -1
- package/dist/server/lib/utils.d.ts +0 -39
- package/dist/server/lib/utils.d.ts.map +0 -1
- package/dist/server/timeback.d.ts +0 -85
- package/dist/server/timeback.d.ts.map +0 -1
- package/dist/server/types.d.ts +0 -337
- package/dist/server/types.d.ts.map +0 -1
- package/dist/shared/constants.d.ts +0 -18
- package/dist/shared/constants.d.ts.map +0 -1
- package/dist/shared/types.d.ts +0 -100
- package/dist/shared/types.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -1,447 +1,59 @@
|
|
|
1
|
-
#
|
|
1
|
+
# timeback
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## Table of Contents
|
|
6
|
-
|
|
7
|
-
- [Installation](#installation)
|
|
8
|
-
- [Quick Start](#quick-start)
|
|
9
|
-
- [Server Adapters](#server-adapters)
|
|
10
|
-
- [Next.js](#nextjs)
|
|
11
|
-
- [Nuxt](#nuxt)
|
|
12
|
-
- [SvelteKit](#sveltekit)
|
|
13
|
-
- [SolidStart](#solidstart)
|
|
14
|
-
- [TanStack Start](#tanstack-start)
|
|
15
|
-
- [Express](#express)
|
|
16
|
-
- [Client Adapters](#client-adapters)
|
|
17
|
-
- [React](#react)
|
|
18
|
-
- [Vue](#vue)
|
|
19
|
-
- [Svelte](#svelte)
|
|
20
|
-
- [Solid](#solid)
|
|
21
|
-
- [Identity Modes](#identity-modes)
|
|
22
|
-
- [Identity-Only Integration](#identity-only-integration)
|
|
23
|
-
- [Activity Tracking](#activity-tracking)
|
|
3
|
+
CLI for the Timeback platform.
|
|
24
4
|
|
|
25
5
|
## Installation
|
|
26
6
|
|
|
27
7
|
```bash
|
|
28
|
-
|
|
8
|
+
bun add -g timeback
|
|
29
9
|
# or
|
|
30
|
-
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Quick Start
|
|
34
|
-
|
|
35
|
-
1. Create a server instance with your credentials
|
|
36
|
-
2. Mount the route handlers for your framework
|
|
37
|
-
3. Wrap your app with the client provider
|
|
38
|
-
4. Use hooks/composables to track activities
|
|
39
|
-
|
|
40
|
-
## Server Adapters
|
|
41
|
-
|
|
42
|
-
All server adapters use the same core configuration:
|
|
43
|
-
|
|
44
|
-
```typescript
|
|
45
|
-
// lib/timeback.ts
|
|
46
|
-
import { createServer } from 'timeback'
|
|
47
|
-
|
|
48
|
-
export const timeback = await createServer({
|
|
49
|
-
env: 'staging', // 'development' | 'staging' | 'production'
|
|
50
|
-
api: {
|
|
51
|
-
clientId: process.env.TIMEBACK_API_CLIENT_ID!,
|
|
52
|
-
clientSecret: process.env.TIMEBACK_API_CLIENT_SECRET!,
|
|
53
|
-
},
|
|
54
|
-
identity: {
|
|
55
|
-
mode: 'sso',
|
|
56
|
-
clientId: process.env.AWS_COGNITO_CLIENT_ID!,
|
|
57
|
-
clientSecret: process.env.AWS_COGNITO_CLIENT_SECRET!,
|
|
58
|
-
redirectUri: 'http://localhost:3000/api/auth/sso/callback/timeback',
|
|
59
|
-
onCallbackSuccess: ({ user, redirect }) => {
|
|
60
|
-
// Set session, then redirect
|
|
61
|
-
return redirect('/')
|
|
62
|
-
},
|
|
63
|
-
onCallbackError: ({ error, redirect }) => {
|
|
64
|
-
console.error('SSO Error:', error)
|
|
65
|
-
return redirect('/?error=sso_failed')
|
|
66
|
-
},
|
|
67
|
-
getUser: () => getSession(), // Return current user or undefined
|
|
68
|
-
},
|
|
69
|
-
})
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### Next.js
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
// app/api/timeback/[...timeback]/route.ts
|
|
76
|
-
import { toNextjsHandler } from 'timeback/nextjs'
|
|
77
|
-
|
|
78
|
-
import { timeback } from '@/lib/timeback'
|
|
79
|
-
|
|
80
|
-
export const { GET, POST } = toNextjsHandler(timeback)
|
|
10
|
+
bunx timeback
|
|
81
11
|
```
|
|
82
12
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
// server/middleware/timeback.ts
|
|
87
|
-
import { nuxtHandler } from 'timeback/nuxt'
|
|
88
|
-
|
|
89
|
-
import { timeback } from '../lib/timeback'
|
|
90
|
-
|
|
91
|
-
export default defineEventHandler(async event => {
|
|
92
|
-
const response = await nuxtHandler({
|
|
93
|
-
timeback,
|
|
94
|
-
event,
|
|
95
|
-
})
|
|
96
|
-
if (response) return response
|
|
97
|
-
})
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### SvelteKit
|
|
101
|
-
|
|
102
|
-
```typescript
|
|
103
|
-
// src/hooks.server.ts
|
|
104
|
-
import { building } from '$app/environment'
|
|
105
|
-
import { timeback } from '$lib/timeback'
|
|
106
|
-
import { svelteKitHandler } from 'timeback/svelte-kit'
|
|
107
|
-
|
|
108
|
-
import type { Handle } from '@sveltejs/kit'
|
|
109
|
-
|
|
110
|
-
export const handle: Handle = ({ event, resolve }) => {
|
|
111
|
-
return svelteKitHandler({
|
|
112
|
-
timeback,
|
|
113
|
-
event,
|
|
114
|
-
resolve,
|
|
115
|
-
building,
|
|
116
|
-
})
|
|
117
|
-
}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
### SolidStart
|
|
121
|
-
|
|
122
|
-
```typescript
|
|
123
|
-
// src/middleware.ts
|
|
124
|
-
import { createMiddleware } from '@solidjs/start/middleware'
|
|
125
|
-
import { timeback } from '~/lib/timeback'
|
|
126
|
-
import { solidStartHandler } from 'timeback/solid-start'
|
|
127
|
-
|
|
128
|
-
export default createMiddleware({
|
|
129
|
-
onRequest: [
|
|
130
|
-
async event => {
|
|
131
|
-
const response = await solidStartHandler({
|
|
132
|
-
timeback,
|
|
133
|
-
event,
|
|
134
|
-
})
|
|
135
|
-
if (response) return response
|
|
136
|
-
},
|
|
137
|
-
],
|
|
138
|
-
})
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### TanStack Start
|
|
142
|
-
|
|
143
|
-
```typescript
|
|
144
|
-
// src/routes/api/timeback/$.ts
|
|
145
|
-
import { createFileRoute } from '@tanstack/react-router'
|
|
146
|
-
import { toTanStackStartHandler } from 'timeback/tanstack-start'
|
|
147
|
-
|
|
148
|
-
import { timeback } from '@/lib/timeback'
|
|
149
|
-
|
|
150
|
-
const handlers = toTanStackStartHandler(timeback)
|
|
151
|
-
|
|
152
|
-
export const Route = createFileRoute('/api/timeback/$')({
|
|
153
|
-
server: { handlers },
|
|
154
|
-
})
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
### Express
|
|
158
|
-
|
|
159
|
-
```typescript
|
|
160
|
-
// server.ts
|
|
161
|
-
import express from 'express'
|
|
162
|
-
import { toExpressMiddleware } from 'timeback/express'
|
|
163
|
-
|
|
164
|
-
import { timeback } from './lib/timeback'
|
|
165
|
-
|
|
166
|
-
const app = express()
|
|
167
|
-
app.use(express.json())
|
|
168
|
-
app.use('/api/timeback', toExpressMiddleware(timeback))
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
## Client Adapters
|
|
172
|
-
|
|
173
|
-
### React
|
|
174
|
-
|
|
175
|
-
```tsx
|
|
176
|
-
// app/providers.tsx
|
|
177
|
-
'use client'
|
|
178
|
-
|
|
179
|
-
import { TimebackProvider } from 'timeback/react'
|
|
180
|
-
|
|
181
|
-
export function Providers({ children }: { children: React.ReactNode }) {
|
|
182
|
-
return <TimebackProvider>{children}</TimebackProvider>
|
|
183
|
-
}
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
```tsx
|
|
187
|
-
// components/ActivityTracker.tsx
|
|
188
|
-
import { useEffect } from 'react'
|
|
189
|
-
import { SignInButton, useTimeback } from 'timeback/react'
|
|
190
|
-
|
|
191
|
-
function MyComponent() {
|
|
192
|
-
const timeback = useTimeback()
|
|
193
|
-
|
|
194
|
-
useEffect(() => {
|
|
195
|
-
if (!timeback) return
|
|
196
|
-
|
|
197
|
-
const activity = timeback.activity
|
|
198
|
-
.new({ id: 'lesson-1', name: 'Intro', courseCode: 'MATH-101' })
|
|
199
|
-
.start()
|
|
200
|
-
|
|
201
|
-
return () => {
|
|
202
|
-
activity.end()
|
|
203
|
-
}
|
|
204
|
-
}, [timeback])
|
|
205
|
-
|
|
206
|
-
return <SignInButton size="lg" />
|
|
207
|
-
}
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
### Vue
|
|
211
|
-
|
|
212
|
-
```vue
|
|
213
|
-
<!-- app.vue -->
|
|
214
|
-
<script setup>
|
|
215
|
-
import { TimebackProvider } from 'timeback/vue'
|
|
216
|
-
</script>
|
|
13
|
+
## Usage
|
|
217
14
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
</TimebackProvider>
|
|
222
|
-
</template>
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
```vue
|
|
226
|
-
<!-- components/ActivityTracker.vue -->
|
|
227
|
-
<script setup>
|
|
228
|
-
import { SignInButton, useTimeback } from 'timeback/vue'
|
|
229
|
-
import { onMounted, onUnmounted } from 'vue'
|
|
230
|
-
|
|
231
|
-
const timeback = useTimeback()
|
|
232
|
-
let activity
|
|
233
|
-
|
|
234
|
-
onMounted(() => {
|
|
235
|
-
if (timeback.value) {
|
|
236
|
-
activity = timeback.value.activity
|
|
237
|
-
.new({ id: 'lesson-1', name: 'Intro', courseCode: 'MATH-101' })
|
|
238
|
-
.start()
|
|
239
|
-
}
|
|
240
|
-
})
|
|
241
|
-
|
|
242
|
-
onUnmounted(() => activity?.end())
|
|
243
|
-
</script>
|
|
244
|
-
|
|
245
|
-
<template>
|
|
246
|
-
<SignInButton size="lg" />
|
|
247
|
-
</template>
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
### Svelte
|
|
251
|
-
|
|
252
|
-
```svelte
|
|
253
|
-
<!-- +layout.svelte -->
|
|
254
|
-
<script>
|
|
255
|
-
import { initTimeback } from 'timeback/svelte'
|
|
256
|
-
|
|
257
|
-
initTimeback()
|
|
258
|
-
|
|
259
|
-
let { children } = $props()
|
|
260
|
-
</script>
|
|
261
|
-
|
|
262
|
-
{@render children()}
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
```svelte
|
|
266
|
-
<!-- +page.svelte -->
|
|
267
|
-
<script>
|
|
268
|
-
import { onMount, onDestroy } from 'svelte'
|
|
269
|
-
import { SignInButton, timeback } from 'timeback/svelte'
|
|
270
|
-
|
|
271
|
-
let activity
|
|
272
|
-
|
|
273
|
-
onMount(() => {
|
|
274
|
-
if ($timeback) {
|
|
275
|
-
activity = $timeback.activity
|
|
276
|
-
.new({ id: 'lesson-1', name: 'Intro', courseCode: 'MATH-101' })
|
|
277
|
-
.start()
|
|
278
|
-
}
|
|
279
|
-
})
|
|
280
|
-
|
|
281
|
-
onDestroy(() => activity?.end())
|
|
282
|
-
</script>
|
|
283
|
-
|
|
284
|
-
<SignInButton size="lg" />
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
### Solid
|
|
288
|
-
|
|
289
|
-
```tsx
|
|
290
|
-
// app.tsx
|
|
291
|
-
import { TimebackProvider } from 'timeback/solid'
|
|
292
|
-
|
|
293
|
-
export default function App() {
|
|
294
|
-
return (
|
|
295
|
-
<TimebackProvider>
|
|
296
|
-
<Router root={props => <Suspense>{props.children}</Suspense>}>
|
|
297
|
-
<FileRoutes />
|
|
298
|
-
</Router>
|
|
299
|
-
</TimebackProvider>
|
|
300
|
-
)
|
|
301
|
-
}
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
```tsx
|
|
305
|
-
// components/ActivityTracker.tsx
|
|
306
|
-
import { onCleanup, onMount } from 'solid-js'
|
|
307
|
-
import { SignInButton, useTimeback } from 'timeback/solid'
|
|
308
|
-
|
|
309
|
-
function MyComponent() {
|
|
310
|
-
const timeback = useTimeback()
|
|
311
|
-
let activity
|
|
312
|
-
|
|
313
|
-
onMount(() => {
|
|
314
|
-
if (!timeback) return
|
|
315
|
-
|
|
316
|
-
activity = timeback.activity
|
|
317
|
-
.new({ id: 'lesson-1', name: 'Intro', courseCode: 'MATH-101' })
|
|
318
|
-
.start()
|
|
319
|
-
})
|
|
320
|
-
|
|
321
|
-
onCleanup(() => activity?.end())
|
|
322
|
-
|
|
323
|
-
return <SignInButton size="lg" />
|
|
324
|
-
}
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
## Identity Modes
|
|
328
|
-
|
|
329
|
-
### SSO Mode
|
|
330
|
-
|
|
331
|
-
Uses Timeback as the identity provider via OIDC:
|
|
332
|
-
|
|
333
|
-
```typescript
|
|
334
|
-
identity: {
|
|
335
|
-
mode: 'sso',
|
|
336
|
-
clientId: process.env.AWS_COGNITO_CLIENT_ID!,
|
|
337
|
-
clientSecret: process.env.AWS_COGNITO_CLIENT_SECRET!,
|
|
338
|
-
redirectUri: 'http://localhost:3000/api/auth/sso/callback/timeback',
|
|
339
|
-
onCallbackSuccess: ({ user, state, redirect }) => redirect('/'),
|
|
340
|
-
onCallbackError: ({ error, redirect }) => redirect('/?error=sso_failed'),
|
|
341
|
-
getUser: () => getCurrentSession(),
|
|
342
|
-
}
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
### Custom Mode
|
|
346
|
-
|
|
347
|
-
For apps with existing auth (Clerk, Auth0, Supabase, etc.):
|
|
348
|
-
|
|
349
|
-
```typescript
|
|
350
|
-
identity: {
|
|
351
|
-
mode: 'custom',
|
|
352
|
-
getUser: async (req) => {
|
|
353
|
-
const session = await getSession(req)
|
|
354
|
-
if (!session) return undefined
|
|
355
|
-
return { id: session.userId, email: session.email, name: session.name }
|
|
356
|
-
},
|
|
357
|
-
}
|
|
15
|
+
```bash
|
|
16
|
+
timeback <command> [options]
|
|
17
|
+
timeback --help
|
|
358
18
|
```
|
|
359
19
|
|
|
360
|
-
##
|
|
20
|
+
## Commands
|
|
361
21
|
|
|
362
|
-
|
|
22
|
+
### `timeback api`
|
|
363
23
|
|
|
364
|
-
|
|
365
|
-
- Does not require `timeback.config.ts`
|
|
366
|
-
- Only exposes identity routes (sign-in, callback, sign-out)
|
|
24
|
+
Interact with education data APIs.
|
|
367
25
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
// lib/timeback.ts
|
|
372
|
-
import { createIdentityServer } from 'timeback'
|
|
373
|
-
|
|
374
|
-
export const timeback = createIdentityServer({
|
|
375
|
-
env: 'production',
|
|
376
|
-
identity: {
|
|
377
|
-
mode: 'sso',
|
|
378
|
-
clientId: process.env.AWS_COGNITO_CLIENT_ID!,
|
|
379
|
-
clientSecret: process.env.AWS_COGNITO_CLIENT_SECRET!,
|
|
380
|
-
onCallbackSuccess: async ({ user, tokens, redirect }) => {
|
|
381
|
-
// Create your own session, then redirect
|
|
382
|
-
await createSession(user)
|
|
383
|
-
return redirect('/')
|
|
384
|
-
},
|
|
385
|
-
onCallbackError: ({ error, redirect }) => {
|
|
386
|
-
console.error('SSO Error:', error)
|
|
387
|
-
return redirect('/login?error=sso_failed')
|
|
388
|
-
},
|
|
389
|
-
getUser: req => getSessionFromRequest(req),
|
|
390
|
-
},
|
|
391
|
-
})
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
### Next.js
|
|
395
|
-
|
|
396
|
-
```typescript
|
|
397
|
-
// app/api/timeback/[...timeback]/route.ts
|
|
398
|
-
import { toNextjsHandler } from 'timeback/nextjs'
|
|
26
|
+
```bash
|
|
27
|
+
# Discovery
|
|
28
|
+
timeback api describe --service oneroster
|
|
399
29
|
|
|
400
|
-
|
|
30
|
+
# CRUD
|
|
31
|
+
timeback api oneroster schools list --env production
|
|
32
|
+
timeback api oneroster users get <id>
|
|
33
|
+
timeback api oneroster users create --file user.json
|
|
34
|
+
timeback api oneroster users delete <id>
|
|
401
35
|
|
|
402
|
-
|
|
36
|
+
# Filtering
|
|
37
|
+
timeback api oneroster enrollments list --active --classes id1,id2
|
|
38
|
+
timeback api oneroster users list --role teacher --max 100
|
|
403
39
|
```
|
|
404
40
|
|
|
405
|
-
|
|
41
|
+
See `timeback api oneroster --help` for all resources and options.
|
|
406
42
|
|
|
407
|
-
|
|
408
|
-
// server.ts
|
|
409
|
-
import express from 'express'
|
|
410
|
-
import { toExpressMiddleware } from 'timeback/express'
|
|
43
|
+
## Configuration
|
|
411
44
|
|
|
412
|
-
|
|
45
|
+
API clients read credentials from environment variables:
|
|
413
46
|
|
|
414
|
-
|
|
415
|
-
|
|
47
|
+
```bash
|
|
48
|
+
# OneRoster
|
|
49
|
+
export ONEROSTER_BASE_URL="https://api.example.com"
|
|
50
|
+
export ONEROSTER_TOKEN_URL="https://auth.example.com/oauth2/token"
|
|
51
|
+
export ONEROSTER_CLIENT_ID="your-client-id"
|
|
52
|
+
export ONEROSTER_CLIENT_SECRET="your-client-secret"
|
|
416
53
|
```
|
|
417
54
|
|
|
418
|
-
|
|
55
|
+
## Debug Mode
|
|
419
56
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
Activities track time spent on learning content:
|
|
423
|
-
|
|
424
|
-
```typescript
|
|
425
|
-
// Start an activity
|
|
426
|
-
const activity = timeback.activity
|
|
427
|
-
.new({
|
|
428
|
-
id: 'lesson-123',
|
|
429
|
-
name: 'Introduction to Fractions',
|
|
430
|
-
courseCode: 'MATH-101',
|
|
431
|
-
})
|
|
432
|
-
.start()
|
|
433
|
-
|
|
434
|
-
// Pause/resume
|
|
435
|
-
activity.pause()
|
|
436
|
-
activity.resume()
|
|
437
|
-
|
|
438
|
-
// End with metrics
|
|
439
|
-
await activity.end({
|
|
440
|
-
totalQuestions: 10,
|
|
441
|
-
correctQuestions: 8,
|
|
442
|
-
xpEarned: 80,
|
|
443
|
-
masteredUnits: 1,
|
|
444
|
-
})
|
|
57
|
+
```bash
|
|
58
|
+
DEBUG=1 timeback api oneroster schools list
|
|
445
59
|
```
|
|
446
|
-
|
|
447
|
-
The SDK automatically sends activity data to your server, which forwards it to the Timeback API.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config types for timeback.config.ts files.
|
|
3
|
+
*
|
|
4
|
+
* Re-exported from `@timeback/types` so users can import `timeback/config`
|
|
5
|
+
* for editor IntelliSense in TS config files. SDK users can also use
|
|
6
|
+
* `@timeback/sdk/config` which exports the same types.
|
|
7
|
+
*/
|
|
8
|
+
export type { CourseConfig, CourseDefaults, CourseGoals, CourseIds, CourseMetadata, CourseMetrics, CourseType, PublishStatus, TimebackConfig, } from '@timeback/types';
|