@xeonr/console-shell 0.4.2 → 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.
Files changed (85) hide show
  1. package/dist/CommandPalette.d.ts +3 -2
  2. package/dist/CommandPalette.d.ts.map +1 -1
  3. package/dist/CommandPalette.js +78 -10
  4. package/dist/CommandPalette.js.map +1 -1
  5. package/dist/ConsoleProvider.d.ts +39 -4
  6. package/dist/ConsoleProvider.d.ts.map +1 -1
  7. package/dist/ConsoleProvider.js +19 -3
  8. package/dist/ConsoleProvider.js.map +1 -1
  9. package/dist/ConsoleShell.d.ts +63 -3
  10. package/dist/ConsoleShell.d.ts.map +1 -1
  11. package/dist/ConsoleShell.js +142 -8
  12. package/dist/ConsoleShell.js.map +1 -1
  13. package/dist/ContextRow.d.ts +2 -0
  14. package/dist/ContextRow.d.ts.map +1 -0
  15. package/dist/ContextRow.js +235 -0
  16. package/dist/ContextRow.js.map +1 -0
  17. package/dist/Gate.d.ts +25 -0
  18. package/dist/Gate.d.ts.map +1 -0
  19. package/dist/Gate.js +38 -0
  20. package/dist/Gate.js.map +1 -0
  21. package/dist/ScopeCard.d.ts +4 -0
  22. package/dist/ScopeCard.d.ts.map +1 -0
  23. package/dist/ScopeCard.js +228 -0
  24. package/dist/ScopeCard.js.map +1 -0
  25. package/dist/ScopeRail.d.ts.map +1 -1
  26. package/dist/ScopeRail.js +42 -1
  27. package/dist/ScopeRail.js.map +1 -1
  28. package/dist/SectionSidebar.d.ts +6 -4
  29. package/dist/SectionSidebar.d.ts.map +1 -1
  30. package/dist/SectionSidebar.js +68 -23
  31. package/dist/SectionSidebar.js.map +1 -1
  32. package/dist/TopBar.d.ts.map +1 -1
  33. package/dist/TopBar.js +16 -2
  34. package/dist/TopBar.js.map +1 -1
  35. package/dist/context.d.ts +82 -0
  36. package/dist/context.d.ts.map +1 -0
  37. package/dist/context.js +65 -0
  38. package/dist/context.js.map +1 -0
  39. package/dist/crumb.d.ts +9 -0
  40. package/dist/crumb.d.ts.map +1 -1
  41. package/dist/crumb.js +20 -2
  42. package/dist/crumb.js.map +1 -1
  43. package/dist/crumbs.d.ts +19 -0
  44. package/dist/crumbs.d.ts.map +1 -0
  45. package/dist/crumbs.js +43 -0
  46. package/dist/crumbs.js.map +1 -0
  47. package/dist/index.d.ts +10 -2
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +10 -2
  50. package/dist/index.js.map +1 -1
  51. package/dist/links.d.ts +5 -4
  52. package/dist/links.d.ts.map +1 -1
  53. package/dist/links.js +5 -15
  54. package/dist/links.js.map +1 -1
  55. package/dist/nav.d.ts +66 -4
  56. package/dist/nav.d.ts.map +1 -1
  57. package/dist/nav.js +99 -2
  58. package/dist/nav.js.map +1 -1
  59. package/dist/origin.d.ts +2 -0
  60. package/dist/origin.d.ts.map +1 -0
  61. package/dist/origin.js +14 -0
  62. package/dist/origin.js.map +1 -0
  63. package/dist/place.d.ts +26 -0
  64. package/dist/place.d.ts.map +1 -0
  65. package/dist/place.js +53 -0
  66. package/dist/place.js.map +1 -0
  67. package/dist/scope.d.ts +35 -0
  68. package/dist/scope.d.ts.map +1 -0
  69. package/dist/scope.js +42 -0
  70. package/dist/scope.js.map +1 -0
  71. package/dist/screen.d.ts +38 -0
  72. package/dist/screen.d.ts.map +1 -0
  73. package/dist/screen.js +79 -0
  74. package/dist/screen.js.map +1 -0
  75. package/dist/shellConfig.d.ts +50 -0
  76. package/dist/shellConfig.d.ts.map +1 -0
  77. package/dist/shellConfig.js +24 -0
  78. package/dist/shellConfig.js.map +1 -0
  79. package/dist/types.d.ts +3 -1
  80. package/dist/types.d.ts.map +1 -1
  81. package/package.json +6 -4
  82. package/dist/TeamCard.d.ts +0 -5
  83. package/dist/TeamCard.d.ts.map +0 -1
  84. package/dist/TeamCard.js +0 -152
  85. package/dist/TeamCard.js.map +0 -1
package/dist/nav.js CHANGED
@@ -1,5 +1,102 @@
1
- // The product's own section nav, in the shape container-platform/ui and
2
- // functions/ui already use, so adopting the shell is handing over `NAV`.
1
+ import { matchPath } from "react-router-dom";
2
+ import { isSameOrigin } from "./origin.js";
3
+ /**
4
+ * A 0.4 switcher row: `href` + `internal`, whose highlight the product computes
5
+ * and passes as `active`. It keeps rendering its own flag and is left out of
6
+ * resolution, so a console that has not migrated (auth's scope picker, forest's
7
+ * project rows) looks exactly as it did before the bump.
8
+ */
9
+ export function isLegacySwitcher(item) {
10
+ return item.href !== undefined && item.internal === true && item.to === undefined;
11
+ }
12
+ function joinBase(base, rel) {
13
+ const b = base.replace(/\/+$/, "");
14
+ if (rel === "")
15
+ return b === "" ? "/" : b;
16
+ return `${b}/${rel.replace(/^\/+/, "")}`;
17
+ }
18
+ /** The item's destination and whether it stays in the router. */
19
+ export function itemTarget(item, base) {
20
+ if (item.to !== undefined)
21
+ return { href: item.to, kind: "route" };
22
+ if (item.href !== undefined) {
23
+ const internal = !item.external && (item.internal === true || isSameOrigin(item.href));
24
+ return { href: item.href, kind: internal ? "route" : "external" };
25
+ }
26
+ return { href: joinBase(base, item.path), kind: "route" };
27
+ }
28
+ function trimSlash(p) {
29
+ return p.length > 1 ? p.replace(/\/+$/, "") : p;
30
+ }
31
+ function pathOnly(href) {
32
+ const q = href.search(/[?#]/);
33
+ return trimSlash(q === -1 ? href : href.slice(0, q));
34
+ }
35
+ function isPrefix(prefix, path) {
36
+ if (prefix === "/")
37
+ return path === "/";
38
+ return path === prefix || path.startsWith(`${prefix}/`);
39
+ }
40
+ /**
41
+ * The one answer to "which section am I in". Order: a screen's override (by
42
+ * key) > `active` > the longest matching `match` pattern or path prefix. An
43
+ * item is exact — never a prefix — when it is the index (`path: ""`), when it
44
+ * says `exact`, or when its target is a prefix of a sibling's (so trail's
45
+ * project Overview stops lighting on every project page). External items are
46
+ * never resolved, nor are 0.4 switcher rows (isLegacySwitcher). Hidden items
47
+ * are resolved too: a screen whose item is hidden from the sidebar still names
48
+ * its section in the crumb. On a tie a section (`path`/`to`) beats an `href`.
49
+ */
50
+ export function resolveActive(groups, pathname, base, override) {
51
+ const items = groups.flatMap((g) => g.items).filter((i) => !isLegacySwitcher(i));
52
+ if (override !== undefined) {
53
+ const o = items.find((i) => i.key === override);
54
+ if (o)
55
+ return o;
56
+ }
57
+ const forced = items.find((i) => i.active === true);
58
+ if (forced)
59
+ return forced;
60
+ const here = trimSlash(pathname) || "/";
61
+ const routes = items
62
+ .map((item) => ({ item, ...itemTarget(item, base) }))
63
+ .filter((r) => r.kind === "route")
64
+ .map((r) => ({ ...r, path: pathOnly(r.href) || "/" }));
65
+ const rel = (() => {
66
+ const b = trimSlash(base);
67
+ if (b === "" || b === "/")
68
+ return here.replace(/^\//, "");
69
+ return isPrefix(b, here) ? here.slice(b.length).replace(/^\//, "") : null;
70
+ })();
71
+ let best;
72
+ const offer = (item, length) => {
73
+ const score = length * 2 + (item.href === undefined ? 1 : 0);
74
+ if (!best || score > best.score)
75
+ best = { item, score };
76
+ };
77
+ for (const r of routes) {
78
+ const exact = r.item.exact === true ||
79
+ (r.item.to === undefined && r.item.href === undefined && r.item.path === "") ||
80
+ routes.some((o) => o !== r && o.path !== r.path && isPrefix(r.path, o.path));
81
+ if (exact ? here === r.path : isPrefix(r.path, here))
82
+ offer(r.item, r.path.length);
83
+ const m = r.item.match;
84
+ if (m === undefined || rel === null)
85
+ continue;
86
+ if (typeof m === "function") {
87
+ if (m(rel))
88
+ offer(r.item, joinBase(base, rel).length);
89
+ continue;
90
+ }
91
+ for (const pattern of Array.isArray(m) ? m : [m]) {
92
+ const full = joinBase(base, pattern);
93
+ if (matchPath({ path: full, end: !full.endsWith("*") }, here))
94
+ offer(r.item, full.replace(/\/\*$/, "").length);
95
+ }
96
+ }
97
+ return best?.item;
98
+ }
99
+ /** @deprecated use resolveActive, which also honours `to`, `match`, `exact` and `active` */
3
100
  export function sectionFor(groups, relPath) {
4
101
  const first = relPath.replace(/^\//, "").split("/")[0] ?? "";
5
102
  const all = groups.flatMap((g) => g.items);
package/dist/nav.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"nav.js","sourceRoot":"","sources":["../src/nav.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,yEAAyE;AAwBzE,MAAM,UAAU,UAAU,CAAC,MAAkB,EAAE,OAAe;IAC5D,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7D,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC3C,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAClF,CAAC"}
1
+ {"version":3,"file":"nav.js","sourceRoot":"","sources":["../src/nav.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function isSameOrigin(href: string): boolean;
2
+ //# sourceMappingURL=origin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"origin.d.ts","sourceRoot":"","sources":["../src/origin.ts"],"names":[],"mappings":"AAEA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQlD"}
package/dist/origin.js ADDED
@@ -0,0 +1,14 @@
1
+ // Pure, so nav.ts (and its tests under node) can use it without JSX.
2
+ export function isSameOrigin(href) {
3
+ if (!/^[a-z][a-z0-9+.-]*:|^\/\//i.test(href))
4
+ return true; // relative
5
+ if (typeof window === "undefined")
6
+ return false;
7
+ try {
8
+ return new URL(href, window.location.href).origin === window.location.origin;
9
+ }
10
+ catch {
11
+ return false;
12
+ }
13
+ }
14
+ //# sourceMappingURL=origin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"origin.js","sourceRoot":"","sources":["../src/origin.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAErE,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,WAAW;IACtE,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IAChD,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;IAC/E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,26 @@
1
+ export interface Place {
2
+ /** the lit section's key */
3
+ sectionKey?: string | undefined;
4
+ /** its path relative to base (or the context root) — kept across a switch */
5
+ sectionPath?: string | undefined;
6
+ /** the carried query string ("?env=prod&from=…"), or "" */
7
+ search: string;
8
+ /** where the shell would land: the same section under the target, else its root */
9
+ suggested: string;
10
+ }
11
+ /**
12
+ * A team-rooted base for another team: replace the leading `/${from}` segment
13
+ * of `base` with `/${to}`. Undefined when the base is not rooted at the team
14
+ * (trellis, lantern, auth) — then there is no generic answer and the shell
15
+ * leaves the navigation to the product.
16
+ */
17
+ export declare function swapTeamBase(base: string, from: string | undefined, to: string): string | undefined;
18
+ export declare function joinPath(root: string, rel: string | undefined): string;
19
+ /** The query keys in `search` that `keys` names, as "?a=1&b=2" or "". */
20
+ export declare function pickSearch(search: string, keys: string[]): string;
21
+ /**
22
+ * Add the carried keys to a same-origin href that does not already set them.
23
+ * Another origin is left alone: its scope keys are not ours to send.
24
+ */
25
+ export declare function withCarry(href: string, carried: string): string;
26
+ //# sourceMappingURL=place.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"place.d.ts","sourceRoot":"","sources":["../src/place.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,KAAK;IACpB,4BAA4B;IAC5B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,mFAAmF;IACnF,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAMnG;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGtE;AAED,yEAAyE;AACzE,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAOjE;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAW/D"}
package/dist/place.js ADDED
@@ -0,0 +1,53 @@
1
+ import { isSameOrigin } from "./origin.js";
2
+ /**
3
+ * A team-rooted base for another team: replace the leading `/${from}` segment
4
+ * of `base` with `/${to}`. Undefined when the base is not rooted at the team
5
+ * (trellis, lantern, auth) — then there is no generic answer and the shell
6
+ * leaves the navigation to the product.
7
+ */
8
+ export function swapTeamBase(base, from, to) {
9
+ if (!from)
10
+ return undefined;
11
+ const b = base.replace(/\/+$/, "");
12
+ if (b === `/${from}`)
13
+ return `/${to}`;
14
+ if (b.startsWith(`/${from}/`))
15
+ return `/${to}${b.slice(from.length + 1)}`;
16
+ return undefined;
17
+ }
18
+ export function joinPath(root, rel) {
19
+ const r = root.replace(/\/+$/, "");
20
+ return rel ? `${r}/${rel.replace(/^\/+/, "")}` : r || "/";
21
+ }
22
+ /** The query keys in `search` that `keys` names, as "?a=1&b=2" or "". */
23
+ export function pickSearch(search, keys) {
24
+ if (keys.length === 0 || !search)
25
+ return "";
26
+ const from = new URLSearchParams(search);
27
+ const out = new URLSearchParams();
28
+ for (const k of keys)
29
+ for (const v of from.getAll(k))
30
+ out.append(k, v);
31
+ const s = out.toString();
32
+ return s ? `?${s}` : "";
33
+ }
34
+ /**
35
+ * Add the carried keys to a same-origin href that does not already set them.
36
+ * Another origin is left alone: its scope keys are not ours to send.
37
+ */
38
+ export function withCarry(href, carried) {
39
+ if (!carried || !isSameOrigin(href))
40
+ return href;
41
+ const hash = href.indexOf("#");
42
+ const body = hash === -1 ? href : href.slice(0, hash);
43
+ const frag = hash === -1 ? "" : href.slice(hash);
44
+ const q = body.indexOf("?");
45
+ const path = q === -1 ? body : body.slice(0, q);
46
+ const own = new URLSearchParams(q === -1 ? "" : body.slice(q + 1));
47
+ for (const [k, v] of new URLSearchParams(carried))
48
+ if (!own.has(k))
49
+ own.append(k, v);
50
+ const s = own.toString();
51
+ return `${path}${s ? `?${s}` : ""}${frag}`;
52
+ }
53
+ //# sourceMappingURL=place.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"place.js","sourceRoot":"","sources":["../src/place.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { Requires } from "./nav.ts";
2
+ import type { Me, Scope, Team } from "./types.ts";
3
+ /** Where a scope lands, and who may enter it. */
4
+ export interface ScopeEntry {
5
+ /** the scope's landing; a function receives the console team (team scope needs one) */
6
+ href: string | ((team: Team | null) => string);
7
+ /** shown only when satisfied */
8
+ requires?: Requires | undefined;
9
+ /** the card and menu label, e.g. CP's "All namespaces" for its organisation view */
10
+ label?: string | undefined;
11
+ }
12
+ export type ScopeMap = Partial<Record<Scope, ScopeEntry>>;
13
+ /**
14
+ * A product's own answer to `requires`. When supplied it is the only
15
+ * authority: it receives the shell's verdict as a hint and decides. Products
16
+ * whose roles are their own (Dev's ladder, a platform-admin flag) need this;
17
+ * products whose roles are team-typed application roles need nothing.
18
+ */
19
+ export type Can = (requires: Requires, team: Team | null, shellSays: boolean) => boolean;
20
+ /**
21
+ * The shell's built-in reading: `team:owner` is the team's governance owner
22
+ * (or an org admin); `org:admin` is an organisation administrator; any other
23
+ * string is a team-typed application role the caller holds on `team`.
24
+ */
25
+ export declare function shellSatisfies(requires: Requires, team: Team | null, me: Pick<Me, "isOrgAdmin">): boolean;
26
+ export declare function satisfies(requires: Requires | undefined, team: Team | null, me: Pick<Me, "isOrgAdmin">, can?: Can | undefined): boolean;
27
+ /**
28
+ * The scopes the caller can enter, in a fixed order. Team needs at least one
29
+ * team; a declared scope with `requires` needs it satisfied. Scopes the
30
+ * product did not declare are not offered — except personal and organisation
31
+ * when `fallbacks` says the console home has them.
32
+ */
33
+ export declare function availableScopes(scopes: ScopeMap, team: Team | null, me: Pick<Me, "isOrgAdmin" | "teams">, can?: Can | undefined, fallbacks?: Partial<Record<Scope, boolean>>): Scope[];
34
+ export declare function scopeHref(entry: ScopeEntry, team: Team | null): string;
35
+ //# sourceMappingURL=scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AASlD,iDAAiD;AACjD,MAAM,WAAW,UAAU;IACzB,uFAAuF;IACvF,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,MAAM,CAAC,CAAC;IAC/C,gCAAgC;IAChC,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAChC,oFAAoF;IACpF,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,SAAS,EAAE,OAAO,KAAK,OAAO,CAAC;AAEzF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,YAAY,CAAC,GAAG,OAAO,CAIzG;AAED,wBAAgB,SAAS,CACvB,QAAQ,EAAE,QAAQ,GAAG,SAAS,EAC9B,IAAI,EAAE,IAAI,GAAG,IAAI,EACjB,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,YAAY,CAAC,EAC1B,GAAG,CAAC,EAAE,GAAG,GAAG,SAAS,GACpB,OAAO,CAIT;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,QAAQ,EAChB,IAAI,EAAE,IAAI,GAAG,IAAI,EACjB,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,EACpC,GAAG,CAAC,EAAE,GAAG,GAAG,SAAS,EACrB,SAAS,GAAE,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAM,GAC9C,KAAK,EAAE,CAUT;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAEtE"}
package/dist/scope.js ADDED
@@ -0,0 +1,42 @@
1
+ /**
2
+ * The shell's built-in reading: `team:owner` is the team's governance owner
3
+ * (or an org admin); `org:admin` is an organisation administrator; any other
4
+ * string is a team-typed application role the caller holds on `team`.
5
+ */
6
+ export function shellSatisfies(requires, team, me) {
7
+ if (requires === "org:admin")
8
+ return me.isOrgAdmin;
9
+ if (requires === "team:owner")
10
+ return me.isOrgAdmin || team?.role === "owner";
11
+ return !!team && (team.role === "owner" || team.roles.includes(requires));
12
+ }
13
+ export function satisfies(requires, team, me, can) {
14
+ if (requires === undefined)
15
+ return true;
16
+ const shell = shellSatisfies(requires, team, me);
17
+ return can ? can(requires, team, shell) : shell;
18
+ }
19
+ /**
20
+ * The scopes the caller can enter, in a fixed order. Team needs at least one
21
+ * team; a declared scope with `requires` needs it satisfied. Scopes the
22
+ * product did not declare are not offered — except personal and organisation
23
+ * when `fallbacks` says the console home has them.
24
+ */
25
+ export function availableScopes(scopes, team, me, can, fallbacks = {}) {
26
+ const out = [];
27
+ for (const s of ["team", "personal", "organisation"]) {
28
+ const entry = scopes[s];
29
+ if (s === "team" && me.teams.length === 0)
30
+ continue;
31
+ if (!entry && !fallbacks[s])
32
+ continue;
33
+ if (entry && !satisfies(entry.requires, team, me, can))
34
+ continue;
35
+ out.push(s);
36
+ }
37
+ return out;
38
+ }
39
+ export function scopeHref(entry, team) {
40
+ return typeof entry.href === "function" ? entry.href(team) : entry.href;
41
+ }
42
+ //# sourceMappingURL=scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AA8BA;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,QAAkB,EAAE,IAAiB,EAAE,EAA0B;IAC9F,IAAI,QAAQ,KAAK,WAAW;QAAE,OAAO,EAAE,CAAC,UAAU,CAAC;IACnD,IAAI,QAAQ,KAAK,YAAY;QAAE,OAAO,EAAE,CAAC,UAAU,IAAI,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;IAC9E,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,QAA8B,EAC9B,IAAiB,EACjB,EAA0B,EAC1B,GAAqB;IAErB,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IACjD,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAClD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAgB,EAChB,IAAiB,EACjB,EAAoC,EACpC,GAAqB,EACrB,YAA6C,EAAE;IAE/C,MAAM,GAAG,GAAY,EAAE,CAAC;IACxB,KAAK,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,cAAc,CAAU,EAAE,CAAC;QAC9D,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,KAAK,MAAM,IAAI,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACpD,IAAI,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;YAAE,SAAS;QACtC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC;YAAE,SAAS;QACjE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACd,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAiB,EAAE,IAAiB;IAC5D,OAAO,OAAO,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { type ReactNode } from "react";
2
+ import type { ContextItem } from "./context.ts";
3
+ import type { Scope } from "./types.ts";
4
+ /** The team a screen shows: a slug in the caller's teams, or a read-only owner. */
5
+ export type ScreenTeam = string | {
6
+ slug: string;
7
+ id?: string | undefined;
8
+ name?: string | undefined;
9
+ avatarUrl?: string | undefined;
10
+ };
11
+ export interface ScreenState {
12
+ section?: string | undefined;
13
+ /** an id, a whole item, or "pending" while the screen's data loads */
14
+ context?: string | ContextItem | "pending" | undefined;
15
+ scope?: Scope | undefined;
16
+ /** null: this screen shows no team */
17
+ team?: ScreenTeam | null | undefined;
18
+ }
19
+ export declare function ScreenProvider({ children }: {
20
+ children: (state: ScreenState) => ReactNode;
21
+ }): import("react").JSX.Element;
22
+ /** Light a section from a screen whose route is outside its prefix. Undefined publishes nothing. */
23
+ export declare function useActiveSection(key: string | undefined): void;
24
+ /**
25
+ * Set the current context from loaded data. Undefined while mounted means
26
+ * "pending": the row shows a skeleton instead of the wrong context. Pass a
27
+ * whole item for a context that is not in the list (an org-visible project).
28
+ */
29
+ export declare function useActiveContext(current: string | ContextItem | undefined): void;
30
+ /** This screen's scope, when the layout cannot tell from the route. */
31
+ export declare function useScope(scope: Scope | undefined): void;
32
+ /**
33
+ * Point the card at the team a screen is showing (a ticket's owner). Display
34
+ * only: it never writes the console context. A team the caller is not in is
35
+ * shown read-only. Undefined publishes nothing; null says "no team".
36
+ */
37
+ export declare function useActiveTeam(team: ScreenTeam | null | undefined): void;
38
+ //# sourceMappingURL=screen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen.d.ts","sourceRoot":"","sources":["../src/screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA0E,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/G,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAYxC,mFAAmF;AACnF,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEvI,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;IACvD,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IAC1B,sCAAsC;IACtC,IAAI,CAAC,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC;CACtC;AAmBD,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,SAAS,CAAA;CAAE,+BAyB3F;AAkBD,oGAAoG;AACpG,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,IAAI,CAEhF;AAED,uEAAuE;AACvE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,IAAI,CAEvD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAEvE"}
package/dist/screen.js ADDED
@@ -0,0 +1,79 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext, useEffect, useId, useMemo, useRef, useState } from "react";
3
+ const SinkCtx = createContext(null);
4
+ // An item or a team object is usually built inline, so it is a new object on
5
+ // every render; comparing by value keeps a re-render from becoming a write.
6
+ function same(a, b) {
7
+ if (a === b)
8
+ return true;
9
+ if (typeof a !== "object" || typeof b !== "object" || a === null || b === null)
10
+ return false;
11
+ return JSON.stringify(a) === JSON.stringify(b);
12
+ }
13
+ export function ScreenProvider({ children }) {
14
+ const [entries, setEntries] = useState([]);
15
+ const sink = useMemo(() => ({
16
+ set: (kind, id, value) => setEntries((es) => {
17
+ const i = es.findIndex((e) => e.kind === kind && e.id === id);
18
+ if (i >= 0) {
19
+ if (same(es[i].value, value))
20
+ return es;
21
+ const next = es.slice();
22
+ next[i] = { kind, id, value };
23
+ return next;
24
+ }
25
+ return [...es, { kind, id, value }];
26
+ }),
27
+ clear: (kind, id) => setEntries((es) => (es.some((e) => e.kind === kind && e.id === id) ? es.filter((e) => !(e.kind === kind && e.id === id)) : es)),
28
+ }), []);
29
+ const state = useMemo(() => {
30
+ const out = {};
31
+ for (const e of entries)
32
+ out[e.kind] = e.value; // mount order: innermost last, wins
33
+ return out;
34
+ }, [entries]);
35
+ return _jsx(SinkCtx.Provider, { value: sink, children: children(state) });
36
+ }
37
+ function usePublish(kind, value, publish) {
38
+ const sink = useContext(SinkCtx);
39
+ const id = useId();
40
+ // Keyed by value, not identity: an inline object must not re-run the effect
41
+ // (its cleanup would withdraw and re-add the entry on every render).
42
+ const key = typeof value === "object" && value !== null ? JSON.stringify(value) : value;
43
+ const latest = useRef(value);
44
+ latest.current = value;
45
+ useEffect(() => {
46
+ if (!sink)
47
+ return;
48
+ if (publish)
49
+ sink.set(kind, id, latest.current);
50
+ else
51
+ sink.clear(kind, id);
52
+ }, [sink, kind, id, key, publish]);
53
+ useEffect(() => () => sink?.clear(kind, id), [sink, kind, id]);
54
+ }
55
+ /** Light a section from a screen whose route is outside its prefix. Undefined publishes nothing. */
56
+ export function useActiveSection(key) {
57
+ usePublish("section", key, key !== undefined);
58
+ }
59
+ /**
60
+ * Set the current context from loaded data. Undefined while mounted means
61
+ * "pending": the row shows a skeleton instead of the wrong context. Pass a
62
+ * whole item for a context that is not in the list (an org-visible project).
63
+ */
64
+ export function useActiveContext(current) {
65
+ usePublish("context", current ?? "pending", true);
66
+ }
67
+ /** This screen's scope, when the layout cannot tell from the route. */
68
+ export function useScope(scope) {
69
+ usePublish("scope", scope, scope !== undefined);
70
+ }
71
+ /**
72
+ * Point the card at the team a screen is showing (a ticket's owner). Display
73
+ * only: it never writes the console context. A team the caller is not in is
74
+ * shown read-only. Undefined publishes nothing; null says "no team".
75
+ */
76
+ export function useActiveTeam(team) {
77
+ usePublish("team", team, team !== undefined);
78
+ }
79
+ //# sourceMappingURL=screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen.js","sourceRoot":"","sources":["../src/screen.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AAiC/G,MAAM,OAAO,GAAG,aAAa,CAAc,IAAI,CAAC,CAAC;AAEjD,6EAA6E;AAC7E,4EAA4E;AAC5E,SAAS,IAAI,CAAC,CAAU,EAAE,CAAU;IAClC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC7F,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAAE,QAAQ,EAAmD;IAC1F,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAoD,EAAE,CAAC,CAAC;IAC9F,MAAM,IAAI,GAAG,OAAO,CAClB,GAAG,EAAE,CAAC,CAAC;QACL,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,CACvB,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE;YAChB,MAAM,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACX,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAE,CAAC,KAAK,EAAE,KAAK,CAAC;oBAAE,OAAO,EAAE,CAAC;gBACzC,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC;gBACxB,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;gBAC9B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACtC,CAAC,CAAC;QACJ,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;KACrJ,CAAC,EACF,EAAE,CACH,CAAC;IACF,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE;QACzB,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,IAAI,OAAO;YAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,oCAAoC;QACpF,OAAO,GAAkB,CAAC;IAC5B,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACd,OAAO,KAAC,OAAO,CAAC,QAAQ,IAAC,KAAK,EAAE,IAAI,YAAG,QAAQ,CAAC,KAAK,CAAC,GAAoB,CAAC;AAC7E,CAAC;AAED,SAAS,UAAU,CAAC,IAAU,EAAE,KAAc,EAAE,OAAgB;IAC9D,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IACjC,MAAM,EAAE,GAAG,KAAK,EAAE,CAAC;IACnB,4EAA4E;IAC5E,qEAAqE;IACrE,MAAM,GAAG,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACxF,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;IACvB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,OAAO;YAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;;YAC3C,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC5B,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IACnC,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,gBAAgB,CAAC,GAAuB;IACtD,UAAU,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,KAAK,SAAS,CAAC,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAyC;IACxE,UAAU,CAAC,SAAS,EAAE,OAAO,IAAI,SAAS,EAAE,IAAI,CAAC,CAAC;AACpD,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,QAAQ,CAAC,KAAwB;IAC/C,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC;AAClD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAmC;IAC/D,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,50 @@
1
+ import { type ReactNode } from "react";
2
+ import type { Can, ScopeMap } from "./scope.ts";
3
+ import type { ContextItem, CurrentContext, NavContext } from "./context.ts";
4
+ import type { ScreenTeam } from "./screen.tsx";
5
+ import type { Place } from "./place.ts";
6
+ import type { Scope, Team } from "./types.ts";
7
+ export interface ShellConfig {
8
+ scope: Scope;
9
+ scopes: ScopeMap;
10
+ can?: Can | undefined;
11
+ organisation?: {
12
+ name: string;
13
+ avatarUrl?: string | undefined;
14
+ } | undefined;
15
+ roleLabel?: ((team: Team) => string) | undefined;
16
+ productLabel: string;
17
+ authOrigin: string;
18
+ /** the product's one second context, when it declares one */
19
+ context?: NavContext | undefined;
20
+ /** what the context row shows, after the screen's useActiveContext */
21
+ currentContext: CurrentContext;
22
+ /** the lit section's path relative to the context root (kept on a context switch) */
23
+ sectionPath?: string | undefined;
24
+ onContextChange?: ((item: ContextItem, href: string) => void) | undefined;
25
+ /** the team a screen published with useActiveTeam (display only) */
26
+ screenTeam?: ScreenTeam | null | undefined;
27
+ /** the carried query string ("?env=prod…") for every link the shell renders */
28
+ carried: string;
29
+ /** where you are, and where a switch to `team` would land */
30
+ placeFor(team: Team): Place;
31
+ onScopeChange?: ((scope: Scope, place: Place) => string | void) | undefined;
32
+ /** the sidebar is the 56px icon column */
33
+ collapsed: boolean;
34
+ /** close the phone drawer — every navigation from the chrome does */
35
+ closeDrawer: () => void;
36
+ /** NavItem.countKey → count */
37
+ counts?: Record<string, number | string | undefined> | undefined;
38
+ }
39
+ export declare function ShellConfigProvider({ value, children }: {
40
+ value: ShellConfig;
41
+ children: ReactNode;
42
+ }): import("react").JSX.Element;
43
+ /**
44
+ * Add the shell's carried query keys (ConsoleShell `carryQuery`) to a link, so
45
+ * a product's own links keep the same global scope as the sidebar's. Outside a
46
+ * shell it returns the href unchanged.
47
+ */
48
+ export declare function useShellLink(): (href: string) => string;
49
+ export declare function useShellConfig(): ShellConfig;
50
+ //# sourceMappingURL=shellConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shellConfig.d.ts","sourceRoot":"","sources":["../src/shellConfig.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAO9C,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,QAAQ,CAAC;IACjB,GAAG,CAAC,EAAE,GAAG,GAAG,SAAS,CAAC;IACtB,YAAY,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,GAAG,SAAS,CAAC;IAC5E,SAAS,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,GAAG,SAAS,CAAC;IACjD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IACjC,sEAAsE;IACtE,cAAc,EAAE,cAAc,CAAC;IAC/B,qFAAqF;IACrF,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,eAAe,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC1E,oEAAoE;IACpE,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC;IAC3C,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,KAAK,CAAC;IAC5B,aAAa,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC;IAC5E,0CAA0C;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,qEAAqE;IACrE,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,+BAA+B;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;CAClE;AAID,wBAAgB,mBAAmB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAEnG;AAED;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAIvD;AAED,wBAAgB,cAAc,IAAI,WAAW,CAI5C"}
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext } from "react";
3
+ import { withCarry } from "./place.js";
4
+ const Ctx = createContext(null);
5
+ export function ShellConfigProvider({ value, children }) {
6
+ return _jsx(Ctx.Provider, { value: value, children: children });
7
+ }
8
+ /**
9
+ * Add the shell's carried query keys (ConsoleShell `carryQuery`) to a link, so
10
+ * a product's own links keep the same global scope as the sidebar's. Outside a
11
+ * shell it returns the href unchanged.
12
+ */
13
+ export function useShellLink() {
14
+ const c = useContext(Ctx);
15
+ const carried = c?.carried ?? "";
16
+ return (href) => withCarry(href, carried);
17
+ }
18
+ export function useShellConfig() {
19
+ const c = useContext(Ctx);
20
+ if (!c)
21
+ throw new Error("useShellConfig outside ConsoleShell");
22
+ return c;
23
+ }
24
+ //# sourceMappingURL=shellConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shellConfig.js","sourceRoot":"","sources":["../src/shellConfig.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAkB,MAAM,OAAO,CAAC;AAKlE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAsCvC,MAAM,GAAG,GAAG,aAAa,CAAqB,IAAI,CAAC,CAAC;AAEpD,MAAM,UAAU,mBAAmB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAA+C;IAClG,OAAO,KAAC,GAAG,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAAgB,CAAC;AAC/D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC1B,MAAM,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,EAAE,CAAC;IACjC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAC/D,OAAO,CAAC,CAAC;AACX,CAAC"}
package/dist/types.d.ts CHANGED
@@ -97,7 +97,9 @@ export interface ConsoleClient {
97
97
  }
98
98
  export interface SearchResult {
99
99
  product: string;
100
- kind: "entity" | "action" | "team" | "navigation";
100
+ kind: "entity" | "action" | "team" | "navigation" | "context";
101
+ /** the entity's identity, for deduplicating against the context list (0.5) */
102
+ entityId?: string | undefined;
101
103
  title: string;
102
104
  subtitle?: string | undefined;
103
105
  href: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,KAAK,GAAG,UAAU,GAAG,MAAM,GAAG,cAAc,CAAC;AAEzD,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,MAAM,GACN,iBAAiB,GACjB,YAAY,GACZ,eAAe,GACf,mBAAmB,CAAC;AAExB,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC;AAE/D,wGAAwG;AACxG,MAAM,WAAW,OAAO;IACtB,sEAAsE;IACtE,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,kGAAkG;IAClG,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,eAAe,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;IACzB,oEAAoE;IACpE,OAAO,EAAE,OAAO,CAAC;IACjB,qFAAqF;IACrF,SAAS,EAAE,OAAO,CAAC;IACnB,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAED,MAAM,WAAW,IAAI;IACnB,+DAA+D;IAC/D,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,2BAA2B;IAC3B,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,iEAAiE;IACjE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,mEAAmE;IACnE,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACjC;AAED,MAAM,WAAW,EAAE;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,uEAAuE;IACvE,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CACjC;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC,CAAC;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,kFAAkF;AAClF,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;;OAIG;IACH,cAAc,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAChC,KAAK,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,IAAI,OAAO,CAAC,EAAE,CAAC,CAAC;IAClB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACtD,UAAU,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IACtC,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACpE,iBAAiB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAC3C;;;;;;;;;OASG;IACH,aAAa,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,0EAA0E;IAC1E,MAAM,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CACtE;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;IAC9D,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xeonr/console-shell",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "description": "The Xeonr Cloud Console chrome: product rail, team switcher, section sidebar, top bar, ⌘K and the All-products launcher, plus the console context hooks every product console mounts.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -23,9 +23,10 @@
23
23
  "react-dom": "^19.0.0",
24
24
  "react-router-dom": "^7.0.0",
25
25
  "styled-components": "^6.0.0",
26
- "@xeonr/platform-ui": "^0.4.0"
26
+ "@xeonr/platform-ui": "^0.5.0"
27
27
  },
28
28
  "devDependencies": {
29
+ "@types/node": "^24.19.2",
29
30
  "@types/react": "^19.1.0",
30
31
  "@types/react-dom": "^19.1.0",
31
32
  "react": "^19.1.0",
@@ -33,7 +34,7 @@
33
34
  "react-router-dom": "^7.8.0",
34
35
  "styled-components": "^6.1.19",
35
36
  "typescript": "^5.9.2",
36
- "@xeonr/platform-ui": "0.4.0"
37
+ "@xeonr/platform-ui": "0.5.0"
37
38
  },
38
39
  "dependencies": {
39
40
  "@bufbuild/protobuf": "^2.10.2",
@@ -43,6 +44,7 @@
43
44
  "scripts": {
44
45
  "build": "tsc -p tsconfig.build.json",
45
46
  "lint": "tsc -p tsconfig.json --noEmit && xeonr-check-colour-literals",
46
- "generate": "buf generate"
47
+ "generate": "buf generate",
48
+ "test": "node --test src/*.test.ts"
47
49
  }
48
50
  }
@@ -1,5 +0,0 @@
1
- export declare function TeamCard({ productLabel, authOrigin }: {
2
- productLabel: string;
3
- authOrigin: string;
4
- }): import("react").JSX.Element;
5
- //# sourceMappingURL=TeamCard.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TeamCard.d.ts","sourceRoot":"","sources":["../src/TeamCard.tsx"],"names":[],"mappings":"AAuHA,wBAAgB,QAAQ,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,+BAyGlG"}