@timeback/sdk 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.
Files changed (136) hide show
  1. package/README.md +612 -0
  2. package/dist/client/adapters/react/SignInButton.d.ts +60 -0
  3. package/dist/client/adapters/react/SignInButton.d.ts.map +1 -0
  4. package/dist/client/adapters/react/index.d.ts +47 -0
  5. package/dist/client/adapters/react/index.d.ts.map +1 -0
  6. package/dist/client/adapters/react/index.js +478 -0
  7. package/dist/client/adapters/react/provider.d.ts +78 -0
  8. package/dist/client/adapters/react/provider.d.ts.map +1 -0
  9. package/dist/client/adapters/solid/SignInButton.d.ts +52 -0
  10. package/dist/client/adapters/solid/SignInButton.d.ts.map +1 -0
  11. package/dist/client/adapters/solid/SignInButton.tsx +321 -0
  12. package/dist/client/adapters/solid/context.d.ts +73 -0
  13. package/dist/client/adapters/solid/context.d.ts.map +1 -0
  14. package/dist/client/adapters/solid/context.tsx +91 -0
  15. package/dist/client/adapters/solid/index.d.ts +46 -0
  16. package/dist/client/adapters/solid/index.d.ts.map +1 -0
  17. package/dist/client/adapters/solid/index.ts +50 -0
  18. package/dist/client/adapters/svelte/SignInButton.svelte +234 -0
  19. package/dist/client/adapters/svelte/SignInButton.svelte.d.ts +24 -0
  20. package/dist/client/adapters/svelte/index.d.ts +37 -0
  21. package/dist/client/adapters/svelte/index.d.ts.map +1 -0
  22. package/dist/client/adapters/svelte/index.ts +42 -0
  23. package/dist/client/adapters/svelte/stores.d.ts +66 -0
  24. package/dist/client/adapters/svelte/stores.d.ts.map +1 -0
  25. package/dist/client/adapters/svelte/stores.ts +143 -0
  26. package/dist/client/adapters/vue/SignInButton.vue +260 -0
  27. package/dist/client/adapters/vue/SignInButton.vue.d.ts +53 -0
  28. package/dist/client/adapters/vue/index.d.ts +43 -0
  29. package/dist/client/adapters/vue/index.d.ts.map +1 -0
  30. package/dist/client/adapters/vue/index.ts +48 -0
  31. package/dist/client/adapters/vue/provider.d.ts +94 -0
  32. package/dist/client/adapters/vue/provider.d.ts.map +1 -0
  33. package/dist/client/adapters/vue/provider.ts +147 -0
  34. package/dist/client/index.d.ts +9 -0
  35. package/dist/client/index.d.ts.map +1 -0
  36. package/dist/client/lib/activity/activity.class.d.ts +73 -0
  37. package/dist/client/lib/activity/activity.class.d.ts.map +1 -0
  38. package/dist/client/lib/activity/activity.d.ts +16 -0
  39. package/dist/client/lib/activity/activity.d.ts.map +1 -0
  40. package/dist/client/lib/activity/index.d.ts +6 -0
  41. package/dist/client/lib/activity/index.d.ts.map +1 -0
  42. package/dist/client/lib/utils.d.ts +20 -0
  43. package/dist/client/lib/utils.d.ts.map +1 -0
  44. package/dist/client/namespaces/activity.d.ts +41 -0
  45. package/dist/client/namespaces/activity.d.ts.map +1 -0
  46. package/dist/client/namespaces/auth.d.ts +33 -0
  47. package/dist/client/namespaces/auth.d.ts.map +1 -0
  48. package/dist/client/namespaces/index.d.ts +7 -0
  49. package/dist/client/namespaces/index.d.ts.map +1 -0
  50. package/dist/client/namespaces/user.d.ts +29 -0
  51. package/dist/client/namespaces/user.d.ts.map +1 -0
  52. package/dist/client/timeback-client.class.d.ts +37 -0
  53. package/dist/client/timeback-client.class.d.ts.map +1 -0
  54. package/dist/client/timeback-client.d.ts +29 -0
  55. package/dist/client/timeback-client.d.ts.map +1 -0
  56. package/dist/client.d.ts +30 -0
  57. package/dist/client.d.ts.map +1 -0
  58. package/dist/client.js +198 -0
  59. package/dist/config.d.ts +20 -0
  60. package/dist/config.d.ts.map +1 -0
  61. package/dist/config.js +0 -0
  62. package/dist/edge.d.ts +13 -0
  63. package/dist/edge.d.ts.map +1 -0
  64. package/dist/edge.js +1149 -0
  65. package/dist/identity.d.ts +14 -0
  66. package/dist/identity.d.ts.map +1 -0
  67. package/dist/identity.js +1019 -0
  68. package/dist/index.d.ts +48 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.js +84921 -0
  71. package/dist/server/adapters/express.d.ts +66 -0
  72. package/dist/server/adapters/express.d.ts.map +1 -0
  73. package/dist/server/adapters/express.js +67332 -0
  74. package/dist/server/adapters/native.d.ts +47 -0
  75. package/dist/server/adapters/native.d.ts.map +1 -0
  76. package/dist/server/adapters/native.js +190 -0
  77. package/dist/server/adapters/nextjs.d.ts +32 -0
  78. package/dist/server/adapters/nextjs.d.ts.map +1 -0
  79. package/dist/server/adapters/nextjs.js +202 -0
  80. package/dist/server/adapters/nuxt.d.ts +98 -0
  81. package/dist/server/adapters/nuxt.d.ts.map +1 -0
  82. package/dist/server/adapters/nuxt.js +67401 -0
  83. package/dist/server/adapters/solid-start.d.ts +63 -0
  84. package/dist/server/adapters/solid-start.d.ts.map +1 -0
  85. package/dist/server/adapters/solid-start.js +67300 -0
  86. package/dist/server/adapters/svelte-kit.d.ts +84 -0
  87. package/dist/server/adapters/svelte-kit.d.ts.map +1 -0
  88. package/dist/server/adapters/svelte-kit.js +243 -0
  89. package/dist/server/adapters/tanstack-start.d.ts +42 -0
  90. package/dist/server/adapters/tanstack-start.d.ts.map +1 -0
  91. package/dist/server/adapters/tanstack-start.js +67278 -0
  92. package/dist/server/adapters/types.d.ts +294 -0
  93. package/dist/server/adapters/types.d.ts.map +1 -0
  94. package/dist/server/adapters/utils.d.ts +76 -0
  95. package/dist/server/adapters/utils.d.ts.map +1 -0
  96. package/dist/server/handlers/activity.d.ts +28 -0
  97. package/dist/server/handlers/activity.d.ts.map +1 -0
  98. package/dist/server/handlers/identity-full.d.ts +28 -0
  99. package/dist/server/handlers/identity-full.d.ts.map +1 -0
  100. package/dist/server/handlers/identity-only.d.ts +22 -0
  101. package/dist/server/handlers/identity-only.d.ts.map +1 -0
  102. package/dist/server/handlers/index.d.ts +9 -0
  103. package/dist/server/handlers/index.d.ts.map +1 -0
  104. package/dist/server/handlers/user.d.ts +31 -0
  105. package/dist/server/handlers/user.d.ts.map +1 -0
  106. package/dist/server/index.d.ts +9 -0
  107. package/dist/server/index.d.ts.map +1 -0
  108. package/dist/server/lib/build-activity-events.d.ts +39 -0
  109. package/dist/server/lib/build-activity-events.d.ts.map +1 -0
  110. package/dist/server/lib/build-user-profile.d.ts +62 -0
  111. package/dist/server/lib/build-user-profile.d.ts.map +1 -0
  112. package/dist/server/lib/index.d.ts +14 -0
  113. package/dist/server/lib/index.d.ts.map +1 -0
  114. package/dist/server/lib/logger.d.ts +21 -0
  115. package/dist/server/lib/logger.d.ts.map +1 -0
  116. package/dist/server/lib/oidc.d.ts +76 -0
  117. package/dist/server/lib/oidc.d.ts.map +1 -0
  118. package/dist/server/lib/resolve-activity-course.d.ts +22 -0
  119. package/dist/server/lib/resolve-activity-course.d.ts.map +1 -0
  120. package/dist/server/lib/resolve-timeback-id.d.ts +28 -0
  121. package/dist/server/lib/resolve-timeback-id.d.ts.map +1 -0
  122. package/dist/server/lib/resolve-timeback-user.d.ts +42 -0
  123. package/dist/server/lib/resolve-timeback-user.d.ts.map +1 -0
  124. package/dist/server/lib/utils.d.ts +54 -0
  125. package/dist/server/lib/utils.d.ts.map +1 -0
  126. package/dist/server/timeback-identity.d.ts +19 -0
  127. package/dist/server/timeback-identity.d.ts.map +1 -0
  128. package/dist/server/timeback.d.ts +68 -0
  129. package/dist/server/timeback.d.ts.map +1 -0
  130. package/dist/server/types.d.ts +421 -0
  131. package/dist/server/types.d.ts.map +1 -0
  132. package/dist/shared/constants.d.ts +18 -0
  133. package/dist/shared/constants.d.ts.map +1 -0
  134. package/dist/shared/types.d.ts +159 -0
  135. package/dist/shared/types.d.ts.map +1 -0
  136. package/package.json +119 -0
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Native Fetch API Handler
3
+ *
4
+ * Universal handler for any runtime that supports the Web Fetch API:
5
+ * Bun, Deno, Cloudflare Workers, Hono, etc.
6
+ */
7
+ import type { AnyTimebackInput, NativeHandlerOptions } from './types';
8
+ /**
9
+ * Create a native Fetch API handler.
10
+ *
11
+ * Returns a universal `(Request) => Promise<Response>` handler that works
12
+ * with any Fetch API native runtime.
13
+ *
14
+ * Accepts either the full Timeback instance or just the handlers:
15
+ * - `toNativeHandler(timeback)`
16
+ * - `toNativeHandler(timeback.handle)`
17
+ *
18
+ * Also accepts identity-only instances from `createTimebackIdentity()`.
19
+ *
20
+ * @param input - Timeback instance or handlers (full or identity-only)
21
+ * @returns Universal request handler
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * import { createTimeback } from '@timeback/sdk'
26
+ * import { toNativeHandler } from '@timeback/sdk/native'
27
+ *
28
+ * const timeback = await createTimeback({ ... })
29
+ *
30
+ * // Simple usage
31
+ * const handler = toNativeHandler(timeback)
32
+ *
33
+ * // With custom callback path
34
+ * const handler = toNativeHandler({
35
+ * timeback,
36
+ * callbackPath: '/api/auth/sso/callback/timeback',
37
+ * })
38
+ *
39
+ * // Bun
40
+ * Bun.serve({ fetch: handler })
41
+ *
42
+ * // Deno
43
+ * Deno.serve(handler)
44
+ * ```
45
+ */
46
+ export declare function toNativeHandler(input: AnyTimebackInput | NativeHandlerOptions): (req: Request) => Promise<Response>;
47
+ //# sourceMappingURL=native.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/native.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAYrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,eAAe,CAC9B,KAAK,EAAE,gBAAgB,GAAG,oBAAoB,GAC5C,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAwCrC"}
@@ -0,0 +1,190 @@
1
+ import { createRequire } from "node:module";
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
18
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
19
+
20
+ // src/server/lib/utils.ts
21
+ function mapEnvForApi(env) {
22
+ if (env === "local" || env === "staging") {
23
+ return "staging";
24
+ }
25
+ return "production";
26
+ }
27
+ function jsonResponse(data, status = 200, headers) {
28
+ const responseHeaders = new Headers(headers);
29
+ responseHeaders.set("Content-Type", "application/json");
30
+ return new Response(JSON.stringify(data), { status, headers: responseHeaders });
31
+ }
32
+ function redirectResponse(url, headers) {
33
+ const responseHeaders = new Headers(headers);
34
+ responseHeaders.set("Location", url);
35
+ return new Response(null, { status: 302, headers: responseHeaders });
36
+ }
37
+ function encodeBase64Url(data) {
38
+ const json = JSON.stringify(data);
39
+ return btoa(json).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
40
+ }
41
+ function decodeBase64Url(encoded) {
42
+ const padded = encoded.replace(/-/g, "+").replace(/_/g, "/");
43
+ const json = atob(padded);
44
+ return JSON.parse(json);
45
+ }
46
+
47
+ // src/shared/constants.ts
48
+ var ROUTES = {
49
+ ACTIVITY: "/activity",
50
+ IDENTITY: {
51
+ SIGNIN: "/identity/signin",
52
+ SIGNOUT: "/identity/signout",
53
+ CALLBACK: "/identity/callback"
54
+ },
55
+ USER: {
56
+ ME: "/user/me"
57
+ }
58
+ };
59
+
60
+ // src/server/adapters/utils.ts
61
+ function normalizePathname(path) {
62
+ const raw = path.trim();
63
+ if (raw === "") {
64
+ return "/";
65
+ }
66
+ const queryIndex = raw.indexOf("?");
67
+ if (queryIndex === -1) {
68
+ return raw;
69
+ }
70
+ const pathname = raw.slice(0, queryIndex);
71
+ if (pathname === "") {
72
+ return "/";
73
+ }
74
+ return pathname;
75
+ }
76
+ function normalizeBasePath(basePath) {
77
+ let raw = normalizePathname(basePath);
78
+ if (raw !== "" && !raw.startsWith("/")) {
79
+ raw = `/${raw}`;
80
+ }
81
+ if (raw === "/" || raw === "") {
82
+ return "";
83
+ }
84
+ if (raw.endsWith("/")) {
85
+ return raw.slice(0, -1);
86
+ }
87
+ return raw;
88
+ }
89
+ function matchTimebackRoute(params) {
90
+ const method = params.method.toUpperCase();
91
+ const pathname = normalizePathname(params.pathname);
92
+ const callbackPath = params.callbackPath ? normalizePathname(params.callbackPath) : undefined;
93
+ if (callbackPath && pathname === callbackPath) {
94
+ return method === "GET" ? "identity.callback" : null;
95
+ }
96
+ const basePathInput = params.basePath;
97
+ const hasBasePath = basePathInput !== undefined;
98
+ const basePath = hasBasePath ? normalizeBasePath(basePathInput) : undefined;
99
+ const matchesRelative = (relative) => {
100
+ if (method === "GET") {
101
+ if (relative === ROUTES.IDENTITY.SIGNIN)
102
+ return "identity.signIn";
103
+ if (relative === ROUTES.IDENTITY.CALLBACK)
104
+ return "identity.callback";
105
+ if (relative === ROUTES.IDENTITY.SIGNOUT)
106
+ return "identity.signOut";
107
+ if (relative === ROUTES.USER.ME)
108
+ return "user.me";
109
+ }
110
+ if (method === "POST") {
111
+ if (relative === ROUTES.ACTIVITY)
112
+ return "activity";
113
+ }
114
+ return null;
115
+ };
116
+ if (hasBasePath && basePath !== undefined) {
117
+ if (basePath !== "" && pathname === basePath)
118
+ return null;
119
+ if (basePath !== "" && !pathname.startsWith(`${basePath}/`))
120
+ return null;
121
+ const relativeRaw = basePath === "" ? pathname : pathname.slice(basePath.length);
122
+ const relative = relativeRaw.startsWith("/") ? relativeRaw : `/${relativeRaw}`;
123
+ return matchesRelative(relative);
124
+ }
125
+ if (method === "GET") {
126
+ if (pathname.endsWith(ROUTES.IDENTITY.SIGNIN))
127
+ return "identity.signIn";
128
+ if (pathname.endsWith(ROUTES.IDENTITY.CALLBACK))
129
+ return "identity.callback";
130
+ if (pathname.endsWith(ROUTES.IDENTITY.SIGNOUT))
131
+ return "identity.signOut";
132
+ if (pathname.endsWith(ROUTES.USER.ME))
133
+ return "user.me";
134
+ }
135
+ if (method === "POST") {
136
+ if (pathname.endsWith(ROUTES.ACTIVITY))
137
+ return "activity";
138
+ }
139
+ return null;
140
+ }
141
+ function getHandlers(input) {
142
+ return "handle" in input ? input.handle : input;
143
+ }
144
+ function hasActivityHandler(handlers) {
145
+ return "activity" in handlers;
146
+ }
147
+ function hasUserHandler(handlers) {
148
+ return "user" in handlers;
149
+ }
150
+
151
+ // src/server/adapters/native.ts
152
+ function isNativeHandlerOptions(v) {
153
+ return typeof v === "object" && v !== null && "timeback" in v;
154
+ }
155
+ function toNativeHandler(input) {
156
+ const { timeback, callbackPath } = isNativeHandlerOptions(input) ? input : { timeback: input, callbackPath: undefined };
157
+ const handle = getHandlers(timeback);
158
+ return (req) => {
159
+ const url = new URL(req.url);
160
+ const path = url.pathname;
161
+ const method = req.method;
162
+ const route = matchTimebackRoute({
163
+ pathname: path,
164
+ method,
165
+ callbackPath
166
+ });
167
+ if (route === "identity.signIn")
168
+ return handle.identity.signIn(req);
169
+ if (route === "identity.callback")
170
+ return handle.identity.callback(req);
171
+ if (route === "identity.signOut")
172
+ return Promise.resolve(handle.identity.signOut());
173
+ if (route === "user.me") {
174
+ if (!hasUserHandler(handle)) {
175
+ return Promise.resolve(jsonResponse({ error: "Not found" }, 404));
176
+ }
177
+ return handle.user.me(req);
178
+ }
179
+ if (route === "activity") {
180
+ if (!hasActivityHandler(handle)) {
181
+ return Promise.resolve(jsonResponse({ error: "Not found" }, 404));
182
+ }
183
+ return handle.activity(req);
184
+ }
185
+ return Promise.resolve(jsonResponse({ error: "Not found" }, 404));
186
+ };
187
+ }
188
+ export {
189
+ toNativeHandler
190
+ };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Next.js Adapter
3
+ *
4
+ * Adapts Timeback handlers for Next.js App Router.
5
+ */
6
+ import type { AnyTimebackInput, NextjsHandlers } from './types';
7
+ /**
8
+ * Convert Timeback instance to Next.js App Router handlers.
9
+ *
10
+ * Wraps the native handler with the `{ GET, POST, ... }` structure
11
+ * required by Next.js App Router.
12
+ *
13
+ * Accepts either the full Timeback instance or just the handlers:
14
+ * - `toNextjsHandler(timeback)`
15
+ * - `toNextjsHandler(timeback.handle)`
16
+ *
17
+ * Also accepts identity-only instances from `createTimebackIdentity()`.
18
+ *
19
+ * @param input - Timeback instance or handlers (full or identity-only)
20
+ * @returns Object with HTTP method handlers for Next.js App Router
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * // app/api/timeback/[...timeback]/route.ts
25
+ * import { timeback } from '@/lib/timeback'
26
+ * import { toNextjsHandler } from '@timeback/sdk/nextjs'
27
+ *
28
+ * export const { GET, POST } = toNextjsHandler(timeback)
29
+ * ```
30
+ */
31
+ export declare function toNextjsHandler(input: AnyTimebackInput): NextjsHandlers;
32
+ //# sourceMappingURL=nextjs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nextjs.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/nextjs.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE/D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,gBAAgB,GAAG,cAAc,CAUvE"}
@@ -0,0 +1,202 @@
1
+ import { createRequire } from "node:module";
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __toESM = (mod, isNodeMode, target) => {
8
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
9
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
+ for (let key of __getOwnPropNames(mod))
11
+ if (!__hasOwnProp.call(to, key))
12
+ __defProp(to, key, {
13
+ get: () => mod[key],
14
+ enumerable: true
15
+ });
16
+ return to;
17
+ };
18
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
19
+
20
+ // src/server/lib/utils.ts
21
+ function mapEnvForApi(env) {
22
+ if (env === "local" || env === "staging") {
23
+ return "staging";
24
+ }
25
+ return "production";
26
+ }
27
+ function jsonResponse(data, status = 200, headers) {
28
+ const responseHeaders = new Headers(headers);
29
+ responseHeaders.set("Content-Type", "application/json");
30
+ return new Response(JSON.stringify(data), { status, headers: responseHeaders });
31
+ }
32
+ function redirectResponse(url, headers) {
33
+ const responseHeaders = new Headers(headers);
34
+ responseHeaders.set("Location", url);
35
+ return new Response(null, { status: 302, headers: responseHeaders });
36
+ }
37
+ function encodeBase64Url(data) {
38
+ const json = JSON.stringify(data);
39
+ return btoa(json).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
40
+ }
41
+ function decodeBase64Url(encoded) {
42
+ const padded = encoded.replace(/-/g, "+").replace(/_/g, "/");
43
+ const json = atob(padded);
44
+ return JSON.parse(json);
45
+ }
46
+
47
+ // src/shared/constants.ts
48
+ var ROUTES = {
49
+ ACTIVITY: "/activity",
50
+ IDENTITY: {
51
+ SIGNIN: "/identity/signin",
52
+ SIGNOUT: "/identity/signout",
53
+ CALLBACK: "/identity/callback"
54
+ },
55
+ USER: {
56
+ ME: "/user/me"
57
+ }
58
+ };
59
+
60
+ // src/server/adapters/utils.ts
61
+ function normalizePathname(path) {
62
+ const raw = path.trim();
63
+ if (raw === "") {
64
+ return "/";
65
+ }
66
+ const queryIndex = raw.indexOf("?");
67
+ if (queryIndex === -1) {
68
+ return raw;
69
+ }
70
+ const pathname = raw.slice(0, queryIndex);
71
+ if (pathname === "") {
72
+ return "/";
73
+ }
74
+ return pathname;
75
+ }
76
+ function normalizeBasePath(basePath) {
77
+ let raw = normalizePathname(basePath);
78
+ if (raw !== "" && !raw.startsWith("/")) {
79
+ raw = `/${raw}`;
80
+ }
81
+ if (raw === "/" || raw === "") {
82
+ return "";
83
+ }
84
+ if (raw.endsWith("/")) {
85
+ return raw.slice(0, -1);
86
+ }
87
+ return raw;
88
+ }
89
+ function matchTimebackRoute(params) {
90
+ const method = params.method.toUpperCase();
91
+ const pathname = normalizePathname(params.pathname);
92
+ const callbackPath = params.callbackPath ? normalizePathname(params.callbackPath) : undefined;
93
+ if (callbackPath && pathname === callbackPath) {
94
+ return method === "GET" ? "identity.callback" : null;
95
+ }
96
+ const basePathInput = params.basePath;
97
+ const hasBasePath = basePathInput !== undefined;
98
+ const basePath = hasBasePath ? normalizeBasePath(basePathInput) : undefined;
99
+ const matchesRelative = (relative) => {
100
+ if (method === "GET") {
101
+ if (relative === ROUTES.IDENTITY.SIGNIN)
102
+ return "identity.signIn";
103
+ if (relative === ROUTES.IDENTITY.CALLBACK)
104
+ return "identity.callback";
105
+ if (relative === ROUTES.IDENTITY.SIGNOUT)
106
+ return "identity.signOut";
107
+ if (relative === ROUTES.USER.ME)
108
+ return "user.me";
109
+ }
110
+ if (method === "POST") {
111
+ if (relative === ROUTES.ACTIVITY)
112
+ return "activity";
113
+ }
114
+ return null;
115
+ };
116
+ if (hasBasePath && basePath !== undefined) {
117
+ if (basePath !== "" && pathname === basePath)
118
+ return null;
119
+ if (basePath !== "" && !pathname.startsWith(`${basePath}/`))
120
+ return null;
121
+ const relativeRaw = basePath === "" ? pathname : pathname.slice(basePath.length);
122
+ const relative = relativeRaw.startsWith("/") ? relativeRaw : `/${relativeRaw}`;
123
+ return matchesRelative(relative);
124
+ }
125
+ if (method === "GET") {
126
+ if (pathname.endsWith(ROUTES.IDENTITY.SIGNIN))
127
+ return "identity.signIn";
128
+ if (pathname.endsWith(ROUTES.IDENTITY.CALLBACK))
129
+ return "identity.callback";
130
+ if (pathname.endsWith(ROUTES.IDENTITY.SIGNOUT))
131
+ return "identity.signOut";
132
+ if (pathname.endsWith(ROUTES.USER.ME))
133
+ return "user.me";
134
+ }
135
+ if (method === "POST") {
136
+ if (pathname.endsWith(ROUTES.ACTIVITY))
137
+ return "activity";
138
+ }
139
+ return null;
140
+ }
141
+ function getHandlers(input) {
142
+ return "handle" in input ? input.handle : input;
143
+ }
144
+ function hasActivityHandler(handlers) {
145
+ return "activity" in handlers;
146
+ }
147
+ function hasUserHandler(handlers) {
148
+ return "user" in handlers;
149
+ }
150
+
151
+ // src/server/adapters/native.ts
152
+ function isNativeHandlerOptions(v) {
153
+ return typeof v === "object" && v !== null && "timeback" in v;
154
+ }
155
+ function toNativeHandler(input) {
156
+ const { timeback, callbackPath } = isNativeHandlerOptions(input) ? input : { timeback: input, callbackPath: undefined };
157
+ const handle = getHandlers(timeback);
158
+ return (req) => {
159
+ const url = new URL(req.url);
160
+ const path = url.pathname;
161
+ const method = req.method;
162
+ const route = matchTimebackRoute({
163
+ pathname: path,
164
+ method,
165
+ callbackPath
166
+ });
167
+ if (route === "identity.signIn")
168
+ return handle.identity.signIn(req);
169
+ if (route === "identity.callback")
170
+ return handle.identity.callback(req);
171
+ if (route === "identity.signOut")
172
+ return Promise.resolve(handle.identity.signOut());
173
+ if (route === "user.me") {
174
+ if (!hasUserHandler(handle)) {
175
+ return Promise.resolve(jsonResponse({ error: "Not found" }, 404));
176
+ }
177
+ return handle.user.me(req);
178
+ }
179
+ if (route === "activity") {
180
+ if (!hasActivityHandler(handle)) {
181
+ return Promise.resolve(jsonResponse({ error: "Not found" }, 404));
182
+ }
183
+ return handle.activity(req);
184
+ }
185
+ return Promise.resolve(jsonResponse({ error: "Not found" }, 404));
186
+ };
187
+ }
188
+
189
+ // src/server/adapters/nextjs.ts
190
+ function toNextjsHandler(input) {
191
+ const handler = toNativeHandler(input);
192
+ return {
193
+ GET: handler,
194
+ POST: handler,
195
+ PUT: handler,
196
+ DELETE: handler,
197
+ PATCH: handler
198
+ };
199
+ }
200
+ export {
201
+ toNextjsHandler
202
+ };
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Nuxt Adapter
3
+ *
4
+ * Adapts Timeback handlers for Nuxt 3.
5
+ * Supports both middleware-based (recommended) and route-based approaches.
6
+ *
7
+ * This adapter does NOT import h3 or nuxt - it uses minimal interfaces
8
+ * that are compatible with H3's event structure.
9
+ */
10
+ import type { AnyTimebackInput, NuxtHandlerOptions, NuxtHandlers, NuxtLikeEvent } from './types';
11
+ /**
12
+ * Nuxt server middleware handler for Timeback.
13
+ *
14
+ * This is the **recommended** approach for Nuxt 3 integration.
15
+ * It intercepts requests at the middleware level before they reach route handlers.
16
+ *
17
+ * Returns a Response if the request matches a Timeback route, or undefined
18
+ * to let the request continue to other handlers.
19
+ *
20
+ * @param options - Handler options
21
+ * @returns Response from Timeback or undefined to continue
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * // server/middleware/timeback.ts
26
+ * import { timeback } from '~/lib/timeback'
27
+ * import { nuxtHandler } from '@timeback/sdk/nuxt'
28
+ *
29
+ * export default defineEventHandler(async (event) => {
30
+ * const response = await nuxtHandler({
31
+ * timeback,
32
+ * event,
33
+ * })
34
+ *
35
+ * if (response) {
36
+ * return response
37
+ * }
38
+ * })
39
+ * ```
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * // server/middleware/timeback.ts - with custom callback path
44
+ * import { timeback } from '~/lib/timeback'
45
+ * import { nuxtHandler } from '@timeback/sdk/nuxt'
46
+ *
47
+ * export default defineEventHandler(async (event) => {
48
+ * const response = await nuxtHandler({
49
+ * timeback,
50
+ * event,
51
+ * callbackPath: '/api/auth/sso/callback/timeback',
52
+ * })
53
+ *
54
+ * if (response) {
55
+ * return response
56
+ * }
57
+ * })
58
+ * ```
59
+ */
60
+ export declare function nuxtHandler<TEvent extends NuxtLikeEvent>(options: NuxtHandlerOptions<TEvent>): Promise<Response | undefined>;
61
+ /**
62
+ * Convert Timeback instance to Nuxt route handlers.
63
+ *
64
+ * This is an **alternative** approach using Nuxt's catch-all route handlers.
65
+ * Use this if you prefer explicit route files over middleware.
66
+ *
67
+ * Accepts either the full Timeback instance or just the handlers:
68
+ * - `toNuxtHandler(timeback)`
69
+ * - `toNuxtHandler(timeback.handle)`
70
+ *
71
+ * Also accepts identity-only instances from `createTimebackIdentity()`.
72
+ *
73
+ * @param input - Timeback instance or handlers (full or identity-only), or options object
74
+ * @returns Object with HTTP method handlers for Nuxt
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * // server/api/timeback/[...timeback].ts
79
+ * import { timeback } from '~/lib/timeback'
80
+ * import { toNuxtHandler } from '@timeback/sdk/nuxt'
81
+ *
82
+ * const handlers = toNuxtHandler(timeback)
83
+ *
84
+ * export default defineEventHandler(async (event) => {
85
+ * const method = event.request?.method ?? event.node?.req?.method ?? 'GET'
86
+ * const handler = handlers[method as keyof typeof handlers]
87
+ * if (handler) {
88
+ * return handler(event)
89
+ * }
90
+ * return new Response('Method not allowed', { status: 405 })
91
+ * })
92
+ * ```
93
+ */
94
+ export declare function toNuxtHandler(input: AnyTimebackInput | {
95
+ timeback: AnyTimebackInput;
96
+ callbackPath?: string;
97
+ }): NuxtHandlers;
98
+ //# sourceMappingURL=nuxt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nuxt.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/nuxt.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAWH,OAAO,KAAK,EACX,gBAAgB,EAEhB,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,MAAM,SAAS,CAAA;AAuMhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,wBAAsB,WAAW,CAAC,MAAM,SAAS,aAAa,EAC7D,OAAO,EAAE,kBAAkB,CAAC,MAAM,CAAC,GACjC,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CA6B/B;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,aAAa,CAC5B,KAAK,EAAE,gBAAgB,GAAG;IAAE,QAAQ,EAAE,gBAAgB,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7E,YAAY,CAwCd"}