@lpshanley/oidc-start-react 0.4.3 → 0.6.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 +7 -3
- package/dist/client.d.ts +8 -7
- package/dist/client.js +5 -2
- package/dist/functions.d.ts +8 -9
- package/dist/functions.js +4 -3
- package/dist/functions.server.d.ts +2 -2
- package/dist/functions.server.js +13 -4
- package/dist/middleware.js +2 -2
- package/dist/routes.d.ts +2 -1
- package/dist/routes.js +2 -4
- package/dist/routes.server.d.ts +2 -2
- package/dist/routes.server.js +5 -5
- package/dist/sign-out.server.d.ts +2 -1
- package/dist/sign-out.server.js +2 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ Register a confidential web client with your OIDC provider. If your app runs at
|
|
|
21
21
|
| Sign-in redirect URI | `http://localhost:5173/callback` |
|
|
22
22
|
| Post-logout redirect URI | `http://localhost:5173/` |
|
|
23
23
|
|
|
24
|
-
Set these values in your **server environment**. Generate `SESSION_SECRET` once with `openssl rand -hex 32` and reuse it across server instances.
|
|
24
|
+
Set these values in your **server environment**. Generate `SESSION_SECRET` once with `openssl rand -hex 32` and reuse it across server instances. Email is optional. Use `displayName(user)` for a name, email, or neutral account label.
|
|
25
25
|
|
|
26
26
|
```dotenv
|
|
27
27
|
APP_ORIGIN=http://localhost:5173
|
|
@@ -32,7 +32,7 @@ OIDC_CLIENT_SECRET=your-client-secret
|
|
|
32
32
|
SESSION_SECRET=
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
Import `createOidcCore` and the `
|
|
35
|
+
Import `createOidcCore` and the `SessionRegistry` type from `@lpshanley/oidc-start-react/server` in your server module. For local development, copy the example’s `auth.server.ts` into `src/auth.server.ts`. It exports an `auth` instance configured with `callbackPath: '/callback'` and `postLogoutPath: '/'`. The example admits any authenticated user and keeps active sessions in memory. For deployment, set `allowSession` to your access policy and use a durable session registry shared by all instances. [Copy auth.server.ts](https://github.com/lpshanley/oidc-start/blob/main/examples/tanstack-start/src/auth.server.ts) · [Core configuration and storage](https://www.npmjs.com/package/@lpshanley/oidc-start-core)
|
|
36
36
|
|
|
37
37
|
## 2. Register the request middleware
|
|
38
38
|
|
|
@@ -114,7 +114,7 @@ function Home() {
|
|
|
114
114
|
}
|
|
115
115
|
```
|
|
116
116
|
|
|
117
|
-
Call `signOut()` for the current session or `signOut({ everywhere: true })` for all of this user's sessions in this app.
|
|
117
|
+
Call `signOut()` for the current session or `signOut({ everywhere: true })` for all of this user's sessions in this app. Use `signOut({ providerLogout: false })` to end only the application session. These options use the same CSRF-protected POST server function. If the session registry is unavailable, the server returns 503 so the user can retry.
|
|
118
118
|
|
|
119
119
|
Use `useAuth().hasRole('admin')` to show role-specific UI. It returns false for signed-out users and sessions without a roles claim. Check authorization again in the server handler that reads private data or performs the action.
|
|
120
120
|
|
|
@@ -255,3 +255,7 @@ A guest or stale session is sent to the local sign-in endpoint with the same `ma
|
|
|
255
255
|
Inside the server handler for a sensitive action, call `checkRecentAuth({ maxAge: 300 })` from `@lpshanley/oidc-start-react/server` before performing the action. If `isStale` is true, stop the mutation and offer `signIn({ maxAge: 300, returnPathname: '/settings' })`. Check again when the user submits the action after returning. Pick the maximum age in the server's policy.
|
|
256
256
|
|
|
257
257
|
The age is in seconds and comes from the provider's ID-token `auth_time`. Signed-out users, existing sessions without that claim, and expired authentication all require sign-in. Token refresh preserves the original authentication time. A sign-in with `maxAge: 0` requests fresh authentication.
|
|
258
|
+
|
|
259
|
+
## Upgrading to 0.5
|
|
260
|
+
|
|
261
|
+
See the [migration guide](https://github.com/lpshanley/oidc-start/blob/main/docs/migration-0.5.md). `getAuth` and guards distinguish absent sessions from denied admission (403) and temporary authentication outages (503); only an absent session starts automatic sign-in. User email is optional and issuer identity is explicit.
|
package/dist/client.d.ts
CHANGED
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
import { type ReactElement, type ReactNode } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import type { AuthSession, SignInOptions, SignOutOptions } from "@lpshanley/oidc-start-core/models";
|
|
3
3
|
/** Supply the root loader's getAuth() result for SSR and client navigation. */
|
|
4
4
|
export declare function AuthProvider({ auth, children }: {
|
|
5
5
|
auth: AuthSession;
|
|
6
6
|
children: ReactNode;
|
|
7
7
|
}): import("react").FunctionComponentElement<import("react").ProviderProps<{
|
|
8
8
|
user: {
|
|
9
|
+
issuer: string;
|
|
9
10
|
sub: string;
|
|
10
|
-
email: string;
|
|
11
11
|
name: string | null;
|
|
12
|
+
email?: string | undefined;
|
|
12
13
|
picture?: string | null | undefined;
|
|
13
14
|
roles?: string[] | undefined;
|
|
14
15
|
} | null;
|
|
15
16
|
} | undefined>>;
|
|
16
17
|
/** The user supplied by the current root loader, or null when signed out. */
|
|
17
18
|
export declare function useUser(): {
|
|
19
|
+
issuer: string;
|
|
18
20
|
sub: string;
|
|
19
|
-
email: string;
|
|
20
21
|
name: string | null;
|
|
22
|
+
email?: string | undefined;
|
|
21
23
|
picture?: string | null | undefined;
|
|
22
24
|
roles?: string[] | undefined;
|
|
23
25
|
} | null;
|
|
@@ -31,9 +33,10 @@ export declare function SignedOut({ children }: {
|
|
|
31
33
|
}): ReactElement | null;
|
|
32
34
|
export declare function useAuth(): {
|
|
33
35
|
user: {
|
|
36
|
+
issuer: string;
|
|
34
37
|
sub: string;
|
|
35
|
-
email: string;
|
|
36
38
|
name: string | null;
|
|
39
|
+
email?: string | undefined;
|
|
37
40
|
picture?: string | null | undefined;
|
|
38
41
|
roles?: string[] | undefined;
|
|
39
42
|
} | null;
|
|
@@ -41,8 +44,6 @@ export declare function useAuth(): {
|
|
|
41
44
|
signIn(options?: SignInOptions): Promise<void>;
|
|
42
45
|
signOut: {
|
|
43
46
|
(): Promise<never>;
|
|
44
|
-
(options?:
|
|
45
|
-
everywhere?: boolean;
|
|
46
|
-
}): Promise<never>;
|
|
47
|
+
(options?: SignOutOptions): Promise<never>;
|
|
47
48
|
};
|
|
48
49
|
};
|
package/dist/client.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createContext, createElement, Fragment, useContext } from "react";
|
|
2
2
|
import { useServerFn } from "@tanstack/react-start";
|
|
3
|
-
import { hasRole } from "@lpshanley/oidc-start-core/
|
|
3
|
+
import { hasRole } from "@lpshanley/oidc-start-core/helpers";
|
|
4
4
|
import { getSignInUrl, signOut } from "./functions.js";
|
|
5
5
|
const AuthContext = createContext(undefined);
|
|
6
6
|
/** Supply the root loader's getAuth() result for SSR and client navigation. */
|
|
@@ -26,7 +26,10 @@ export function useAuth() {
|
|
|
26
26
|
const user = useUser();
|
|
27
27
|
const signOutAndRedirect = useServerFn(signOut);
|
|
28
28
|
function signOutUser(options) {
|
|
29
|
-
return signOutAndRedirect({ data:
|
|
29
|
+
return signOutAndRedirect({ data: options ? {
|
|
30
|
+
everywhere: options.everywhere === true,
|
|
31
|
+
providerLogout: options.providerLogout,
|
|
32
|
+
} : undefined });
|
|
30
33
|
}
|
|
31
34
|
return {
|
|
32
35
|
user,
|
package/dist/functions.d.ts
CHANGED
|
@@ -2,9 +2,10 @@ import { z } from "zod";
|
|
|
2
2
|
/** The signed-in user, or null. Never returns tokens. */
|
|
3
3
|
export declare const getAuth: import("@tanstack/react-start").OptionalFetcher<undefined, undefined, Promise<{
|
|
4
4
|
user: {
|
|
5
|
+
issuer: string;
|
|
5
6
|
sub: string;
|
|
6
|
-
email: string;
|
|
7
7
|
name: string | null;
|
|
8
|
+
email?: string | undefined;
|
|
8
9
|
picture?: string | null | undefined;
|
|
9
10
|
roles?: string[] | undefined;
|
|
10
11
|
} | null;
|
|
@@ -18,9 +19,10 @@ type GuardOptions = {
|
|
|
18
19
|
/** Guard route navigation and supply a signed-in user to descendant routes. */
|
|
19
20
|
export declare function requireAuth(options: GuardOptions): Promise<{
|
|
20
21
|
user: {
|
|
22
|
+
issuer: string;
|
|
21
23
|
sub: string;
|
|
22
|
-
email: string;
|
|
23
24
|
name: string | null;
|
|
25
|
+
email?: string | undefined;
|
|
24
26
|
picture?: string | null | undefined;
|
|
25
27
|
roles?: string[] | undefined;
|
|
26
28
|
};
|
|
@@ -30,9 +32,10 @@ export declare function requireRecentAuth(options: GuardOptions & {
|
|
|
30
32
|
maxAge: number;
|
|
31
33
|
}): Promise<{
|
|
32
34
|
user: {
|
|
35
|
+
issuer: string;
|
|
33
36
|
sub: string;
|
|
34
|
-
email: string;
|
|
35
37
|
name: string | null;
|
|
38
|
+
email?: string | undefined;
|
|
36
39
|
picture?: string | null | undefined;
|
|
37
40
|
roles?: string[] | undefined;
|
|
38
41
|
};
|
|
@@ -42,15 +45,11 @@ export declare const getSignInUrl: import("@tanstack/react-start").OptionalFetch
|
|
|
42
45
|
returnPathname: z.ZodOptional<z.ZodString>;
|
|
43
46
|
maxAge: z.ZodOptional<z.ZodNumber>;
|
|
44
47
|
loginHint: z.ZodOptional<z.ZodString>;
|
|
45
|
-
prompt: z.ZodOptional<z.
|
|
46
|
-
none: "none";
|
|
47
|
-
login: "login";
|
|
48
|
-
consent: "consent";
|
|
49
|
-
select_account: "select_account";
|
|
50
|
-
}>>;
|
|
48
|
+
prompt: z.ZodOptional<z.ZodString>;
|
|
51
49
|
}, z.core.$strip>>, Promise<string>>;
|
|
52
50
|
/** Clears the session and redirects to provider logout. In a component, call via useServerFn. */
|
|
53
51
|
export declare const signOut: import("@tanstack/react-start").OptionalFetcher<undefined, z.ZodOptional<z.ZodObject<{
|
|
54
52
|
everywhere: z.ZodOptional<z.ZodBoolean>;
|
|
53
|
+
providerLogout: z.ZodOptional<z.ZodBoolean>;
|
|
55
54
|
}, z.core.$strip>>, Promise<never>>;
|
|
56
55
|
export {};
|
package/dist/functions.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createServerFn } from "@tanstack/react-start";
|
|
2
2
|
import { redirect } from "@tanstack/react-router";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
-
import { sanitizeReturnPath
|
|
4
|
+
import { sanitizeReturnPath } from "@lpshanley/oidc-start-core/helpers";
|
|
5
|
+
import { signInOptionsSchema, signOutOptionsSchema } from "@lpshanley/oidc-start-core/models";
|
|
5
6
|
// Server functions after WorkOS's server-functions.ts; bodies load lazily so
|
|
6
7
|
// server code stays out of the client bundle.
|
|
7
8
|
/** The signed-in user, or null. Never returns tokens. */
|
|
@@ -45,8 +46,8 @@ export const getSignInUrl = createServerFn({ method: "GET" })
|
|
|
45
46
|
});
|
|
46
47
|
/** Clears the session and redirects to provider logout. In a component, call via useServerFn. */
|
|
47
48
|
export const signOut = createServerFn({ method: "POST" })
|
|
48
|
-
.validator(
|
|
49
|
+
.validator(signOutOptionsSchema.optional())
|
|
49
50
|
.handler(async ({ data }) => {
|
|
50
51
|
const { signOutBody } = await import("./functions.server.js");
|
|
51
|
-
return signOutBody(data
|
|
52
|
+
return signOutBody(data);
|
|
52
53
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { AuthSession, SignInOptions } from "@lpshanley/oidc-start-core/models";
|
|
1
|
+
import type { AuthSession, SignInOptions, SignOutOptions } from "@lpshanley/oidc-start-core/models";
|
|
2
2
|
export declare function getAuthBody(): AuthSession;
|
|
3
3
|
export declare function getRecentAuthBody(maxAge: number): AuthSession;
|
|
4
4
|
export declare function getSignInUrlBody(options?: SignInOptions): Promise<string>;
|
|
5
|
-
export declare function signOutBody(
|
|
5
|
+
export declare function signOutBody(options?: SignOutOptions): Promise<never>;
|
package/dist/functions.server.js
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import { redirect } from "@tanstack/react-router";
|
|
2
|
-
import { setResponseHeader } from "@tanstack/react-start/server";
|
|
2
|
+
import { setResponseHeader, setResponseStatus } from "@tanstack/react-start/server";
|
|
3
3
|
import { endSession } from "./sign-out.server.js";
|
|
4
4
|
import { checkRecentAuth, getOidcContext } from "./context.js";
|
|
5
5
|
export function getAuthBody() {
|
|
6
6
|
setResponseHeader("Cache-Control", "no-store");
|
|
7
|
-
|
|
7
|
+
const auth = getOidcContext().auth();
|
|
8
|
+
if (auth.status === "denied" || auth.status === "unavailable") {
|
|
9
|
+
const status = auth.status === "denied" ? 403 : 503;
|
|
10
|
+
setResponseStatus(status);
|
|
11
|
+
// Loader errors must serialize during SSR. A thrown Response cannot.
|
|
12
|
+
throw Object.assign(new Error(auth.status === "denied"
|
|
13
|
+
? "Your account does not have access."
|
|
14
|
+
: "Authentication is temporarily unavailable. Try again."), { status });
|
|
15
|
+
}
|
|
16
|
+
return { user: auth.user };
|
|
8
17
|
}
|
|
9
18
|
export function getRecentAuthBody(maxAge) {
|
|
10
19
|
const auth = getAuthBody();
|
|
@@ -17,8 +26,8 @@ export async function getSignInUrlBody(options) {
|
|
|
17
26
|
context.appendSetCookie(line);
|
|
18
27
|
return url;
|
|
19
28
|
}
|
|
20
|
-
export async function signOutBody(
|
|
21
|
-
const result = await endSession(
|
|
29
|
+
export async function signOutBody(options = {}) {
|
|
30
|
+
const result = await endSession(options);
|
|
22
31
|
if (result instanceof Response)
|
|
23
32
|
throw result;
|
|
24
33
|
throw redirect({ href: result, reloadDocument: true });
|
package/dist/middleware.js
CHANGED
|
@@ -28,7 +28,7 @@ export function oidcMiddleware(setup) {
|
|
|
28
28
|
core ??= createOidcCore(setup);
|
|
29
29
|
}
|
|
30
30
|
const call = callContext(context);
|
|
31
|
-
const { cookies, session, setCookies } = await core.resolve(request, call);
|
|
31
|
+
const { cookies, session, setCookies, status, reason } = await core.resolve(request, call);
|
|
32
32
|
let sessionUpdates = setCookies;
|
|
33
33
|
const appended = [];
|
|
34
34
|
const oidc = {
|
|
@@ -37,7 +37,7 @@ export function oidcMiddleware(setup) {
|
|
|
37
37
|
cookies,
|
|
38
38
|
session,
|
|
39
39
|
call,
|
|
40
|
-
auth: () => ({ user: session?.user ?? null }),
|
|
40
|
+
auth: () => ({ user: session?.user ?? null, status, reason }),
|
|
41
41
|
appendSetCookie: (line) => appended.push(line),
|
|
42
42
|
discardSessionUpdates: () => { sessionUpdates = []; },
|
|
43
43
|
};
|
package/dist/routes.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SignOutOptions } from "@lpshanley/oidc-start-core/models";
|
|
1
2
|
import type { CallbackRouteOptions, SignInRouteOptions } from "./routes.server.js";
|
|
2
3
|
export type { CallbackRouteOptions, SignInRouteOptions };
|
|
3
4
|
type RouteHandler = (args: {
|
|
@@ -10,4 +11,4 @@ export declare function handleCallbackRoute(options?: CallbackRouteOptions): Rou
|
|
|
10
11
|
/** POST: the provider's back-channel logout; ends the sessions its token names. */
|
|
11
12
|
export declare function handleBackchannelLogoutRoute(): RouteHandler;
|
|
12
13
|
/** POST: clears the session and redirects to the provider logout. */
|
|
13
|
-
export declare function handleSignOutRoute(): RouteHandler;
|
|
14
|
+
export declare function handleSignOutRoute(options?: SignOutOptions): RouteHandler;
|
package/dist/routes.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// Server route handler factories, after WorkOS's handleCallbackRoute. They run
|
|
2
|
-
// behind oidcMiddleware, which applies the cookies they queue.
|
|
3
1
|
/** GET: redirects to the provider; `?returnPathname=` sets the destination. */
|
|
4
2
|
export function handleSignInRoute(options = {}) {
|
|
5
3
|
return async ({ request }) => {
|
|
@@ -22,9 +20,9 @@ export function handleBackchannelLogoutRoute() {
|
|
|
22
20
|
};
|
|
23
21
|
}
|
|
24
22
|
/** POST: clears the session and redirects to the provider logout. */
|
|
25
|
-
export function handleSignOutRoute() {
|
|
23
|
+
export function handleSignOutRoute(options = {}) {
|
|
26
24
|
return async ({ request }) => {
|
|
27
25
|
const { signOutRoute } = await import("./routes.server.js");
|
|
28
|
-
return signOutRoute(request);
|
|
26
|
+
return signOutRoute(request, options);
|
|
29
27
|
};
|
|
30
28
|
}
|
package/dist/routes.server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CallbackErrorReason } from "@lpshanley/oidc-start-core";
|
|
2
|
-
import type { SignInOptions } from "@lpshanley/oidc-start-core/models";
|
|
2
|
+
import type { SignInOptions, SignOutOptions } from "@lpshanley/oidc-start-core/models";
|
|
3
3
|
type FailureOptions = {
|
|
4
4
|
/** Where to send the browser when sign-in fails. Defaults to a 400. */
|
|
5
5
|
errorRedirectUrl?: string;
|
|
@@ -16,6 +16,6 @@ export type CallbackRouteOptions = FailureOptions & {
|
|
|
16
16
|
};
|
|
17
17
|
export declare function signInRoute(request: Request, options: SignInRouteOptions): Promise<Response>;
|
|
18
18
|
export declare function callbackRoute(request: Request, options: CallbackRouteOptions): Promise<Response>;
|
|
19
|
-
export declare function signOutRoute(request: Request): Promise<Response>;
|
|
19
|
+
export declare function signOutRoute(request: Request, options?: SignOutOptions): Promise<Response>;
|
|
20
20
|
export declare function backchannelLogoutRoute(request: Request): Promise<Response>;
|
|
21
21
|
export {};
|
package/dist/routes.server.js
CHANGED
|
@@ -58,27 +58,27 @@ export async function callbackRoute(request, options) {
|
|
|
58
58
|
headers: { "Content-Type": "text/plain", "Cache-Control": "no-store" },
|
|
59
59
|
});
|
|
60
60
|
}
|
|
61
|
-
context.core.report({ operation: "callback", error: result.error, context: context.call });
|
|
61
|
+
context.core.report({ operation: "callback", reason: result.reason, error: result.error, context: context.call });
|
|
62
62
|
if (options.onError)
|
|
63
63
|
return options.onError({ reason: result.reason, request });
|
|
64
64
|
return failure(request, options);
|
|
65
65
|
}
|
|
66
|
-
export async function signOutRoute(request) {
|
|
66
|
+
export async function signOutRoute(request, options = {}) {
|
|
67
67
|
if (request.method !== "POST") {
|
|
68
68
|
return new Response("Method Not Allowed", {
|
|
69
69
|
status: 405,
|
|
70
|
-
headers: { Allow: "POST" },
|
|
70
|
+
headers: { Allow: "POST", "Cache-Control": "no-store" },
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
73
|
const form = await request.formData().catch(() => undefined);
|
|
74
|
-
const result = await endSession(form?.get("everywhere") === "1");
|
|
74
|
+
const result = await endSession({ ...options, everywhere: options.everywhere || form?.get("everywhere") === "1" });
|
|
75
75
|
return result instanceof Response ? result : redirectTo(result, 303);
|
|
76
76
|
}
|
|
77
77
|
export async function backchannelLogoutRoute(request) {
|
|
78
78
|
if (request.method !== "POST") {
|
|
79
79
|
return new Response("Method Not Allowed", {
|
|
80
80
|
status: 405,
|
|
81
|
-
headers: { Allow: "POST" },
|
|
81
|
+
headers: { Allow: "POST", "Cache-Control": "no-store" },
|
|
82
82
|
});
|
|
83
83
|
}
|
|
84
84
|
const context = getOidcContext();
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import type { SignOutOptions } from "@lpshanley/oidc-start-core/models";
|
|
2
|
+
export declare function endSession(options?: SignOutOptions): Promise<string | Response>;
|
package/dist/sign-out.server.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { getOidcContext } from "./context.js";
|
|
2
|
-
export async function endSession(
|
|
2
|
+
export async function endSession(options = {}) {
|
|
3
3
|
const context = getOidcContext();
|
|
4
4
|
// A failed revocation must leave the incoming cookie available for retry.
|
|
5
5
|
// A successful sign-out supplies all deletions for that same incoming jar.
|
|
6
6
|
context.discardSessionUpdates?.();
|
|
7
7
|
let result;
|
|
8
8
|
try {
|
|
9
|
-
result = await context.core.signOut(context.request, context.cookies, context.session, context.call,
|
|
9
|
+
result = await context.core.signOut(context.request, context.cookies, context.session, context.call, options);
|
|
10
10
|
}
|
|
11
11
|
catch (error) {
|
|
12
12
|
context.core.report({ operation: "end-session", error, context: context.call });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lpshanley/oidc-start-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"node": ">=22.12.0"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@lpshanley/oidc-start-core": "0.
|
|
43
|
+
"@lpshanley/oidc-start-core": "0.6.0",
|
|
44
44
|
"zod": "4.6.7"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
}
|
|
67
67
|
},
|
|
68
68
|
"scripts": {
|
|
69
|
-
"build": "tsc -p tsconfig.build.json",
|
|
69
|
+
"build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.build.json",
|
|
70
70
|
"typecheck": "tsc --noEmit",
|
|
71
71
|
"test": "vitest run",
|
|
72
72
|
"check-package": "publint --strict"
|