@aglyn/aglyn 1.0.0-beta.150 → 1.0.0-beta.151
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/package.json +10 -10
- package/src/lib/app-utils/console-routes.d.ts +0 -6
- package/src/lib/app-utils/console-routes.js +0 -2
- package/src/lib/app-utils/console-routes.js.map +1 -1
- package/src/lib/app-utils/docs-help.generated.d.ts +12 -0
- package/src/lib/app-utils/docs-help.generated.js +27 -0
- package/src/lib/app-utils/docs-help.generated.js.map +1 -1
- package/src/lib/app-utils/index.d.ts +1 -0
- package/src/lib/app-utils/index.js +1 -0
- package/src/lib/app-utils/index.js.map +1 -1
- package/src/lib/app-utils/staff-role-gate.d.ts +56 -0
- package/src/lib/app-utils/staff-role-gate.js +46 -0
- package/src/lib/app-utils/staff-role-gate.js.map +1 -0
- package/src/lib/plugin-manager/feature-plugins.d.ts +61 -0
- package/src/lib/plugin-manager/feature-plugins.js.map +1 -1
- package/src/lib/plugin-manager/plugin-site-cache.d.ts +78 -0
- package/src/lib/plugin-manager/plugin-site-cache.js +125 -0
- package/src/lib/plugin-manager/plugin-site-cache.js.map +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/index.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2022 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Full app-utils surface = server-safe utils + the client-only React\n// contexts. Split so `@aglyn/aglyn/server` can re-export just `./server`\n// (no `createContext`) for tenant Server Components (AGL-405); this barrel,\n// reached via `@aglyn/aglyn`, keeps both for client consumers unchanged.\nexport * from './server'\nexport * from './contexts'\n"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,qEAAqE;AACrE,yEAAyE;AACzE,4EAA4E;AAC5E,yEAAyE;AACzE,cAAc,cAAU;AACxB,cAAc,gBAAY"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/index.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2022 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// Full app-utils surface = server-safe utils + the client-only React\n// contexts. Split so `@aglyn/aglyn/server` can re-export just `./server`\n// (no `createContext`) for tenant Server Components (AGL-405); this barrel,\n// reached via `@aglyn/aglyn`, keeps both for client consumers unchanged.\nexport * from './server'\nexport * from './contexts'\nexport * from './staff-role-gate'\n"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,qEAAqE;AACrE,yEAAyE;AACzE,4EAA4E;AAC5E,yEAAyE;AACzE,cAAc,cAAU;AACxB,cAAc,gBAAY;AAC1B,cAAc,uBAAmB"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
export interface StaffRoleGate {
|
|
18
|
+
/**
|
|
19
|
+
* `false` while the claim is still resolving. Nothing may be BLOCKED in
|
|
20
|
+
* that window: rendering a refusal there would flash a disabled button at
|
|
21
|
+
* every super-staff member on every admin page load.
|
|
22
|
+
*/
|
|
23
|
+
ready: boolean;
|
|
24
|
+
/** Whether the viewer's role is one the route admits. `false` until `ready`. */
|
|
25
|
+
admitted: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* The one thing call sites branch on: a RESOLVED claim the route would
|
|
28
|
+
* refuse. Deliberately not `!admitted` — that is true during the
|
|
29
|
+
* unresolved window too, and would disable the control for everyone for a
|
|
30
|
+
* beat.
|
|
31
|
+
*/
|
|
32
|
+
blocked: boolean;
|
|
33
|
+
/** The reason to show when `blocked`, else `undefined`. */
|
|
34
|
+
reason?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The viewer's standing against the set of roles a route admits (AGL-2131,
|
|
38
|
+
* moved out of the console app by AGL-3080 so a plugin's staff page can ask
|
|
39
|
+
* the same question).
|
|
40
|
+
*
|
|
41
|
+
* Pure, and takes the role rather than reading it: the claim lives in the
|
|
42
|
+
* app's session, and a staff page the shell mounts is handed the resolved
|
|
43
|
+
* value. `null` means "still reading the token", and it is also what a
|
|
44
|
+
* non-staff viewer resolves to — who never reaches an `/admin` page at all,
|
|
45
|
+
* because the staff gate 404s them first. Treating both as unresolved is
|
|
46
|
+
* therefore right for the only population that gets here.
|
|
47
|
+
*
|
|
48
|
+
* Not every gated act is super-only: `/api/admin/org-override` admits
|
|
49
|
+
* `billing` for plan and quota writes and reserves only `releaseFlags` for
|
|
50
|
+
* `super`. A gate that could only say "super" would disable that dialog for
|
|
51
|
+
* the role whose entire purpose it is — trading one dishonest control for
|
|
52
|
+
* another.
|
|
53
|
+
*/
|
|
54
|
+
export declare function resolveStaffRoleGate(role: string | null | undefined, allowed: readonly string[]): StaffRoleGate;
|
|
55
|
+
/** The single sentence every blocked super-only control says. */
|
|
56
|
+
export declare const SUPER_STAFF_ONLY_REASON = "This action requires the super staff role. Ask someone who holds it.";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ /**
|
|
17
|
+
* The viewer's standing against the set of roles a route admits (AGL-2131,
|
|
18
|
+
* moved out of the console app by AGL-3080 so a plugin's staff page can ask
|
|
19
|
+
* the same question).
|
|
20
|
+
*
|
|
21
|
+
* Pure, and takes the role rather than reading it: the claim lives in the
|
|
22
|
+
* app's session, and a staff page the shell mounts is handed the resolved
|
|
23
|
+
* value. `null` means "still reading the token", and it is also what a
|
|
24
|
+
* non-staff viewer resolves to — who never reaches an `/admin` page at all,
|
|
25
|
+
* because the staff gate 404s them first. Treating both as unresolved is
|
|
26
|
+
* therefore right for the only population that gets here.
|
|
27
|
+
*
|
|
28
|
+
* Not every gated act is super-only: `/api/admin/org-override` admits
|
|
29
|
+
* `billing` for plan and quota writes and reserves only `releaseFlags` for
|
|
30
|
+
* `super`. A gate that could only say "super" would disable that dialog for
|
|
31
|
+
* the role whose entire purpose it is — trading one dishonest control for
|
|
32
|
+
* another.
|
|
33
|
+
*/ export function resolveStaffRoleGate(role, allowed) {
|
|
34
|
+
const ready = role !== null && role !== undefined;
|
|
35
|
+
const admitted = ready && allowed.includes(String(role));
|
|
36
|
+
const blocked = ready && !admitted;
|
|
37
|
+
return {
|
|
38
|
+
ready,
|
|
39
|
+
admitted,
|
|
40
|
+
blocked,
|
|
41
|
+
reason: blocked ? `This action requires the ${allowed.join(' or ')} staff role. ` + 'Ask someone who holds it.' : undefined
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** The single sentence every blocked super-only control says. */ export const SUPER_STAFF_ONLY_REASON = 'This action requires the super staff role. Ask someone who holds it.';
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=staff-role-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../libs/aglyn/src/lib/app-utils/staff-role-gate.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport interface StaffRoleGate {\n /**\n * `false` while the claim is still resolving. Nothing may be BLOCKED in\n * that window: rendering a refusal there would flash a disabled button at\n * every super-staff member on every admin page load.\n */\n ready: boolean\n /** Whether the viewer's role is one the route admits. `false` until `ready`. */\n admitted: boolean\n /**\n * The one thing call sites branch on: a RESOLVED claim the route would\n * refuse. Deliberately not `!admitted` — that is true during the\n * unresolved window too, and would disable the control for everyone for a\n * beat.\n */\n blocked: boolean\n /** The reason to show when `blocked`, else `undefined`. */\n reason?: string\n}\n\n/**\n * The viewer's standing against the set of roles a route admits (AGL-2131,\n * moved out of the console app by AGL-3080 so a plugin's staff page can ask\n * the same question).\n *\n * Pure, and takes the role rather than reading it: the claim lives in the\n * app's session, and a staff page the shell mounts is handed the resolved\n * value. `null` means \"still reading the token\", and it is also what a\n * non-staff viewer resolves to — who never reaches an `/admin` page at all,\n * because the staff gate 404s them first. Treating both as unresolved is\n * therefore right for the only population that gets here.\n *\n * Not every gated act is super-only: `/api/admin/org-override` admits\n * `billing` for plan and quota writes and reserves only `releaseFlags` for\n * `super`. A gate that could only say \"super\" would disable that dialog for\n * the role whose entire purpose it is — trading one dishonest control for\n * another.\n */\nexport function resolveStaffRoleGate(\n role: string | null | undefined,\n allowed: readonly string[],\n): StaffRoleGate {\n const ready = role !== null && role !== undefined\n const admitted = ready && allowed.includes(String(role))\n const blocked = ready && !admitted\n return {\n ready,\n admitted,\n blocked,\n reason: blocked\n ? `This action requires the ${allowed.join(' or ')} staff role. ` +\n 'Ask someone who holds it.'\n : undefined,\n }\n}\n\n/** The single sentence every blocked super-only control says. */\nexport const SUPER_STAFF_ONLY_REASON =\n 'This action requires the super staff role. Ask someone who holds it.'\n"],"names":["resolveStaffRoleGate","role","allowed","ready","undefined","admitted","includes","String","blocked","reason","join","SUPER_STAFF_ONLY_REASON"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAsBD;;;;;;;;;;;;;;;;;CAiBC,GACD,OAAO,SAASA,qBACdC,IAA+B,EAC/BC,OAA0B;IAE1B,MAAMC,QAAQF,SAAS,QAAQA,SAASG;IACxC,MAAMC,WAAWF,SAASD,QAAQI,QAAQ,CAACC,OAAON;IAClD,MAAMO,UAAUL,SAAS,CAACE;IAC1B,OAAO;QACLF;QACAE;QACAG;QACAC,QAAQD,UACJ,CAAC,yBAAyB,EAAEN,QAAQQ,IAAI,CAAC,QAAQ,aAAa,CAAC,GAC/D,8BACAN;IACN;AACF;AAEA,+DAA+D,GAC/D,OAAO,MAAMO,0BACX,uEAAsE"}
|
|
@@ -1242,6 +1242,48 @@ export interface ConsoleUpgradeNotice {
|
|
|
1242
1242
|
export interface ConsoleStaffPageProps {
|
|
1243
1243
|
/** The page's own console path, `/admin/{id}`. */
|
|
1244
1244
|
basePath: string;
|
|
1245
|
+
/**
|
|
1246
|
+
* Path segments beneath {@link basePath}, `[]` on the page's own URL
|
|
1247
|
+
* (AGL-3080). Only ever non-empty for a page that declared
|
|
1248
|
+
* {@link ConsoleStaffPage.ownsSubtree}.
|
|
1249
|
+
*
|
|
1250
|
+
* The staff twin of {@link ConsolePluginPageProps.segments}, and for the
|
|
1251
|
+
* same case: a queue is a list, and a row of it is a page. A staff page
|
|
1252
|
+
* without this could only ever BE the list.
|
|
1253
|
+
*/
|
|
1254
|
+
segments?: readonly string[];
|
|
1255
|
+
/**
|
|
1256
|
+
* The viewer's staff ROLE, or `null` while the claim is still resolving
|
|
1257
|
+
* (AGL-3080).
|
|
1258
|
+
*
|
|
1259
|
+
* Not every staff act is open to every staff role — six are `super`-only
|
|
1260
|
+
* on the server — and a page that cannot tell renders live controls to a
|
|
1261
|
+
* `support` engineer who clicks them and gets a raw 403. Pass it to
|
|
1262
|
+
* `resolveStaffRoleGate` and render the verdict with
|
|
1263
|
+
* `BlockedControl`; `null` must never be treated as a refusal, or every
|
|
1264
|
+
* page flashes a disabled button at the people who may use it.
|
|
1265
|
+
*
|
|
1266
|
+
* ⚠️ NOT the boundary. The routes verify the decoded token per request and
|
|
1267
|
+
* refuse regardless of what rendered. This exists so the console stops
|
|
1268
|
+
* promising what the server will refuse.
|
|
1269
|
+
*/
|
|
1270
|
+
staffRole?: string | null;
|
|
1271
|
+
/**
|
|
1272
|
+
* Console destinations a staff page may link ACROSS to, built by the shell
|
|
1273
|
+
* (AGL-3080) — the staff twin of {@link ConsolePluginOrgMount}'s paths,
|
|
1274
|
+
* and for the same reason: a plugin cannot import the console's route
|
|
1275
|
+
* table, and a plugin that rebuilt one of these from a string would break
|
|
1276
|
+
* silently the day the console moved it.
|
|
1277
|
+
*/
|
|
1278
|
+
staffPaths?: ConsoleStaffPagePaths;
|
|
1279
|
+
}
|
|
1280
|
+
export interface ConsoleStaffPagePaths {
|
|
1281
|
+
/**
|
|
1282
|
+
* The staff console's page for one workspace. `undefined` on a deployment
|
|
1283
|
+
* that has no such page, which a caller renders as no link rather than a
|
|
1284
|
+
* dead one.
|
|
1285
|
+
*/
|
|
1286
|
+
orgDetail(orgId: string): string | undefined;
|
|
1245
1287
|
}
|
|
1246
1288
|
/**
|
|
1247
1289
|
* A page a plugin adds to the STAFF area (AGL-2939): a tab in the staff
|
|
@@ -1274,6 +1316,25 @@ export interface ConsoleStaffPage {
|
|
|
1274
1316
|
icon?: MdiIconProps;
|
|
1275
1317
|
docsTopic?: string;
|
|
1276
1318
|
};
|
|
1319
|
+
/**
|
|
1320
|
+
* Whether this page claims every path beneath `/admin/{id}` too
|
|
1321
|
+
* (AGL-3080) — the staff twin of {@link ConsoleNavItem.ownsSubtree}, with
|
|
1322
|
+
* the same trade and the same duty.
|
|
1323
|
+
*
|
|
1324
|
+
* The case is a staff QUEUE: the list is the page, and each row opens one
|
|
1325
|
+
* submission. The set of ids is a property of the data, so no static list
|
|
1326
|
+
* could enumerate them, and without this every row's URL is a 404.
|
|
1327
|
+
*
|
|
1328
|
+
* A page that claims its subtree can no longer tell a typo from an id, so
|
|
1329
|
+
* it takes on saying "no such thing" itself — which a queue has to be able
|
|
1330
|
+
* to do anyway for a submission withdrawn while a link to it was still in
|
|
1331
|
+
* a reviewer's inbox.
|
|
1332
|
+
*
|
|
1333
|
+
* The console's own staff routes keep winning their segments either way:
|
|
1334
|
+
* a static path beats a dynamic one segment by segment, so `/admin/orgs/1`
|
|
1335
|
+
* is still the orgs route and never a staff page's subtree.
|
|
1336
|
+
*/
|
|
1337
|
+
ownsSubtree?: boolean;
|
|
1277
1338
|
Component: ComponentType<ConsoleStaffPageProps>;
|
|
1278
1339
|
}
|
|
1279
1340
|
export interface ConsoleExtension {
|