sekisho 0.2.1 → 0.3.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 +69 -22
- package/dist/factory.cjs +1 -0
- package/dist/factory.d.ts +65 -0
- package/dist/factory.mjs +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +36 -101
- package/dist/index.mjs +1 -1
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<h1 align="center">⛩️ sekisho</h1>
|
|
2
2
|
<p align="center"><sup>(関所, <em>historical checkpoint for travel and security</em> in Japanese)</sup></p>
|
|
3
|
-
<p align="center">Authentication and Access Control for any React app
|
|
3
|
+
<p align="center">Authentication and Access Control for any React app <a href="https://sekisho-demo.pages.dev" target="_blank">online demo</a></p>
|
|
4
4
|
|
|
5
5
|
----
|
|
6
6
|
|
|
@@ -61,38 +61,38 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|
|
61
61
|
}
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
By default, `SekishoProvider` already includes `
|
|
64
|
+
By default, `SekishoProvider` already includes `NotAuthenticatedBoundary` that will catch any `NotAuthenticatedError` thrown by `needLogin()` in the subtree. But if you have special error handling needs in certain parts of your app, you can also always import `NotAuthenticatedBoundary` directly to wrap those parts:
|
|
65
65
|
|
|
66
66
|
```tsx
|
|
67
|
-
import {
|
|
67
|
+
import { NotAuthenticatedBoundary } from 'sekisho';
|
|
68
68
|
|
|
69
69
|
function SomePartOfApp() {
|
|
70
70
|
return (
|
|
71
|
-
<
|
|
71
|
+
<NotAuthenticatedBoundary>
|
|
72
72
|
{/* ... */}
|
|
73
|
-
</
|
|
73
|
+
</NotAuthenticatedBoundary>
|
|
74
74
|
);
|
|
75
75
|
}
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
And if you are using Next.js App Router and `error.tsx` file, due to Next.js layout, page, and error boundary heirarchy, you will also need to wrap the `error.tsx` with `
|
|
78
|
+
And if you are using Next.js App Router and `error.tsx` file, due to Next.js layout, page, and error boundary heirarchy, you will also need to wrap the `error.tsx` with `NotAuthenticatedErrorWrapper`:
|
|
79
79
|
|
|
80
80
|
```tsx
|
|
81
81
|
// app/error.tsx
|
|
82
82
|
'use client';
|
|
83
83
|
|
|
84
|
-
import {
|
|
84
|
+
import { NotAuthenticatedErrorWrapper } from 'sekisho';
|
|
85
85
|
|
|
86
86
|
export default function ErrorPage({ error, reset }) {
|
|
87
87
|
return (
|
|
88
|
-
<
|
|
88
|
+
<NotAuthenticatedErrorWrapper error={error}>
|
|
89
89
|
{/* Your existing error UI goes in here */}
|
|
90
|
-
</
|
|
90
|
+
</NotAuthenticatedErrorWrapper>
|
|
91
91
|
);
|
|
92
92
|
}
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
-
> `
|
|
95
|
+
> `NotAuthenticatedErrorWrapper` is actually used by `NotAuthenticatedBoundary` internally, containing all the core logic.
|
|
96
96
|
|
|
97
97
|
### Triggering a login redirect
|
|
98
98
|
|
|
@@ -133,10 +133,10 @@ export const requireAuthMiddleware: Middleware = (useSWRNext) => (key, fetcher,
|
|
|
133
133
|
|
|
134
134
|
### Restricting access
|
|
135
135
|
|
|
136
|
-
Wrap any part of the UI with `
|
|
136
|
+
Wrap any part of the UI with `AccessRestrictedContainer` and call `accessRestricted()` inside it when the user lacks the required role or permission. Unlike `needLogin()`, which triggers a global redirect via `onNeedLogin`, `accessRestricted()` is local — `AccessRestrictedContainer` simply renders `fallback` in place of its children:
|
|
137
137
|
|
|
138
138
|
```tsx
|
|
139
|
-
import { accessRestricted,
|
|
139
|
+
import { accessRestricted, AccessRestrictedContainer } from 'sekisho';
|
|
140
140
|
|
|
141
141
|
function AdminPanel() {
|
|
142
142
|
const { role } = useCurrentUser();
|
|
@@ -150,16 +150,16 @@ function AdminPanel() {
|
|
|
150
150
|
|
|
151
151
|
function Page() {
|
|
152
152
|
return (
|
|
153
|
-
<
|
|
153
|
+
<AccessRestrictedContainer
|
|
154
154
|
fallback={<p>You don't have permission to view this section.</p>}
|
|
155
155
|
>
|
|
156
156
|
<AdminPanel />
|
|
157
|
-
</
|
|
157
|
+
</AccessRestrictedContainer>
|
|
158
158
|
);
|
|
159
159
|
}
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
-
This kinda like `<Suspense />` but for access control instead. And like `<Suspense />`, you can have multiple `
|
|
162
|
+
This kinda like `<Suspense />` but for access control instead. And like `<Suspense />`, you can have multiple `AccessRestrictedContainer`s nested independently — each one only catches the `accessRestricted()` calls within its own subtree.
|
|
163
163
|
|
|
164
164
|
## Explanation
|
|
165
165
|
|
|
@@ -167,12 +167,12 @@ Sekisho is built on top of React's error boundaries. Both `needLogin()` and `acc
|
|
|
167
167
|
|
|
168
168
|
| Function | Error thrown | Caught by | Behaviour |
|
|
169
169
|
|---|---|---|---|
|
|
170
|
-
| `needLogin()` | `NotAuthenticatedError` | `
|
|
171
|
-
| `accessRestricted()` | `AccessRestrictedError` | `
|
|
170
|
+
| `needLogin()` | `NotAuthenticatedError` | `NotAuthenticatedBoundary` / `NotAuthenticatedErrorWrapper` | Calls `onNeedLogin` from `SekishoProvider` (global redirect) |
|
|
171
|
+
| `accessRestricted()` | `AccessRestrictedError` | `AccessRestrictedContainer` | Renders the `fallback` prop in place of children (local swap) |
|
|
172
172
|
|
|
173
|
-
Each boundary re-throws errors it does not own, so `
|
|
173
|
+
Each boundary re-throws errors it does not own, so `AccessRestrictedContainer` never swallows an auth error, and `NotAuthenticatedBoundary` never swallows an access error. Your own error boundaries are unaffected by either.
|
|
174
174
|
|
|
175
|
-
With `
|
|
175
|
+
With `NotAuthenticatedErrorWrapper` / `NotAuthenticatedBoundary` you can create protected and unprotected routes in any React app:
|
|
176
176
|
|
|
177
177
|
**Next.js App Router**
|
|
178
178
|
|
|
@@ -180,7 +180,7 @@ With `SekishoErrorWrapper` / `SekishoErrorBoundary` you can create protected and
|
|
|
180
180
|
app/
|
|
181
181
|
├── (protected)/ ← all protected routes goes under here
|
|
182
182
|
│ ├── layout.tsx ← wrap children with <SekishoProvider> here
|
|
183
|
-
│ ├── error.tsx ← wrap with <
|
|
183
|
+
│ ├── error.tsx ← wrap with <NotAuthenticatedErrorWrapper> here
|
|
184
184
|
│ └── page.tsx ← homepage, where you call needLogin() when authentication is needed
|
|
185
185
|
├── (unprotected)/ ← all unprotected routes goes under here
|
|
186
186
|
│ └── login/
|
|
@@ -206,9 +206,9 @@ const router = createBrowserRouter([
|
|
|
206
206
|
{
|
|
207
207
|
component() {
|
|
208
208
|
return (
|
|
209
|
-
<
|
|
209
|
+
<NotAuthenticatedBoundary>
|
|
210
210
|
<Outlet />
|
|
211
|
-
</
|
|
211
|
+
</NotAuthenticatedBoundary>
|
|
212
212
|
);
|
|
213
213
|
},
|
|
214
214
|
children: [
|
|
@@ -221,6 +221,53 @@ const router = createBrowserRouter([
|
|
|
221
221
|
]);
|
|
222
222
|
```
|
|
223
223
|
|
|
224
|
+
## Build your own guard
|
|
225
|
+
|
|
226
|
+
Sekisho also provides a low-level abstraction `createSekisho` from `sekisho/factory` for building your own custom gate with the same underlying mechanism. Let's say you want to build a guard for new user onboarding flow, where users need to complete their profile before accessing certain parts of the app:
|
|
227
|
+
|
|
228
|
+
```tsx
|
|
229
|
+
import { createSekisho } from 'sekisho/factory';
|
|
230
|
+
|
|
231
|
+
const [requireOnboarding, OnboardingGate] = createSekisho('OnboardingRequired');
|
|
232
|
+
|
|
233
|
+
function Dashboard() {
|
|
234
|
+
const user = useUser();
|
|
235
|
+
|
|
236
|
+
if (!user.profileComplete) {
|
|
237
|
+
requireOnboarding('Profile incomplete');
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// actual dashboard content
|
|
241
|
+
return <div>Welcome back, {user.name}</div>;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function OnboardingGuard({ error }) {
|
|
245
|
+
redirect('/onboarding');
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Wrap your app with the boundary component
|
|
249
|
+
function Page() {
|
|
250
|
+
return (
|
|
251
|
+
<OnboardingGate
|
|
252
|
+
fallback={<OnboardingGuard />}
|
|
253
|
+
// or you can pass a component that receives the error prop
|
|
254
|
+
fallbackComponent={OnboardingGuard}
|
|
255
|
+
>
|
|
256
|
+
<Dashboard />
|
|
257
|
+
</OnboardingGate>
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
The `createSekisho()` factory returns a 4-tuple: `[throwFn, BoundaryComponent, isError, ErrorClass]`. You can name each element whatever makes sense for your use case:
|
|
263
|
+
|
|
264
|
+
- **`throwFn`** — Call this during render to trigger the guard when a condition is unmet
|
|
265
|
+
- **`BoundaryComponent`** — Error boundary that catches errors thrown by `throwFn`. Accepts `fallback` (static UI) or `fallbackComponent` (component that receives `{ error }`)
|
|
266
|
+
- **`isError`** — Type guard to check if an error is from this guard (useful in middleware or error handlers)
|
|
267
|
+
- **`ErrorClass`** — The error constructor, if you need `instanceof` checks
|
|
268
|
+
|
|
269
|
+
Each call to `createSekisho()` is isolated — guards never accidentally catch each other's errors, even if nested.
|
|
270
|
+
|
|
224
271
|
## License
|
|
225
272
|
|
|
226
273
|
[MIT](LICENSE)
|
package/dist/factory.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";Object.defineProperty(exports,"__esModule",{value:!0});var r=require("react/jsx-runtime"),e=require("foxact/create-stackless-error"),t=require("react");exports.createSekisho=function(s){let o=new WeakSet;class n extends Error{constructor(r){super(r),this.digest="BAILOUT_TO_CLIENT_SIDE_RENDERING",this.name=s??"SekishoGuardError",o.add(this)}}function a(r){return!!r&&"object"==typeof r&&o.has(r)}class c extends t.Component{constructor(r){super(r),this.state={caughtError:null}}static getDerivedStateFromError(r){if(a(r))return{caughtError:r};throw r}render(){let{caughtError:e}=this.state;if(null!==e){let{fallback:t,fallbackComponent:s}=this.props;return s?r.jsx(s,{error:e}):t}return this.props.children}}return[function(r){throw e.createStacklessError(()=>new n(r))},c,a,n]};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/** Base interface for every guard error created by `createSekisho`. */
|
|
2
|
+
interface SekishoGuardError extends Error {
|
|
3
|
+
readonly digest: 'BAILOUT_TO_CLIENT_SIDE_RENDERING';
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Props accepted by the boundary component returned from `createSekisho`.
|
|
7
|
+
*
|
|
8
|
+
* Exactly one of `fallback` or `fallbackComponent` must be provided:
|
|
9
|
+
*
|
|
10
|
+
* - `fallback` — a static `ReactNode` rendered in place of children when the
|
|
11
|
+
* guard fires (access-control pattern).
|
|
12
|
+
* - `fallbackComponent` — a React component that receives `{ error }` as props.
|
|
13
|
+
* Use this when you need the caught error object, e.g. to trigger a
|
|
14
|
+
* navigation side-effect (auth pattern).
|
|
15
|
+
*/
|
|
16
|
+
type SekishoGuardBoundaryProps = React.PropsWithChildren & ({
|
|
17
|
+
fallback: React.ReactNode;
|
|
18
|
+
fallbackComponent?: never;
|
|
19
|
+
} | {
|
|
20
|
+
fallback?: never;
|
|
21
|
+
fallbackComponent: React.ComponentType<{
|
|
22
|
+
error: SekishoGuardError;
|
|
23
|
+
}>;
|
|
24
|
+
});
|
|
25
|
+
interface SekishoGuardBoundaryState {
|
|
26
|
+
caughtError: SekishoGuardError | null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Creates a paired guard throw function, error boundary component, type guard,
|
|
30
|
+
* and error class — all isolated from every other guard in the tree.
|
|
31
|
+
*
|
|
32
|
+
* Call the returned throw function anywhere in the React render phase to signal
|
|
33
|
+
* that a condition is unmet. The nearest boundary component in the tree will
|
|
34
|
+
* catch it and render its `fallback` prop instead of `children`. Every other
|
|
35
|
+
* error boundary — including ones from other `createSekisho()` calls —
|
|
36
|
+
* re-throws the error unchanged.
|
|
37
|
+
*
|
|
38
|
+
* Returns a 4-tuple so each element can be named freely on destructure:
|
|
39
|
+
* `[throwFn, BoundaryComponent, isError, ErrorClass]`
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* // Access-control pattern — static fallback element:
|
|
43
|
+
* const [requireOnboarding, OnboardingGate] = createSekisho();
|
|
44
|
+
*
|
|
45
|
+
* <OnboardingGate fallback={<OnboardingWizard />}>
|
|
46
|
+
* <Profile />
|
|
47
|
+
* </OnboardingGate>
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* // Callback pattern — component receives the error object:
|
|
51
|
+
* const [requireAuth, AuthGate] = createSekisho();
|
|
52
|
+
*
|
|
53
|
+
* <AuthGate fallbackComponent={AuthErrorHandler}>
|
|
54
|
+
* <Dashboard />
|
|
55
|
+
* </AuthGate>
|
|
56
|
+
*/
|
|
57
|
+
declare function createSekisho(errorName?: string): [
|
|
58
|
+
throwError: (message: string) => never,
|
|
59
|
+
BoundaryComponent: React.ComponentClass<SekishoGuardBoundaryProps, SekishoGuardBoundaryState>,
|
|
60
|
+
isError: (error: unknown) => error is SekishoGuardError,
|
|
61
|
+
ErrorClass: new (message: string) => SekishoGuardError
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
export { createSekisho };
|
|
65
|
+
export type { SekishoGuardBoundaryProps, SekishoGuardBoundaryState, SekishoGuardError };
|
package/dist/factory.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as r}from"react/jsx-runtime";import{createStacklessError as t}from"foxact/create-stackless-error";import{Component as e}from"react";function o(o){let s=new WeakSet;class n extends Error{constructor(r){super(r),this.digest="BAILOUT_TO_CLIENT_SIDE_RENDERING",this.name=o??"SekishoGuardError",s.add(this)}}function i(r){return!!r&&"object"==typeof r&&s.has(r)}return[function(r){throw t(()=>new n(r))},class extends e{constructor(r){super(r),this.state={caughtError:null}}static getDerivedStateFromError(r){if(i(r))return{caughtError:r};throw r}render(){let{caughtError:t}=this.state;if(null!==t){let{fallback:e,fallbackComponent:o}=this.props;return o?r(o,{error:t}):e}return this.props.children}},i,n]}export{o as createSekisho};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("
|
|
1
|
+
"use client";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react/jsx-runtime"),r=require("foxact/use-isomorphic-layout-effect"),t=require("foxact/use-stable-handler-only-when-you-know-what-you-are-doing-or-you-will-be-fired"),o=require("./factory.cjs"),s=require("foxact/nullthrow"),i=require("react");let n=i.createContext(null),[c,u,a,l]=o.createSekisho("NotAuthenticatedError");function d({error:e,children:o}){let{onNeedLogin:c}=s.nullthrow(i.useContext(n),"useSekishoOptions must be used within a SekishoOptionsProvider"),u=a(e),l=t.useStableHandler(c);return(r.useLayoutEffect(()=>{u&&l()},[u,l]),u)?null:o}function p({children:r}){return e.jsx(u,{fallbackComponent:d,children:r})}let[h,x,f,k]=o.createSekisho("AccessRestrictedError");Object.defineProperty(exports,"createSekisho",{enumerable:!0,get:function(){return o.createSekisho}}),exports.AccessRestrictedContainer=x,exports.AccessRestrictedError=k,exports.NotAuthenticatedBoundary=p,exports.NotAuthenticatedError=l,exports.NotAuthenticatedErrorWrapper=d,exports.SekishoAccessContainer=x,exports.SekishoErrorBoundary=p,exports.SekishoErrorWrapper=d,exports.SekishoProvider=function({children:r,...t}){return e.jsx(n.Provider,{value:t,children:e.jsx(p,{children:r})})},exports.accessRestricted=h,exports.isAccessRestrictedError=f,exports.isNeedLoginError=a,exports.needLogin=c;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,64 +1,39 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import
|
|
2
|
+
import * as __factory from './factory.js';
|
|
3
|
+
import { SekishoGuardBoundaryProps } from './factory.js';
|
|
4
|
+
export { SekishoGuardBoundaryProps, SekishoGuardBoundaryState, SekishoGuardError, createSekisho } from './factory.js';
|
|
3
5
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
6
|
|
|
5
|
-
declare
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
* it will find the nearest Suspense boundary and render its fallback (on
|
|
12
|
-
* the client it would find the nearest error boundary instead).
|
|
13
|
-
*
|
|
14
|
-
* For various purposes, Next.js also uses this mechanism to bail out of
|
|
15
|
-
* server-side rendering to do client-side rendering only. Thus Next.js
|
|
16
|
-
* create this magic digest 'BAILOUT_TO_CLIENT_SIDE_RENDERING' that does
|
|
17
|
-
* nothing but allow every error report (console, reportError, etc.) to
|
|
18
|
-
* skip this error
|
|
19
|
-
*
|
|
20
|
-
* Next.js doesn't handle this error in any special way. It is React itself
|
|
21
|
-
* who contains the "special handling".
|
|
22
|
-
*
|
|
23
|
-
* So we can safely re-use this digest to make sure that the error is not
|
|
24
|
-
* reported by Next.js
|
|
25
|
-
*/
|
|
26
|
-
readonly digest = "BAILOUT_TO_CLIENT_SIDE_RENDERING";
|
|
7
|
+
declare const needLogin: (message: string) => never;
|
|
8
|
+
declare const isNeedLoginError: (error: unknown) => error is __factory.SekishoGuardError;
|
|
9
|
+
declare const NotAuthenticatedError: new (message: string) => __factory.SekishoGuardError;
|
|
10
|
+
|
|
11
|
+
interface NotAuthenticatedErrorWrapperProps extends React.PropsWithChildren {
|
|
12
|
+
error: unknown | null | undefined;
|
|
27
13
|
}
|
|
28
|
-
|
|
14
|
+
/** @deprecated `SekishoErrorWrapperProps` has since been renamed to `NotAuthenticatedErrorWrapperProps` */
|
|
15
|
+
type SekishoErrorWrapperProps = NotAuthenticatedErrorWrapperProps;
|
|
29
16
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* The error is caught by the nearest `SekishoErrorWrapper` or
|
|
33
|
-
* `SekishoErrorBoundary`, which then calls the `onNeedLogin` callback supplied
|
|
34
|
-
* to `SekishoProvider`.
|
|
17
|
+
* The actual error handling and redirection logic for "Not Authenticated" error.
|
|
35
18
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
19
|
+
* Used internally by `NotAuthenticatedBoundary`. You can also use this directly in
|
|
20
|
+
* a Next.js `app/error.tsx` file for custom error handling.
|
|
38
21
|
*/
|
|
39
|
-
declare function
|
|
22
|
+
declare function NotAuthenticatedErrorWrapper({ error, children }: NotAuthenticatedErrorWrapperProps): react.ReactNode;
|
|
40
23
|
|
|
41
|
-
interface
|
|
42
|
-
error: unknown | null | undefined;
|
|
24
|
+
interface NotAuthenticatedBoundaryProps extends React.PropsWithChildren {
|
|
43
25
|
}
|
|
44
26
|
/**
|
|
45
|
-
*
|
|
27
|
+
* Error boundary that catches `NotAuthenticatedError` thrown by `needLogin()`
|
|
28
|
+
* within its subtree and calls the `onNeedLogin` callback from `SekishoProvider`.
|
|
29
|
+
* All other errors are re-thrown to the next boundary up the tree.
|
|
46
30
|
*
|
|
47
|
-
* This is
|
|
48
|
-
* you
|
|
31
|
+
* This is included inside `SekishoProvider` automatically; you only need to use
|
|
32
|
+
* it directly if you want a narrower boundary for a specific subtree.
|
|
49
33
|
*/
|
|
50
|
-
declare function
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
interface SekishoErrorBoundaryState {
|
|
55
|
-
needLoginErrorObject: unknown | null | undefined;
|
|
56
|
-
}
|
|
57
|
-
declare class SekishoErrorBoundary extends Component<SekishoErrorBoundaryProps, SekishoErrorBoundaryState> {
|
|
58
|
-
constructor(props: SekishoErrorBoundaryProps);
|
|
59
|
-
static getDerivedStateFromError(this: void, error: unknown): SekishoErrorBoundaryState;
|
|
60
|
-
render(): React.ReactNode;
|
|
61
|
-
}
|
|
34
|
+
declare function NotAuthenticatedBoundary({ children }: NotAuthenticatedBoundaryProps): React.ReactNode;
|
|
35
|
+
/** @deprecated `SekishoErrorBoundaryProps` has since been renamed to `NotAuthenticatedBoundaryProps` */
|
|
36
|
+
type SekishoErrorBoundaryProps = NotAuthenticatedBoundaryProps;
|
|
62
37
|
|
|
63
38
|
interface SekishoOptions {
|
|
64
39
|
onNeedLogin: () => void;
|
|
@@ -68,55 +43,15 @@ interface SekishoProviderProps extends React.PropsWithChildren, SekishoOptions {
|
|
|
68
43
|
}
|
|
69
44
|
declare function SekishoProvider({ children, ...auth }: SekishoProviderProps): react_jsx_runtime.JSX.Element;
|
|
70
45
|
|
|
71
|
-
declare
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
* nothing but allow every error report (console, reportError, etc.) to
|
|
84
|
-
* skip this error
|
|
85
|
-
*
|
|
86
|
-
* Next.js doesn't handle this error in any special way. It is React itself
|
|
87
|
-
* who contains the "special handling".
|
|
88
|
-
*
|
|
89
|
-
* So we can safely re-use this digest to make sure that the error is not
|
|
90
|
-
* reported by Next.js
|
|
91
|
-
*/
|
|
92
|
-
readonly digest = "BAILOUT_TO_CLIENT_SIDE_RENDERING";
|
|
93
|
-
}
|
|
94
|
-
declare function isAccessRestrictedError(error: unknown): error is AccessRestrictedError;
|
|
95
|
-
/**
|
|
96
|
-
* Throw an `AccessRestrictedError` from anywhere in the React render phase.
|
|
97
|
-
*
|
|
98
|
-
* The error is caught by the nearest `SekishoAccessContainer`, which renders
|
|
99
|
-
* its `fallback` prop instead of its children. Any other error boundary in the
|
|
100
|
-
* tree (including `SekishoErrorBoundary`) re-throws it unchanged.
|
|
101
|
-
*/
|
|
102
|
-
declare function accessRestricted(message: string): never;
|
|
103
|
-
|
|
104
|
-
interface SekishoAccessContainerProps extends React.PropsWithChildren {
|
|
105
|
-
fallback: React.ReactNode;
|
|
106
|
-
}
|
|
107
|
-
interface State {
|
|
108
|
-
restricted: boolean;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Error boundary that catches `AccessRestrictedError` thrown by
|
|
112
|
-
* `accessRestricted()` within its subtree and renders `fallback` in place of
|
|
113
|
-
* `children`. All other errors are re-thrown to the next boundary up the tree.
|
|
114
|
-
*/
|
|
115
|
-
declare class SekishoAccessContainer extends Component<SekishoAccessContainerProps, State> {
|
|
116
|
-
constructor(props: SekishoAccessContainerProps);
|
|
117
|
-
static getDerivedStateFromError(this: void, error: unknown): State;
|
|
118
|
-
render(): React.ReactNode;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export { AccessRestrictedError, NotAuthenticatedError, SekishoAccessContainer, SekishoErrorBoundary, SekishoErrorWrapper, SekishoProvider, accessRestricted, isAccessRestrictedError, isNeedLoginError, needLogin };
|
|
122
|
-
export type { SekishoAccessContainerProps, SekishoErrorBoundaryProps, SekishoErrorWrapperProps, SekishoOptions, SekishoProviderProps };
|
|
46
|
+
declare const accessRestricted: (message: string) => never;
|
|
47
|
+
declare const AccessRestrictedContainer: react.ComponentClass<SekishoGuardBoundaryProps, __factory.SekishoGuardBoundaryState>;
|
|
48
|
+
declare const isAccessRestrictedError: (error: unknown) => error is __factory.SekishoGuardError;
|
|
49
|
+
declare const AccessRestrictedError: new (message: string) => __factory.SekishoGuardError;
|
|
50
|
+
type AccessRestrictedContainerProps = SekishoGuardBoundaryProps;
|
|
51
|
+
/** @deprecated `SekishoAccessContainer` has since been renamed to `AccessRestrictedContainer` */
|
|
52
|
+
declare const SekishoAccessContainer: react.ComponentClass<SekishoGuardBoundaryProps, __factory.SekishoGuardBoundaryState>;
|
|
53
|
+
/** @deprecated `SekishoAccessContainerProps` has since been renamed to `AccessRestrictedContainerProps` */
|
|
54
|
+
type SekishoAccessContainerProps = AccessRestrictedContainerProps;
|
|
55
|
+
|
|
56
|
+
export { AccessRestrictedContainer, AccessRestrictedError, NotAuthenticatedBoundary, NotAuthenticatedError, NotAuthenticatedErrorWrapper, SekishoAccessContainer, NotAuthenticatedBoundary as SekishoErrorBoundary, NotAuthenticatedErrorWrapper as SekishoErrorWrapper, SekishoProvider, accessRestricted, isAccessRestrictedError, isNeedLoginError, needLogin };
|
|
57
|
+
export type { AccessRestrictedContainerProps, NotAuthenticatedBoundaryProps, NotAuthenticatedErrorWrapperProps, SekishoAccessContainerProps, SekishoErrorBoundaryProps, SekishoErrorWrapperProps, SekishoOptions, SekishoProviderProps };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{
|
|
1
|
+
"use client";import{jsx as r}from"react/jsx-runtime";import{useLayoutEffect as e}from"foxact/use-isomorphic-layout-effect";import{useStableHandler as t}from"foxact/use-stable-handler-only-when-you-know-what-you-are-doing-or-you-will-be-fired";import{createSekisho as o}from"./factory.mjs";export{createSekisho}from"./factory.mjs";import{nullthrow as i}from"foxact/nullthrow";import{createContext as n,useContext as c}from"react";let s=n(null),[a,u,d,h]=o("NotAuthenticatedError");function l({error:r,children:o}){let{onNeedLogin:n}=i(c(s),"useSekishoOptions must be used within a SekishoOptionsProvider"),a=d(r),u=t(n);return(e(()=>{a&&u()},[a,u]),a)?null:o}function f({children:e}){return r(u,{fallbackComponent:l,children:e})}function m({children:e,...t}){return r(s.Provider,{value:t,children:r(f,{children:e})})}let[p,A,y,E]=o("AccessRestrictedError"),k=A;export{A as AccessRestrictedContainer,E as AccessRestrictedError,f as NotAuthenticatedBoundary,h as NotAuthenticatedError,l as NotAuthenticatedErrorWrapper,k as SekishoAccessContainer,f as SekishoErrorBoundary,l as SekishoErrorWrapper,m as SekishoProvider,p as accessRestricted,y as isAccessRestrictedError,d as isNeedLoginError,a as needLogin};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sekisho",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Authentication and Access Control for any React app",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -21,6 +21,12 @@
|
|
|
21
21
|
"require": "./dist/index.cjs",
|
|
22
22
|
"default": "./dist/index.cjs"
|
|
23
23
|
},
|
|
24
|
+
"./factory": {
|
|
25
|
+
"types": "./dist/factory.d.ts",
|
|
26
|
+
"import": "./dist/factory.mjs",
|
|
27
|
+
"require": "./dist/factory.cjs",
|
|
28
|
+
"default": "./dist/factory.cjs"
|
|
29
|
+
},
|
|
24
30
|
"./package.json": "./package.json"
|
|
25
31
|
},
|
|
26
32
|
"author": "Sukka <https://skk.moe>",
|
|
@@ -29,7 +35,7 @@
|
|
|
29
35
|
"foxact": "^0.3.1"
|
|
30
36
|
},
|
|
31
37
|
"devDependencies": {
|
|
32
|
-
"@swc/core": "^1.15.
|
|
38
|
+
"@swc/core": "^1.15.33",
|
|
33
39
|
"@types/react": "^19.2.14",
|
|
34
40
|
"bunchee": "^6.10.0"
|
|
35
41
|
},
|