timeback 0.1.2 → 0.1.3

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 (74) hide show
  1. package/README.md +152 -15
  2. package/dist/client/adapters/react/index.d.ts +1 -1
  3. package/dist/client/adapters/react/index.d.ts.map +1 -1
  4. package/dist/client/adapters/solid/index.d.ts +1 -1
  5. package/dist/client/adapters/solid/index.d.ts.map +1 -1
  6. package/dist/client/adapters/solid/index.ts +1 -1
  7. package/dist/client/adapters/svelte/index.d.ts +1 -1
  8. package/dist/client/adapters/svelte/index.d.ts.map +1 -1
  9. package/dist/client/adapters/svelte/index.ts +1 -1
  10. package/dist/client/adapters/vue/index.d.ts +1 -1
  11. package/dist/client/adapters/vue/index.d.ts.map +1 -1
  12. package/dist/client/adapters/vue/index.ts +1 -1
  13. package/dist/client.d.ts +1 -1
  14. package/dist/client.d.ts.map +1 -1
  15. package/dist/edge.d.ts +13 -0
  16. package/dist/edge.d.ts.map +1 -0
  17. package/dist/edge.js +1149 -0
  18. package/dist/identity.d.ts +14 -0
  19. package/dist/identity.d.ts.map +1 -0
  20. package/dist/identity.js +1019 -0
  21. package/dist/index.d.ts +8 -7
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +8979 -150
  24. package/dist/server/adapters/express.d.ts +2 -2
  25. package/dist/server/adapters/express.d.ts.map +1 -1
  26. package/dist/server/adapters/express.js +8827 -82
  27. package/dist/server/adapters/native.d.ts +3 -3
  28. package/dist/server/adapters/native.d.ts.map +1 -1
  29. package/dist/server/adapters/native.js +114 -441
  30. package/dist/server/adapters/nextjs.d.ts +1 -1
  31. package/dist/server/adapters/nextjs.js +114 -441
  32. package/dist/server/adapters/nuxt.d.ts +1 -1
  33. package/dist/server/adapters/nuxt.d.ts.map +1 -1
  34. package/dist/server/adapters/nuxt.js +8899 -177
  35. package/dist/server/adapters/solid-start.d.ts +1 -1
  36. package/dist/server/adapters/solid-start.d.ts.map +1 -1
  37. package/dist/server/adapters/solid-start.js +8819 -86
  38. package/dist/server/adapters/svelte-kit.d.ts +1 -1
  39. package/dist/server/adapters/svelte-kit.d.ts.map +1 -1
  40. package/dist/server/adapters/svelte-kit.js +130 -469
  41. package/dist/server/adapters/tanstack-start.d.ts +1 -1
  42. package/dist/server/adapters/tanstack-start.d.ts.map +1 -1
  43. package/dist/server/adapters/tanstack-start.js +8793 -51
  44. package/dist/server/adapters/utils.d.ts +42 -0
  45. package/dist/server/adapters/utils.d.ts.map +1 -1
  46. package/dist/server/handlers/activity.d.ts +1 -1
  47. package/dist/server/handlers/activity.d.ts.map +1 -1
  48. package/dist/server/handlers/identity-full.d.ts +28 -0
  49. package/dist/server/handlers/identity-full.d.ts.map +1 -0
  50. package/dist/server/handlers/identity-only.d.ts +22 -0
  51. package/dist/server/handlers/identity-only.d.ts.map +1 -0
  52. package/dist/server/handlers/index.d.ts +1 -1
  53. package/dist/server/handlers/index.d.ts.map +1 -1
  54. package/dist/server/handlers/user.d.ts +1 -1
  55. package/dist/server/handlers/user.d.ts.map +1 -1
  56. package/dist/server/index.d.ts +3 -4
  57. package/dist/server/index.d.ts.map +1 -1
  58. package/dist/server/lib/index.d.ts +2 -1
  59. package/dist/server/lib/index.d.ts.map +1 -1
  60. package/dist/server/lib/resolve-timeback-user.d.ts +42 -0
  61. package/dist/server/lib/resolve-timeback-user.d.ts.map +1 -0
  62. package/dist/server/lib/utils.d.ts +15 -0
  63. package/dist/server/lib/utils.d.ts.map +1 -1
  64. package/dist/server/timeback-identity.d.ts +19 -0
  65. package/dist/server/timeback-identity.d.ts.map +1 -0
  66. package/dist/server/timeback.d.ts +25 -42
  67. package/dist/server/timeback.d.ts.map +1 -1
  68. package/dist/server/types.d.ts +100 -35
  69. package/dist/server/types.d.ts.map +1 -1
  70. package/dist/shared/types.d.ts +49 -5
  71. package/dist/shared/types.d.ts.map +1 -1
  72. package/package.json +10 -1
  73. package/dist/server/handlers/identity.d.ts +0 -24
  74. package/dist/server/handlers/identity.d.ts.map +0 -1
@@ -9,6 +9,48 @@ import type { AnyTimebackInput } from './types';
9
9
  * Union of handler types returned by getHandlers.
10
10
  */
11
11
  type AnyHandlers = Handlers | IdentityOnlyHandlers;
12
+ /**
13
+ * A canonical route identifier for Timeback's built-in endpoints.
14
+ */
15
+ type TimebackRouteId = 'identity.signIn' | 'identity.callback' | 'identity.signOut' | 'user.me' | 'activity';
16
+ /**
17
+ * Normalize a path-like string to a pathname only (no query string).
18
+ *
19
+ * Some frameworks may provide path-like values that include a query string
20
+ * (e.g. `/api/timeback/identity/signin?returnTo=/`). Route matching should
21
+ * operate on pathnames only.
22
+ *
23
+ * @param path - Path-like string (may include query string)
24
+ * @returns Pathname only (no query string)
25
+ */
26
+ export declare function normalizePathname(path: string): string;
27
+ /**
28
+ * Attempt to map a request to a Timeback built-in route.
29
+ *
30
+ * This consolidates route matching logic so adapters don't each re-implement
31
+ * their own `endsWith(...)` chains.
32
+ *
33
+ * Matching strategy:
34
+ * - If `callbackPath` is provided and equals the request pathname, treat it as
35
+ * the identity callback route (GET only).
36
+ * - If `basePath` is provided, match *exactly* against `basePath + ROUTES.*`
37
+ * by stripping the base path and comparing the relative path.
38
+ * - If `basePath` is not provided, fall back to suffix matching (`endsWith`)
39
+ * to support catch-all mounts where the mount prefix isn't known.
40
+ *
41
+ * @param params - Matching inputs
42
+ * @param params.pathname - Request pathname (may include query string; will be normalized)
43
+ * @param params.method - HTTP method
44
+ * @param params.basePath - Optional base path (recommended when available)
45
+ * @param params.callbackPath - Optional custom callback path
46
+ * @returns A matched route id, or null if not a Timeback route
47
+ */
48
+ export declare function matchTimebackRoute(params: {
49
+ pathname: string;
50
+ method: string;
51
+ basePath?: string;
52
+ callbackPath?: string;
53
+ }): TimebackRouteId | null;
12
54
  /**
13
55
  * Extract handlers from flexible input.
14
56
  *
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C;;GAEG;AACH,KAAK,WAAW,GAAG,QAAQ,GAAG,oBAAoB,CAAA;AAElD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,WAAW,CAEhE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,GAAG,QAAQ,IAAI,QAAQ,CAE9E;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,WAAW,GAAG,QAAQ,IAAI,QAAQ,CAE1E"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C;;GAEG;AACH,KAAK,WAAW,GAAG,QAAQ,GAAG,oBAAoB,CAAA;AAElD;;GAEG;AACH,KAAK,eAAe,GACjB,iBAAiB,GACjB,mBAAmB,GACnB,kBAAkB,GAClB,SAAS,GACT,UAAU,CAAA;AAEb;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAqBtD;AA8BD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IAC1C,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;CACrB,GAAG,eAAe,GAAG,IAAI,CAsDzB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,WAAW,CAEhE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,GAAG,QAAQ,IAAI,QAAQ,CAE9E;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,WAAW,GAAG,QAAQ,IAAI,QAAQ,CAE1E"}
@@ -11,7 +11,7 @@ interface ActivityHandlerConfig {
11
11
  env: Environment;
12
12
  identity: IdentityConfig;
13
13
  appConfig: AppConfig;
14
- apiCredentials: ApiCredentials;
14
+ api: ApiCredentials;
15
15
  }
16
16
  /**
17
17
  * Activity handler type.
@@ -1 +1 @@
1
- {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/activity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAkCtF;;GAEG;AACH,UAAU,qBAAqB;IAC9B,GAAG,EAAE,WAAW,CAAA;IAChB,QAAQ,EAAE,cAAc,CAAA;IACxB,SAAS,EAAE,SAAS,CAAA;IACpB,cAAc,EAAE,cAAc,CAAA;CAC9B;AAED;;GAEG;AACH,KAAK,eAAe,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE1D;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,eAAe,CAuCpF"}
1
+ {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/activity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAkCtF;;GAEG;AACH,UAAU,qBAAqB;IAC9B,GAAG,EAAE,WAAW,CAAA;IAChB,QAAQ,EAAE,cAAc,CAAA;IACxB,SAAS,EAAE,SAAS,CAAA;IACpB,GAAG,EAAE,cAAc,CAAA;CACnB;AAED;;GAEG;AACH,KAAK,eAAe,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE1D;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,eAAe,CAuCpF"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Identity Handlers (full SDK)
3
+ *
4
+ * This module includes Timeback user resolution and therefore depends on Timeback API access.
5
+ */
6
+ import type { TimebackClient } from '@timeback/core';
7
+ import type { ApiCredentials, Environment, IdentityConfig } from '../types';
8
+ type FullIdentityHandlerParams<TState = unknown> = {
9
+ env: Environment;
10
+ identity: IdentityConfig<TState>;
11
+ api: {
12
+ credentials: ApiCredentials;
13
+ getClient: () => TimebackClient;
14
+ };
15
+ };
16
+ /**
17
+ * Create identity route handlers (full SDK).
18
+ *
19
+ * @param params - Handler configuration
20
+ * @returns Identity handlers
21
+ */
22
+ export declare function createIdentityHandlers<TState = unknown>(params: FullIdentityHandlerParams<TState>): {
23
+ signIn: (req: Request) => Promise<Response>;
24
+ callback: (req: Request) => Promise<Response>;
25
+ signOut: () => Response;
26
+ };
27
+ export {};
28
+ //# sourceMappingURL=identity-full.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-full.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/identity-full.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAiBH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,KAAK,EACX,cAAc,EAGd,WAAW,EACX,cAAc,EAEd,MAAM,UAAU,CAAA;AAEjB,KAAK,yBAAyB,CAAC,MAAM,GAAG,OAAO,IAAI;IAClD,GAAG,EAAE,WAAW,CAAA;IAChB,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC,CAAA;IAChC,GAAG,EAAE;QACJ,WAAW,EAAE,cAAc,CAAA;QAC3B,SAAS,EAAE,MAAM,cAAc,CAAA;KAC/B,CAAA;CACD,CAAA;AAwQD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,GAAG,OAAO,EACtD,MAAM,EAAE,yBAAyB,CAAC,MAAM,CAAC,GACvC;IACF,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC3C,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC7C,OAAO,EAAE,MAAM,QAAQ,CAAA;CACvB,CAQA"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Identity Handlers (identity-only)
3
+ *
4
+ * This module is intentionally minimal and does NOT import Timeback API client code.
5
+ * It is safe to include in edge runtimes (e.g. Cloudflare Workers / workerd).
6
+ */
7
+ import type { Environment, IdentityOnlyCallbackSuccessContext, SsoIdentityConfig } from '../types';
8
+ /**
9
+ * Create identity route handlers (identity-only mode).
10
+ *
11
+ * @param params - Handler configuration
12
+ * @returns Identity-only handlers
13
+ */
14
+ export declare function createIdentityOnlyHandlers<TState = unknown>(params: {
15
+ env: Environment;
16
+ identity: SsoIdentityConfig<TState, IdentityOnlyCallbackSuccessContext<TState>>;
17
+ }): {
18
+ signIn: (req: Request) => Promise<Response>;
19
+ callback: (req: Request) => Promise<Response>;
20
+ signOut: () => Response;
21
+ };
22
+ //# sourceMappingURL=identity-only.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-only.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/identity-only.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAEX,WAAW,EACX,kCAAkC,EAClC,iBAAiB,EACjB,MAAM,UAAU,CAAA;AAuPjB;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,EAAE;IACpE,GAAG,EAAE,WAAW,CAAA;IAChB,QAAQ,EAAE,iBAAiB,CAAC,MAAM,EAAE,kCAAkC,CAAC,MAAM,CAAC,CAAC,CAAA;CAC/E;;;;EAYA"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Route handlers for Timeback server operations.
5
5
  */
6
- export { createIdentityHandlers } from './identity';
6
+ export { createIdentityHandlers } from './identity-full';
7
7
  export { createActivityHandler } from './activity';
8
8
  export { createUserHandler } from './user';
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAA"}
@@ -10,7 +10,7 @@ import type { ApiCredentials, Environment, IdentityConfig } from '../types';
10
10
  interface UserHandlerConfig {
11
11
  env: Environment;
12
12
  identity: IdentityConfig;
13
- apiCredentials: ApiCredentials;
13
+ api: ApiCredentials;
14
14
  }
15
15
  /**
16
16
  * User handler type.
@@ -1 +1 @@
1
- {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/user.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAE3E;;GAEG;AACH,UAAU,iBAAiB;IAC1B,GAAG,EAAE,WAAW,CAAA;IAChB,QAAQ,EAAE,cAAc,CAAA;IACxB,cAAc,EAAE,cAAc,CAAA;CAC9B;AAED;;GAEG;AACH,KAAK,WAAW,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAEtD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,WAAW,CA4BxE"}
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/user.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAE3E;;GAEG;AACH,UAAU,iBAAiB;IAC1B,GAAG,EAAE,WAAW,CAAA;IAChB,QAAQ,EAAE,cAAc,CAAA;IACxB,GAAG,EAAE,cAAc,CAAA;CACnB;AAED;;GAEG;AACH,KAAK,WAAW,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAEtD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,WAAW,CA4BxE"}
@@ -3,8 +3,7 @@
3
3
  *
4
4
  * Server-side exports for the Timeback SDK.
5
5
  */
6
- export { createServer, createIdentityServer } from './timeback';
7
- export type { TimebackConfig, TimebackInstance, Environment, ApiCredentials, IdentityConfig, SsoIdentityConfig, CustomIdentityConfig, Handlers, IdentityOnlyConfig, IdentityOnlyInstance, IdentityOnlyHandlers, BuildStateContext, CallbackSuccessContext, CallbackErrorContext, OIDCTokens, OIDCUserInfo, } from './types';
8
- export type { CallbackSuccessContext as IdentityCallbackSuccess } from './types';
9
- export type { CallbackErrorContext as IdentityCallbackError } from './types';
6
+ export { createTimeback } from './timeback';
7
+ export { createTimebackIdentity } from './timeback-identity';
8
+ export type { TimebackConfig, TimebackInstance, Environment, ApiCredentials, IdentityConfig, SsoIdentityConfig, CustomIdentityConfig, Handlers, IdentityOnlyConfig, IdentityOnlyInstance, IdentityOnlyHandlers, BuildStateContext, CallbackSuccessContext, IdentityOnlyCallbackSuccessContext, CallbackErrorContext, OIDCTokens, OIDCUserInfo, IdpData, TimebackUserResolutionErrorCode, } from './types';
10
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAC/D,YAAY,EAEX,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,QAAQ,EAER,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EAEpB,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACpB,UAAU,EACV,YAAY,GACZ,MAAM,SAAS,CAAA;AAEhB,YAAY,EAAE,sBAAsB,IAAI,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAChF,YAAY,EAAE,oBAAoB,IAAI,qBAAqB,EAAE,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAC5D,YAAY,EAEX,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,QAAQ,EAER,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EAEpB,iBAAiB,EACjB,sBAAsB,EACtB,kCAAkC,EAClC,oBAAoB,EACpB,UAAU,EACV,YAAY,EACZ,OAAO,EAEP,+BAA+B,GAC/B,MAAM,SAAS,CAAA"}
@@ -4,6 +4,7 @@
4
4
  * Internal utilities for the server SDK.
5
5
  */
6
6
  export { getIssuer, buildAuthorizationUrl, exchangeCodeForTokens, getUserInfo } from './oidc';
7
- export { jsonResponse, redirectResponse, encodeBase64Url, decodeBase64Url } from './utils';
7
+ export { jsonResponse, redirectResponse, encodeBase64Url, decodeBase64Url, mapEnvForApi, } from './utils';
8
8
  export { ssoLog, oidcLog, createScopedLogger } from './logger';
9
+ export { resolveTimebackUserByEmail, TimebackUserResolutionError } from './resolve-timeback-user';
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/lib/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAC7F,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAC1F,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/lib/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAC7F,OAAO,EACN,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,YAAY,GACZ,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAC9D,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Timeback User Resolution
3
+ *
4
+ * Resolves the Timeback user by email using server credentials.
5
+ */
6
+ import { TimebackClient } from '@timeback/core';
7
+ import type { TimebackAuthUser } from '../../shared/types';
8
+ import type { ApiCredentials, Environment, OIDCUserInfo, TimebackUserResolutionErrorCode } from '../types';
9
+ /**
10
+ * Error thrown when Timeback user resolution fails.
11
+ */
12
+ export declare class TimebackUserResolutionError extends Error {
13
+ readonly code: TimebackUserResolutionErrorCode;
14
+ constructor(message: string, code: TimebackUserResolutionErrorCode);
15
+ }
16
+ interface ResolveTimebackUserByEmailParams {
17
+ /** Environment (staging/production) */
18
+ env: Environment;
19
+ /** API credentials for Timeback API */
20
+ apiCredentials: ApiCredentials;
21
+ /** OIDC user info from the IdP */
22
+ userInfo: OIDCUserInfo;
23
+ /**
24
+ * Optional pre-configured Timeback client to use (e.g. `timeback.api`).
25
+ *
26
+ * When provided, this function will use it and will NOT close it.
27
+ */
28
+ client?: TimebackClient;
29
+ }
30
+ /**
31
+ * Resolve a TimebackAuthUser by looking up the Timeback user via email.
32
+ *
33
+ * Uses server API credentials to query OneRoster for a user matching the IdP email.
34
+ * Strict mode: fails if no user found or if multiple users match (ambiguous).
35
+ *
36
+ * @param params - Resolution parameters
37
+ * @returns Resolved TimebackAuthUser with Timeback profile and IdP claims
38
+ * @throws {TimebackUserResolutionError} If resolution fails
39
+ */
40
+ export declare function resolveTimebackUserByEmail(params: ResolveTimebackUserByEmailParams): Promise<TimebackAuthUser>;
41
+ export {};
42
+ //# sourceMappingURL=resolve-timeback-user.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-timeback-user.d.ts","sourceRoot":"","sources":["../../../src/server/lib/resolve-timeback-user.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAM/C,OAAO,KAAK,EAAkB,gBAAgB,EAAmB,MAAM,oBAAoB,CAAA;AAC3F,OAAO,KAAK,EACX,cAAc,EACd,WAAW,EACX,YAAY,EACZ,+BAA+B,EAC/B,MAAM,UAAU,CAAA;AAIjB;;GAEG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;aAGpC,IAAI,EAAE,+BAA+B;IAFtD,YACC,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,+BAA+B,EAIrD;CACD;AAED,UAAU,gCAAgC;IACzC,uCAAuC;IACvC,GAAG,EAAE,WAAW,CAAA;IAChB,uCAAuC;IACvC,cAAc,EAAE,cAAc,CAAA;IAC9B,kCAAkC;IAClC,QAAQ,EAAE,YAAY,CAAA;IACtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,cAAc,CAAA;CACvB;AAkBD;;;;;;;;;GASG;AACH,wBAAsB,0BAA0B,CAC/C,MAAM,EAAE,gCAAgC,GACtC,OAAO,CAAC,gBAAgB,CAAC,CAiG3B"}
@@ -3,6 +3,21 @@
3
3
  *
4
4
  * Internal utility functions for the server SDK.
5
5
  */
6
+ import type { Environment } from '../types';
7
+ /**
8
+ * Map SDK environment to the environment used for outbound Timeback API calls.
9
+ *
10
+ * The SDK's `env` config controls runtime mode, but for outbound service calls
11
+ * (OneRoster, Caliper, etc.) we need a real Timeback environment:
12
+ *
13
+ * - `local` → `staging` (local dev uses staging services)
14
+ * - `staging` → `staging`
15
+ * - `production` → `production`
16
+ *
17
+ * @param env - SDK environment setting
18
+ * @returns Environment to use for TimebackClient
19
+ */
20
+ export declare function mapEnvForApi(env: Environment): 'staging' | 'production';
6
21
  /**
7
22
  * Create a JSON response.
8
23
  *
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/server/lib/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,SAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,QAAQ,CAItF;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,QAAQ,CAI7E;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAIrD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,CAKrD"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/server/lib/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE3C;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,GAAG,SAAS,GAAG,YAAY,CAMvE;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,SAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,QAAQ,CAItF;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,QAAQ,CAI7E;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAIrD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,CAKrD"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Timeback Server SDK (Identity-only)
3
+ *
4
+ * This file is intentionally Node-free so it can be used in edge runtimes
5
+ * (e.g. Cloudflare Workers / workerd) without pulling in Node-only deps
6
+ * like `jiti`, `fs`, etc.
7
+ */
8
+ import type { IdentityOnlyConfig, IdentityOnlyInstance } from './types';
9
+ /**
10
+ * Create an identity-only Timeback server instance.
11
+ *
12
+ * Use this when you only need SSO authentication without activity tracking
13
+ * or Timeback API integration. Does not require `timeback.config.ts`.
14
+ *
15
+ * @param config - Identity-only configuration
16
+ * @returns Identity-only Timeback server instance
17
+ */
18
+ export declare function createTimebackIdentity<TState = unknown>(config: IdentityOnlyConfig<TState>): IdentityOnlyInstance<TState>;
19
+ //# sourceMappingURL=timeback-identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeback-identity.d.ts","sourceRoot":"","sources":["../../src/server/timeback-identity.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAEvE;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,GAAG,OAAO,EACtD,MAAM,EAAE,kBAAkB,CAAC,MAAM,CAAC,GAChC,oBAAoB,CAAC,MAAM,CAAC,CAY9B"}
@@ -3,83 +3,66 @@
3
3
  *
4
4
  * Factory functions to create Timeback server instances.
5
5
  */
6
- import type { IdentityOnlyConfig, IdentityOnlyInstance, TimebackConfig, TimebackInstance } from './types';
6
+ import type { TimebackConfig, TimebackInstance } from './types';
7
7
  /**
8
8
  * Create a Timeback server instance.
9
9
  *
10
10
  * Returns a framework-agnostic instance with raw handlers.
11
+ *
11
12
  * Use an adapter to integrate with your framework:
12
13
  * - `toNextjsHandler()` for Next.js App Router
13
14
  * - `toHonoApp()` / `toHonoMiddleware()` for Hono
14
15
  * - `toExpressMiddleware()` / `mountExpressRoutes()` for Express
15
16
  *
17
+ * When using SSO mode, the callback receives an enriched `TimebackAuthUser` with
18
+ * `user.id` being the canonical Timeback user ID (timebackId).
19
+ *
16
20
  * @param config - Server configuration
17
21
  * @returns Timeback instance with handlers
18
22
  *
19
- * @example
23
+ * @example SSO mode
20
24
  * ```typescript
21
- * import { createServer } from 'timeback'
25
+ * import { createTimeback } from 'timeback'
22
26
  * import { toNextjsHandler } from 'timeback/nextjs'
23
27
  *
24
- * const timeback = await createServer({
28
+ * const timeback = await createTimeback({
25
29
  * env: 'production',
26
30
  * api: {
27
31
  * clientId: process.env.TIMEBACK_API_CLIENT_ID!,
28
32
  * clientSecret: process.env.TIMEBACK_API_CLIENT_SECRET!,
29
33
  * },
30
34
  * identity: {
31
- * mode: 'custom',
32
- * getUser: async (req) => {
33
- * const session = await getSession(req)
34
- * return {
35
- * id: session.userId,
36
- * email: session.user.email,
37
- * name: session.user.name,
38
- * }
35
+ * mode: 'sso',
36
+ * clientId: process.env.AWS_COGNITO_CLIENT_ID!,
37
+ * clientSecret: process.env.AWS_COGNITO_CLIENT_SECRET!,
38
+ * onCallbackSuccess: async ({ user, state, redirect }) => {
39
+ * // user.id is the timebackId (canonical stable identifier)
40
+ * await setSession({ id: user.id, email: user.email })
41
+ * return redirect(state.returnTo ?? '/')
39
42
  * },
43
+ * onCallbackError: ({ error, redirect }) => redirect('/?error=sso_failed'),
44
+ * getUser: (req) => getSessionUser(req),
40
45
  * },
41
46
  * })
42
47
  *
43
48
  * // For Next.js App Router
44
49
  * export const { GET, POST } = toNextjsHandler(timeback)
45
50
  * ```
46
- */
47
- export declare function createServer(config: TimebackConfig): Promise<TimebackInstance>;
48
- /**
49
- * Create an identity-only Timeback server instance.
50
- *
51
- * Use this when you only need SSO authentication without activity tracking
52
- * or Timeback API integration. Does not require `timeback.config.ts`.
53
- *
54
- * @param config - Identity-only configuration
55
- * @returns Identity-only instance with SSO handlers
56
51
  *
57
- * @example
52
+ * @example Custom identity mode (bring your own auth)
58
53
  * ```typescript
59
- * import { createIdentityServer } from 'timeback'
60
- * import { toNextjsHandler } from 'timeback/nextjs'
61
- *
62
- * const timeback = createIdentityServer({
54
+ * const timeback = await createTimeback({
63
55
  * env: 'production',
56
+ * api: { ... },
64
57
  * identity: {
65
- * mode: 'sso',
66
- * clientId: process.env.AWS_COGNITO_CLIENT_ID!,
67
- * clientSecret: process.env.AWS_COGNITO_CLIENT_SECRET!,
68
- * onCallbackSuccess: ({ user, redirect }) => {
69
- * // Set session, then redirect
70
- * return redirect('/')
71
- * },
72
- * onCallbackError: ({ error, redirect }) => {
73
- * console.error('SSO Error:', error)
74
- * return redirect('/?error=sso_failed')
58
+ * mode: 'custom',
59
+ * getUser: async (req) => {
60
+ * const session = await getSession(req)
61
+ * return session ? { id: session.userId, email: session.email } : undefined
75
62
  * },
76
- * getUser: (req) => getSession(req),
77
63
  * },
78
64
  * })
79
- *
80
- * // For Next.js App Router
81
- * export const { GET, POST } = toNextjsHandler(timeback)
82
65
  * ```
83
66
  */
84
- export declare function createIdentityServer<TState = unknown>(config: IdentityOnlyConfig<TState>): IdentityOnlyInstance<TState>;
67
+ export declare function createTimeback<TState = unknown>(config: TimebackConfig<TState>): Promise<TimebackInstance<TState>>;
85
68
  //# sourceMappingURL=timeback.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"timeback.d.ts","sourceRoot":"","sources":["../../src/server/timeback.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAEX,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,MAAM,SAAS,CAAA;AAEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAwCpF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,GAAG,OAAO,EACpD,MAAM,EAAE,kBAAkB,CAAC,MAAM,CAAC,GAChC,oBAAoB,CAAC,MAAM,CAAC,CAY9B"}
1
+ {"version":3,"file":"timeback.d.ts","sourceRoot":"","sources":["../../src/server/timeback.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AACH,wBAAsB,cAAc,CAAC,MAAM,GAAG,OAAO,EACpD,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,GAC5B,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAgEnC"}
@@ -3,11 +3,16 @@
3
3
  *
4
4
  * Configuration and internal types for the server SDK.
5
5
  */
6
- import type { TimebackUser } from '../shared/types';
6
+ import type { TimebackClient } from '@timeback/core';
7
+ import type { TimebackAuthUser, TimebackIdentity } from '../shared/types';
7
8
  /**
8
9
  * Environment configuration.
9
10
  */
10
11
  export type Environment = 'local' | 'staging' | 'production';
12
+ /**
13
+ * Error codes for Timeback user resolution failures.
14
+ */
15
+ export type TimebackUserResolutionErrorCode = 'missing_email' | 'timeback_user_not_found' | 'timeback_user_ambiguous' | 'timeback_user_lookup_failed';
11
16
  /**
12
17
  * API credentials for Timeback API calls.
13
18
  */
@@ -82,15 +87,48 @@ export interface BuildStateContext {
82
87
  url: URL;
83
88
  }
84
89
  /**
85
- * Context passed to onCallbackSuccess hook.
90
+ * Raw identity provider data (tokens and user info claims).
91
+ */
92
+ export interface IdpData {
93
+ /** OIDC tokens from the identity provider */
94
+ tokens: OIDCTokens;
95
+ /** User info claims from the identity provider */
96
+ userInfo: OIDCUserInfo;
97
+ }
98
+ /**
99
+ * Context passed to onCallbackSuccess hook for full SDK (createTimeback).
100
+ *
101
+ * When using `createTimeback()` with SSO mode, the `user` field contains the
102
+ * enriched `TimebackAuthUser` with `timebackId` as the canonical identifier. Raw IdP
103
+ * data is available under `idp`.
86
104
  */
87
105
  export interface CallbackSuccessContext<TState = unknown> {
106
+ /** Authenticated user with Timeback profile and IdP claims */
107
+ user: TimebackAuthUser;
108
+ /** Raw identity provider data (tokens and user info) */
109
+ idp: IdpData;
110
+ /** State data from buildState (if provided) */
111
+ state: TState | undefined;
112
+ /** The incoming callback request */
113
+ req: Request;
114
+ /** Helper to create a redirect response */
115
+ redirect: (url: string, headers?: HeadersInit) => Response;
116
+ /** Helper to create a JSON response */
117
+ json: <T>(data: T, status?: number, headers?: HeadersInit) => Response;
118
+ }
119
+ /**
120
+ * Context passed to onCallbackSuccess hook for identity-only SDK (createTimebackIdentity).
121
+ *
122
+ * When using `createTimebackIdentity()`, the `user` field contains raw OIDC user info
123
+ * claims (no Timeback profile enrichment).
124
+ */
125
+ export interface IdentityOnlyCallbackSuccessContext<TState = unknown> {
88
126
  /** OIDC tokens from the identity provider */
89
127
  tokens: OIDCTokens;
90
128
  /** User info claims from the identity provider */
91
129
  user: OIDCUserInfo;
92
130
  /** State data from buildState (if provided) */
93
- state: TState;
131
+ state: TState | undefined;
94
132
  /** The incoming callback request */
95
133
  req: Request;
96
134
  /** Helper to create a redirect response */
@@ -116,11 +154,9 @@ export interface CallbackErrorContext<TState = unknown> {
116
154
  json: <T>(data: T, status?: number, headers?: HeadersInit) => Response;
117
155
  }
118
156
  /**
119
- * SSO identity configuration.
120
- *
121
- * Provides full control over the OIDC flow without managing user sessions.
157
+ * Base SSO identity configuration fields (shared between full and identity-only).
122
158
  */
123
- export interface SsoIdentityConfig<TState = unknown> {
159
+ interface BaseSsoIdentityConfig<TState = unknown> {
124
160
  mode: 'sso';
125
161
  /** OIDC client ID */
126
162
  clientId: string;
@@ -163,29 +199,6 @@ export interface SsoIdentityConfig<TState = unknown> {
163
199
  * ```
164
200
  */
165
201
  buildState?: (ctx: BuildStateContext) => TState;
166
- /**
167
- * Called after successful OIDC authentication.
168
- *
169
- * Use this to:
170
- * 1. Upsert the user in your database
171
- * 2. Set your own session cookie
172
- * 3. Redirect to the appropriate page
173
- *
174
- * @param ctx - Context with tokens, user info, state, and helpers
175
- * @returns Response (typically a redirect)
176
- *
177
- * @example
178
- * ```typescript
179
- * onCallbackSuccess: async ({ user, state, redirect }) => {
180
- * await db.user.upsert({ where: { email: user.email }, ... })
181
- * const session = await createSession(user)
182
- * return redirect(state.returnTo ?? '/', {
183
- * 'Set-Cookie': `session=${session.id}; HttpOnly; Path=/`,
184
- * })
185
- * }
186
- * ```
187
- */
188
- onCallbackSuccess: (ctx: CallbackSuccessContext<TState>) => Promise<Response> | Response;
189
202
  /**
190
203
  * Called when OIDC authentication fails.
191
204
  *
@@ -200,7 +213,7 @@ export interface SsoIdentityConfig<TState = unknown> {
200
213
  * }
201
214
  * ```
202
215
  */
203
- onCallbackError?: (ctx: CallbackErrorContext<TState>) => Promise<Response> | Response;
216
+ onCallbackError?(ctx: CallbackErrorContext<TState>): Promise<Response> | Response;
204
217
  /**
205
218
  * Get the current user from the request.
206
219
  *
@@ -223,7 +236,39 @@ export interface SsoIdentityConfig<TState = unknown> {
223
236
  * getUser: (req) => currentUser
224
237
  * ```
225
238
  */
226
- getUser: (req: Request) => Promise<TimebackUser | undefined> | TimebackUser | undefined;
239
+ getUser(req: Request): Promise<TimebackIdentity | undefined> | TimebackIdentity | undefined;
240
+ }
241
+ /**
242
+ * SSO identity configuration for full SDK (createTimeback).
243
+ *
244
+ * When using `createTimeback()`, the SSO callback provides an enriched `TimebackAuthUser`
245
+ * with `timebackId` as the canonical identifier. The SDK resolves the Timeback
246
+ * user by email using server API credentials.
247
+ */
248
+ export interface SsoIdentityConfig<TState = unknown, TSuccessContext = CallbackSuccessContext<TState>> extends BaseSsoIdentityConfig<TState> {
249
+ /**
250
+ * Called after successful OIDC authentication and Timeback user resolution.
251
+ *
252
+ * The `user` field contains the enriched `TimebackAuthUser` with:
253
+ * - `id`: Timeback user ID (canonical stable identifier)
254
+ * - `email`, `name`: User profile data
255
+ * - `claims`: Raw IdP claims (sub, firstName, lastName, pictureUrl)
256
+ *
257
+ * Raw IdP data (tokens, userInfo) is available under `idp`.
258
+ *
259
+ * @param ctx - Context with enriched user, IdP data, state, and helpers
260
+ * @returns Response (typically a redirect)
261
+ *
262
+ * @example
263
+ * ```typescript
264
+ * onCallbackSuccess: async ({ user, state, redirect }) => {
265
+ * // user.id is the timebackId (canonical identifier)
266
+ * await setSession({ id: user.id, email: user.email })
267
+ * return redirect(state.returnTo ?? '/')
268
+ * }
269
+ * ```
270
+ */
271
+ onCallbackSuccess(ctx: TSuccessContext): Promise<Response> | Response;
227
272
  }
228
273
  /**
229
274
  * Custom identity configuration.
@@ -241,7 +286,7 @@ export interface CustomIdentityConfig {
241
286
  * @param req - The incoming request
242
287
  * @returns User object or undefined (sync or async)
243
288
  */
244
- getUser: (req: Request) => Promise<TimebackUser | undefined> | TimebackUser | undefined;
289
+ getUser(req: Request): Promise<TimebackIdentity | undefined> | TimebackIdentity | undefined;
245
290
  }
246
291
  /**
247
292
  * Identity configuration (SSO or custom).
@@ -296,6 +341,25 @@ export interface TimebackInstance<TState = unknown> {
296
341
  config: TimebackConfig<TState>;
297
342
  /** Request handlers */
298
343
  handle: Handlers;
344
+ /**
345
+ * Direct access to the Timeback API client.
346
+ *
347
+ * This is an escape hatch for advanced use cases that need to call Timeback
348
+ * services (OneRoster, Edubridge, Caliper, QTI) beyond what the SDK handlers
349
+ * provide. The client is created lazily on first access.
350
+ *
351
+ * Note: For `env: 'local'`, outbound API calls use `staging` environment.
352
+ *
353
+ * @example
354
+ * ```typescript
355
+ * // List users from OneRoster
356
+ * const { data: users } = await timeback.api.oneroster.users.list({ limit: 10 })
357
+ *
358
+ * // Send a Caliper event
359
+ * await timeback.api.caliper.emit(event)
360
+ * ```
361
+ */
362
+ api: TimebackClient;
299
363
  }
300
364
  /**
301
365
  * Identity-only configuration.
@@ -307,7 +371,7 @@ export interface IdentityOnlyConfig<TState = unknown> {
307
371
  /** Environment */
308
372
  env: Environment;
309
373
  /** Identity configuration (SSO mode required for identity-only) */
310
- identity: SsoIdentityConfig<TState>;
374
+ identity: SsoIdentityConfig<TState, IdentityOnlyCallbackSuccessContext<TState>>;
311
375
  }
312
376
  /**
313
377
  * Identity-only handlers.
@@ -326,7 +390,7 @@ export interface IdentityOnlyHandlers {
326
390
  /**
327
391
  * Identity-only SDK instance.
328
392
  *
329
- * Returned by `createIdentityServer()` for SSO-only integrations.
393
+ * Returned by `createTimebackIdentity()` for SSO-only integrations.
330
394
  */
331
395
  export interface IdentityOnlyInstance<TState = unknown> {
332
396
  /** Configuration */
@@ -334,4 +398,5 @@ export interface IdentityOnlyInstance<TState = unknown> {
334
398
  /** Request handlers (identity only) */
335
399
  handle: IdentityOnlyHandlers;
336
400
  }
401
+ export {};
337
402
  //# sourceMappingURL=types.d.ts.map