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
@@ -66,7 +66,7 @@ export declare function svelteKitHandler<TEvent extends SvelteKitRequestEvent>(o
66
66
  * - `toSvelteKitHandler(timeback)`
67
67
  * - `toSvelteKitHandler(timeback.handle)`
68
68
  *
69
- * Also accepts identity-only instances from `createIdentityServer()`.
69
+ * Also accepts identity-only instances from `createTimebackIdentity()`.
70
70
  *
71
71
  * @param input - Timeback instance or handlers (full or identity-only)
72
72
  * @returns Object with HTTP method handlers for SvelteKit
@@ -1 +1 @@
1
- {"version":3,"file":"svelte-kit.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/svelte-kit.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EACX,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EAErB,MAAM,SAAS,CAAA;AA2BhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,SAAS,qBAAqB,EAC1E,OAAO,EAAE,uBAAuB,CAAC,MAAM,CAAC,GACtC,OAAO,CAAC,QAAQ,CAAC,CA8EnB;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAgB7E"}
1
+ {"version":3,"file":"svelte-kit.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/svelte-kit.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EACX,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EAErB,MAAM,SAAS,CAAA;AAMhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,SAAS,qBAAqB,EAC1E,OAAO,EAAE,uBAAuB,CAAC,MAAM,CAAC,GACtC,OAAO,CAAC,QAAQ,CAAC,CAqDnB;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAgB7E"}
@@ -17,6 +17,33 @@ var __toESM = (mod, isNodeMode, target) => {
17
17
  };
18
18
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
19
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
+
20
47
  // src/shared/constants.ts
21
48
  var ROUTES = {
22
49
  ACTIVITY: "/activity",
@@ -30,443 +57,87 @@ var ROUTES = {
30
57
  }
31
58
  };
32
59
 
33
- // ../internal/logger/src/debug.ts
34
- var patterns = null;
35
- var debugAll = false;
36
- var debugEnvSet = false;
37
- function patternToRegex(pattern) {
38
- const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
39
- const regexStr = escaped.replace(/\*/g, ".*");
40
- return new RegExp(`^${regexStr}$`);
41
- }
42
- function parseDebugEnv() {
43
- if (patterns !== null)
44
- return;
45
- patterns = [];
46
- if (typeof process === "undefined" || !process.env?.DEBUG) {
47
- debugEnvSet = false;
48
- return;
49
- }
50
- debugEnvSet = true;
51
- const debugValue = process.env.DEBUG.trim();
52
- if (debugValue === "1" || debugValue === "true" || debugValue === "*") {
53
- debugAll = true;
54
- return;
55
- }
56
- const parts = debugValue.split(",").map((p) => p.trim()).filter(Boolean);
57
- for (const part of parts) {
58
- if (part.startsWith("-")) {
59
- patterns.push({
60
- regex: patternToRegex(part.slice(1)),
61
- exclude: true
62
- });
63
- } else {
64
- patterns.push({
65
- regex: patternToRegex(part),
66
- exclude: false
67
- });
68
- }
69
- }
70
- const hasInclude = patterns.some((p) => !p.exclude);
71
- if (!hasInclude && patterns.length > 0) {
72
- debugAll = true;
73
- }
74
- }
75
- function shouldShowDebug(scope) {
76
- parseDebugEnv();
77
- if (!debugEnvSet) {
78
- return true;
79
- }
80
- if (debugAll) {
81
- if (scope) {
82
- for (const pattern of patterns) {
83
- if (pattern.exclude && pattern.regex.test(scope)) {
84
- return false;
85
- }
86
- }
87
- }
88
- return true;
89
- }
90
- if (!scope) {
91
- return false;
92
- }
93
- for (const pattern of patterns) {
94
- if (pattern.exclude && pattern.regex.test(scope)) {
95
- return false;
96
- }
97
- }
98
- for (const pattern of patterns) {
99
- if (!pattern.exclude && pattern.regex.test(scope)) {
100
- return true;
101
- }
102
- }
103
- return false;
104
- }
105
-
106
- // ../internal/logger/src/env.ts
107
- function isBrowser() {
108
- return typeof globalThis !== "undefined" && "window" in globalThis;
109
- }
110
- function detectEnvironment() {
111
- if (isBrowser()) {
112
- return "browser";
60
+ // src/server/adapters/utils.ts
61
+ function normalizePathname(path) {
62
+ const raw = path.trim();
63
+ if (raw === "") {
64
+ return "/";
113
65
  }
114
- if (typeof process !== "undefined" && process.env) {
115
- if (process.env["NODE_ENV"] === "test" || process.env["BUN_ENV"] === "test") {
116
- return "test";
117
- }
118
- if (false) {}
119
- if (process.env.CI || process.env.GITHUB_ACTIONS || process.env.GITLAB_CI || process.env.CIRCLECI || process.env.JENKINS_URL || process.env.BUILDKITE) {
120
- return "ci";
121
- }
66
+ const queryIndex = raw.indexOf("?");
67
+ if (queryIndex === -1) {
68
+ return raw;
122
69
  }
123
- return "terminal";
124
- }
125
-
126
- // ../internal/logger/src/formatters/terminal.ts
127
- var nodeInspect;
128
- if (!isBrowser()) {
129
- try {
130
- const util = await import("node:util");
131
- nodeInspect = util.inspect;
132
- } catch {}
133
- }
134
- var colors = {
135
- reset: "\x1B[0m",
136
- bold: "\x1B[1m",
137
- dim: "\x1B[2m",
138
- red: "\x1B[31m",
139
- yellow: "\x1B[33m",
140
- blue: "\x1B[34m",
141
- cyan: "\x1B[36m"
142
- };
143
- function getLevelColor(level) {
144
- switch (level) {
145
- case "debug":
146
- return colors.blue;
147
- case "info":
148
- return colors.cyan;
149
- case "warn":
150
- return colors.yellow;
151
- case "error":
152
- return colors.red;
70
+ const pathname = raw.slice(0, queryIndex);
71
+ if (pathname === "") {
72
+ return "/";
153
73
  }
74
+ return pathname;
154
75
  }
155
- function getConsoleMethod(level) {
156
- switch (level) {
157
- case "debug":
158
- return console.debug;
159
- case "info":
160
- return console.info;
161
- case "warn":
162
- return console.warn;
163
- case "error":
164
- return console.error;
76
+ function normalizeBasePath(basePath) {
77
+ let raw = normalizePathname(basePath);
78
+ if (raw !== "" && !raw.startsWith("/")) {
79
+ raw = `/${raw}`;
165
80
  }
166
- }
167
- function formatContext(context) {
168
- if (nodeInspect) {
169
- return nodeInspect(context, {
170
- depth: null,
171
- colors: true,
172
- breakLength: 80,
173
- compact: false
174
- });
81
+ if (raw === "/" || raw === "") {
82
+ return "";
175
83
  }
176
- return JSON.stringify(context, null, 2);
177
- }
178
- var terminalFormatter = (entry) => {
179
- const levelColor = getLevelColor(entry.level);
180
- const consoleMethod = getConsoleMethod(entry.level);
181
- const levelUpper = entry.level.toUpperCase().padEnd(5);
182
- const isoString = entry.timestamp.toISOString().replace(/\.\d{3}Z$/, "");
183
- const timestamp = `${colors.dim}[${isoString}]${colors.reset}`;
184
- const level = `${levelColor}${levelUpper}${colors.reset}`;
185
- const scope = entry.scope ? `${colors.bold}[${entry.scope}]${colors.reset} ` : "";
186
- const prefix = `${timestamp} ${level} ${scope}${entry.message}`;
187
- if (entry.context && Object.keys(entry.context).length > 0) {
188
- consoleMethod(prefix, formatContext(entry.context));
189
- } else {
190
- consoleMethod(prefix);
84
+ if (raw.endsWith("/")) {
85
+ return raw.slice(0, -1);
191
86
  }
192
- };
193
- // ../internal/logger/src/formatters/ci.ts
194
- var LEVEL_PREFIX = {
195
- debug: "[DEBUG]",
196
- info: "[INFO]",
197
- warn: "[WARN]",
198
- error: "[ERROR]"
199
- };
200
- function formatContext2(context) {
201
- return Object.entries(context).map(([key, value]) => `${key}=${formatValue(value)}`).join(" ");
202
- }
203
- function formatValue(value) {
204
- if (typeof value === "string")
205
- return value;
206
- if (typeof value === "number")
207
- return String(value);
208
- if (typeof value === "boolean")
209
- return String(value);
210
- if (value === null)
211
- return "null";
212
- if (value === undefined)
213
- return "undefined";
214
- return JSON.stringify(value);
87
+ return raw;
215
88
  }
216
- var ciFormatter = (entry) => {
217
- const parts = [];
218
- parts.push(entry.timestamp.toISOString());
219
- parts.push(LEVEL_PREFIX[entry.level]);
220
- if (entry.scope) {
221
- parts.push(`[${entry.scope}]`);
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;
222
95
  }
223
- parts.push(entry.message);
224
- if (entry.context && Object.keys(entry.context).length > 0) {
225
- parts.push(formatContext2(entry.context));
226
- }
227
- console.log(parts.join(" "));
228
- };
229
- // ../internal/logger/src/formatters/production.ts
230
- var productionFormatter = (entry) => {
231
- const output = {
232
- timestamp: entry.timestamp.toISOString(),
233
- level: entry.level,
234
- ...entry.scope && { scope: entry.scope },
235
- msg: entry.message
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;
236
115
  };
237
- if (entry.context && Object.keys(entry.context).length > 0) {
238
- Object.assign(output, entry.context);
239
- }
240
- console.log(JSON.stringify(output));
241
- };
242
- // ../internal/logger/src/formatters/browser.ts
243
- var LEVEL_STYLES = {
244
- debug: "color: gray",
245
- info: "color: #0ea5e9",
246
- warn: "color: #f59e0b",
247
- error: "color: #ef4444; font-weight: bold"
248
- };
249
- var LEVEL_METHODS = {
250
- debug: "log",
251
- info: "info",
252
- warn: "warn",
253
- error: "error"
254
- };
255
- var browserFormatter = (entry) => {
256
- const method = LEVEL_METHODS[entry.level];
257
- const style = LEVEL_STYLES[entry.level];
258
- const prefix = entry.scope ? `[${entry.scope}]` : "";
259
- const label = `%c${prefix} ${entry.message}`;
260
- if (entry.context && Object.keys(entry.context).length > 0) {
261
- console[method](label, style, entry.context);
262
- } else {
263
- console[method](label, style);
264
- }
265
- };
266
- // ../internal/logger/src/logger.ts
267
- var LOG_LEVELS = ["debug", "info", "warn", "error"];
268
- function getFormatter(env) {
269
- switch (env) {
270
- case "terminal":
271
- return terminalFormatter;
272
- case "ci":
273
- return ciFormatter;
274
- case "production":
275
- return productionFormatter;
276
- case "browser":
277
- return browserFormatter;
278
- case "test":
279
- return () => {};
280
- }
281
- }
282
- function getDefaultMinLevel() {
283
- if (typeof process !== "undefined" && process.env?.DEBUG) {
284
- return "debug";
285
- }
286
- return "info";
287
- }
288
- function shouldLog(level, minLevel) {
289
- return LOG_LEVELS.indexOf(level) >= LOG_LEVELS.indexOf(minLevel);
290
- }
291
-
292
- class Logger {
293
- scope;
294
- minLevel;
295
- environment;
296
- formatter;
297
- defaultContext;
298
- constructor(options = {}) {
299
- this.scope = options.scope;
300
- this.minLevel = options.minLevel ?? getDefaultMinLevel();
301
- this.defaultContext = options.defaultContext ?? {};
302
- this.environment = options.environment ?? detectEnvironment();
303
- this.formatter = getFormatter(this.environment);
304
- }
305
- child(scope) {
306
- const childScope = this.scope ? `${this.scope}:${scope}` : scope;
307
- return new Logger({
308
- scope: childScope,
309
- minLevel: this.minLevel,
310
- environment: this.environment,
311
- defaultContext: { ...this.defaultContext }
312
- });
313
- }
314
- withContext(context) {
315
- return new Logger({
316
- scope: this.scope,
317
- minLevel: this.minLevel,
318
- environment: this.environment,
319
- defaultContext: { ...this.defaultContext, ...context }
320
- });
321
- }
322
- debug(message, context) {
323
- this.log("debug", message, context);
324
- }
325
- info(message, context) {
326
- this.log("info", message, context);
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);
327
124
  }
328
- warn(message, context) {
329
- this.log("warn", message, context);
330
- }
331
- error(message, context) {
332
- this.log("error", message, context);
333
- }
334
- log(level, message, context) {
335
- if (level === "debug" && !shouldShowDebug(this.scope)) {
336
- return;
337
- }
338
- if (!shouldLog(level, this.minLevel)) {
339
- return;
340
- }
341
- const entry = {
342
- level,
343
- message,
344
- scope: this.scope,
345
- context: context || Object.keys(this.defaultContext).length > 0 ? { ...this.defaultContext, ...context } : undefined,
346
- timestamp: new Date
347
- };
348
- this.formatter(entry);
349
- }
350
- }
351
- function createLogger(options = {}) {
352
- return new Logger(options);
353
- }
354
- // src/server/lib/logger.ts
355
- function isDebug() {
356
- try {
357
- const debug = typeof process === "undefined" ? undefined : process.env.DEBUG;
358
- return debug === "1" || debug === "true";
359
- } catch {
360
- return false;
361
- }
362
- }
363
- function createScopedLogger(scope) {
364
- return createLogger({
365
- scope: `timeback:${scope}`,
366
- minLevel: isDebug() ? "debug" : "warn"
367
- });
368
- }
369
- var ssoLog = createScopedLogger("sso");
370
- var oidcLog = createScopedLogger("oidc");
371
-
372
- // src/server/lib/oidc.ts
373
- var discoveryCache = new Map;
374
- async function fetchDiscoveryDocument(issuer) {
375
- const cached = discoveryCache.get(issuer);
376
- if (cached) {
377
- return cached;
378
- }
379
- const url = `${issuer}/.well-known/openid-configuration`;
380
- const response = await fetch(url);
381
- if (!response.ok) {
382
- oidcLog.error("Discovery fetch failed", { status: response.status });
383
- throw new Error(`Failed to fetch OIDC discovery: ${response.statusText}`);
384
- }
385
- const doc = await response.json();
386
- oidcLog.debug("Fetched OIDC discovery document", {
387
- authEndpoint: doc.authorization_endpoint,
388
- tokenEndpoint: doc.token_endpoint
389
- });
390
- discoveryCache.set(issuer, doc);
391
- return doc;
392
- }
393
- function getIssuer(env) {
394
- switch (env) {
395
- case "production":
396
- return "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_3uhuoRM3R";
397
- case "staging":
398
- return "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_5EUwTP9XD";
399
- case "local":
400
- throw new Error("Local environment is not yet supported for OIDC");
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";
401
134
  }
402
- }
403
- async function buildAuthorizationUrl(params) {
404
- const discovery = await fetchDiscoveryDocument(params.issuer);
405
- const url = new URL(discovery.authorization_endpoint);
406
- url.searchParams.set("response_type", "code");
407
- url.searchParams.set("client_id", params.clientId);
408
- url.searchParams.set("redirect_uri", params.redirectUri);
409
- url.searchParams.set("scope", "openid profile email");
410
- url.searchParams.set("state", params.state);
411
- return url.toString();
412
- }
413
- async function exchangeCodeForTokens(params) {
414
- const discovery = await fetchDiscoveryDocument(params.issuer);
415
- const response = await fetch(discovery.token_endpoint, {
416
- method: "POST",
417
- headers: {
418
- "Content-Type": "application/x-www-form-urlencoded"
419
- },
420
- body: new URLSearchParams({
421
- grant_type: "authorization_code",
422
- client_id: params.clientId,
423
- client_secret: params.clientSecret,
424
- code: params.code,
425
- redirect_uri: params.redirectUri
426
- })
427
- });
428
- if (!response.ok) {
429
- const text = await response.text();
430
- oidcLog.error("Token exchange failed", { status: response.status, body: text });
431
- throw new Error(`Token exchange failed: ${response.status} ${text}`);
135
+ if (method === "POST") {
136
+ if (pathname.endsWith(ROUTES.ACTIVITY))
137
+ return "activity";
432
138
  }
433
- const tokens = await response.json();
434
- oidcLog.debug("Received tokens from IdP", { expiresIn: tokens.expires_in });
435
- return tokens;
436
- }
437
- async function getUserInfo(params) {
438
- const discovery = await fetchDiscoveryDocument(params.issuer);
439
- const response = await fetch(discovery.userinfo_endpoint, {
440
- headers: {
441
- Authorization: `Bearer ${params.accessToken}`
442
- }
443
- });
444
- if (!response.ok) {
445
- throw new Error(`UserInfo request failed: ${response.statusText}`);
446
- }
447
- return response.json();
448
- }
449
- // src/server/lib/utils.ts
450
- function jsonResponse(data, status = 200, headers) {
451
- const responseHeaders = new Headers(headers);
452
- responseHeaders.set("Content-Type", "application/json");
453
- return new Response(JSON.stringify(data), { status, headers: responseHeaders });
139
+ return null;
454
140
  }
455
- function redirectResponse(url, headers) {
456
- const responseHeaders = new Headers(headers);
457
- responseHeaders.set("Location", url);
458
- return new Response(null, { status: 302, headers: responseHeaders });
459
- }
460
- function encodeBase64Url(data) {
461
- const json = JSON.stringify(data);
462
- return btoa(json).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
463
- }
464
- function decodeBase64Url(encoded) {
465
- const padded = encoded.replace(/-/g, "+").replace(/_/g, "/");
466
- const json = atob(padded);
467
- return JSON.parse(json);
468
- }
469
- // src/server/adapters/utils.ts
470
141
  function getHandlers(input) {
471
142
  return "handle" in input ? input.handle : input;
472
143
  }
@@ -488,36 +159,34 @@ function toNativeHandler(input) {
488
159
  const url = new URL(req.url);
489
160
  const path = url.pathname;
490
161
  const method = req.method;
491
- if (method === "GET") {
492
- if (path.endsWith(ROUTES.IDENTITY.SIGNIN)) {
493
- return handle.identity.signIn(req);
494
- }
495
- if (path.endsWith(ROUTES.IDENTITY.CALLBACK) || callbackPath && path.endsWith(callbackPath)) {
496
- return handle.identity.callback(req);
497
- }
498
- if (path.endsWith(ROUTES.IDENTITY.SIGNOUT)) {
499
- return Promise.resolve(handle.identity.signOut());
500
- }
501
- }
502
- if (hasUserHandler(handle)) {
503
- if (method === "GET" && path.endsWith(ROUTES.USER.ME)) {
504
- return handle.user.me(req);
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));
505
176
  }
177
+ return handle.user.me(req);
506
178
  }
507
- if (hasActivityHandler(handle)) {
508
- if (method === "POST" && path.endsWith(ROUTES.ACTIVITY)) {
509
- return handle.activity(req);
179
+ if (route === "activity") {
180
+ if (!hasActivityHandler(handle)) {
181
+ return Promise.resolve(jsonResponse({ error: "Not found" }, 404));
510
182
  }
183
+ return handle.activity(req);
511
184
  }
512
185
  return Promise.resolve(jsonResponse({ error: "Not found" }, 404));
513
186
  };
514
187
  }
515
188
 
516
189
  // src/server/adapters/svelte-kit.ts
517
- function isTimebackPath(pathname, basePath) {
518
- const normalizedBase = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath;
519
- return pathname.startsWith(`${normalizedBase}/`) || pathname === normalizedBase || pathname.endsWith(ROUTES.IDENTITY.SIGNIN) || pathname.endsWith(ROUTES.IDENTITY.CALLBACK) || pathname.endsWith(ROUTES.IDENTITY.SIGNOUT) || pathname.endsWith(ROUTES.ACTIVITY) || pathname.endsWith(ROUTES.USER.ME);
520
- }
521
190
  async function svelteKitHandler(options) {
522
191
  const {
523
192
  timeback,
@@ -534,32 +203,24 @@ async function svelteKitHandler(options) {
534
203
  const handle = getHandlers(timeback);
535
204
  const path = url.pathname;
536
205
  const method = request.method;
537
- if (callbackPath && path === callbackPath && method === "GET") {
538
- return await handle.identity.callback(request);
539
- }
540
- if (!isTimebackPath(path, basePath)) {
206
+ const route = matchTimebackRoute({ pathname: path, method, basePath, callbackPath });
207
+ if (!route)
541
208
  return resolve(event);
542
- }
543
- if (method === "GET") {
544
- if (path.endsWith(ROUTES.IDENTITY.SIGNIN)) {
545
- return await handle.identity.signIn(request);
546
- }
547
- if (path.endsWith(ROUTES.IDENTITY.CALLBACK)) {
548
- return await handle.identity.callback(request);
549
- }
550
- if (path.endsWith(ROUTES.IDENTITY.SIGNOUT)) {
551
- return handle.identity.signOut();
552
- }
553
- }
554
- if (hasUserHandler(handle)) {
555
- if (method === "GET" && path.endsWith(ROUTES.USER.ME)) {
556
- return await handle.user.me(request);
557
- }
558
- }
559
- if (hasActivityHandler(handle)) {
560
- if (method === "POST" && path.endsWith(ROUTES.ACTIVITY)) {
561
- return await handle.activity(request);
562
- }
209
+ if (route === "identity.signOut")
210
+ return handle.identity.signOut();
211
+ if (route === "identity.signIn")
212
+ return await handle.identity.signIn(request);
213
+ if (route === "identity.callback")
214
+ return await handle.identity.callback(request);
215
+ if (route === "user.me") {
216
+ if (!hasUserHandler(handle))
217
+ return resolve(event);
218
+ return await handle.user.me(request);
219
+ }
220
+ if (route === "activity") {
221
+ if (!hasActivityHandler(handle))
222
+ return resolve(event);
223
+ return await handle.activity(request);
563
224
  }
564
225
  return resolve(event);
565
226
  }
@@ -15,7 +15,7 @@ import type { AnyTimebackInput, TanStackStartHandlerOptions, TanStackStartHandle
15
15
  * - `toTanStackStartHandler(timeback)`
16
16
  * - `toTanStackStartHandler(timeback.handle)`
17
17
  *
18
- * Also accepts identity-only instances from `createIdentityServer()`.
18
+ * Also accepts identity-only instances from `createTimebackIdentity()`.
19
19
  *
20
20
  * @param input - Timeback instance or handlers (full or identity-only), or options object
21
21
  * @returns Object with HTTP method handlers for TanStack Start
@@ -1 +1 @@
1
- {"version":3,"file":"tanstack-start.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/tanstack-start.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EACX,gBAAgB,EAEhB,2BAA2B,EAC3B,qBAAqB,EACrB,MAAM,SAAS,CAAA;AAMhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,sBAAsB,CACrC,KAAK,EAAE,gBAAgB,GAAG,2BAA2B,GACnD,qBAAqB,CAkDvB;AAcD;;GAEG;AACH,eAAO,MAAM,oBAAoB,+BAAyB,CAAA"}
1
+ {"version":3,"file":"tanstack-start.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/tanstack-start.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EACX,gBAAgB,EAEhB,2BAA2B,EAC3B,qBAAqB,EACrB,MAAM,SAAS,CAAA;AAMhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,sBAAsB,CACrC,KAAK,EAAE,gBAAgB,GAAG,2BAA2B,GACnD,qBAAqB,CAsCvB;AAcD;;GAEG;AACH,eAAO,MAAM,oBAAoB,+BAAyB,CAAA"}