@superfunctions/oauth-router 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # @superfunctions/oauth-router
2
+
3
+ Reusable OAuth route factories for browser-auth and connection-management flows.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @superfunctions/oauth-router @superfunctions/oauth-flow @superfunctions/http
9
+ ```
10
+
11
+ Use an HTTP adapter such as `@superfunctions/http-express`, `@superfunctions/http-fastify`, or `@superfunctions/http-hono` in the consuming app.
12
+
13
+ ## Quick Start
14
+
15
+ ```ts
16
+ import { createOAuthBrowserRoutes } from "@superfunctions/oauth-router";
17
+
18
+ const routes = createOAuthBrowserRoutes({
19
+ basePath: "/auth/social",
20
+ flowService,
21
+ async resolveStartInput(request) {
22
+ return (await request.json()) as never;
23
+ },
24
+ });
25
+ ```
26
+
27
+ ## Package Boundary
28
+
29
+ `@superfunctions/oauth-router` owns route factories only:
30
+
31
+ - `createOAuthBrowserRoutes(...)`
32
+ - `createOAuthConnectionRoutes(...)`
33
+ - secure default route metadata
34
+ - per-route `routeMeta` overrides
35
+
36
+ It does not create framework servers, resolve sessions, or persist OAuth state by itself.
37
+
38
+ ## Production Notes
39
+
40
+ - Browser routes default to `start=none`, `callback=none`, `disconnect=hybrid`.
41
+ - Connection routes default to `start=hybrid`, `callback=none`, `disconnect=hybrid`.
42
+ - Override route metadata explicitly when your app requires stronger auth or different OpenAPI annotations.
43
+ - Keep callback routes reachable without session enforcement unless your app handles provider callbacks through another trust boundary.
44
+
45
+ ## Related Packages
46
+
47
+ - OAuth core primitives: [../oauth-core/README.md](../oauth-core/README.md)
48
+ - Flow orchestration: [../oauth-flow/README.md](../oauth-flow/README.md)
49
+ - HTTP primitives: [../oauth-http/README.md](../oauth-http/README.md)
@@ -0,0 +1,22 @@
1
+ import type { HttpRouteMeta, Route, RouteContext } from "@superfunctions/http";
2
+ import type { OAuthFlowCallbackInput, OAuthFlowCallbackResult, OAuthFlowDisconnectInput, OAuthFlowService, OAuthFlowStartInput } from "@superfunctions/oauth-flow";
3
+ export type OAuthBrowserCallbackMode = "redirect" | "json";
4
+ export type OAuthBrowserRouteMetaOverrides = {
5
+ start?: HttpRouteMeta;
6
+ callback?: HttpRouteMeta;
7
+ disconnect?: HttpRouteMeta;
8
+ };
9
+ export interface OAuthBrowserRouteConfig {
10
+ basePath: string;
11
+ flowService: OAuthFlowService;
12
+ resolveStartInput: (request: Request, context: RouteContext) => Promise<OAuthFlowStartInput> | OAuthFlowStartInput;
13
+ resolveDisconnectInput?: (request: Request, context: RouteContext) => Promise<Omit<OAuthFlowDisconnectInput, "providerId" | "requestId">> | Omit<OAuthFlowDisconnectInput, "providerId" | "requestId">;
14
+ resolveCallbackInput?: (request: Request, context: RouteContext) => Promise<Partial<Omit<OAuthFlowCallbackInput, "providerId" | "requestId">>> | Partial<Omit<OAuthFlowCallbackInput, "providerId" | "requestId">>;
15
+ callbackMode?: OAuthBrowserCallbackMode | ((result: OAuthFlowCallbackResult, request: Request, context: RouteContext) => Promise<OAuthBrowserCallbackMode> | OAuthBrowserCallbackMode);
16
+ getRedirectLocation?: (result: OAuthFlowCallbackResult, request: Request, context: RouteContext) => Promise<string> | string;
17
+ serializeCallbackResult?: (result: OAuthFlowCallbackResult, request: Request, context: RouteContext) => Promise<unknown> | unknown;
18
+ routeMeta?: OAuthBrowserRouteMetaOverrides;
19
+ requestIdHeader?: string;
20
+ }
21
+ export declare function createOAuthBrowserRoutes(config: OAuthBrowserRouteConfig): Route[];
22
+ //# sourceMappingURL=browser-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-routes.d.ts","sourceRoot":"","sources":["../src/browser-routes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,aAAa,EAAoB,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAChH,OAAO,KAAK,EACV,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACxB,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,MAAM,wBAAwB,GAAG,UAAU,GAAG,MAAM,CAAC;AAE3D,MAAM,MAAM,8BAA8B,GAAG;IAC3C,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,UAAU,CAAC,EAAE,aAAa,CAAC;CAC5B,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,mBAAmB,CAAC,GAAG,mBAAmB,CAAC;IACnH,sBAAsB,CAAC,EAAE,CACvB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,YAAY,KAClB,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,YAAY,GAAG,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,wBAAwB,EAAE,YAAY,GAAG,WAAW,CAAC,CAAC;IACtI,oBAAoB,CAAC,EAAE,CACrB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,YAAY,KAClB,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC;IACpJ,YAAY,CAAC,EAAE,wBAAwB,GAAG,CAAC,CACzC,MAAM,EAAE,uBAAuB,EAC/B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,YAAY,KAClB,OAAO,CAAC,wBAAwB,CAAC,GAAG,wBAAwB,CAAC,CAAC;IACnE,mBAAmB,CAAC,EAAE,CACpB,MAAM,EAAE,uBAAuB,EAC/B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,YAAY,KAClB,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAC9B,uBAAuB,CAAC,EAAE,CACxB,MAAM,EAAE,uBAAuB,EAC/B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,YAAY,KAClB,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAChC,SAAS,CAAC,EAAE,8BAA8B,CAAC;IAC3C,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,uBAAuB,GAAG,KAAK,EAAE,CAsEjF"}
@@ -0,0 +1,175 @@
1
+ import { BadRequestError } from "@superfunctions/http";
2
+ export function createOAuthBrowserRoutes(config) {
3
+ const requestIdHeader = (config.requestIdHeader ?? "x-request-id").toLowerCase();
4
+ return [
5
+ {
6
+ method: "POST",
7
+ path: joinPath(config.basePath, "start"),
8
+ meta: resolveRouteMeta({ auth: { mode: "none" } }, config.routeMeta?.start),
9
+ handler: async (request, context) => {
10
+ const requestId = request.headers.get(requestIdHeader) ?? undefined;
11
+ const input = await config.resolveStartInput(request, context);
12
+ const result = await config.flowService.start({
13
+ ...input,
14
+ requestId: requestId ?? input.requestId
15
+ });
16
+ return Response.json(result);
17
+ }
18
+ },
19
+ {
20
+ method: "GET",
21
+ path: joinPath(config.basePath, "callback/:provider"),
22
+ meta: resolveRouteMeta({ auth: { mode: "none" } }, config.routeMeta?.callback),
23
+ handler: async (request, context) => {
24
+ const requestId = request.headers.get(requestIdHeader) ?? undefined;
25
+ const resolvedInput = (await config.resolveCallbackInput?.(request, context)) ?? {};
26
+ const url = new URL(request.url);
27
+ const callbackResult = await config.flowService.handleCallback({
28
+ providerId: context.params.provider,
29
+ code: asRequiredString(resolvedInput.code ?? url.searchParams.get("code"), "code"),
30
+ state: asRequiredString(resolvedInput.state ?? url.searchParams.get("state"), "state"),
31
+ redirectUri: asRequiredString(resolvedInput.redirectUri ??
32
+ url.searchParams.get("redirectUri") ??
33
+ inferCallbackRedirectUri(url), "redirectUri"),
34
+ requestId
35
+ });
36
+ const mode = await resolveCallbackMode(config.callbackMode, callbackResult, request, context);
37
+ if (mode === "redirect") {
38
+ const location = await resolveRedirectLocation(config, callbackResult, request, context);
39
+ return Response.redirect(location, 302);
40
+ }
41
+ const payload = config.serializeCallbackResult
42
+ ? await config.serializeCallbackResult(callbackResult, request, context)
43
+ : callbackResult;
44
+ return Response.json(payload);
45
+ }
46
+ },
47
+ {
48
+ method: "POST",
49
+ path: joinPath(config.basePath, "disconnect/:provider"),
50
+ meta: resolveRouteMeta({ auth: { mode: "hybrid" } }, config.routeMeta?.disconnect),
51
+ handler: async (request, context) => {
52
+ const requestId = request.headers.get(requestIdHeader) ?? undefined;
53
+ const input = (await config.resolveDisconnectInput?.(request, context)) ??
54
+ (await parseDisconnectBody(request));
55
+ const result = await config.flowService.disconnect({
56
+ ...input,
57
+ providerId: context.params.provider,
58
+ requestId
59
+ });
60
+ return Response.json(result);
61
+ }
62
+ }
63
+ ];
64
+ }
65
+ function resolveRouteMeta(defaultMeta, overrideMeta) {
66
+ if (!overrideMeta) {
67
+ return defaultMeta;
68
+ }
69
+ return {
70
+ ...defaultMeta,
71
+ ...overrideMeta,
72
+ auth: mergeAuthMeta(defaultMeta.auth, overrideMeta.auth),
73
+ openapi: mergeOpenApiMeta(defaultMeta.openapi, overrideMeta.openapi)
74
+ };
75
+ }
76
+ function mergeAuthMeta(defaultMeta, overrideMeta) {
77
+ if (!defaultMeta) {
78
+ return overrideMeta ? { ...overrideMeta } : undefined;
79
+ }
80
+ if (!overrideMeta) {
81
+ return { ...defaultMeta };
82
+ }
83
+ return {
84
+ ...defaultMeta,
85
+ ...overrideMeta
86
+ };
87
+ }
88
+ function mergeOpenApiMeta(defaultMeta, overrideMeta) {
89
+ if (!defaultMeta) {
90
+ return overrideMeta ? { ...overrideMeta } : undefined;
91
+ }
92
+ if (!overrideMeta) {
93
+ return { ...defaultMeta };
94
+ }
95
+ return {
96
+ ...defaultMeta,
97
+ ...overrideMeta
98
+ };
99
+ }
100
+ function joinPath(basePath, suffix) {
101
+ const normalizedBase = basePath.startsWith("/") ? basePath : `/${basePath}`;
102
+ return `${normalizedBase.replace(/\/$/, "")}/${suffix.replace(/^\//, "")}`;
103
+ }
104
+ function asRequiredString(value, field) {
105
+ if (typeof value !== "string" || value.length === 0) {
106
+ throw new BadRequestError(`${field} is required`, "OAUTH_ROUTE_INVALID_INPUT");
107
+ }
108
+ return value;
109
+ }
110
+ async function resolveCallbackMode(mode, result, request, context) {
111
+ if (!mode) {
112
+ return "json";
113
+ }
114
+ if (typeof mode === "function") {
115
+ return mode(result, request, context);
116
+ }
117
+ return mode;
118
+ }
119
+ async function resolveRedirectLocation(config, result, request, context) {
120
+ if (config.getRedirectLocation) {
121
+ return config.getRedirectLocation(result, request, context);
122
+ }
123
+ if (result.subject.kind === "browser-auth" && result.subject.returnTo) {
124
+ return result.subject.returnTo;
125
+ }
126
+ return new URL("/", request.url).toString();
127
+ }
128
+ async function parseDisconnectBody(request) {
129
+ const body = asJsonObject(await parseJsonBody(request), "disconnect body");
130
+ return {
131
+ connectionId: asRequiredString(body.connectionId, "connectionId"),
132
+ revokeRemote: asOptionalBoolean(body.revokeRemote, "revokeRemote"),
133
+ tokenTypeHint: asTokenTypeHint(body.tokenTypeHint)
134
+ };
135
+ }
136
+ async function parseJsonBody(request) {
137
+ try {
138
+ return await request.json();
139
+ }
140
+ catch {
141
+ throw new BadRequestError("disconnect body must be valid JSON", "OAUTH_ROUTE_INVALID_INPUT");
142
+ }
143
+ }
144
+ function inferCallbackRedirectUri(url) {
145
+ const redirectUrl = new URL(url.toString());
146
+ for (const transientParam of ["code", "state", "redirectUri", "error", "error_description", "error_uri"]) {
147
+ redirectUrl.searchParams.delete(transientParam);
148
+ }
149
+ return redirectUrl.toString();
150
+ }
151
+ function asJsonObject(value, field) {
152
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
153
+ throw new BadRequestError(`${field} must be a JSON object`, "OAUTH_ROUTE_INVALID_INPUT");
154
+ }
155
+ return value;
156
+ }
157
+ function asOptionalBoolean(value, field) {
158
+ if (value === undefined) {
159
+ return undefined;
160
+ }
161
+ if (typeof value !== "boolean") {
162
+ throw new BadRequestError(`${field} must be a boolean`, "OAUTH_ROUTE_INVALID_INPUT");
163
+ }
164
+ return value;
165
+ }
166
+ function asTokenTypeHint(value) {
167
+ if (value === undefined) {
168
+ return undefined;
169
+ }
170
+ if (value === "access_token" || value === "refresh_token") {
171
+ return value;
172
+ }
173
+ throw new BadRequestError("tokenTypeHint must be access_token or refresh_token", "OAUTH_ROUTE_INVALID_INPUT");
174
+ }
175
+ //# sourceMappingURL=browser-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-routes.js","sourceRoot":"","sources":["../src/browser-routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { HttpRouteMeta, Route, RouteContext } from "@superfunctions/http";
2
+ import type { OAuthFlowCallbackInput, OAuthFlowCallbackResult, OAuthFlowDisconnectInput, OAuthFlowService, OAuthFlowStartInput } from "@superfunctions/oauth-flow";
3
+ export type OAuthConnectionRouteMetaOverrides = {
4
+ start?: HttpRouteMeta;
5
+ callback?: HttpRouteMeta;
6
+ disconnect?: HttpRouteMeta;
7
+ };
8
+ export interface OAuthConnectionRouteConfig {
9
+ basePath: string;
10
+ flowService: OAuthFlowService;
11
+ resolveStartInput: (request: Request, context: RouteContext) => Promise<OAuthFlowStartInput> | OAuthFlowStartInput;
12
+ resolveDisconnectInput?: (request: Request, context: RouteContext) => Promise<Omit<OAuthFlowDisconnectInput, "providerId" | "requestId">> | Omit<OAuthFlowDisconnectInput, "providerId" | "requestId">;
13
+ resolveCallbackInput?: (request: Request, context: RouteContext) => Promise<Partial<Omit<OAuthFlowCallbackInput, "providerId" | "requestId">>> | Partial<Omit<OAuthFlowCallbackInput, "providerId" | "requestId">>;
14
+ serializeCallbackResult?: (result: OAuthFlowCallbackResult, request: Request, context: RouteContext) => Promise<unknown> | unknown;
15
+ routeMeta?: OAuthConnectionRouteMetaOverrides;
16
+ requestIdHeader?: string;
17
+ }
18
+ export declare function createOAuthConnectionRoutes(config: OAuthConnectionRouteConfig): Route[];
19
+ //# sourceMappingURL=connection-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-routes.d.ts","sourceRoot":"","sources":["../src/connection-routes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,aAAa,EAAoB,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAChH,OAAO,KAAK,EACV,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACxB,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,MAAM,iCAAiC,GAAG;IAC9C,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,UAAU,CAAC,EAAE,aAAa,CAAC;CAC5B,CAAC;AAEF,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,mBAAmB,CAAC,GAAG,mBAAmB,CAAC;IACnH,sBAAsB,CAAC,EAAE,CACvB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,YAAY,KAClB,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,YAAY,GAAG,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,wBAAwB,EAAE,YAAY,GAAG,WAAW,CAAC,CAAC;IACtI,oBAAoB,CAAC,EAAE,CACrB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,YAAY,KAClB,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC;IACpJ,uBAAuB,CAAC,EAAE,CACxB,MAAM,EAAE,uBAAuB,EAC/B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,YAAY,KAClB,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAChC,SAAS,CAAC,EAAE,iCAAiC,CAAC;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,0BAA0B,GAAG,KAAK,EAAE,CAgEvF"}
@@ -0,0 +1,152 @@
1
+ import { BadRequestError } from "@superfunctions/http";
2
+ export function createOAuthConnectionRoutes(config) {
3
+ const requestIdHeader = (config.requestIdHeader ?? "x-request-id").toLowerCase();
4
+ return [
5
+ {
6
+ method: "POST",
7
+ path: joinPath(config.basePath, "start"),
8
+ meta: resolveRouteMeta({ auth: { mode: "hybrid" } }, config.routeMeta?.start),
9
+ handler: async (request, context) => {
10
+ const requestId = request.headers.get(requestIdHeader) ?? undefined;
11
+ const input = await config.resolveStartInput(request, context);
12
+ const result = await config.flowService.start({
13
+ ...input,
14
+ requestId: requestId ?? input.requestId
15
+ });
16
+ return Response.json(result);
17
+ }
18
+ },
19
+ {
20
+ method: "GET",
21
+ path: joinPath(config.basePath, "callback/:provider"),
22
+ meta: resolveRouteMeta({ auth: { mode: "none" } }, config.routeMeta?.callback),
23
+ handler: async (request, context) => {
24
+ const requestId = request.headers.get(requestIdHeader) ?? undefined;
25
+ const resolvedInput = (await config.resolveCallbackInput?.(request, context)) ?? {};
26
+ const url = new URL(request.url);
27
+ const callbackResult = await config.flowService.handleCallback({
28
+ providerId: context.params.provider,
29
+ code: asRequiredString(resolvedInput.code ?? url.searchParams.get("code"), "code"),
30
+ state: asRequiredString(resolvedInput.state ?? url.searchParams.get("state"), "state"),
31
+ redirectUri: asRequiredString(resolvedInput.redirectUri ??
32
+ url.searchParams.get("redirectUri") ??
33
+ inferCallbackRedirectUri(url), "redirectUri"),
34
+ requestId
35
+ });
36
+ const payload = config.serializeCallbackResult
37
+ ? await config.serializeCallbackResult(callbackResult, request, context)
38
+ : callbackResult;
39
+ return Response.json(payload);
40
+ }
41
+ },
42
+ {
43
+ method: "POST",
44
+ path: joinPath(config.basePath, "disconnect/:provider"),
45
+ meta: resolveRouteMeta({ auth: { mode: "hybrid" } }, config.routeMeta?.disconnect),
46
+ handler: async (request, context) => {
47
+ const requestId = request.headers.get(requestIdHeader) ?? undefined;
48
+ const input = (await config.resolveDisconnectInput?.(request, context)) ??
49
+ (await parseDisconnectBody(request));
50
+ const result = await config.flowService.disconnect({
51
+ ...input,
52
+ providerId: context.params.provider,
53
+ requestId
54
+ });
55
+ return Response.json(result);
56
+ }
57
+ }
58
+ ];
59
+ }
60
+ function resolveRouteMeta(defaultMeta, overrideMeta) {
61
+ if (!overrideMeta) {
62
+ return defaultMeta;
63
+ }
64
+ return {
65
+ ...defaultMeta,
66
+ ...overrideMeta,
67
+ auth: mergeAuthMeta(defaultMeta.auth, overrideMeta.auth),
68
+ openapi: mergeOpenApiMeta(defaultMeta.openapi, overrideMeta.openapi)
69
+ };
70
+ }
71
+ function mergeAuthMeta(defaultMeta, overrideMeta) {
72
+ if (!defaultMeta) {
73
+ return overrideMeta ? { ...overrideMeta } : undefined;
74
+ }
75
+ if (!overrideMeta) {
76
+ return { ...defaultMeta };
77
+ }
78
+ return {
79
+ ...defaultMeta,
80
+ ...overrideMeta
81
+ };
82
+ }
83
+ function mergeOpenApiMeta(defaultMeta, overrideMeta) {
84
+ if (!defaultMeta) {
85
+ return overrideMeta ? { ...overrideMeta } : undefined;
86
+ }
87
+ if (!overrideMeta) {
88
+ return { ...defaultMeta };
89
+ }
90
+ return {
91
+ ...defaultMeta,
92
+ ...overrideMeta
93
+ };
94
+ }
95
+ function joinPath(basePath, suffix) {
96
+ const normalizedBase = basePath.startsWith("/") ? basePath : `/${basePath}`;
97
+ return `${normalizedBase.replace(/\/$/, "")}/${suffix.replace(/^\//, "")}`;
98
+ }
99
+ function asRequiredString(value, field) {
100
+ if (typeof value !== "string" || value.length === 0) {
101
+ throw new BadRequestError(`${field} is required`, "OAUTH_ROUTE_INVALID_INPUT");
102
+ }
103
+ return value;
104
+ }
105
+ async function parseDisconnectBody(request) {
106
+ const body = asJsonObject(await parseJsonBody(request), "disconnect body");
107
+ return {
108
+ connectionId: asRequiredString(body.connectionId, "connectionId"),
109
+ revokeRemote: asOptionalBoolean(body.revokeRemote, "revokeRemote"),
110
+ tokenTypeHint: asTokenTypeHint(body.tokenTypeHint)
111
+ };
112
+ }
113
+ async function parseJsonBody(request) {
114
+ try {
115
+ return await request.json();
116
+ }
117
+ catch {
118
+ throw new BadRequestError("disconnect body must be valid JSON", "OAUTH_ROUTE_INVALID_INPUT");
119
+ }
120
+ }
121
+ function inferCallbackRedirectUri(url) {
122
+ const redirectUrl = new URL(url.toString());
123
+ for (const transientParam of ["code", "state", "redirectUri", "error", "error_description", "error_uri"]) {
124
+ redirectUrl.searchParams.delete(transientParam);
125
+ }
126
+ return redirectUrl.toString();
127
+ }
128
+ function asJsonObject(value, field) {
129
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
130
+ throw new BadRequestError(`${field} must be a JSON object`, "OAUTH_ROUTE_INVALID_INPUT");
131
+ }
132
+ return value;
133
+ }
134
+ function asOptionalBoolean(value, field) {
135
+ if (value === undefined) {
136
+ return undefined;
137
+ }
138
+ if (typeof value !== "boolean") {
139
+ throw new BadRequestError(`${field} must be a boolean`, "OAUTH_ROUTE_INVALID_INPUT");
140
+ }
141
+ return value;
142
+ }
143
+ function asTokenTypeHint(value) {
144
+ if (value === undefined) {
145
+ return undefined;
146
+ }
147
+ if (value === "access_token" || value === "refresh_token") {
148
+ return value;
149
+ }
150
+ throw new BadRequestError("tokenTypeHint must be access_token or refresh_token", "OAUTH_ROUTE_INVALID_INPUT");
151
+ }
152
+ //# sourceMappingURL=connection-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-routes.js","sourceRoot":"","sources":["../src/connection-routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export * from "./browser-routes.js";
2
+ export * from "./connection-routes.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./browser-routes.js";
2
+ export * from "./connection-routes.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@superfunctions/oauth-router",
3
+ "version": "0.0.1",
4
+ "description": "Reusable OAuth route factories for Superfunctions",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "test": "vitest --config ./vitest.config.ts --run",
20
+ "test:watch": "vitest --config ./vitest.config.ts --watch",
21
+ "lint": "echo 'lint not configured'",
22
+ "typecheck": "tsc --noEmit",
23
+ "clean": "rm -rf dist"
24
+ },
25
+ "keywords": [
26
+ "oauth",
27
+ "router",
28
+ "superfunctions"
29
+ ],
30
+ "author": "21n",
31
+ "license": "MIT",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/21nCo/super-functions.git",
35
+ "directory": "packages/oauth-router"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "dependencies": {
41
+ "@superfunctions/http": "0.1.3",
42
+ "@superfunctions/oauth-flow": "0.0.1"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^22.0.0",
46
+ "typescript": "^5.6.0",
47
+ "vitest": "^3.2.4"
48
+ }
49
+ }