@jskit-ai/kernel 0.1.53 → 0.1.55

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.
@@ -0,0 +1,5 @@
1
+ export function redirectToChild(childTarget?: string): (to?: any) => {
2
+ path: string;
3
+ query: any;
4
+ hash: string;
5
+ };
@@ -0,0 +1,45 @@
1
+ import { resolveLinkPath } from "../shared/support/linkPath.js";
2
+ import { splitPathQueryAndHash } from "../shared/support/queryPath.js";
3
+
4
+ function queryStringToObject(queryString = "") {
5
+ const normalizedQueryString = String(queryString || "").trim().replace(/^\?+/, "");
6
+ if (!normalizedQueryString) {
7
+ return undefined;
8
+ }
9
+
10
+ const params = new URLSearchParams(normalizedQueryString);
11
+ const query = {};
12
+
13
+ for (const [key, value] of params.entries()) {
14
+ if (!Object.prototype.hasOwnProperty.call(query, key)) {
15
+ query[key] = value;
16
+ continue;
17
+ }
18
+
19
+ if (Array.isArray(query[key])) {
20
+ query[key].push(value);
21
+ continue;
22
+ }
23
+
24
+ query[key] = [query[key], value];
25
+ }
26
+
27
+ return query;
28
+ }
29
+
30
+ function redirectToChild(childTarget = "") {
31
+ const normalizedChildTarget = String(childTarget || "").trim();
32
+
33
+ return function redirectToChildRoute(to = {}) {
34
+ const resolvedTarget = resolveLinkPath(String(to?.path || "/"), normalizedChildTarget);
35
+ const { pathname, queryString, hash } = splitPathQueryAndHash(resolvedTarget);
36
+
37
+ return {
38
+ path: pathname || "/",
39
+ query: queryStringToObject(queryString) ?? to?.query,
40
+ hash: hash || String(to?.hash || "")
41
+ };
42
+ };
43
+ }
44
+
45
+ export { redirectToChild };
@@ -0,0 +1,40 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { redirectToChild } from "./pageRedirects.js";
4
+
5
+ test("redirectToChild resolves a child path and preserves incoming query and hash", () => {
6
+ const redirect = redirectToChild("general");
7
+
8
+ assert.deepEqual(redirect({
9
+ path: "/home/settings/",
10
+ query: {
11
+ tab: "profile"
12
+ },
13
+ hash: "#advanced"
14
+ }), {
15
+ path: "/home/settings/general",
16
+ query: {
17
+ tab: "profile"
18
+ },
19
+ hash: "#advanced"
20
+ });
21
+ });
22
+
23
+ test("redirectToChild uses child query and hash when the target declares them", () => {
24
+ const redirect = redirectToChild("general?tab=security&filter=a&filter=b#advanced");
25
+
26
+ assert.deepEqual(redirect({
27
+ path: "/home/settings",
28
+ query: {
29
+ stale: "value"
30
+ },
31
+ hash: "#old"
32
+ }), {
33
+ path: "/home/settings/general",
34
+ query: {
35
+ tab: "security",
36
+ filter: ["a", "b"]
37
+ },
38
+ hash: "#advanced"
39
+ });
40
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/kernel",
3
- "version": "0.1.53",
3
+ "version": "0.1.55",
4
4
  "type": "module",
5
5
  "dependencies": {
6
6
  "typebox": "^1.0.81"
@@ -14,6 +14,10 @@
14
14
  "types": "./client/index.d.ts",
15
15
  "default": "./client/index.js"
16
16
  },
17
+ "./client/pageRedirects": {
18
+ "types": "./client/pageRedirects.d.ts",
19
+ "default": "./client/pageRedirects.js"
20
+ },
17
21
  "./client/moduleBootstrap": "./client/moduleBootstrap.js",
18
22
  "./client/vite": "./client/vite/index.js",
19
23
  "./server/actions": "./server/actions/index.js",
@@ -98,7 +98,7 @@ test("discoverShellOutletTargetsFromApp includes installed package placement out
98
98
  placements: {
99
99
  outlets: [
100
100
  {
101
- target: "workspace-tools:primary-menu",
101
+ target: "admin-cog:primary-menu",
102
102
  defaultLinkComponentToken: "local.main.ui.surface-aware-menu-link-item",
103
103
  source: "src/client/components/UsersWorkspaceToolsWidget.vue"
104
104
  }
@@ -113,10 +113,10 @@ test("discoverShellOutletTargetsFromApp includes installed package placement out
113
113
  const discovered = await discoverShellOutletTargetsFromApp({ appRoot });
114
114
  assert.deepEqual(
115
115
  discovered.targets.map((entry) => entry.id),
116
- ["shell-layout:primary-menu", "workspace-tools:primary-menu"]
116
+ ["admin-cog:primary-menu", "shell-layout:primary-menu"]
117
117
  );
118
- assert.deepEqual(discovered.targets[1], {
119
- id: "workspace-tools:primary-menu",
118
+ assert.deepEqual(discovered.targets[0], {
119
+ id: "admin-cog:primary-menu",
120
120
  default: false,
121
121
  defaultLinkComponentToken: "local.main.ui.surface-aware-menu-link-item",
122
122
  sourcePath: "package:@example/users-web:src/client/components/UsersWorkspaceToolsWidget.vue",
@@ -125,10 +125,10 @@ test("discoverShellOutletTargetsFromApp includes installed package placement out
125
125
 
126
126
  const target = await resolveShellOutletPlacementTargetFromApp({
127
127
  appRoot,
128
- placement: "workspace-tools:primary-menu",
128
+ placement: "admin-cog:primary-menu",
129
129
  context: "ui-generator"
130
130
  });
131
- assert.equal(target.id, "workspace-tools:primary-menu");
131
+ assert.equal(target.id, "admin-cog:primary-menu");
132
132
  });
133
133
  });
134
134
 
@@ -140,7 +140,7 @@ test("discoverShellOutletTargetsFromApp applies app config default-link override
140
140
  `export const config = {
141
141
  ui: {
142
142
  outletDefaults: {
143
- "workspace-tools:primary-menu": {
143
+ "admin-cog:primary-menu": {
144
144
  linkComponentToken: "local.main.ui.surface-aware-menu-link-item"
145
145
  }
146
146
  }
@@ -178,7 +178,7 @@ test("discoverShellOutletTargetsFromApp applies app config default-link override
178
178
  placements: {
179
179
  outlets: [
180
180
  {
181
- target: "workspace-tools:primary-menu",
181
+ target: "admin-cog:primary-menu",
182
182
  defaultLinkComponentToken: "local.main.ui.surface-aware-menu-link-item"
183
183
  }
184
184
  ]