@lpshanley/oidc-start-react 0.0.0-stage → 0.1.0-next.0
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 +17 -2
- package/dist/context.d.ts +17 -0
- package/dist/context.js +16 -0
- package/dist/functions.d.ts +17 -0
- package/dist/functions.js +21 -0
- package/dist/functions.server.d.ts +4 -0
- package/dist/functions.server.js +21 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/middleware.d.ts +19 -0
- package/dist/middleware.js +50 -0
- package/dist/routes.d.ts +13 -0
- package/dist/routes.js +30 -0
- package/dist/routes.server.d.ts +10 -0
- package/dist/routes.server.js +73 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +1 -0
- package/dist/sign-out.server.d.ts +1 -0
- package/dist/sign-out.server.js +18 -0
- package/package.json +60 -3
package/README.md
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @lpshanley/oidc-start-react
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
TanStack Start for React bindings for `@lpshanley/oidc-start-core`. Install alongside the application's React Start and React Router packages.
|
|
4
|
+
|
|
5
|
+
In a custom `src/start.ts`, register `createCsrfMiddleware({ filter: (ctx) => ctx.handlerType === 'serverFn' })` from `@tanstack/react-start` before `oidcMiddleware({ core: () => auth })` in `requestMiddleware`. This restores Start's same-origin check for browser RPCs. Here `auth` is the server-side core configured by the host. You can also read a core from the context supplied by earlier server middleware. In a file shared with the browser, load server-only composition inside the server boundary.
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { createFileRoute } from '@tanstack/react-router'
|
|
9
|
+
import { handleCallbackRoute } from '@lpshanley/oidc-start-react'
|
|
10
|
+
|
|
11
|
+
export const Route = createFileRoute('/auth/callback')({
|
|
12
|
+
server: { handlers: { GET: handleCallbackRoute() } },
|
|
13
|
+
})
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Register `handleSignInRoute()` on GET and `handleSignOutRoute()` and `handleBackchannelLogoutRoute()` on POST. Add `server.middleware: [createCsrfMiddleware()]` to the browser sign-out route as well. The provider posts signed tokens to the separate back-channel route without a browser Origin header, so leave that route outside the browser CSRF check.
|
|
17
|
+
|
|
18
|
+
Import `getAuth`, `getSignInUrl` and `signOut` from `@lpshanley/oidc-start-react/functions`. In a React component, bind `const signOutAndRedirect = useServerFn(signOut)` from TanStack Start and call it in the click handler so the router follows the logout redirect. Use `getOidcContext` from `@lpshanley/oidc-start-react/server` inside server handlers. The adapter ships ESM with its server-function declarations intact for the consuming app's Start compiler.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { OidcCallContext } from "@lpshanley/oidc-start-core/config";
|
|
2
|
+
import type { OidcAuth, OidcCore } from "@lpshanley/oidc-start-core";
|
|
3
|
+
import type { Session } from "@lpshanley/oidc-start-core";
|
|
4
|
+
/** Request-scoped auth state that oidcMiddleware places in Start's context. */
|
|
5
|
+
export type OidcContext = {
|
|
6
|
+
core: OidcCore;
|
|
7
|
+
request: Request;
|
|
8
|
+
cookies: Map<string, string>;
|
|
9
|
+
session: Session | null;
|
|
10
|
+
/** The caller's request context, when one was provided upstream. */
|
|
11
|
+
call: OidcCallContext | undefined;
|
|
12
|
+
auth: () => OidcAuth;
|
|
13
|
+
/** Queue a Set-Cookie line for the final response. */
|
|
14
|
+
appendSetCookie: (line: string) => void;
|
|
15
|
+
};
|
|
16
|
+
/** The current request's OIDC context; throws outside the middleware. */
|
|
17
|
+
export declare function getOidcContext(): OidcContext;
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { getGlobalStartContext } from "@tanstack/react-start";
|
|
2
|
+
const NOT_CONFIGURED = "OIDC middleware is not configured. Add oidcMiddleware() to requestMiddleware in src/start.ts.";
|
|
3
|
+
function isOidcContext(value) {
|
|
4
|
+
return (typeof value === "object" &&
|
|
5
|
+
value !== null &&
|
|
6
|
+
"core" in value &&
|
|
7
|
+
"auth" in value &&
|
|
8
|
+
"appendSetCookie" in value);
|
|
9
|
+
}
|
|
10
|
+
/** The current request's OIDC context; throws outside the middleware. */
|
|
11
|
+
export function getOidcContext() {
|
|
12
|
+
const context = getGlobalStartContext();
|
|
13
|
+
if (!isOidcContext(context?.oidc))
|
|
14
|
+
throw new Error(NOT_CONFIGURED);
|
|
15
|
+
return context.oidc;
|
|
16
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** The signed-in user, or null. Never returns tokens. */
|
|
3
|
+
export declare const getAuth: import("@tanstack/react-start").OptionalFetcher<undefined, undefined, Promise<{
|
|
4
|
+
user: {
|
|
5
|
+
sub: string;
|
|
6
|
+
email: string;
|
|
7
|
+
name: string | null;
|
|
8
|
+
picture?: string | null | undefined;
|
|
9
|
+
roles?: string[] | undefined;
|
|
10
|
+
} | null;
|
|
11
|
+
}>>;
|
|
12
|
+
/** An authorization URL; also queues the flow's verifier cookie. */
|
|
13
|
+
export declare const getSignInUrl: import("@tanstack/react-start").OptionalFetcher<undefined, z.ZodOptional<z.ZodObject<{
|
|
14
|
+
returnPathname: z.ZodOptional<z.ZodString>;
|
|
15
|
+
}, z.core.$strip>>, Promise<string>>;
|
|
16
|
+
/** Clears the session and redirects to provider logout. In a component, call via useServerFn. */
|
|
17
|
+
export declare const signOut: import("@tanstack/react-start").OptionalFetcher<undefined, undefined, Promise<never>>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createServerFn } from "@tanstack/react-start";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
// Server functions after WorkOS's server-functions.ts; bodies load lazily so
|
|
4
|
+
// server code stays out of the client bundle.
|
|
5
|
+
/** The signed-in user, or null. Never returns tokens. */
|
|
6
|
+
export const getAuth = createServerFn({ method: "GET" }).handler(async () => {
|
|
7
|
+
const { getAuthBody } = await import("./functions.server.js");
|
|
8
|
+
return getAuthBody();
|
|
9
|
+
});
|
|
10
|
+
/** An authorization URL; also queues the flow's verifier cookie. */
|
|
11
|
+
export const getSignInUrl = createServerFn({ method: "GET" })
|
|
12
|
+
.validator(z.object({ returnPathname: z.string().optional() }).optional())
|
|
13
|
+
.handler(async ({ data }) => {
|
|
14
|
+
const { getSignInUrlBody } = await import("./functions.server.js");
|
|
15
|
+
return getSignInUrlBody(data?.returnPathname);
|
|
16
|
+
});
|
|
17
|
+
/** Clears the session and redirects to provider logout. In a component, call via useServerFn. */
|
|
18
|
+
export const signOut = createServerFn({ method: "POST" }).handler(async () => {
|
|
19
|
+
const { signOutBody } = await import("./functions.server.js");
|
|
20
|
+
return signOutBody();
|
|
21
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { redirect } from "@tanstack/react-router";
|
|
2
|
+
import { setResponseHeader } from "@tanstack/react-start/server";
|
|
3
|
+
import { endSession } from "./sign-out.server.js";
|
|
4
|
+
import { getOidcContext } from "./context.js";
|
|
5
|
+
export function getAuthBody() {
|
|
6
|
+
setResponseHeader("Cache-Control", "no-store");
|
|
7
|
+
return { user: getOidcContext().auth().user };
|
|
8
|
+
}
|
|
9
|
+
export async function getSignInUrlBody(returnPathname) {
|
|
10
|
+
const context = getOidcContext();
|
|
11
|
+
const { url, setCookies } = await context.core.signIn(context.request, context.cookies, returnPathname, context.call);
|
|
12
|
+
for (const line of setCookies)
|
|
13
|
+
context.appendSetCookie(line);
|
|
14
|
+
return url;
|
|
15
|
+
}
|
|
16
|
+
export async function signOutBody() {
|
|
17
|
+
const result = await endSession();
|
|
18
|
+
if (result instanceof Response)
|
|
19
|
+
throw result;
|
|
20
|
+
throw redirect({ href: result, reloadDocument: true });
|
|
21
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export type { OidcCallContext, OidcErrorEvent, OidcMiddlewareOptions, } from "@lpshanley/oidc-start-core/config";
|
|
2
|
+
export { type OidcMiddlewareSetup, oidcMiddleware } from "./middleware.js";
|
|
3
|
+
export { type CallbackRouteOptions, handleBackchannelLogoutRoute, handleCallbackRoute, handleSignInRoute, handleSignOutRoute, } from "./routes.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { OidcMiddlewareOptions } from "@lpshanley/oidc-start-core/config";
|
|
2
|
+
import type { OidcContext } from "./context.js";
|
|
3
|
+
import type { OidcCore } from "@lpshanley/oidc-start-core";
|
|
4
|
+
export type OidcMiddlewareSetup = OidcMiddlewareOptions | {
|
|
5
|
+
/**
|
|
6
|
+
* A core the app composed itself, resolved on first request from
|
|
7
|
+
* the context earlier request middleware provided.
|
|
8
|
+
*/
|
|
9
|
+
core: (context: unknown) => OidcCore;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Request middleware after WorkOS's authkitMiddleware: resolves the session
|
|
13
|
+
* (refreshing or clearing it as needed), exposes it as `context.oidc`, and
|
|
14
|
+
* appends every queued Set-Cookie line to the final response. Create it once
|
|
15
|
+
* outside createStart so discovery and refresh state persist across requests.
|
|
16
|
+
*/
|
|
17
|
+
export declare function oidcMiddleware(setup: OidcMiddlewareSetup): import("@tanstack/react-start").RequestMiddlewareAfterServer<{}, undefined, {
|
|
18
|
+
oidc: OidcContext;
|
|
19
|
+
}>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createMiddleware } from "@tanstack/react-start";
|
|
2
|
+
/** `context.requestContext` from an earlier middleware, when it has the shape. */
|
|
3
|
+
function callContext(context) {
|
|
4
|
+
const value = context
|
|
5
|
+
?.requestContext;
|
|
6
|
+
if (typeof value !== "object" || value === null)
|
|
7
|
+
return undefined;
|
|
8
|
+
const { correlationId, deadline, signal } = value;
|
|
9
|
+
return {
|
|
10
|
+
...(signal instanceof AbortSignal ? { signal } : {}),
|
|
11
|
+
correlationId: typeof correlationId === "string" ? correlationId : undefined,
|
|
12
|
+
deadline: typeof deadline === "number" ? deadline : undefined,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Request middleware after WorkOS's authkitMiddleware: resolves the session
|
|
17
|
+
* (refreshing or clearing it as needed), exposes it as `context.oidc`, and
|
|
18
|
+
* appends every queued Set-Cookie line to the final response. Create it once
|
|
19
|
+
* outside createStart so discovery and refresh state persist across requests.
|
|
20
|
+
*/
|
|
21
|
+
export function oidcMiddleware(setup) {
|
|
22
|
+
let core;
|
|
23
|
+
return createMiddleware({ type: "request" }).server(async ({ request, next, context }) => {
|
|
24
|
+
if ("core" in setup)
|
|
25
|
+
core ??= setup.core(context);
|
|
26
|
+
else {
|
|
27
|
+
const { createOidcCore } = await import("@lpshanley/oidc-start-core");
|
|
28
|
+
core ??= createOidcCore(setup);
|
|
29
|
+
}
|
|
30
|
+
const call = callContext(context);
|
|
31
|
+
const { cookies, session, setCookies } = await core.resolve(request, call);
|
|
32
|
+
const pending = [...setCookies];
|
|
33
|
+
const oidc = {
|
|
34
|
+
core,
|
|
35
|
+
request,
|
|
36
|
+
cookies,
|
|
37
|
+
session,
|
|
38
|
+
call,
|
|
39
|
+
auth: () => ({ user: session?.user ?? null }),
|
|
40
|
+
appendSetCookie: (line) => pending.push(line),
|
|
41
|
+
};
|
|
42
|
+
const result = await next({ context: { oidc } });
|
|
43
|
+
if (pending.length) {
|
|
44
|
+
// Start must receive its original response to serialize RPC redirects.
|
|
45
|
+
const { appendResponseHeader } = await import("@tanstack/react-start/server");
|
|
46
|
+
appendResponseHeader("Set-Cookie", pending);
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
});
|
|
50
|
+
}
|
package/dist/routes.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CallbackRouteOptions } from "./routes.server.js";
|
|
2
|
+
export type { CallbackRouteOptions };
|
|
3
|
+
type RouteHandler = (args: {
|
|
4
|
+
request: Request;
|
|
5
|
+
}) => Promise<Response>;
|
|
6
|
+
/** GET: redirects to the provider; `?returnPathname=` sets the destination. */
|
|
7
|
+
export declare function handleSignInRoute(options?: CallbackRouteOptions): RouteHandler;
|
|
8
|
+
/** GET: completes sign-in and redirects to the sanitized return path. */
|
|
9
|
+
export declare function handleCallbackRoute(options?: CallbackRouteOptions): RouteHandler;
|
|
10
|
+
/** POST: the provider's back-channel logout; ends the sessions its token names. */
|
|
11
|
+
export declare function handleBackchannelLogoutRoute(): RouteHandler;
|
|
12
|
+
/** POST: clears the session and redirects to the provider logout. */
|
|
13
|
+
export declare function handleSignOutRoute(): RouteHandler;
|
package/dist/routes.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Server route handler factories, after WorkOS's handleCallbackRoute. They run
|
|
2
|
+
// behind oidcMiddleware, which applies the cookies they queue.
|
|
3
|
+
/** GET: redirects to the provider; `?returnPathname=` sets the destination. */
|
|
4
|
+
export function handleSignInRoute(options = {}) {
|
|
5
|
+
return async ({ request }) => {
|
|
6
|
+
const { signInRoute } = await import("./routes.server.js");
|
|
7
|
+
return signInRoute(request, options);
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
/** GET: completes sign-in and redirects to the sanitized return path. */
|
|
11
|
+
export function handleCallbackRoute(options = {}) {
|
|
12
|
+
return async ({ request }) => {
|
|
13
|
+
const { callbackRoute } = await import("./routes.server.js");
|
|
14
|
+
return callbackRoute(request, options);
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/** POST: the provider's back-channel logout; ends the sessions its token names. */
|
|
18
|
+
export function handleBackchannelLogoutRoute() {
|
|
19
|
+
return async ({ request }) => {
|
|
20
|
+
const { backchannelLogoutRoute } = await import("./routes.server.js");
|
|
21
|
+
return backchannelLogoutRoute(request);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** POST: clears the session and redirects to the provider logout. */
|
|
25
|
+
export function handleSignOutRoute() {
|
|
26
|
+
return async ({ request }) => {
|
|
27
|
+
const { signOutRoute } = await import("./routes.server.js");
|
|
28
|
+
return signOutRoute(request);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type CallbackRouteOptions = {
|
|
2
|
+
/** Where to send the browser when sign-in fails. Defaults to a 400. */
|
|
3
|
+
errorRedirectUrl?: string;
|
|
4
|
+
/** Shown when the host denies a session to an authenticated user. */
|
|
5
|
+
accessDeniedMessage?: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function signInRoute(request: Request, options: CallbackRouteOptions): Promise<Response>;
|
|
8
|
+
export declare function callbackRoute(request: Request, options: CallbackRouteOptions): Promise<Response>;
|
|
9
|
+
export declare function signOutRoute(request: Request): Promise<Response>;
|
|
10
|
+
export declare function backchannelLogoutRoute(request: Request): Promise<Response>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { endSession } from "./sign-out.server.js";
|
|
2
|
+
import { getOidcContext } from "./context.js";
|
|
3
|
+
import { SessionAccessDeniedError } from "@lpshanley/oidc-start-core";
|
|
4
|
+
function redirectTo(location, status) {
|
|
5
|
+
return new Response(null, {
|
|
6
|
+
status,
|
|
7
|
+
headers: { Location: location, "Cache-Control": "no-store" },
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
function failure(request, options, operation, error) {
|
|
11
|
+
// Provider error details go to onError, never into the response.
|
|
12
|
+
const context = getOidcContext();
|
|
13
|
+
context.core.report({ operation, error, context: context.call });
|
|
14
|
+
if (options.errorRedirectUrl) {
|
|
15
|
+
return redirectTo(new URL(options.errorRedirectUrl, request.url).toString(), 303);
|
|
16
|
+
}
|
|
17
|
+
return new Response("Authentication failed. Restart sign-in.", {
|
|
18
|
+
status: 400,
|
|
19
|
+
headers: { "Content-Type": "text/plain", "Cache-Control": "no-store" },
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export async function signInRoute(request, options) {
|
|
23
|
+
const context = getOidcContext();
|
|
24
|
+
try {
|
|
25
|
+
const { url, setCookies } = await context.core.signIn(request, context.cookies, new URL(request.url).searchParams.get("returnPathname"), context.call);
|
|
26
|
+
for (const line of setCookies)
|
|
27
|
+
context.appendSetCookie(line);
|
|
28
|
+
return redirectTo(url, 307);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
return failure(request, options, "sign-in", error);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export async function callbackRoute(request, options) {
|
|
35
|
+
const context = getOidcContext();
|
|
36
|
+
const result = await context.core.callback(request, context.cookies, context.call);
|
|
37
|
+
for (const line of result.setCookies)
|
|
38
|
+
context.appendSetCookie(line);
|
|
39
|
+
if (result.ok)
|
|
40
|
+
return redirectTo(result.location, 307);
|
|
41
|
+
if (result.error instanceof SessionAccessDeniedError) {
|
|
42
|
+
return new Response(options.accessDeniedMessage ?? "Your account does not have access.", {
|
|
43
|
+
status: 403,
|
|
44
|
+
headers: { "Content-Type": "text/plain", "Cache-Control": "no-store" },
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return failure(request, options, "callback", result.error);
|
|
48
|
+
}
|
|
49
|
+
export async function signOutRoute(request) {
|
|
50
|
+
if (request.method !== "POST") {
|
|
51
|
+
return new Response("Method Not Allowed", {
|
|
52
|
+
status: 405,
|
|
53
|
+
headers: { Allow: "POST" },
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
const form = await request.formData().catch(() => undefined);
|
|
57
|
+
const result = await endSession(form?.get("everywhere") === "1");
|
|
58
|
+
return result instanceof Response ? result : redirectTo(result, 303);
|
|
59
|
+
}
|
|
60
|
+
export async function backchannelLogoutRoute(request) {
|
|
61
|
+
if (request.method !== "POST") {
|
|
62
|
+
return new Response("Method Not Allowed", {
|
|
63
|
+
status: 405,
|
|
64
|
+
headers: { Allow: "POST" },
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
const context = getOidcContext();
|
|
68
|
+
const { status } = await context.core.backchannelLogout(request, context.call);
|
|
69
|
+
return new Response(null, {
|
|
70
|
+
status,
|
|
71
|
+
headers: { "Cache-Control": "no-store" },
|
|
72
|
+
});
|
|
73
|
+
}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { getOidcContext, type OidcContext } from "./context.js";
|
package/dist/server.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { getOidcContext } from "./context.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function endSession(everywhere?: boolean): Promise<string | Response>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { getOidcContext } from "./context.js";
|
|
2
|
+
export async function endSession(everywhere = false) {
|
|
3
|
+
const context = getOidcContext();
|
|
4
|
+
let result;
|
|
5
|
+
try {
|
|
6
|
+
result = await context.core.signOut(context.request, context.cookies, context.session, context.call, everywhere);
|
|
7
|
+
}
|
|
8
|
+
catch (error) {
|
|
9
|
+
context.core.report({ operation: "end-session", error, context: context.call });
|
|
10
|
+
return new Response("Sign-out could not be recorded. Try again.", {
|
|
11
|
+
status: 503,
|
|
12
|
+
headers: { "Content-Type": "text/plain", "Cache-Control": "no-store" },
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
for (const line of result.setCookies)
|
|
16
|
+
context.appendSetCookie(line);
|
|
17
|
+
return result.location;
|
|
18
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,63 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lpshanley/oidc-start-react",
|
|
3
|
-
"version": "0.0.0
|
|
4
|
-
"
|
|
5
|
-
|
|
3
|
+
"version": "0.1.0-next.0",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/lpshanley/oidc-start.git",
|
|
7
|
+
"directory": "packages/react"
|
|
8
|
+
},
|
|
9
|
+
"description": "TanStack Start for React bindings for OpenID Connect",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./functions": {
|
|
19
|
+
"types": "./dist/functions.d.ts",
|
|
20
|
+
"import": "./dist/functions.js"
|
|
21
|
+
},
|
|
22
|
+
"./server": {
|
|
23
|
+
"types": "./dist/server.d.ts",
|
|
24
|
+
"import": "./dist/server.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=22.12.0"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@lpshanley/oidc-start-core": "0.1.0-next.0",
|
|
39
|
+
"zod": "4.6.7"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"typescript": "6.0.3",
|
|
43
|
+
"vitest": "5.0.5",
|
|
44
|
+
"publint": "^0.3.0",
|
|
45
|
+
"@types/node": "22.20.2",
|
|
46
|
+
"@tanstack/react-router": "1.170.46",
|
|
47
|
+
"@tanstack/react-start": "1.169.4",
|
|
48
|
+
"react": "19.3.1",
|
|
49
|
+
"react-dom": "19.3.1",
|
|
50
|
+
"@types/react": "^19.2.0",
|
|
51
|
+
"@types/react-dom": "^19.2.0"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"@tanstack/react-router": "^1.170.44",
|
|
55
|
+
"@tanstack/react-start": "^1.169.2"
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "tsc -p tsconfig.build.json",
|
|
59
|
+
"typecheck": "tsc --noEmit",
|
|
60
|
+
"test": "vitest run",
|
|
61
|
+
"check-package": "publint --strict"
|
|
62
|
+
}
|
|
6
63
|
}
|