@react-protected/core 0.2.0-beta.2 → 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/CHANGELOG.md ADDED
@@ -0,0 +1,36 @@
1
+ # @react-protected/core
2
+
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - cb262d3: loader, action and middleware support
8
+
9
+ ## 0.2.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 05cda4d: Update roadmap and docs
14
+
15
+ ### Patch Changes
16
+
17
+ - 4b835f6: Docs added
18
+ - 11a6537: Configure Changesets-based release automation and public package publish metadata.
19
+
20
+ ## 0.2.0-beta.2
21
+
22
+ ### Minor Changes
23
+
24
+ - 05cda4d: Update roadmap and docs
25
+
26
+ ## 0.1.1-beta.1
27
+
28
+ ### Patch Changes
29
+
30
+ - 4b835f6: Docs added
31
+
32
+ ## 0.1.1-beta.0
33
+
34
+ ### Patch Changes
35
+
36
+ - 11a6537: Configure Changesets-based release automation and public package publish metadata.
package/README.md CHANGED
@@ -1,22 +1,6 @@
1
1
  # @react-protected/core
2
2
 
3
- Framework-agnostic access-control logic. No dependency on React, a router, or a store.
4
-
5
- ---
6
-
7
- ## Installation
8
-
9
- ```bash
10
- npm install @react-protected/core
11
- ```
12
-
13
- ```bash
14
- yarn add @react-protected/core
15
- ```
16
-
17
- ```bash
18
- pnpm add @react-protected/core
19
- ```
3
+ Framework-agnostic access-control logic. No dependency on React, a router, or redirect policy.
20
4
 
21
5
  ## Usage
22
6
 
@@ -27,36 +11,20 @@ const guard = createGuard({
27
11
  getUser: () => store.getState().user,
28
12
  hasRole: (user, roles) => roles.some((role) => user.roles.includes(role)),
29
13
  hasPermission: (user, permissions) =>
30
- permissions.every((p) => user.permissions.includes(p)),
14
+ permissions.every((permission) => user.permissions.includes(permission)),
31
15
  })
32
16
 
33
17
  const result = guard.check({ access: 'authenticated', roles: ['admin'] })
34
18
 
35
- if (result.allowed) {
36
- // permit access
37
- } else {
38
- // result.reason: 'unauthenticated' | 'forbidden'
19
+ if (!result.allowed) {
20
+ // result.reason: 'unauthenticated' | 'authenticated' | 'forbidden'
39
21
  }
40
22
  ```
41
23
 
42
- ### Implicit auth requirement
43
-
44
- When `roles` or `permissions` are set without an explicit `access` field, the route is treated as `'authenticated'` automatically:
45
-
46
- ```ts
47
- guard.check({ roles: ['admin'] })
48
- // equivalent to: guard.check({ access: 'authenticated', roles: ['admin'] })
49
- ```
50
-
51
- ## Packages
52
-
53
- | Package | Description |
54
- | --- | --- |
55
- | `@react-protected/core` | This package — pure access-control logic |
56
- | `@react-protected/react` | React context, hooks, and `HasAccess` component |
57
- | `@react-protected/react-router` | Adapter for React Router |
24
+ Supported access levels:
58
25
 
59
- ## Documentation
26
+ - `'public'`
27
+ - `'authenticated'`
28
+ - `'unauthenticated'`
60
29
 
61
- - [Core API](https://github.com/astakhovaskold/react-protected/blob/main/docs/en/api/core.md)
62
- - [Examples](https://github.com/astakhovaskold/react-protected/blob/main/docs/en/README.md)
30
+ When `roles` or `permissions` are set without `access`, the guard treats the config as authenticated-only.
@@ -1,2 +1,11 @@
1
1
  import { Guard, GuardOptions } from './types';
2
+ /**
3
+ * Creates a guard that evaluates access against the current user.
4
+ *
5
+ * @typeParam TUser - User shape returned by `getUser`.
6
+ * @param options - Access callbacks and user accessors used by the guard.
7
+ * @returns A reusable guard with resolved defaults for authentication, role, and permission checks.
8
+ * @remarks When `roles` or `permissions` are provided without `access`, the guard treats the config
9
+ * as authenticated-only.
10
+ */
2
11
  export declare function createGuard<TUser = unknown>(options: GuardOptions<TUser>): Guard<TUser>;
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function u(r){const s={getUser:r.getUser,isAuthenticated:r.isAuthenticated??(e=>e!==null),hasRole:r.hasRole??(()=>!1),hasPermission:r.hasPermission??(()=>!1)};return{check:e=>{var a,l,n,i;const t=s.getUser(),o=s.isAuthenticated(t);return((e.access??"public")==="authenticated"||!!((a=e.roles)!=null&&a.length)||!!((l=e.permissions)!=null&&l.length))&&!o?{allowed:!1,reason:"unauthenticated"}:(n=e.roles)!=null&&n.length&&t&&!s.hasRole(t,e.roles)?{allowed:!1,reason:"forbidden"}:(i=e.permissions)!=null&&i.length&&t&&!s.hasPermission(t,e.permissions)?{allowed:!1,reason:"forbidden"}:{allowed:!0}},options:s}}exports.createGuard=u;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function c(a){const s={getUser:a.getUser,isAuthenticated:a.isAuthenticated??(e=>e!==null),hasRole:a.hasRole??(()=>!1),hasPermission:a.hasPermission??(()=>!1)};return{check:e=>{var n,o,i,u;const t=s.getUser(),r=s.isAuthenticated(t),l=e.access??"public",d=l==="authenticated"||!!((n=e.roles)!=null&&n.length)||!!((o=e.permissions)!=null&&o.length);return l==="unauthenticated"?r?{allowed:!1,reason:"authenticated"}:{allowed:!0}:d&&!r?{allowed:!1,reason:"unauthenticated"}:(i=e.roles)!=null&&i.length&&t&&!s.hasRole(t,e.roles)?{allowed:!1,reason:"forbidden"}:(u=e.permissions)!=null&&u.length&&t&&!s.hasPermission(t,e.permissions)?{allowed:!1,reason:"forbidden"}:{allowed:!0}},options:s}}exports.createGuard=c;
package/dist/index.js CHANGED
@@ -1,16 +1,16 @@
1
- function d(r) {
1
+ function c(a) {
2
2
  const s = {
3
- getUser: r.getUser,
4
- isAuthenticated: r.isAuthenticated ?? ((e) => e !== null),
5
- hasRole: r.hasRole ?? (() => !1),
6
- hasPermission: r.hasPermission ?? (() => !1)
3
+ getUser: a.getUser,
4
+ isAuthenticated: a.isAuthenticated ?? ((e) => e !== null),
5
+ hasRole: a.hasRole ?? (() => !1),
6
+ hasPermission: a.hasPermission ?? (() => !1)
7
7
  };
8
8
  return { check: (e) => {
9
- var a, n, l, i;
10
- const t = s.getUser(), o = s.isAuthenticated(t);
11
- return ((e.access ?? "public") === "authenticated" || !!((a = e.roles) != null && a.length) || !!((n = e.permissions) != null && n.length)) && !o ? { allowed: !1, reason: "unauthenticated" } : (l = e.roles) != null && l.length && t && !s.hasRole(t, e.roles) ? { allowed: !1, reason: "forbidden" } : (i = e.permissions) != null && i.length && t && !s.hasPermission(t, e.permissions) ? { allowed: !1, reason: "forbidden" } : { allowed: !0 };
9
+ var l, o, i, u;
10
+ const t = s.getUser(), r = s.isAuthenticated(t), n = e.access ?? "public", h = n === "authenticated" || !!((l = e.roles) != null && l.length) || !!((o = e.permissions) != null && o.length);
11
+ return n === "unauthenticated" ? r ? { allowed: !1, reason: "authenticated" } : { allowed: !0 } : h && !r ? { allowed: !1, reason: "unauthenticated" } : (i = e.roles) != null && i.length && t && !s.hasRole(t, e.roles) ? { allowed: !1, reason: "forbidden" } : (u = e.permissions) != null && u.length && t && !s.hasPermission(t, e.permissions) ? { allowed: !1, reason: "forbidden" } : { allowed: !0 };
12
12
  }, options: s };
13
13
  }
14
14
  export {
15
- d as createGuard
15
+ c as createGuard
16
16
  };
package/dist/types.d.ts CHANGED
@@ -1,26 +1,76 @@
1
- export type AccessLevel = 'public' | 'authenticated';
1
+ /**
2
+ * Access level handled by the framework-agnostic guard.
3
+ */
4
+ export type AccessLevel = 'public' | 'authenticated' | 'unauthenticated';
5
+ /**
6
+ * Access requirements consumed by `guard.check()` and adapter components.
7
+ */
2
8
  export type AccessConfig = {
9
+ /**
10
+ * Declares whether access is public, requires an authenticated user, or requires
11
+ * an unauthenticated user.
12
+ * Defaults to `'public'` when omitted.
13
+ */
3
14
  access?: AccessLevel;
15
+ /**
16
+ * Roles that must be satisfied by your `hasRole` callback.
17
+ */
4
18
  roles?: Array<string>;
19
+ /**
20
+ * Permissions that must be satisfied by your `hasPermission` callback.
21
+ */
5
22
  permissions?: Array<string>;
23
+ /**
24
+ * Optional metadata for application-specific access logic.
25
+ */
6
26
  meta?: Record<string, unknown>;
7
27
  };
28
+ /**
29
+ * Result returned by `guard.check()`.
30
+ */
8
31
  export type AccessResult = {
9
32
  allowed: true;
10
33
  } | {
11
34
  allowed: false;
12
35
  reason: 'unauthenticated';
36
+ } | {
37
+ allowed: false;
38
+ reason: 'authenticated';
13
39
  } | {
14
40
  allowed: false;
15
41
  reason: 'forbidden';
16
42
  };
43
+ /**
44
+ * Callbacks and accessors used to create a guard instance.
45
+ */
17
46
  export type GuardOptions<TUser = unknown> = {
47
+ /**
48
+ * Returns the current user or `null` when no user is available.
49
+ */
18
50
  getUser: () => TUser | null;
51
+ /**
52
+ * Overrides the default authenticated check of `user !== null`.
53
+ */
19
54
  isAuthenticated?: (user: TUser | null) => boolean;
55
+ /**
56
+ * Determines whether the current user satisfies the requested roles.
57
+ */
20
58
  hasRole?: (user: TUser, roles: Array<string>) => boolean;
59
+ /**
60
+ * Determines whether the current user satisfies the requested permissions.
61
+ */
21
62
  hasPermission?: (user: TUser, permissions: Array<string>) => boolean;
22
63
  };
64
+ /**
65
+ * Guard instance returned by `createGuard()`.
66
+ */
23
67
  export type Guard<TUser = unknown> = {
68
+ /**
69
+ * Evaluates whether the current user satisfies the provided access config.
70
+ */
24
71
  check: (config: AccessConfig) => AccessResult;
72
+ /**
73
+ * Resolved guard callbacks with built-in defaults applied.
74
+ */
25
75
  options: Required<GuardOptions<TUser>>;
26
76
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-protected/core",
3
- "version": "0.2.0-beta.2",
3
+ "version": "0.3.0",
4
4
  "license": "MIT",
5
5
  "description": "Framework-agnostic route protection logic",
6
6
  "main": "./dist/index.cjs",
@@ -22,7 +22,8 @@
22
22
  }
23
23
  },
24
24
  "files": [
25
- "dist"
25
+ "dist",
26
+ "CHANGELOG.md"
26
27
  ],
27
28
  "devDependencies": {
28
29
  "vite": "^5.0.0",