@aiquants/authz-react-router 0.8.1 → 0.8.3

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/dist/index.d.ts CHANGED
@@ -1,184 +1,53 @@
1
- import * as react_router from 'react-router';
2
- import * as react from 'react';
3
- import { ReactNode, CSSProperties } from 'react';
4
- import * as _aiquants_authz_core from '@aiquants/authz-core';
5
- import { EffectivePermission, DenyInfo, AuthzAction, MergedScope, AuthzGrant, AuthzRole, AuthzResource, AuthzUser, AuthzAssignment, AuthzGroupRoleAssignment, AuthzGroupSummary, AuthzAdminStore } from '@aiquants/authz-core';
6
-
7
- /**
8
- * React Router (v7) adapter: binds `appKey` + the DI ports and exposes the loader/action authorization API.
9
- * React Router (v7) 向けアダプタ。`appKey` と DI ポートを束ね、loader/action 用の認可 API を公開するモジュール。
10
- *
11
- * 設計上の中心的な不変条件は **判定は 1 回だけ** ということ。ガード (`requirePermission`) と
12
- * UI 表示用の権限ビューは同一の実効権限から導出されるため、「画面は開けるのに一覧では false」
13
- * という乖離が構造的に起こり得ない。
14
- */
15
-
1
+ import * as react_router from "react-router";
2
+ import * as react from "react";
3
+ import { ReactNode, CSSProperties } from "react";
4
+ import * as _aiquants_authz_core from "@aiquants/authz-core";
5
+ import { EffectivePermission, DenyInfo, AuthzAction, MergedScope, AuthzGrant, AuthzRole, AuthzResource, AuthzUser, AuthzAssignment, AuthzGroupRoleAssignment, AuthzGroupSummary, AuthzAdminStore } from "@aiquants/authz-core";
16
6
  type Awaitable<T> = T | Promise<T>;
17
7
  type AuthzUserId = string | number;
18
- /**
19
- * Thrown when the API itself is called incorrectly (bad arguments, missing port) — a programmer error,
20
- * never an authorization decision. It is deliberately NOT an `AuthzDeniedError`: a misuse must surface as a
21
- * loud 500, not as a silent 403 that looks like a permission problem.
22
- * API の使い方が誤っている場合に送出される例外。認可拒否 (403) とは明確に区別されるプログラマ向けエラー。
23
- */
24
8
  declare class AuthzUsageError extends Error {
25
9
  constructor(message: string);
26
10
  }
27
- /**
28
- * Arguments handed to the {@link AuthzConfig.getEffectivePermissions} port.
29
- * 実効権限ポートへ渡す引数。
30
- *
31
- * `tenantId` is a **required, non-empty string**. It is never absent and never `null`: a port that
32
- * receives no tenant would have to guess, and the only guess an SQL adapter can make — omit the
33
- * predicate — returns every tenant's grants. That inversion is the failure this contract removes.
34
- * `tenantId` は必須かつ非空 (欠落を「全テナント」に読み替える経路を型ごと塞ぐ形)。
35
- */
36
11
  type EffectivePermissionsQuery = {
37
12
  userId: AuthzUserId | null;
38
13
  tenantId: string;
39
14
  groupIds?: (string | number)[];
40
15
  appKey: string;
41
- /** Always a de-duplicated, non-empty list — the port may load them all in one round-trip. Read-only: the adapter reports on exactly these keys. */
42
16
  resourceKeys: readonly string[];
43
17
  };
44
18
  type AuthzConfig = {
45
- /** Stable app identifier (e.g. "quants"). Bound into every permission query. */
46
19
  appKey: string;
47
- /** Resolve the acting user id from the request (cookie/session/openid → the consumer's user id). */
48
20
  resolveUserId: (request: Request) => Awaitable<AuthzUserId | null | undefined>;
49
- /**
50
- * Resolve the acting tenant id from the request (header / cookie / subdomain → tenant id).
51
- * **Required**: every permission question is asked within exactly one tenant, so a host that
52
- * cannot name it must not be able to ask at all. Returning a blank string raises
53
- * `AuthzTenantError` — it is never read as "no filter" / "every tenant".
54
- * リクエストからテナント ID を解決するポート (必須)。空文字は「全テナント」ではなく例外。
55
- */
56
21
  resolveTenantId: (request: Request) => Awaitable<string>;
57
- /**
58
- * Prove the acting identity may act **as** the resolved tenant. **Required**, with no permissive
59
- * default: `resolveTenantId` only says *which* tenant was named, and that name comes from a
60
- * client-influenced channel (header / sub-domain / cookie). Without this seam a user of tenant A
61
- * is authorized inside tenant B by naming tenant B — B's `@authenticated` grants apply and every
62
- * downstream tenant check still passes, because the permission genuinely belongs to B.
63
- * リクエストが名乗ったテナントへの帰属証明 (必須・既定値なし)。テナント名は利用者が影響できる経路から
64
- * 来るため、これが無いと「別テナントを名乗るだけで越境認可」になる。
65
- *
66
- * Called once per check, **before** any permission is loaded. `userId` is `null` for an anonymous
67
- * caller; the host decides whether that tenant's `@anonymous` grants may be used (they are public
68
- * by construction, so `true` is the usual answer).
69
- * 権限読込より前に 1 回だけ呼ばれる。匿名呼び出しの扱いはホストが決める。
70
- */
71
22
  assertTenantMembership: (request: Request, tenantId: string, userId: AuthzUserId | null) => Awaitable<boolean>;
72
- /**
73
- * Optionally resolve acting user's group IDs, for the tenant the request was scoped to.
74
- * リクエストのスコープとなったテナントに対して、実行ユーザーのグループ ID を解決する任意ポート。
75
- *
76
- * `tenantId` is the value `resolveTenantId` already produced and validated, so a host never has to
77
- * derive the tenant a second time — a second derivation is a second thing that can disagree.
78
- * `tenantId` は解決・検証済みの値 (ホスト側での二重解決を不要にし、乖離の余地を作らないため)。
79
- */
80
23
  resolveGroupIds?: (request: Request, tenantId: string) => Awaitable<(string | number)[] | null | undefined>;
81
- /**
82
- * Load effective permissions for (user, app, resources) — **one call, many resources** (typically
83
- * `getEffectivePermissionsMany` from `@aiquants/authz-drizzle`). A key with no grants may be omitted or
84
- * mapped to `null`; both mean "no permission" (fail-close).
85
- */
86
24
  getEffectivePermissions: (args: EffectivePermissionsQuery) => Awaitable<Record<string, EffectivePermission | null | undefined> | null | undefined>;
87
- /**
88
- * Optional: every resource key registered for this app **within `tenantId`** (typically
89
- * `listResourceKeys` from `@aiquants/authz-drizzle`, whose 4th argument is that same tenant).
90
- * Configuring it is what makes `getMyPermissions(request)` — with no resource list — legal;
91
- * without it that call throws {@link AuthzUsageError} instead of guessing.
92
- * 指定テナントに登録済みの全リソースキーを返す任意ポート。
93
- *
94
- * The tenant is handed in already resolved and validated: making the host re-derive it from the
95
- * raw `Request` would create a second, divergable tenant source, and a host that derived it
96
- * differently (or could not) would report on another tenant's resource keys.
97
- * テナントは解決・検証済みの値として渡す (ホスト側での再導出は第 2 のテナント源となり乖離するため)。
98
- *
99
- * Called only after `assertTenantMembership` has proven the caller may act as `tenantId`: the set of
100
- * registered keys is itself that tenant's information, so a non-member must not be able to provoke
101
- * this query at all.
102
- * 帰属証明を通った後にのみ呼ばれる (登録済みキーの集合自体がテナントの情報であるため)。
103
- */
104
25
  listResourceKeys?: (request: Request, tenantId: string) => Awaitable<readonly string[] | null | undefined>;
105
- /** Default deny handler. If omitted, denies throw AuthzDeniedError (403). */
106
26
  onDeny?: (info: DenyInfo) => void;
107
27
  };
108
28
  type RequirePermissionOptions = {
109
- /** When set, denials `throw redirect(failureRedirect)` instead of throwing 403. */
110
29
  failureRedirect?: string;
111
30
  };
112
- /**
113
- * Serializable per-resource permission summary for UI (loader → component).
114
- * UI 向けの直列化可能なリソース単位権限サマリ (loader からコンポーネントへ受け渡す形)。
115
- *
116
- * 真偽値は `can` 接頭辞で統一されている。`delete` のような素の動詞名は分割代入できず
117
- * (`const { delete } = view` は構文エラー)、フックの戻り値との二重語彙も生むため採用しない。
118
- */
119
31
  type PermissionView<K extends string = string> = {
120
32
  resourceKey: K;
121
33
  canRead: boolean;
122
34
  canCreate: boolean;
123
35
  canUpdate: boolean;
124
36
  canDelete: boolean;
125
- /** create ∪ update */
126
37
  canWrite: boolean;
127
- /** read granted but row and/or column restricted (→ △ partial). */
128
38
  readPartial: boolean;
129
39
  actions: AuthzAction[];
130
40
  };
131
- /** Result of a successful {@link createAuthz} guard. ガード成功時の戻り値。 */
132
41
  type RequirePermissionResult<K extends string = string> = {
133
42
  userId: AuthzUserId | null;
134
- /** The tenant the decision was made within (always present, never blank). 判定を行ったテナント。 */
135
43
  tenantId: string;
136
- /** Effective row/column scope for the guarded action — apply as WHERE / column mask. */
137
44
  scope: MergedScope;
138
- /** UI view derived from the **same** evaluation as the guard decision (no second lookup). */
139
45
  permission: PermissionView<K>;
140
46
  };
141
- /**
142
- * Permission views keyed by the exact resource keys that were requested.
143
- * 要求したキーで型付けした権限ビュー群。
144
- *
145
- * リテラルのキーを渡した場合だけ「そのキーは必ず存在する」形になる。`string[]` のようにキーが実行時に
146
- * しか分からない場合は `| undefined` を含む索引型へ落ち、存在チェックを強制する (総和型の索引を
147
- * 名乗ると、要求していないキーが型の上では必ず存在することになり、元の不具合と同じ罠に戻る)。
148
- *
149
- * ⚠️ キーは配列の **要素型** から導かれる。`flag ? ["a"] : ["b"]` のように要素型が合併になる式では、
150
- * 実行時に片方しか無くても型の上では両方が存在する扱いになる。リテラル配列を直接渡すか
151
- * `resourceKeysOf(registry)` を使うこと。
152
- * ⚠️ 戻り値を `Record<string, …>` 型の変数へ代入すると、その文脈から `K` が `string` へ広がり
153
- * 索引型 (値は `| undefined`) に落ちる。リテラルキーの保証が要る箇所では代入先を広げないこと。
154
- * ⚠️ 戻り値は素のオブジェクト。要求していない `toString` などのキーを読むと `Object.prototype` の
155
- * メンバが返る (索引型の `| undefined` とは一致しない)。要求したキーだけを読むこと。
156
- */
157
47
  type PermissionViewMap<K extends string> = string extends K ? Record<string, PermissionView | undefined> : {
158
48
  [P in K]: PermissionView<P>;
159
49
  };
160
- /**
161
- * Map an EffectivePermission to a serializable {@link PermissionView}.
162
- * 実効権限を直列化可能な {@link PermissionView} へ変換する処理。
163
- *
164
- * @returns The UI-facing permission summary (all-false when `perm` is absent). UI 表示用の権限サマリ。
165
- */
166
50
  declare function toPermissionView<K extends string>(resourceKey: K, perm: EffectivePermission | null | undefined): PermissionView<K>;
167
- /**
168
- * React Router adapter. Binds `appKey` and the DI deps, exposing:
169
- * - `requirePermission(request, {resourceKey, action}, options?)` → `{ userId, tenantId, scope, permission }` on allow
170
- * (apply row WHERE / column mask with `scope`; render `permission` in the UI); denies throw 403 or redirect.
171
- * Every check is scoped to the tenant `resolveTenantId` returns, that tenant must be one the caller is proven
172
- * to belong to (`assertTenantMembership`, else deny `not-a-tenant-member`), and a permission issued for
173
- * another tenant is denied (`tenant-mismatch`) rather than trusted.
174
- * - `getMyPermissions(request, {resourceKeys})` → `Record<resourceKey, PermissionView>` for the UI,
175
- * or `getMyPermissions(request)` for every registered resource when `listResourceKeys` is configured.
176
- * Membership is proven **before** that resource list is read, so naming a foreign tenant never reveals
177
- * which resources it has registered.
178
- * `appKey` と DI ポートを束ね、ガードと自己権限取得の 2 面だけを公開するファクトリ。
179
- *
180
- * @returns The bound `requirePermission` / `getMyPermissions` pair. 結線済みの認可 API 一式。
181
- */
182
51
  declare function createAuthz(config: AuthzConfig): {
183
52
  requirePermission: <K extends string>(request: Request, query: {
184
53
  resourceKey: K;
@@ -193,21 +62,6 @@ declare function createAuthz(config: AuthzConfig): {
193
62
  }): Promise<Record<string, PermissionView | undefined>>;
194
63
  };
195
64
  };
196
-
197
- /**
198
- * The label contract of the authorization admin UI: its string shape, the English defaults, and the
199
- * per-section merge that resolves a host's partial overrides against them.
200
- * 認可管理 UI のラベル契約 (文言の型・英語既定値・部分上書きを解決するセクション単位マージ)。
201
- *
202
- * A host overrides whole sections through `createAuthzAdminRoutes(..., { labels })`; sections it
203
- * leaves out keep the defaults, so a partial translation never blanks a screen.
204
- * アプリ側は `createAuthzAdminRoutes(..., { labels })` でセクション単位に上書きする形
205
- * (未指定セクションは既定値のまま残るため、部分翻訳でも画面が空にならない)。
206
- */
207
- /**
208
- * Authz admin UI strings (i18n). Defaults are English; override per-section via `createAuthzAdminRoutes(..., { labels })`.
209
- * 認可管理 UI の文言 (i18n)。既定は英語で、セクション単位に上書きできる形。
210
- */
211
65
  type AuthzAdminLabels = {
212
66
  title: string;
213
67
  myPermission: string;
@@ -219,10 +73,6 @@ type AuthzAdminLabels = {
219
73
  group_roles: string;
220
74
  graph: string;
221
75
  };
222
- /**
223
- * Strings shared by every tab, including the tenant column / field every tenant-scoped table shows.
224
- * 全タブ共通の文言 (テナント列・テナント入力欄を含む)。
225
- */
226
76
  common: {
227
77
  add: string;
228
78
  save: string;
@@ -325,27 +175,10 @@ type PartialAuthzAdminLabels = {
325
175
  error?: Partial<AuthzAdminLabels["error"]>;
326
176
  warn?: Partial<AuthzAdminLabels["warn"]>;
327
177
  };
328
- /**
329
- * Merge partial overrides onto the English defaults, one section at a time.
330
- * 部分的な上書きを英語の既定値へセクション単位で統合する処理。
331
- *
332
- * The merge is shallow **per section**, not a whole-object replace: a host that overrides only
333
- * `grants.note` keeps every other `grants` string instead of losing them.
334
- * 統合はセクション単位の浅いマージであり全体置換ではない形
335
- * (`grants.note` だけを上書きしても、同セクションの他文言は失われない)。
336
- *
337
- * @param over Partial overrides, or `undefined` to keep the defaults. 部分的な上書き (`undefined` なら既定値のまま)。
338
- * @returns The fully resolved label set. 解決済みの全文言。
339
- */
340
178
  declare function resolveLabels(over?: PartialAuthzAdminLabels): AuthzAdminLabels;
341
-
342
179
  type WithLabels = {
343
180
  labels: AuthzAdminLabels;
344
181
  };
345
- /**
346
- * Loader payload of any tenant-scoped tab: the tenant every row on screen was loaded for.
347
- * テナント単位タブの loader ペイロード共通部 (画面上の全行を読み込んだテナント)。
348
- */
349
182
  type WithTenant = {
350
183
  tenantId: string;
351
184
  };
@@ -367,88 +200,24 @@ type AuthzLayoutProps = {
367
200
  annotation: React.ReactNode;
368
201
  }) => React.ReactNode;
369
202
  };
370
- /**
371
- * Layout route for a nested route configuration; the active tab is rendered through `Outlet`.
372
- * ネストルート構成用のレイアウト (子タブは `Outlet` で描画)。`routes.ts` をネスト構成にする場合の入口。
373
- *
374
- * @param props Optional header renderer. 任意のヘッダ描画関数。
375
- * @returns The framed admin page hosting the nested route. ネストされた子ルートを収めた管理画面。
376
- */
377
203
  declare function AuthzLayout({ renderHeader }?: AuthzLayoutProps): react.JSX.Element;
378
- /**
379
- * Build the admin UI's error boundary with labels baked in.
380
- * ラベルを埋め込んだ認可管理 UI のエラー境界を生成する処理。
381
- *
382
- * An error boundary cannot read loader data, so its wording cannot come from the loader the way
383
- * every tab's does; the host injects its own locale here instead.
384
- * エラー境界は loader データを読めないため、他タブのようにラベルを loader から得られない形
385
- * (アプリ側が自分のロケールをここで注入する)。
386
- *
387
- * @param over Partial label overrides; omitted sections keep the English defaults. 部分的なラベル上書き (未指定は英語の既定値)。
388
- * @returns An error boundary component bound to those labels. そのラベルを束縛したエラー境界コンポーネント。
389
- */
390
204
  declare function makeAuthzErrorBoundary(over?: PartialAuthzAdminLabels): () => React.ReactElement;
391
- /**
392
- * The error boundary bound to the package's English default labels.
393
- * 英語 (既定ラベル) のエラー境界。i18n する場合は {@link makeAuthzErrorBoundary} を使う形。
394
- */
395
205
  declare const AuthzErrorBoundary: () => React.ReactElement;
396
206
  type AuthzRolesData = WithLabels & WithTenant & {
397
207
  roles: AuthzRole[];
398
208
  selfAdminRoleIds?: number[];
399
209
  };
400
- /**
401
- * Roles tab: lists the tenant's roles and offers create / rename / enable / delete.
402
- * ロールタブ。当該テナントのロール一覧と、作成・改名・有効切替・削除の操作を提供するコンポーネント。
403
- *
404
- * Reads {@link AuthzRolesData}; the tenant shown in every row is the one the guard resolved, which
405
- * the loader also echoes as `tenantId`.
406
- * {@link AuthzRolesData} を読む形。表示するテナントはガードが解決したもの (loader が `tenantId` として同梱)。
407
- *
408
- * @returns The roles tab. ロールタブ。
409
- */
410
210
  declare function AuthzRolesView(): react.JSX.Element;
411
211
  type AuthzResourcesData = WithLabels & WithTenant & {
412
212
  resources: AuthzResource[];
413
213
  };
414
- /**
415
- * Resources tab: lists the tenant's resources and offers create / rename / delete.
416
- * リソースタブ。当該テナントのリソース一覧と、作成・改名・削除の操作を提供するコンポーネント。
417
- *
418
- * Reads {@link AuthzResourcesData}; the tenant shown is the guard-resolved one.
419
- * {@link AuthzResourcesData} を読む形 (表示するテナントはガードが解決したもの)。
420
- *
421
- * @returns The resources tab. リソースタブ。
422
- */
423
214
  declare function AuthzResourcesView(): react.JSX.Element;
424
- /**
425
- * Grants tab payload. `roles` / `resources` are the **full** rows, not just the id + key pairs the
426
- * select boxes need: a grant row carries no tenant of its own, so the referenced role's projected
427
- * tenant is what the tenant column shows.
428
- * 付与タブのペイロード。`roles` / `resources` は全項目を持つ行 (付与行にテナント列が無く、参照先ロールの実テナントを表示するため)。
429
- */
430
215
  type AuthzGrantsData = WithLabels & WithTenant & {
431
216
  grants: AuthzGrant[];
432
217
  roles: AuthzRole[];
433
218
  resources: AuthzResource[];
434
219
  };
435
- /**
436
- * Permissions tab: lists the tenant's grants and offers grant / re-scope / revoke.
437
- * 権限付与タブ。当該テナントの付与一覧と、付与・スコープ変更・削除の操作を提供するコンポーネント。
438
- *
439
- * Reads {@link AuthzGrantsData}; its role and resource pickers are already narrowed to the
440
- * guard-resolved tenant by the loader, so a cross-tenant pair cannot be selected here.
441
- * {@link AuthzGrantsData} を読む形。ロール・リソースの選択肢は loader が解決済みテナントへ絞ってあるため、
442
- * 越境した組み合わせは選べない。
443
- *
444
- * @returns The permissions tab. 権限付与タブ。
445
- */
446
220
  declare function AuthzGrantsView(): react.JSX.Element;
447
- /**
448
- * User-assignment tab payload. `roles` holds the **full** role rows because `TDUserRole` has no tenant
449
- * column: the assignment's tenant is the one projected onto the role it points at.
450
- * ユーザー割当タブのペイロード。`TDUserRole` にテナント列が無いため、`roles` は参照先ロールの実テナントを含む全項目行。
451
- */
452
221
  type AuthzUserRolesData = WithLabels & WithTenant & {
453
222
  assignments: AuthzAssignment[];
454
223
  roles: AuthzRole[];
@@ -456,33 +225,12 @@ type AuthzUserRolesData = WithLabels & WithTenant & {
456
225
  actorUserId?: number;
457
226
  selfAdminRoleIds?: number[];
458
227
  };
459
- /**
460
- * User-roles tab: lists the tenant's user assignments and offers assign / unassign.
461
- * ユーザー割当タブ。当該テナントのユーザー×ロール割当一覧と、割当・解除の操作を提供するコンポーネント。
462
- *
463
- * Reads {@link AuthzUserRolesData}; removing an assignment that supports the actor's own admin
464
- * status is confirmed first through {@link confirmGuard}.
465
- * {@link AuthzUserRolesData} を読む形 (実行者自身の管理権限を支える割当の解除は {@link confirmGuard} で確認)。
466
- *
467
- * @returns The user-roles tab. ユーザー割当タブ。
468
- */
469
228
  declare function AuthzUserRolesView(): react.JSX.Element;
470
229
  type AuthzGroupRolesData = WithLabels & WithTenant & {
471
230
  groupRoles: AuthzGroupRoleAssignment[];
472
231
  roles: AuthzRole[];
473
232
  groups: AuthzGroupSummary[];
474
233
  };
475
- /**
476
- * Group-roles tab: lists the tenant's group assignments and offers assign / unassign.
477
- * グループ割当タブ。当該テナントのグループ×ロール割当一覧と、割当・解除の操作を提供するコンポーネント。
478
- *
479
- * Reads {@link AuthzGroupRolesData}. See the module docstring for its known layout deviations from
480
- * the other tabs (hard-coded confirmation text, no tenant column, error alert placed differently).
481
- * {@link AuthzGroupRolesData} を読む形。他タブとの既知の逸脱 (確認文言のハードコード・テナント列の非表示・
482
- * エラー表示位置の相違) はモジュール冒頭の記載を参照。
483
- *
484
- * @returns The group-roles tab. グループ割当タブ。
485
- */
486
234
  declare function AuthzGroupRolesView(): react.JSX.Element;
487
235
  type AuthzGraphData = WithLabels & WithTenant & {
488
236
  users: AuthzUser[];
@@ -494,16 +242,6 @@ type AuthzGraphData = WithLabels & WithTenant & {
494
242
  groups?: AuthzGroupSummary[];
495
243
  };
496
244
  type AuthzNodeType = "user" | "group" | "role" | "resource";
497
- /**
498
- * Graph tab: the authorization relations of the tenant, as a topology map or as linked columns.
499
- * グラフタブ。当該テナントの認可関係を、トポロジ図または連動カラム表示で俯瞰するコンポーネント。
500
- *
501
- * Reads {@link AuthzGraphData}. Selecting a node filters the other three columns to what that node
502
- * actually reaches, and the search box narrows every column at once.
503
- * {@link AuthzGraphData} を読む形 (ノード選択で他 3 カラムを到達範囲に絞り、検索は全カラムへ同時適用)。
504
- *
505
- * @returns The graph tab. グラフタブ。
506
- */
507
245
  declare function AuthzGraphView(): react.JSX.Element;
508
246
  type AuthzAdminAppViewProps = {
509
247
  renderHeader?: (props: {
@@ -511,19 +249,7 @@ type AuthzAdminAppViewProps = {
511
249
  annotation: React.ReactNode;
512
250
  }) => React.ReactNode;
513
251
  };
514
- /**
515
- * Render the whole admin UI from a single splat route (`authz/*`), without depending on any store.
516
- * スプラット (`authz/*`) 1 ルートで認可管理 UI 全体を描画するコンポーネント (store 非依存)。
517
- *
518
- * The loader's `segment` selects the tab; the shell and the tab read one merged loader payload
519
- * (the segment's rows plus `myPermissions` and `labels` at the top level).
520
- * loader が返す `segment` に応じてタブを選ぶ形 (外枠と各ビューは統合済みの同一 loader データを読む)。
521
- *
522
- * @param props Optional header renderer. 任意のヘッダ描画関数。
523
- * @returns The admin page for the requested segment. 要求セグメントに対応する管理画面。
524
- */
525
252
  declare function AuthzAdminAppView({ renderHeader }?: AuthzAdminAppViewProps): react.JSX.Element;
526
-
527
253
  type Req = {
528
254
  request: Request;
529
255
  };
@@ -531,121 +257,36 @@ type PermissionQuery = {
531
257
  resourceKey: string;
532
258
  action: AuthzAction;
533
259
  };
534
- /**
535
- * Everything a guarded admin request resolved to: the tenant it acts within and the acting user.
536
- * ガード済みの管理リクエストが解決した文脈 (操作対象テナントと実行ユーザー)。
537
- *
538
- * Both fields are required. The tenant is what every store call is scoped by, and the user id is what
539
- * the audit columns and the "last administrator" warning are computed from; neither has a meaningful
540
- * "absent" value on this route.
541
- * 双方必須 (テナントは全ストア呼び出しの絞り込み、ユーザー ID は監査列と自己管理者判定の基準)。
542
- */
543
260
  type AuthzAdminContext = {
544
261
  tenantId: string;
545
262
  userId: string | number;
546
263
  };
547
264
  type CreateAuthzAdminServerOptions = {
548
265
  store: AuthzAdminStore;
549
- /** 管理画面のガード資源キー(既定 `authz_admin`)。 */
550
266
  resourceKey?: string;
551
- /** 未ログインをログインへ誘導する(例: throw redirect(...))。 */
552
267
  requireUser: (request: Request) => Promise<unknown>;
553
- /**
554
- * Authorization guard supplied by the app (from `createAuthz`); allow → `{ userId, tenantId, permission }`.
555
- * 認可ガード (アプリの createAuthz 由来)。allow で { userId, tenantId, permission } を返すポート。
556
- * `userId` は nullable(未解決/万一の public 付与)であり、createAuthzAdminServer 内で deny する
557
- * (管理経路は監査・自己権限計算に実 id が必須のため非 null を保証)。
558
- * `tenantId` は **ガードが判定に使ったテナントそのもの**。ここで捨てて画面側が別経路で引き直すと、
559
- * 「A テナントの権限で B テナントを編集できる」という越境が構造的に開く。
560
- * `permission` は **同一判定から導かれた** 自己権限ビューであり、表示用に再取得しない
561
- * (再取得は「ガードは通るのにバッジは権限なし」という乖離の温床)。
562
- */
563
268
  requirePermission: (request: Request, query: PermissionQuery) => Promise<{
564
269
  userId: string | number | null;
565
270
  tenantId: string;
566
271
  permission: PermissionView;
567
272
  }>;
568
- /** 文言の部分上書き(既定は日本語)。 */
569
273
  labels?: PartialAuthzAdminLabels;
570
274
  };
571
- /**
572
- * Build the authorization admin UI's server side: one guard seam, per-tab data loaders, and the
573
- * loader / action pair of every route.
574
- * 認可管理 UI のサーバ側 (単一のガードシーム、タブ別データ取得、各ルートの loader/action) を構築する処理。
575
- *
576
- * Every route entry is guarded through the app-supplied `requirePermission`, whose result — the
577
- * tenant, the acting user, and the self-permission view — comes from **one** evaluation and is
578
- * carried onward as an {@link AuthzAdminContext}. Nothing here re-derives the tenant from the request
579
- * or re-loads the permission for display: a second lookup can disagree with the first, which is
580
- * exactly the "guard allows but the badge says denied" failure, and re-deriving the tenant is how a
581
- * screen ends up editing a tenant the guard never authorized.
582
- * 各ルートはアプリ由来の `requirePermission` を通し、その 1 回の判定から得たテナント・実行ユーザー・
583
- * 自己権限を {@link AuthzAdminContext} として持ち回る形 (テナントの引き直しも表示用の再取得も行わない)。
584
- *
585
- * Writes never trust the submitted ids: each one is re-loaded from a tenant-scoped listing and, where
586
- * the row carries its own tenant, compared against it. A missing row and a foreign row are answered
587
- * identically, so the screen cannot be used as a cross-tenant existence oracle.
588
- * 書き込みは送信された id を信用せず、テナント絞り込みの一覧から引き直して帰属を確認する形
589
- * (「存在しない」と「別テナント」は同じ応答にし、他テナントの存在確認手段にしない)。
590
- *
591
- * @param opts Store port, guard seams, admin resource key and label overrides.
592
- * store ポート・ガードシーム・管理リソースキー・文言上書き。
593
- * @returns The labels, the guarded resource key, `layoutGuard`, and every route's loader / action.
594
- * 文言・ガード対象リソースキー・`layoutGuard`・各ルートの loader/action。
595
- */
596
275
  declare function createAuthzAdminServer(opts: CreateAuthzAdminServerOptions): {
597
- /** 露出: スプラットマウント(app.ts)がガードを 1 回だけ行うために使う。 */
598
276
  labels: AuthzAdminLabels;
599
277
  resourceKey: string;
600
278
  layoutGuard: (request: Request) => Promise<AuthzAdminContext & {
601
279
  myPermissions: Record<string, PermissionView | undefined>;
602
280
  }>;
603
- /** /authz レイアウト: requireUser(302) → requirePermission(read, 403)。自己権限はガードの戻り値から得る。 */
604
281
  layout: {
605
- /**
606
- * Layout loader: guard once, then hand the shell the tenant and the self-permission map.
607
- * レイアウトの loader。ガードを 1 回だけ行い、テナントと自己権限マップを外枠へ渡す処理。
608
- *
609
- * @param args The route arguments (request only). ルート引数 (request のみ)。
610
- * @returns The layout payload. レイアウトの表示データ。
611
- * @throws {Response} `302` when unauthenticated, `403` when the read is denied. 未認証は 302、拒否は 403。
612
- */
613
282
  loader({ request }: Req): Promise<AuthzLayoutData>;
614
283
  };
615
- /** /authz index → roles へ。 */
616
284
  index: {
617
- /**
618
- * Index loader: the admin root has no view of its own, so it redirects to the roles tab.
619
- * インデックスの loader。管理ルートは固有の表示を持たないためロールタブへ転送する処理。
620
- *
621
- * @returns Never returns; always throws the redirect. 常に転送を送出 (正常復帰しない)。
622
- * @throws {Response} The `/authz/roles` redirect. `/authz/roles` への転送。
623
- */
624
285
  loader(): never;
625
286
  };
626
287
  roles: {
627
288
  data: (ctx: AuthzAdminContext) => Promise<AuthzRolesData>;
628
- /**
629
- * Roles tab loader: guard for `read`, then load the tab within the guarded tenant.
630
- * ロールタブの loader。`read` をガードし、ガード済みテナントの範囲で読み込む処理。
631
- *
632
- * @param args The route arguments (request only). ルート引数 (request のみ)。
633
- * @returns The roles tab payload. ロールタブの表示データ。
634
- * @throws {AuthzDeniedError} When the read is denied. 読み取りが拒否された場合。
635
- */
636
289
  loader({ request }: Req): Promise<AuthzRolesData>;
637
- /**
638
- * Roles tab action: create / save / toggle / delete, each guarded for its own verb.
639
- * ロールタブの action。作成・保存・有効切替・削除を、それぞれの動詞でガードして実行する処理。
640
- *
641
- * `create` and `save` additionally reconcile the submitted `tenantId` with the guarded one
642
- * before the store is called, and every id is re-loaded through `ownedRole`.
643
- * `create`/`save` は送信された `tenantId` をガード側と突合し、id は必ず `ownedRole` で引き直す形。
644
- *
645
- * @param args The route arguments (request only). ルート引数 (request のみ)。
646
- * @returns `{ ok: true }`, or a `400` payload on a validation failure. 成功、または検証失敗時の 400 応答。
647
- * @throws {Response} `403` when the guard denies the verb. 動詞のガードが拒否した場合。
648
- */
649
290
  action({ request }: Req): Promise<react_router.UNSAFE_DataWithResponseInit<{
650
291
  error: string;
651
292
  }> | {
@@ -654,27 +295,7 @@ declare function createAuthzAdminServer(opts: CreateAuthzAdminServerOptions): {
654
295
  };
655
296
  resources: {
656
297
  data: (ctx: AuthzAdminContext) => Promise<AuthzResourcesData>;
657
- /**
658
- * Resources tab loader: guard for `read`, then load the tab within the guarded tenant.
659
- * リソースタブの loader。`read` をガードし、ガード済みテナントの範囲で読み込む処理。
660
- *
661
- * @param args The route arguments (request only). ルート引数 (request のみ)。
662
- * @returns The resources tab payload. リソースタブの表示データ。
663
- * @throws {AuthzDeniedError} When the read is denied. 読み取りが拒否された場合。
664
- */
665
298
  loader({ request }: Req): Promise<AuthzResourcesData>;
666
- /**
667
- * Resources tab action: create / save / delete, each guarded for its own verb.
668
- * リソースタブの action。作成・保存・削除を、それぞれの動詞でガードして実行する処理。
669
- *
670
- * `create` reconciles the submitted `tenantId` with the guarded one; `save` and `delete`
671
- * re-load the id through `ownedResource` instead of trusting the form.
672
- * `create` は送信 `tenantId` を突合し、`save`/`delete` は `ownedResource` で id を引き直す形。
673
- *
674
- * @param args The route arguments (request only). ルート引数 (request のみ)。
675
- * @returns `{ ok: true }`, or a `400` payload on a validation failure. 成功、または検証失敗時の 400 応答。
676
- * @throws {Response} `403` when the guard denies the verb. 動詞のガードが拒否した場合。
677
- */
678
299
  action({ request }: Req): Promise<react_router.UNSAFE_DataWithResponseInit<{
679
300
  error: string;
680
301
  }> | {
@@ -683,28 +304,7 @@ declare function createAuthzAdminServer(opts: CreateAuthzAdminServerOptions): {
683
304
  };
684
305
  grants: {
685
306
  data: (ctx: AuthzAdminContext) => Promise<AuthzGrantsData>;
686
- /**
687
- * Grants tab loader: guard for `read`, then load the tab within the guarded tenant.
688
- * 権限付与タブの loader。`read` をガードし、ガード済みテナントの範囲で読み込む処理。
689
- *
690
- * @param args The route arguments (request only). ルート引数 (request のみ)。
691
- * @returns The grants tab payload. 権限付与タブの表示データ。
692
- * @throws {AuthzDeniedError} When the read is denied. 読み取りが拒否された場合。
693
- */
694
307
  loader({ request }: Req): Promise<AuthzGrantsData>;
695
- /**
696
- * Grants tab action: create / save / delete, each guarded for its own verb.
697
- * 権限付与タブの action。作成・保存・削除を、それぞれの動詞でガードして実行する処理。
698
- *
699
- * A grant links two rows, so `create` proves **both** the role and the resource belong to
700
- * the guarded tenant; `save` and `delete` prove the grant itself through `assertOwnedGrant`.
701
- * 付与は 2 行を結ぶため `create` はロール・リソース双方の帰属を証明し、`save`/`delete` は
702
- * `assertOwnedGrant` で付与自体の帰属を証明する形。
703
- *
704
- * @param args The route arguments (request only). ルート引数 (request のみ)。
705
- * @returns `{ ok: true }`, or a `400` payload on a validation failure. 成功、または検証失敗時の 400 応答。
706
- * @throws {Response} `403` when the guard denies the verb. 動詞のガードが拒否した場合。
707
- */
708
308
  action({ request }: Req): Promise<react_router.UNSAFE_DataWithResponseInit<{
709
309
  error: string;
710
310
  }> | {
@@ -713,28 +313,7 @@ declare function createAuthzAdminServer(opts: CreateAuthzAdminServerOptions): {
713
313
  };
714
314
  userRoles: {
715
315
  data: (ctx: AuthzAdminContext) => Promise<AuthzUserRolesData>;
716
- /**
717
- * User-roles tab loader: guard for `read`, then load the tab within the guarded tenant.
718
- * ユーザー割当タブの loader。`read` をガードし、ガード済みテナントの範囲で読み込む処理。
719
- *
720
- * @param args The route arguments (request only). ルート引数 (request のみ)。
721
- * @returns The user-roles tab payload. ユーザー割当タブの表示データ。
722
- * @throws {AuthzDeniedError} When the read is denied. 読み取りが拒否された場合。
723
- */
724
316
  loader({ request }: Req): Promise<AuthzUserRolesData>;
725
- /**
726
- * User-roles tab action: assign / remove, each guarded for its own verb.
727
- * ユーザー割当タブの action。割当・解除を、それぞれの動詞でガードして実行する処理。
728
- *
729
- * The assignment row carries no tenant of its own, so both ends are proven — the user
730
- * through `assertOwnedUser` and the role through `ownedRole` — before the store is called.
731
- * 割当行はテナントを持たないため、ユーザー側 (`assertOwnedUser`) とロール側 (`ownedRole`) の
732
- * 両端の帰属を証明してからストアを呼ぶ形。
733
- *
734
- * @param args The route arguments (request only). ルート引数 (request のみ)。
735
- * @returns `{ ok: true }`, or a `400` payload on a validation failure. 成功、または検証失敗時の 400 応答。
736
- * @throws {Response} `403` when the guard denies the verb. 動詞のガードが拒否した場合。
737
- */
738
317
  action({ request }: Req): Promise<react_router.UNSAFE_DataWithResponseInit<{
739
318
  error: string;
740
319
  }> | {
@@ -743,27 +322,7 @@ declare function createAuthzAdminServer(opts: CreateAuthzAdminServerOptions): {
743
322
  };
744
323
  groupRoles: {
745
324
  data: (ctx: AuthzAdminContext) => Promise<AuthzGroupRolesData>;
746
- /**
747
- * Group-roles tab loader: guard for `read`, then load the tab within the guarded tenant.
748
- * グループ割当タブの loader。`read` をガードし、ガード済みテナントの範囲で読み込む処理。
749
- *
750
- * @param args The route arguments (request only). ルート引数 (request のみ)。
751
- * @returns The group-roles tab payload. グループ割当タブの表示データ。
752
- * @throws {AuthzDeniedError} When the read is denied. 読み取りが拒否された場合。
753
- */
754
325
  loader({ request }: Req): Promise<AuthzGroupRolesData>;
755
- /**
756
- * Group-roles tab action: assign / remove, each guarded for its own verb.
757
- * グループ割当タブの action。割当・解除を、それぞれの動詞でガードして実行する処理。
758
- *
759
- * As with user roles the link row carries no tenant, so both the group (`ownedGroup`) and
760
- * the role (`ownedRole`) are proven to belong to the guarded tenant first.
761
- * ユーザー割当と同様に割当行はテナントを持たないため、グループ側・ロール側双方の帰属を先に証明する形。
762
- *
763
- * @param args The route arguments (request only). ルート引数 (request のみ)。
764
- * @returns `{ ok: true }`, or a `400` payload on a validation failure. 成功、または検証失敗時の 400 応答。
765
- * @throws {Response} `403` when the guard denies the verb. 動詞のガードが拒否した場合。
766
- */
767
326
  action({ request }: Req): Promise<react_router.UNSAFE_DataWithResponseInit<{
768
327
  error: string;
769
328
  }> | {
@@ -772,32 +331,16 @@ declare function createAuthzAdminServer(opts: CreateAuthzAdminServerOptions): {
772
331
  };
773
332
  graph: {
774
333
  data: (ctx: AuthzAdminContext) => Promise<AuthzGraphData>;
775
- /**
776
- * Graph tab loader: guard for `read`, then load every listing of the guarded tenant.
777
- * グラフタブの loader。`read` をガードし、ガード済みテナントの全一覧を読み込む処理。
778
- *
779
- * @param args The route arguments (request only). ルート引数 (request のみ)。
780
- * @returns The graph tab payload. グラフタブの表示データ。
781
- * @throws {AuthzDeniedError} When the read is denied. 読み取りが拒否された場合。
782
- */
783
334
  loader({ request }: Req): Promise<AuthzGraphData>;
784
335
  };
785
336
  };
786
-
787
337
  type RouteArgs = {
788
338
  request: Request;
789
339
  params: Record<string, string | undefined>;
790
340
  };
791
341
  type CreateAuthzAdminAppOptions = CreateAuthzAdminServerOptions & {
792
- /** マウントのベースパス(タブリンク/未指定セグメントのリダイレクト先)。既定 `/authz`。 */
793
342
  basePath?: string;
794
343
  };
795
- /**
796
- * Build the loader/action pair that serves the whole authorization admin UI from one splat route.
797
- * 認可管理 UI 全体を 1 本のスプラットルートで提供する loader/action 対を生成するファクトリ。
798
- *
799
- * @returns The route `loader` / `action` plus the underlying server for direct use. ルートの loader/action と内部サーバ。
800
- */
801
344
  declare function createAuthzAdminApp(opts: CreateAuthzAdminAppOptions): {
802
345
  loader: (args: RouteArgs) => Promise<{
803
346
  labels: AuthzAdminLabels;
@@ -915,16 +458,6 @@ declare function createAuthzAdminApp(opts: CreateAuthzAdminAppOptions): {
915
458
  };
916
459
  };
917
460
  };
918
-
919
- /**
920
- * Inline styles shared by the admin tabs, keyed by role.
921
- * 管理タブ共通のインラインスタイル (役割名をキーとする形)。
922
- *
923
- * `satisfies` is used rather than a `Record<string, CSSProperties>` annotation: the annotation
924
- * erases the key set, so a typo such as `ui.dangerBtn` type-checks and silently renders unstyled.
925
- * `Record<string, CSSProperties>` の注釈ではなく `satisfies` を用いる形 (注釈はキー集合を消し、
926
- * `ui.dangerBtn` のような綴り誤りが型検査を素通りして無装飾描画になるため)。
927
- */
928
461
  declare const ui: {
929
462
  page: {
930
463
  padding: string;
@@ -1069,72 +602,27 @@ declare const ui: {
1069
602
  padding: string;
1070
603
  };
1071
604
  };
1072
- /**
1073
- * Stack a label above its control, keeping the two from overlapping and the tabs consistent.
1074
- * ラベルを上、コントロールを下に縦積みするフィールド (重なり防止・レイアウト統一)。
1075
- *
1076
- * A `<div>` rather than a `<label>`: the control is expected to carry its own `aria-label`.
1077
- * `<label>` ではなく `<div>` で構成する形 (コントロール側が `aria-label` を持つ前提のため)。
1078
- *
1079
- * @param props The label text, an optional hint, and the control to wrap. ラベル文言・任意の補足・包むコントロール。
1080
- * @returns The stacked field. 縦積みされたフィールド。
1081
- */
1082
605
  declare function Field({ label, hint, children }: {
1083
606
  label: string;
1084
607
  hint?: string;
1085
608
  children: ReactNode;
1086
609
  }): react.JSX.Element;
1087
- /**
1088
- * Render an error message as an assertive alert, or nothing when there is no message.
1089
- * エラーメッセージを `role="alert"` で表示するコンポーネント (メッセージが無ければ何も描画しない形)。
1090
- *
1091
- * @param props The message to show, if any. 表示するメッセージ (省略可)。
1092
- * @returns The alert element, or `null`. アラート要素、または `null`。
1093
- */
1094
610
  declare function ErrorAlert({ message }: {
1095
611
  message?: string;
1096
612
  }): react.JSX.Element | null;
1097
-
1098
613
  type MyPermissionGroupItem = {
1099
- /** Expected or actual resource key */
1100
614
  resourceKey?: string;
1101
- /** Human-readable resource display name (e.g. "NI", "KT", "オリジナル") */
1102
615
  resourceName: string;
1103
- /** Permission view data for this resource */
1104
616
  permission: PermissionView | null | undefined;
1105
- /** Expected resource key to detect mismatches with permission.resourceKey during development */
1106
617
  expectedResourceKey?: string;
1107
- /** Nesting level for hierarchical rendering (0: root, 1: child, etc.) */
1108
618
  level?: number;
1109
- /** Optional child items for hierarchical rendering */
1110
619
  children?: MyPermissionGroupItem[];
1111
620
  };
1112
- /**
1113
- * Flattens hierarchical items tree into a single array with computed nesting levels.
1114
- * 木構造またはフラット配列のアイテムに level 属性を付与してフラット化する処理。
1115
- */
1116
621
  declare function flattenGroupItems(items: MyPermissionGroupItem[], currentLevel?: number): MyPermissionGroupItem[];
1117
622
  type MyPermissionGroupStatusProps = {
1118
- /** List of resources and their permissions */
1119
623
  items: MyPermissionGroupItem[];
1120
- /** Prefix label shown before group items or inside popover header. Default: "あなたの権限" */
1121
624
  prefixLabel?: string;
1122
- /**
1123
- * Display style variant:
1124
- * - "pills": Inline parent label + compact status tags per item
1125
- * - "popover": Compact single button trigger opening detailed popup card
1126
- * Default: "pills"
1127
- */
1128
625
  variant?: "pills" | "popover";
1129
- /**
1130
- * Component size variant:
1131
- * - "2xs": Ultra micro size for extremely dense UI
1132
- * - "xs": Extra small size for compact headers
1133
- * - "sm": Small size
1134
- * - "md": Standard default size
1135
- * - "lg": Larger size
1136
- * Default: "md"
1137
- */
1138
626
  size?: "2xs" | "xs" | "sm" | "md" | "lg";
1139
627
  labels?: {
1140
628
  read?: string;
@@ -1149,107 +637,50 @@ type MyPermissionGroupStatusProps = {
1149
637
  className?: string;
1150
638
  style?: CSSProperties;
1151
639
  };
1152
- /**
1153
- * Get human-readable summary text and style for a resource permission.
1154
- * 権限状態から簡潔なサマリテキストとスタイルを判定 (カスタムラベル対応)。
1155
- */
1156
640
  declare function getPermissionSummary(permission: PermissionView | null | undefined, customLabels?: MyPermissionGroupStatusProps["labels"]): {
1157
641
  text: string;
1158
642
  color: string;
1159
643
  bgColor: string;
1160
644
  borderColor: string;
1161
645
  };
1162
- /**
1163
- * Multi-resource "Your Permissions" status component.
1164
- * Supports inline compact pills (Proposal 1) and dropdown popover card (Proposal 2).
1165
- * 複数リソースの権限状態を共通レイアウト(pills/popover)で綺麗に整列・表示するコンポーネント。
1166
- */
1167
646
  declare function MyPermissionGroupStatus({ items, prefixLabel, variant, size, labels, className, style }: MyPermissionGroupStatusProps): react.JSX.Element;
1168
-
1169
647
  type MyPermissionIndicatorProps<K extends string = string> = {
1170
648
  permission: PermissionView<K> | null | undefined;
1171
- /** Human-readable resource display name (e.g. "文書データ"). Falls back to permission.resourceKey. */
1172
649
  resourceName?: string;
1173
- /**
1174
- * Expected resource key. Typed as `NoInfer<K>`, so when the permission carries a literal key
1175
- * (`getMyPermissions` / `requirePermission` both do) a mismatch is a **compile error**; the runtime
1176
- * detector below stays for dynamically-keyed and JavaScript callers.
1177
- */
1178
650
  expectedResourceKey?: NoInfer<K>;
1179
- /** Whether to include resource name/key tooltip. Default true. */
1180
651
  showResourceTooltip?: boolean;
1181
652
  labels?: {
1182
653
  read?: string;
1183
654
  write?: string;
1184
655
  delete?: string;
1185
656
  };
1186
- /** Show a "(部分)" hint when read is partial. Default true. */
1187
657
  showScopeSummary?: boolean;
1188
658
  className?: string;
1189
659
  };
1190
660
  type MyPermissionStatusProps<K extends string = string> = MyPermissionIndicatorProps<K> & {
1191
- /** Label prefix shown before the indicator badges. Default: "あなたの権限" */
1192
661
  prefixLabel?: string;
1193
- /** Whether to display the prefix label. Default: true */
1194
662
  showPrefixLabel?: boolean;
1195
- /** Additional inline styles for wrapper element. */
1196
663
  style?: React.CSSProperties;
1197
664
  };
1198
- /**
1199
- * Format human-readable resource tooltip text.
1200
- * リソース表示名およびキーからツールチップ用テキストを生成。
1201
- */
1202
665
  declare function formatResourceTooltip(resourceKey?: string, resourceName?: string): string | undefined;
1203
- /**
1204
- * Display permission indicator badges for read, write, and delete capabilities.
1205
- * 閲覧・編集・削除の権限状態バッジ群を描画。
1206
- */
1207
666
  declare function MyPermissionIndicator<K extends string = string>({ permission, resourceName, expectedResourceKey, showResourceTooltip, labels, showScopeSummary, className }: MyPermissionIndicatorProps<K>): react.JSX.Element;
1208
- /**
1209
- * Reusable "Your Permissions" status bar component suitable for any application page.
1210
- * 「あなたの権限」ラベルと権限状態インジケータを束ねた再利用可能なコンポーネント。
1211
- */
1212
667
  declare function MyPermissionStatus<K extends string = string>({ permission, resourceName, expectedResourceKey, prefixLabel, showPrefixLabel, showResourceTooltip, labels, showScopeSummary, className, style, }: MyPermissionStatusProps<K>): react.JSX.Element;
1213
-
1214
- /**
1215
- * Resource definition and registry utilities for preventing page-resource mismatches.
1216
- * ページとリソースの表示・権限食い違いを防止するためのリソースレジストリ定義。
1217
- */
1218
668
  type ResourceDefinition = {
1219
- /** Unique resource key used in authorization rules (e.g. "documents") */
1220
669
  key: string;
1221
- /** Human-readable display name (e.g. "文書管理") */
1222
670
  name: string;
1223
- /** Optional description for administration UI */
1224
671
  description?: string;
1225
672
  };
1226
673
  type ResourceDefinitionInput = {
1227
- /** Optional explicit resource key; defaults to the object property name */
1228
674
  key?: string;
1229
- /** Human-readable display name (e.g. "文書管理") */
1230
675
  name: string;
1231
- /** Optional description for administration UI */
1232
676
  description?: string;
1233
677
  };
1234
678
  type ResourceRegistry<T extends Record<string, ResourceDefinition>> = T;
1235
- /**
1236
- * The resource key an entry resolves to: its explicit `key`, otherwise the property name.
1237
- * `key` を明示していればそれ、無ければプロパティ名。
1238
- *
1239
- * `Extract<…, string>` を挟むのは `key?: string` (省略可) が `string | undefined` になり、素の
1240
- * `extends string` では偽になってプロパティ名を名乗ってしまうため (実行時は `key` を使うので型が嘘になる)。
1241
- * `key` を書いていないエントリでは `Extract` が `never` になり、プロパティ名へ落ちる。
1242
- */
1243
- type ResolvedResourceKey<PropertyName extends string, Input extends ResourceDefinitionInput> = [Extract<Input["key"], string>] extends [never] ? PropertyName : Extract<Input["key"], string>;
1244
- /**
1245
- * Define type-safe resource registry for an application.
1246
- * アプリ全体のリソース定義(キー・表示名・説明)を一元管理するヘルパー。
1247
- *
1248
- * 各エントリの `key` はリテラル型のまま保持する。`Record<string, …>` へ広げてしまうと
1249
- * {@link resourceKeysOf} が `string[]` に落ち、権限マップのキー型検査が効かなくなるため。
1250
- *
1251
- * @returns The registry with literal-typed resource keys. リソースキーをリテラル型で保持したレジストリ。
1252
- */
679
+ type ResolvedResourceKey<PropertyName extends string, Input extends ResourceDefinitionInput> = [
680
+ Extract<Input["key"], string>
681
+ ] extends [
682
+ never
683
+ ] ? PropertyName : Extract<Input["key"], string>;
1253
684
  declare function defineResources<const T extends Record<string, ResourceDefinitionInput>>(resources: T): {
1254
685
  [K in keyof T & string]: {
1255
686
  key: ResolvedResourceKey<K, T[K]>;
@@ -1257,54 +688,19 @@ declare function defineResources<const T extends Record<string, ResourceDefiniti
1257
688
  description?: string;
1258
689
  };
1259
690
  };
1260
- /**
1261
- * Extract a registry's resource keys with their literal types preserved.
1262
- * レジストリのリソースキーをリテラル型を保ったまま取り出す処理。
1263
- *
1264
- * `Object.keys(registry)` は `string[]` になり、`getMyPermissions` の戻り値も索引型へ落ちてキーの誤りを
1265
- * 検出できなくなる。加えて `Object.keys` は **プロパティ名** を返すため、`key` を明示したエントリでは
1266
- * 実際のリソースキーと食い違う。
1267
- *
1268
- * ⚠️ 1 エントリでもリテラルでない `key` (例: 変数由来の `string`) を持つと、合併の性質上レジストリ全体の
1269
- * キー型が `string` へ広がり、他のエントリ分のコンパイル時検査も無効になる。`key` は必ずリテラルで書くこと。
1270
- *
1271
- * @returns The registry's resource keys as a literal union array. リテラル合併型のリソースキー配列。
1272
- */
1273
691
  declare function resourceKeysOf<T extends Record<string, {
1274
692
  key: string;
1275
693
  }>>(registry: T): Array<T[keyof T & string]["key"]>;
1276
-
1277
- /**
1278
- * Display-state derivation for a {@link PermissionView} (pure, no React state involved).
1279
- * {@link PermissionView} から表示状態を導出するモジュール (React の状態は一切持たない純粋関数)。
1280
- */
1281
-
1282
694
  type PermState = "full" | "partial" | "none";
1283
- /**
1284
- * Display-oriented reading of a {@link PermissionView}: the same `can*` booleans (safe defaults when the
1285
- * view is absent) plus the ○△× tri-state used by the indicator components.
1286
- * {@link PermissionView} の表示向け読み取り結果。同名の `can*` 真偽値と ○△× の三値状態を併せ持つ形。
1287
- */
1288
695
  type UsePermission = {
1289
696
  canRead: boolean;
1290
697
  canCreate: boolean;
1291
698
  canUpdate: boolean;
1292
699
  canDelete: boolean;
1293
- /** create ∪ update */
1294
700
  canWrite: boolean;
1295
- /** read: none(×) / partial(△, row|col restricted) / full(○). */
1296
701
  readState: PermState;
1297
- /** write = create ∪ update: full(○ both) / partial(△ one) / none(×). */
1298
702
  writeState: PermState;
1299
703
  deleteState: PermState;
1300
704
  };
1301
- /**
1302
- * Derive ○△× display states from a {@link PermissionView}. Pure (safe to call in render);
1303
- * named `usePermission` for ergonomic call-sites.
1304
- * {@link PermissionView} から ○△× の表示状態を導出する純粋関数 (レンダー内から安全に呼べる形)。
1305
- *
1306
- * @returns The permission booleans plus their display states. 権限の真偽値と表示状態の組。
1307
- */
1308
705
  declare function usePermission(view: PermissionView | null | undefined): UsePermission;
1309
-
1310
706
  export { AuthzAdminAppView, type AuthzAdminAppViewProps, type AuthzAdminContext, 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, AuthzUsageError, type AuthzUserId, type AuthzUserRolesData, AuthzUserRolesView, type CreateAuthzAdminAppOptions, type CreateAuthzAdminServerOptions, type EffectivePermissionsQuery, ErrorAlert, Field, type MyPermissionGroupItem, MyPermissionGroupStatus, type MyPermissionGroupStatusProps, MyPermissionIndicator, type MyPermissionIndicatorProps, MyPermissionStatus, type MyPermissionStatusProps, type PartialAuthzAdminLabels, type PermState, type PermissionView, type PermissionViewMap, type RequirePermissionOptions, type RequirePermissionResult, type ResourceDefinition, type ResourceDefinitionInput, type ResourceRegistry, type UsePermission, createAuthz, createAuthzAdminApp, createAuthzAdminServer, defaultAuthzAdminLabels, defineResources, flattenGroupItems, formatResourceTooltip, getPermissionSummary, makeAuthzErrorBoundary, resolveLabels, resourceKeysOf, toPermissionView, ui, usePermission };