@aiquants/authz-react-router 0.4.0 → 0.5.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 CHANGED
@@ -114,7 +114,9 @@ Multiple roles **union** (wider wins): rows OR'd (any `NULL` ⇒ all rows); colu
114
114
 
115
115
  ## API
116
116
 
117
- - `createAuthz({ appKey, resolveUserId, getEffectivePermissions, onDeny? })` → `{ requirePermission, getMyPermissions, requireAndGetPermission }`.
117
+ - `createAuthz({ appKey, resolveUserId, resolveGroupIds?, getEffectivePermissions, onDeny? })` → `{ requirePermission, getMyPermissions, requireAndGetPermission }`.
118
+ - `resolveGroupIds(request)` → the acting user's group ids. Forwarded automatically to `getEffectivePermissions` by both `requirePermission` and `getMyPermissions`, so group-granted roles count toward effective permissions. Returning `null`/`undefined` (or omitting the port) sends no `groupIds` at all.
119
+ ⚠️ Without this port, roles assigned to groups in the admin UI have **no runtime effect** — the store writes succeed and the UI looks correct, so the failure is silent. Cover the wiring with a test.
118
120
  - `requirePermission(request, {resourceKey, action}, options?)` → `{ userId, scope }` on allow (so loaders apply row WHERE / column mask — not just 403). Denies throw `AuthzDeniedError` (403), or `throw redirect(options.failureRedirect)` when set.
119
121
  - `requireAndGetPermission(request, {resourceKey, action}, options?)` → `{ userId, scope, permission }`. Atomically performs guard and fetches matching UI `PermissionView` to prevent page-resource mismatches.
120
122
  - `defineResources({ ... })` → Type-safe centralized resource registry helper for resource keys and display names.
@@ -125,6 +127,15 @@ Multiple roles **union** (wider wins): rows OR'd (any `NULL` ⇒ all rows); colu
125
127
  - `<MyPermissionStatus permission={view} resourceName="Documents" expectedResourceKey="documents" prefixLabel="Your Permissions" />` → Reusable status component combining prefix label and permission indicator badges for any application page.
126
128
  - `<MyPermissionGroupStatus items={[{ resourceName: "Primary Resource", permission: primaryView }, { resourceName: "Sub Resource", permission: subView, level: 1 }]} variant="pills" | "popover" size="xs" labels={{ fullWrite: "Writable", readOnly: "Read-only" }} />` → Multi-resource permission widget for pages with multiple distinct resource scopes. Supports inline status tags (`variant="pills"`), single-button popover cards (`variant="popover"`), hierarchical tree indentation via `level` / `children`, and fully customizable status label mappings (`labels`).
127
129
 
130
+ ## Admin UI tabs
131
+
132
+ The splat-mounted admin app (`createAuthzAdminApp`) serves `roles`, `resources`, `role_permissions`, `user_roles`, plus:
133
+
134
+ - **`group_roles`** — assign/revoke roles for a group. Group names are read from the group table; they are never synthesized from ids.
135
+ - **`graph`** — a read-only topology map of *resource → role → group → user*. Nodes with no connections are hidden, and selecting a node highlights only the paths that actually reach it. Node dimming and edge highlighting are driven by the **same** predicate, so an edge never glows while both of its endpoints are dimmed; edges carry `data-testid` and `data-active` so this stays testable.
136
+
137
+ Reads require `read` on the admin resource; writes require the verb matching their effect (`create` / `update` / `delete`).
138
+
128
139
  ## Demo App
129
140
 
130
141
  This package contains an interactive React Router 7 SPA demo in the `demo/` subdirectory. The demo app runs completely in the browser, using `localStorage` to mock database storage.
package/dist/index.d.mts CHANGED
@@ -1,19 +1,22 @@
1
+ import * as react_router from 'react-router';
1
2
  import * as react from 'react';
2
3
  import { ReactNode, CSSProperties } from 'react';
3
4
  import * as _aiquants_authz_core from '@aiquants/authz-core';
4
- import { EffectivePermission, DenyInfo, AuthzAction, GuardResult, AuthzGrant, AuthzResource, AuthzRole, AuthzAssignment, AuthzUser, AuthzAdminStore } from '@aiquants/authz-core';
5
- import * as react_router from 'react-router';
5
+ import { EffectivePermission, DenyInfo, AuthzAction, GuardResult, AuthzGrant, AuthzUser, AuthzRole, AuthzResource, AuthzAssignment, AuthzGroupRoleAssignment, AuthzGroupSummary, AuthzAdminStore } from '@aiquants/authz-core';
6
6
 
7
7
  type Awaitable<T> = T | Promise<T>;
8
8
  type AuthzUserId = string | number;
9
9
  type AuthzConfig = {
10
10
  /** Stable app identifier (e.g. "quants"). Bound into every permission query. */
11
11
  appKey: string;
12
- /** Resolve the acting user id from the request (cookie/session/openid → TDUsers.id). */
12
+ /** Resolve the acting user id from the request (cookie/session/openid → the consumer's user id). */
13
13
  resolveUserId: (request: Request) => Awaitable<AuthzUserId | null | undefined>;
14
+ /** Optionally resolve acting user's group IDs from the request or session. */
15
+ resolveGroupIds?: (request: Request) => Awaitable<(string | number)[] | null | undefined>;
14
16
  /** Load effective permissions for (user, app, resource) — typically via @aiquants/authz-drizzle. */
15
17
  getEffectivePermissions: (args: {
16
18
  userId: AuthzUserId | null;
19
+ groupIds?: (string | number)[];
17
20
  appKey: string;
18
21
  resourceKey: string;
19
22
  }) => Awaitable<EffectivePermission | null | undefined>;
@@ -70,6 +73,8 @@ type AuthzAdminLabels = {
70
73
  resources: string;
71
74
  role_permissions: string;
72
75
  user_roles: string;
76
+ group_roles: string;
77
+ graph: string;
73
78
  };
74
79
  common: {
75
80
  add: string;
@@ -134,6 +139,15 @@ type AuthzAdminLabels = {
134
139
  newHeading: string;
135
140
  selectPlaceholder: string;
136
141
  };
142
+ groupRoles: {
143
+ heading: string;
144
+ note: string;
145
+ group: string;
146
+ role: string;
147
+ empty: string;
148
+ newHeading: string;
149
+ selectPlaceholder: string;
150
+ };
137
151
  error: {
138
152
  forbiddenTitle: string;
139
153
  forbiddenBody: string;
@@ -157,6 +171,7 @@ type PartialAuthzAdminLabels = {
157
171
  resources?: Partial<AuthzAdminLabels["resources"]>;
158
172
  grants?: Partial<AuthzAdminLabels["grants"]>;
159
173
  userRoles?: Partial<AuthzAdminLabels["userRoles"]>;
174
+ groupRoles?: Partial<AuthzAdminLabels["groupRoles"]>;
160
175
  error?: Partial<AuthzAdminLabels["error"]>;
161
176
  warn?: Partial<AuthzAdminLabels["warn"]>;
162
177
  };
@@ -171,8 +186,21 @@ type AuthzLayoutData = WithLabels & {
171
186
  adminResourceKey: string;
172
187
  basePath?: string;
173
188
  };
189
+ type AuthzLayoutShellProps = {
190
+ children: React.ReactNode;
191
+ renderHeader?: (props: {
192
+ title: string;
193
+ annotation: React.ReactNode;
194
+ }) => React.ReactNode;
195
+ };
196
+ type AuthzLayoutProps = {
197
+ renderHeader?: (props: {
198
+ title: string;
199
+ annotation: React.ReactNode;
200
+ }) => React.ReactNode;
201
+ };
174
202
  /** ネストルート用レイアウト(子は Outlet)。`routes.ts` でネスト構成にする場合に使う。 */
175
- declare function AuthzLayout(): react.JSX.Element;
203
+ declare function AuthzLayout({ renderHeader }?: AuthzLayoutProps): react.JSX.Element;
176
204
  /**
177
205
  * 認可管理 UI のエラー境界。ErrorBoundary は loader データを読めないため、ラベルは
178
206
  * `makeAuthzErrorBoundary(labels)` で注入する(アプリは自分のロケールで生成する)。
@@ -214,12 +242,35 @@ type AuthzUserRolesData = WithLabels & {
214
242
  selfAdminRoleIds?: number[];
215
243
  };
216
244
  declare function AuthzUserRolesView(): react.JSX.Element;
245
+ type AuthzGroupRolesData = WithLabels & {
246
+ groupRoles: AuthzGroupRoleAssignment[];
247
+ roles: AuthzRole[];
248
+ groups: AuthzGroupSummary[];
249
+ };
250
+ declare function AuthzGroupRolesView(): react.JSX.Element;
251
+ type AuthzGraphData = WithLabels & {
252
+ users: AuthzUser[];
253
+ roles: AuthzRole[];
254
+ resources: AuthzResource[];
255
+ grants: AuthzGrant[];
256
+ assignments: AuthzAssignment[];
257
+ groupRoles?: AuthzGroupRoleAssignment[];
258
+ groups?: AuthzGroupSummary[];
259
+ };
260
+ type AuthzNodeType = "user" | "group" | "role" | "resource";
261
+ declare function AuthzGraphView(): react.JSX.Element;
262
+ type AuthzAdminAppViewProps = {
263
+ renderHeader?: (props: {
264
+ title: string;
265
+ annotation: React.ReactNode;
266
+ }) => React.ReactNode;
267
+ };
217
268
  /**
218
269
  * スプラット(`authz/*`)1 ルートで認可管理 UI 全体を描画するコンポーネント(store 非依存)。
219
270
  * loader が返す `segment` に応じて該当タブのビューを描画する。レイアウト殻と各ビューは同一の
220
271
  * loader データ(セグメントデータ + myPermissions + labels をトップレベルに統合)を読む。
221
272
  */
222
- declare function AuthzAdminAppView(): react.JSX.Element;
273
+ declare function AuthzAdminAppView({ renderHeader }?: AuthzAdminAppViewProps): react.JSX.Element;
223
274
 
224
275
  type Req = {
225
276
  request: Request;
@@ -302,6 +353,19 @@ declare function createAuthzAdminServer(opts: CreateAuthzAdminServerOptions): {
302
353
  ok: boolean;
303
354
  }>;
304
355
  };
356
+ groupRoles: {
357
+ data: () => Promise<AuthzGroupRolesData>;
358
+ loader({ request }: Req): Promise<AuthzGroupRolesData>;
359
+ action({ request }: Req): Promise<react_router.UNSAFE_DataWithResponseInit<{
360
+ error: string;
361
+ }> | {
362
+ ok: boolean;
363
+ }>;
364
+ };
365
+ graph: {
366
+ data: () => Promise<AuthzGraphData>;
367
+ loader({ request }: Req): Promise<AuthzGraphData>;
368
+ };
305
369
  };
306
370
 
307
371
  type RouteArgs = {
@@ -358,12 +422,17 @@ declare function createAuthzAdminApp(opts: CreateAuthzAdminAppOptions): {
358
422
  basePath: string;
359
423
  myPermissions: Record<string, PermissionView>;
360
424
  adminResourceKey: string;
425
+ } | {
426
+ labels: AuthzAdminLabels;
427
+ groupRoles: _aiquants_authz_core.AuthzGroupRoleAssignment[];
428
+ roles: _aiquants_authz_core.AuthzRole[];
429
+ groups: _aiquants_authz_core.AuthzGroupSummary[];
430
+ segment: string;
431
+ basePath: string;
432
+ myPermissions: Record<string, PermissionView>;
433
+ adminResourceKey: string;
361
434
  }>;
362
- action: (args: RouteArgs) => Promise<react_router.UNSAFE_DataWithResponseInit<{
363
- error: string;
364
- }> | {
365
- ok: boolean;
366
- }>;
435
+ action: (args: RouteArgs) => Promise<unknown>;
367
436
  server: {
368
437
  labels: AuthzAdminLabels;
369
438
  resourceKey: string;
@@ -431,6 +500,25 @@ declare function createAuthzAdminApp(opts: CreateAuthzAdminAppOptions): {
431
500
  ok: boolean;
432
501
  }>;
433
502
  };
503
+ groupRoles: {
504
+ data: () => Promise<AuthzGroupRolesData>;
505
+ loader({ request }: {
506
+ request: Request;
507
+ }): Promise<AuthzGroupRolesData>;
508
+ action({ request }: {
509
+ request: Request;
510
+ }): Promise<react_router.UNSAFE_DataWithResponseInit<{
511
+ error: string;
512
+ }> | {
513
+ ok: boolean;
514
+ }>;
515
+ };
516
+ graph: {
517
+ data: () => Promise<AuthzGraphData>;
518
+ loader({ request }: {
519
+ request: Request;
520
+ }): Promise<AuthzGraphData>;
521
+ };
434
522
  };
435
523
  };
436
524
 
@@ -554,12 +642,12 @@ declare function formatResourceTooltip(resourceKey?: string, resourceName?: stri
554
642
  * Display permission indicator badges for read, write, and delete capabilities.
555
643
  * 閲覧・編集・削除の権限状態バッジ群を描画。
556
644
  */
557
- declare function MyPermissionIndicator({ permission, resourceName, expectedResourceKey, showResourceTooltip, labels, showScopeSummary, className, }: MyPermissionIndicatorProps): react.JSX.Element;
645
+ declare function MyPermissionIndicator({ permission, resourceName, expectedResourceKey, showResourceTooltip, labels, showScopeSummary, className }: MyPermissionIndicatorProps): react.JSX.Element;
558
646
  /**
559
647
  * Reusable "Your Permissions" status bar component suitable for any application page.
560
648
  * 「あなたの権限」ラベルと権限状態インジケータを束ねた再利用可能なコンポーネント。
561
649
  */
562
- declare function MyPermissionStatus({ permission, resourceName, expectedResourceKey, prefixLabel, showPrefixLabel, showResourceTooltip, labels, showScopeSummary, className, style, }: MyPermissionStatusProps): react.JSX.Element;
650
+ declare function MyPermissionStatus({ permission, resourceName, expectedResourceKey, prefixLabel, showPrefixLabel, showResourceTooltip, labels, showScopeSummary, className, style }: MyPermissionStatusProps): react.JSX.Element;
563
651
 
564
652
  /**
565
653
  * Resource definition and registry utilities for preventing page-resource mismatches.
@@ -607,4 +695,4 @@ type UsePermission = {
607
695
  */
608
696
  declare function usePermission(view: PermissionView | null | undefined): UsePermission;
609
697
 
610
- export { AuthzAdminAppView, type AuthzAdminLabels, type AuthzConfig, AuthzErrorBoundary, type AuthzGrantsData, AuthzGrantsView, AuthzLayout, type AuthzLayoutData, type AuthzResourcesData, AuthzResourcesView, type AuthzRolesData, AuthzRolesView, type AuthzUserId, type AuthzUserRolesData, AuthzUserRolesView, type CreateAuthzAdminAppOptions, type CreateAuthzAdminServerOptions, ErrorAlert, Field, type MyPermissionGroupItem, MyPermissionGroupStatus, type MyPermissionGroupStatusProps, MyPermissionIndicator, type MyPermissionIndicatorProps, MyPermissionStatus, type MyPermissionStatusProps, type PartialAuthzAdminLabels, type PermState, type PermissionView, type RequirePermissionOptions, type ResourceDefinition, type ResourceDefinitionInput, type ResourceRegistry, type UsePermission, createAuthz, createAuthzAdminApp, createAuthzAdminServer, defaultAuthzAdminLabels, defineResources, flattenGroupItems, formatResourceTooltip, getPermissionSummary, makeAuthzErrorBoundary, resolveLabels, toPermissionView, ui, usePermission };
698
+ export { AuthzAdminAppView, type AuthzAdminAppViewProps, type AuthzAdminLabels, type AuthzConfig, AuthzErrorBoundary, type AuthzGrantsData, AuthzGrantsView, type AuthzGraphData, AuthzGraphView, type AuthzGroupRolesData, AuthzGroupRolesView, AuthzLayout, type AuthzLayoutData, type AuthzLayoutProps, type AuthzLayoutShellProps, type AuthzNodeType, type AuthzResourcesData, AuthzResourcesView, type AuthzRolesData, AuthzRolesView, type AuthzUserId, type AuthzUserRolesData, AuthzUserRolesView, type CreateAuthzAdminAppOptions, type CreateAuthzAdminServerOptions, ErrorAlert, Field, type MyPermissionGroupItem, MyPermissionGroupStatus, type MyPermissionGroupStatusProps, MyPermissionIndicator, type MyPermissionIndicatorProps, MyPermissionStatus, type MyPermissionStatusProps, type PartialAuthzAdminLabels, type PermState, type PermissionView, type RequirePermissionOptions, type ResourceDefinition, type ResourceDefinitionInput, type ResourceRegistry, type UsePermission, createAuthz, createAuthzAdminApp, createAuthzAdminServer, defaultAuthzAdminLabels, defineResources, flattenGroupItems, formatResourceTooltip, getPermissionSummary, makeAuthzErrorBoundary, resolveLabels, toPermissionView, ui, usePermission };
package/dist/index.d.ts CHANGED
@@ -1,19 +1,22 @@
1
+ import * as react_router from 'react-router';
1
2
  import * as react from 'react';
2
3
  import { ReactNode, CSSProperties } from 'react';
3
4
  import * as _aiquants_authz_core from '@aiquants/authz-core';
4
- import { EffectivePermission, DenyInfo, AuthzAction, GuardResult, AuthzGrant, AuthzResource, AuthzRole, AuthzAssignment, AuthzUser, AuthzAdminStore } from '@aiquants/authz-core';
5
- import * as react_router from 'react-router';
5
+ import { EffectivePermission, DenyInfo, AuthzAction, GuardResult, AuthzGrant, AuthzUser, AuthzRole, AuthzResource, AuthzAssignment, AuthzGroupRoleAssignment, AuthzGroupSummary, AuthzAdminStore } from '@aiquants/authz-core';
6
6
 
7
7
  type Awaitable<T> = T | Promise<T>;
8
8
  type AuthzUserId = string | number;
9
9
  type AuthzConfig = {
10
10
  /** Stable app identifier (e.g. "quants"). Bound into every permission query. */
11
11
  appKey: string;
12
- /** Resolve the acting user id from the request (cookie/session/openid → TDUsers.id). */
12
+ /** Resolve the acting user id from the request (cookie/session/openid → the consumer's user id). */
13
13
  resolveUserId: (request: Request) => Awaitable<AuthzUserId | null | undefined>;
14
+ /** Optionally resolve acting user's group IDs from the request or session. */
15
+ resolveGroupIds?: (request: Request) => Awaitable<(string | number)[] | null | undefined>;
14
16
  /** Load effective permissions for (user, app, resource) — typically via @aiquants/authz-drizzle. */
15
17
  getEffectivePermissions: (args: {
16
18
  userId: AuthzUserId | null;
19
+ groupIds?: (string | number)[];
17
20
  appKey: string;
18
21
  resourceKey: string;
19
22
  }) => Awaitable<EffectivePermission | null | undefined>;
@@ -70,6 +73,8 @@ type AuthzAdminLabels = {
70
73
  resources: string;
71
74
  role_permissions: string;
72
75
  user_roles: string;
76
+ group_roles: string;
77
+ graph: string;
73
78
  };
74
79
  common: {
75
80
  add: string;
@@ -134,6 +139,15 @@ type AuthzAdminLabels = {
134
139
  newHeading: string;
135
140
  selectPlaceholder: string;
136
141
  };
142
+ groupRoles: {
143
+ heading: string;
144
+ note: string;
145
+ group: string;
146
+ role: string;
147
+ empty: string;
148
+ newHeading: string;
149
+ selectPlaceholder: string;
150
+ };
137
151
  error: {
138
152
  forbiddenTitle: string;
139
153
  forbiddenBody: string;
@@ -157,6 +171,7 @@ type PartialAuthzAdminLabels = {
157
171
  resources?: Partial<AuthzAdminLabels["resources"]>;
158
172
  grants?: Partial<AuthzAdminLabels["grants"]>;
159
173
  userRoles?: Partial<AuthzAdminLabels["userRoles"]>;
174
+ groupRoles?: Partial<AuthzAdminLabels["groupRoles"]>;
160
175
  error?: Partial<AuthzAdminLabels["error"]>;
161
176
  warn?: Partial<AuthzAdminLabels["warn"]>;
162
177
  };
@@ -171,8 +186,21 @@ type AuthzLayoutData = WithLabels & {
171
186
  adminResourceKey: string;
172
187
  basePath?: string;
173
188
  };
189
+ type AuthzLayoutShellProps = {
190
+ children: React.ReactNode;
191
+ renderHeader?: (props: {
192
+ title: string;
193
+ annotation: React.ReactNode;
194
+ }) => React.ReactNode;
195
+ };
196
+ type AuthzLayoutProps = {
197
+ renderHeader?: (props: {
198
+ title: string;
199
+ annotation: React.ReactNode;
200
+ }) => React.ReactNode;
201
+ };
174
202
  /** ネストルート用レイアウト(子は Outlet)。`routes.ts` でネスト構成にする場合に使う。 */
175
- declare function AuthzLayout(): react.JSX.Element;
203
+ declare function AuthzLayout({ renderHeader }?: AuthzLayoutProps): react.JSX.Element;
176
204
  /**
177
205
  * 認可管理 UI のエラー境界。ErrorBoundary は loader データを読めないため、ラベルは
178
206
  * `makeAuthzErrorBoundary(labels)` で注入する(アプリは自分のロケールで生成する)。
@@ -214,12 +242,35 @@ type AuthzUserRolesData = WithLabels & {
214
242
  selfAdminRoleIds?: number[];
215
243
  };
216
244
  declare function AuthzUserRolesView(): react.JSX.Element;
245
+ type AuthzGroupRolesData = WithLabels & {
246
+ groupRoles: AuthzGroupRoleAssignment[];
247
+ roles: AuthzRole[];
248
+ groups: AuthzGroupSummary[];
249
+ };
250
+ declare function AuthzGroupRolesView(): react.JSX.Element;
251
+ type AuthzGraphData = WithLabels & {
252
+ users: AuthzUser[];
253
+ roles: AuthzRole[];
254
+ resources: AuthzResource[];
255
+ grants: AuthzGrant[];
256
+ assignments: AuthzAssignment[];
257
+ groupRoles?: AuthzGroupRoleAssignment[];
258
+ groups?: AuthzGroupSummary[];
259
+ };
260
+ type AuthzNodeType = "user" | "group" | "role" | "resource";
261
+ declare function AuthzGraphView(): react.JSX.Element;
262
+ type AuthzAdminAppViewProps = {
263
+ renderHeader?: (props: {
264
+ title: string;
265
+ annotation: React.ReactNode;
266
+ }) => React.ReactNode;
267
+ };
217
268
  /**
218
269
  * スプラット(`authz/*`)1 ルートで認可管理 UI 全体を描画するコンポーネント(store 非依存)。
219
270
  * loader が返す `segment` に応じて該当タブのビューを描画する。レイアウト殻と各ビューは同一の
220
271
  * loader データ(セグメントデータ + myPermissions + labels をトップレベルに統合)を読む。
221
272
  */
222
- declare function AuthzAdminAppView(): react.JSX.Element;
273
+ declare function AuthzAdminAppView({ renderHeader }?: AuthzAdminAppViewProps): react.JSX.Element;
223
274
 
224
275
  type Req = {
225
276
  request: Request;
@@ -302,6 +353,19 @@ declare function createAuthzAdminServer(opts: CreateAuthzAdminServerOptions): {
302
353
  ok: boolean;
303
354
  }>;
304
355
  };
356
+ groupRoles: {
357
+ data: () => Promise<AuthzGroupRolesData>;
358
+ loader({ request }: Req): Promise<AuthzGroupRolesData>;
359
+ action({ request }: Req): Promise<react_router.UNSAFE_DataWithResponseInit<{
360
+ error: string;
361
+ }> | {
362
+ ok: boolean;
363
+ }>;
364
+ };
365
+ graph: {
366
+ data: () => Promise<AuthzGraphData>;
367
+ loader({ request }: Req): Promise<AuthzGraphData>;
368
+ };
305
369
  };
306
370
 
307
371
  type RouteArgs = {
@@ -358,12 +422,17 @@ declare function createAuthzAdminApp(opts: CreateAuthzAdminAppOptions): {
358
422
  basePath: string;
359
423
  myPermissions: Record<string, PermissionView>;
360
424
  adminResourceKey: string;
425
+ } | {
426
+ labels: AuthzAdminLabels;
427
+ groupRoles: _aiquants_authz_core.AuthzGroupRoleAssignment[];
428
+ roles: _aiquants_authz_core.AuthzRole[];
429
+ groups: _aiquants_authz_core.AuthzGroupSummary[];
430
+ segment: string;
431
+ basePath: string;
432
+ myPermissions: Record<string, PermissionView>;
433
+ adminResourceKey: string;
361
434
  }>;
362
- action: (args: RouteArgs) => Promise<react_router.UNSAFE_DataWithResponseInit<{
363
- error: string;
364
- }> | {
365
- ok: boolean;
366
- }>;
435
+ action: (args: RouteArgs) => Promise<unknown>;
367
436
  server: {
368
437
  labels: AuthzAdminLabels;
369
438
  resourceKey: string;
@@ -431,6 +500,25 @@ declare function createAuthzAdminApp(opts: CreateAuthzAdminAppOptions): {
431
500
  ok: boolean;
432
501
  }>;
433
502
  };
503
+ groupRoles: {
504
+ data: () => Promise<AuthzGroupRolesData>;
505
+ loader({ request }: {
506
+ request: Request;
507
+ }): Promise<AuthzGroupRolesData>;
508
+ action({ request }: {
509
+ request: Request;
510
+ }): Promise<react_router.UNSAFE_DataWithResponseInit<{
511
+ error: string;
512
+ }> | {
513
+ ok: boolean;
514
+ }>;
515
+ };
516
+ graph: {
517
+ data: () => Promise<AuthzGraphData>;
518
+ loader({ request }: {
519
+ request: Request;
520
+ }): Promise<AuthzGraphData>;
521
+ };
434
522
  };
435
523
  };
436
524
 
@@ -554,12 +642,12 @@ declare function formatResourceTooltip(resourceKey?: string, resourceName?: stri
554
642
  * Display permission indicator badges for read, write, and delete capabilities.
555
643
  * 閲覧・編集・削除の権限状態バッジ群を描画。
556
644
  */
557
- declare function MyPermissionIndicator({ permission, resourceName, expectedResourceKey, showResourceTooltip, labels, showScopeSummary, className, }: MyPermissionIndicatorProps): react.JSX.Element;
645
+ declare function MyPermissionIndicator({ permission, resourceName, expectedResourceKey, showResourceTooltip, labels, showScopeSummary, className }: MyPermissionIndicatorProps): react.JSX.Element;
558
646
  /**
559
647
  * Reusable "Your Permissions" status bar component suitable for any application page.
560
648
  * 「あなたの権限」ラベルと権限状態インジケータを束ねた再利用可能なコンポーネント。
561
649
  */
562
- declare function MyPermissionStatus({ permission, resourceName, expectedResourceKey, prefixLabel, showPrefixLabel, showResourceTooltip, labels, showScopeSummary, className, style, }: MyPermissionStatusProps): react.JSX.Element;
650
+ declare function MyPermissionStatus({ permission, resourceName, expectedResourceKey, prefixLabel, showPrefixLabel, showResourceTooltip, labels, showScopeSummary, className, style }: MyPermissionStatusProps): react.JSX.Element;
563
651
 
564
652
  /**
565
653
  * Resource definition and registry utilities for preventing page-resource mismatches.
@@ -607,4 +695,4 @@ type UsePermission = {
607
695
  */
608
696
  declare function usePermission(view: PermissionView | null | undefined): UsePermission;
609
697
 
610
- export { AuthzAdminAppView, type AuthzAdminLabels, type AuthzConfig, AuthzErrorBoundary, type AuthzGrantsData, AuthzGrantsView, AuthzLayout, type AuthzLayoutData, type AuthzResourcesData, AuthzResourcesView, type AuthzRolesData, AuthzRolesView, type AuthzUserId, type AuthzUserRolesData, AuthzUserRolesView, type CreateAuthzAdminAppOptions, type CreateAuthzAdminServerOptions, ErrorAlert, Field, type MyPermissionGroupItem, MyPermissionGroupStatus, type MyPermissionGroupStatusProps, MyPermissionIndicator, type MyPermissionIndicatorProps, MyPermissionStatus, type MyPermissionStatusProps, type PartialAuthzAdminLabels, type PermState, type PermissionView, type RequirePermissionOptions, type ResourceDefinition, type ResourceDefinitionInput, type ResourceRegistry, type UsePermission, createAuthz, createAuthzAdminApp, createAuthzAdminServer, defaultAuthzAdminLabels, defineResources, flattenGroupItems, formatResourceTooltip, getPermissionSummary, makeAuthzErrorBoundary, resolveLabels, toPermissionView, ui, usePermission };
698
+ export { AuthzAdminAppView, type AuthzAdminAppViewProps, type AuthzAdminLabels, type AuthzConfig, AuthzErrorBoundary, type AuthzGrantsData, AuthzGrantsView, type AuthzGraphData, AuthzGraphView, type AuthzGroupRolesData, AuthzGroupRolesView, AuthzLayout, type AuthzLayoutData, type AuthzLayoutProps, type AuthzLayoutShellProps, type AuthzNodeType, type AuthzResourcesData, AuthzResourcesView, type AuthzRolesData, AuthzRolesView, type AuthzUserId, type AuthzUserRolesData, AuthzUserRolesView, type CreateAuthzAdminAppOptions, type CreateAuthzAdminServerOptions, ErrorAlert, Field, type MyPermissionGroupItem, MyPermissionGroupStatus, type MyPermissionGroupStatusProps, MyPermissionIndicator, type MyPermissionIndicatorProps, MyPermissionStatus, type MyPermissionStatusProps, type PartialAuthzAdminLabels, type PermState, type PermissionView, type RequirePermissionOptions, type ResourceDefinition, type ResourceDefinitionInput, type ResourceRegistry, type UsePermission, createAuthz, createAuthzAdminApp, createAuthzAdminServer, defaultAuthzAdminLabels, defineResources, flattenGroupItems, formatResourceTooltip, getPermissionSummary, makeAuthzErrorBoundary, resolveLabels, toPermissionView, ui, usePermission };