@jskit-ai/kernel 0.1.32 → 0.1.34

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.
@@ -18,9 +18,13 @@ test("normalizeShellOutletTargetId validates host:position tokens", () => {
18
18
  test("discoverShellOutletTargetsFromVueSource resolves legal targets and one default", () => {
19
19
  const source = `
20
20
  <template>
21
- <ShellOutlet host="shell-layout" position="top-left" />
22
- <ShellOutlet host="shell-layout" position="primary-menu" default />
23
- <ShellOutlet host="shell-layout" position="secondary-menu" />
21
+ <ShellOutlet target="shell-layout:top-left" />
22
+ <ShellOutlet
23
+ target="shell-layout:primary-menu"
24
+ default
25
+ default-link-component-token="local.main.ui.surface-aware-menu-link-item"
26
+ />
27
+ <ShellOutlet target="shell-layout:secondary-menu" />
24
28
  </template>
25
29
  `;
26
30
 
@@ -33,6 +37,7 @@ test("discoverShellOutletTargetsFromVueSource resolves legal targets and one def
33
37
  discovered.targets.map((entry) => entry.id),
34
38
  ["shell-layout:top-left", "shell-layout:primary-menu", "shell-layout:secondary-menu"]
35
39
  );
40
+ assert.equal(discovered.targets[1].defaultLinkComponentToken, "local.main.ui.surface-aware-menu-link-item");
36
41
  assert.equal(
37
42
  describeShellOutletTargets(discovered.targets),
38
43
  "shell-layout:top-left, shell-layout:primary-menu, shell-layout:secondary-menu"
@@ -46,8 +51,8 @@ test("discoverShellOutletTargetsFromVueSource resolves legal targets and one def
46
51
  test("discoverShellOutletTargetsFromVueSource throws for duplicate targets", () => {
47
52
  const source = `
48
53
  <template>
49
- <ShellOutlet host="shell-layout" position="top-right" />
50
- <ShellOutlet host="shell-layout" position="top-right" />
54
+ <ShellOutlet target="shell-layout:top-right" />
55
+ <ShellOutlet target="shell-layout:top-right" />
51
56
  </template>
52
57
  `;
53
58
 
@@ -60,8 +65,8 @@ test("discoverShellOutletTargetsFromVueSource throws for duplicate targets", ()
60
65
  test("discoverShellOutletTargetsFromVueSource throws for multiple defaults", () => {
61
66
  const source = `
62
67
  <template>
63
- <ShellOutlet host="shell-layout" position="primary-menu" default />
64
- <ShellOutlet host="shell-layout" position="secondary-menu" default />
68
+ <ShellOutlet target="shell-layout:primary-menu" default />
69
+ <ShellOutlet target="shell-layout:secondary-menu" default />
65
70
  </template>
66
71
  `;
67
72
 
@@ -74,11 +79,24 @@ test("discoverShellOutletTargetsFromVueSource throws for multiple defaults", ()
74
79
  test("discoverShellOutletTargetsFromVueSource ignores disabled default markers", () => {
75
80
  const source = `
76
81
  <template>
77
- <ShellOutlet host="shell-layout" position="primary-menu" default="false" />
78
- <ShellOutlet host="shell-layout" position="secondary-menu" />
82
+ <ShellOutlet target="shell-layout:primary-menu" default="false" />
83
+ <ShellOutlet target="shell-layout:secondary-menu" />
79
84
  </template>
80
85
  `;
81
86
 
82
87
  const discovered = discoverShellOutletTargetsFromVueSource(source, { context: "ShellLayout.vue" });
83
88
  assert.equal(discovered.defaultTargetId, "");
84
89
  });
90
+
91
+ test("discoverShellOutletTargetsFromVueSource rejects legacy split outlet attributes", () => {
92
+ const source = `
93
+ <template>
94
+ <ShellOutlet target="shell-layout:primary-menu" host="other-host" position="primary-menu" />
95
+ </template>
96
+ `;
97
+
98
+ assert.throws(
99
+ () => discoverShellOutletTargetsFromVueSource(source, { context: "ShellLayout.vue" }),
100
+ /must declare ShellOutlet targets with "target" only/
101
+ );
102
+ });
@@ -49,7 +49,7 @@ function normalizeVisibilityContext(value = {}) {
49
49
  scopeKind: normalizedScopeKind,
50
50
  requiresActorScope: source.requiresActorScope === true,
51
51
  scopeOwnerId: normalizeOpaqueId(source.scopeOwnerId),
52
- userOwnerId: normalizeOpaqueId(source.userOwnerId)
52
+ userId: normalizeOpaqueId(source.userId)
53
53
  });
54
54
  }
55
55
 
@@ -19,20 +19,20 @@ test("normalizeRouteVisibilityToken normalizes visibility tokens for module-leve
19
19
  });
20
20
 
21
21
  test("normalizeVisibilityContext normalizes mode and owner identifiers", () => {
22
- assert.deepEqual(normalizeVisibilityContext({ visibility: "user", userOwnerId: "7" }), {
22
+ assert.deepEqual(normalizeVisibilityContext({ visibility: "user", userId: "7" }), {
23
23
  visibility: "user",
24
24
  scopeKind: null,
25
25
  requiresActorScope: false,
26
26
  scopeOwnerId: null,
27
- userOwnerId: "7"
27
+ userId: "7"
28
28
  });
29
29
 
30
- assert.deepEqual(normalizeVisibilityContext({ visibility: "workspace_user", scopeOwnerId: "4", userOwnerId: 9 }), {
30
+ assert.deepEqual(normalizeVisibilityContext({ visibility: "workspace_user", scopeOwnerId: "4", userId: 9 }), {
31
31
  visibility: "workspace_user",
32
32
  scopeKind: null,
33
33
  requiresActorScope: false,
34
34
  scopeOwnerId: "4",
35
- userOwnerId: 9
35
+ userId: "9"
36
36
  });
37
37
 
38
38
  assert.deepEqual(normalizeVisibilityContext({ visibility: "workspace", scopeOwnerId: "0" }), {
@@ -40,6 +40,6 @@ test("normalizeVisibilityContext normalizes mode and owner identifiers", () => {
40
40
  scopeKind: null,
41
41
  requiresActorScope: false,
42
42
  scopeOwnerId: "0",
43
- userOwnerId: null
43
+ userId: null
44
44
  });
45
45
  });
@@ -1,14 +1,13 @@
1
1
  import { Type } from "typebox";
2
- import { normalizeText } from "../support/normalize.js";
3
2
  import { normalizeObjectInput } from "./inputNormalization.js";
4
- import { positiveIntegerValidator } from "./recordIdParamsValidator.js";
3
+ import { positiveIntegerValidator, recordIdInputSchema, recordIdValidator } from "./recordIdParamsValidator.js";
5
4
 
6
5
  function normalizeCursorPaginationQuery(input = {}) {
7
6
  const source = normalizeObjectInput(input);
8
7
  const normalized = {};
9
8
 
10
9
  if (Object.hasOwn(source, "cursor")) {
11
- normalized.cursor = normalizeText(source.cursor);
10
+ normalized.cursor = recordIdValidator.normalize(source.cursor);
12
11
  }
13
12
 
14
13
  if (Object.hasOwn(source, "limit")) {
@@ -21,7 +20,7 @@ function normalizeCursorPaginationQuery(input = {}) {
21
20
  const cursorPaginationQueryValidator = Object.freeze({
22
21
  schema: Type.Object(
23
22
  {
24
- cursor: Type.Optional(positiveIntegerValidator.schema),
23
+ cursor: Type.Optional(recordIdInputSchema),
25
24
  limit: Type.Optional(positiveIntegerValidator.schema)
26
25
  },
27
26
  { additionalProperties: false }
@@ -11,9 +11,8 @@ test("cursorPaginationQueryValidator normalizes numeric strings as cursor text",
11
11
 
12
12
  test("cursorPaginationQueryValidator schema rejects opaque cursor strings", () => {
13
13
  assert.equal(
14
- cursorPaginationQueryValidator.schema.properties.cursor.anyOf.some(
15
- (entry) => entry.type === "string" && entry.pattern === "^[1-9][0-9]*$"
16
- ),
14
+ cursorPaginationQueryValidator.schema.properties.cursor.type === "string" &&
15
+ cursorPaginationQueryValidator.schema.properties.cursor.pattern === "^[1-9][0-9]*$",
17
16
  true
18
17
  );
19
18
  });
@@ -8,7 +8,17 @@ export {
8
8
  export { mergeObjectSchemas } from "./mergeObjectSchemas.js";
9
9
  export { mergeValidators } from "./mergeValidators.js";
10
10
  export { nestValidator } from "./nestValidator.js";
11
- export { recordIdParamsValidator, positiveIntegerValidator } from "./recordIdParamsValidator.js";
11
+ export {
12
+ RECORD_ID_PATTERN,
13
+ recordIdSchema,
14
+ recordIdInputSchema,
15
+ nullableRecordIdSchema,
16
+ nullableRecordIdInputSchema,
17
+ recordIdValidator,
18
+ nullableRecordIdValidator,
19
+ recordIdParamsValidator,
20
+ positiveIntegerValidator
21
+ } from "./recordIdParamsValidator.js";
12
22
  export { normalizeSettingsFieldInput, normalizeSettingsFieldOutput } from "./settingsFieldNormalization.js";
13
23
  export {
14
24
  normalizeRequiredFieldList,
@@ -1,23 +1,51 @@
1
1
  import { Type } from "typebox";
2
2
  import { normalizeObjectInput } from "./inputNormalization.js";
3
- import { normalizePositiveInteger, normalizeText } from "../support/normalize.js";
3
+ import { normalizePositiveInteger, normalizeRecordId } from "../support/normalize.js";
4
4
 
5
- function normalizeRecordId(value) {
6
- return normalizePositiveInteger(normalizeText(value));
7
- }
5
+ const RECORD_ID_PATTERN = "^[1-9][0-9]*$";
6
+
7
+ const recordIdSchema = Type.String({
8
+ minLength: 1,
9
+ pattern: RECORD_ID_PATTERN
10
+ });
11
+
12
+ const recordIdInputSchema = recordIdSchema;
13
+
14
+ const nullableRecordIdSchema = Type.Union([recordIdSchema, Type.Null()]);
15
+ const nullableRecordIdInputSchema = Type.Union([recordIdInputSchema, Type.Null()]);
8
16
 
9
17
  const positiveIntegerValidator = Object.freeze({
10
18
  schema: Type.Union([
11
19
  Type.Integer({ minimum: 1 }),
12
- Type.String({ minLength: 1, pattern: "^[1-9][0-9]*$" })
20
+ Type.String({ minLength: 1, pattern: RECORD_ID_PATTERN })
13
21
  ]),
14
- normalize: normalizeRecordId
22
+ normalize(value) {
23
+ return normalizePositiveInteger(value);
24
+ }
25
+ });
26
+
27
+ const recordIdValidator = Object.freeze({
28
+ schema: recordIdInputSchema,
29
+ normalize(value) {
30
+ return normalizeRecordId(value, {
31
+ fallback: ""
32
+ });
33
+ }
34
+ });
35
+
36
+ const nullableRecordIdValidator = Object.freeze({
37
+ schema: nullableRecordIdInputSchema,
38
+ normalize(value) {
39
+ return normalizeRecordId(value, {
40
+ fallback: null
41
+ });
42
+ }
15
43
  });
16
44
 
17
45
  const recordIdParamsValidator = Object.freeze({
18
46
  schema: Type.Object(
19
47
  {
20
- recordId: Type.Optional(positiveIntegerValidator.schema)
48
+ recordId: Type.Optional(recordIdInputSchema)
21
49
  },
22
50
  { additionalProperties: false }
23
51
  ),
@@ -26,11 +54,21 @@ const recordIdParamsValidator = Object.freeze({
26
54
  const normalized = {};
27
55
 
28
56
  if (Object.hasOwn(source, "recordId")) {
29
- normalized.recordId = normalizeRecordId(source.recordId);
57
+ normalized.recordId = recordIdValidator.normalize(source.recordId);
30
58
  }
31
59
 
32
60
  return normalized;
33
61
  }
34
62
  });
35
63
 
36
- export { recordIdParamsValidator, positiveIntegerValidator };
64
+ export {
65
+ RECORD_ID_PATTERN,
66
+ recordIdSchema,
67
+ recordIdInputSchema,
68
+ nullableRecordIdSchema,
69
+ nullableRecordIdInputSchema,
70
+ recordIdValidator,
71
+ nullableRecordIdValidator,
72
+ recordIdParamsValidator,
73
+ positiveIntegerValidator
74
+ };
@@ -3,15 +3,18 @@ import assert from "node:assert/strict";
3
3
 
4
4
  import { recordIdParamsValidator } from "./recordIdParamsValidator.js";
5
5
 
6
- test("recordIdParamsValidator normalizes string id to positive integer", () => {
6
+ test("recordIdParamsValidator normalizes canonical string ids", () => {
7
7
  assert.deepEqual(recordIdParamsValidator.normalize({ recordId: "42" }), {
8
- recordId: 42
8
+ recordId: "42"
9
9
  });
10
10
  });
11
11
 
12
- test("recordIdParamsValidator normalizes invalid id to 0", () => {
12
+ test("recordIdParamsValidator rejects invalid ids", () => {
13
13
  assert.deepEqual(recordIdParamsValidator.normalize({ recordId: "nope" }), {
14
- recordId: 0
14
+ recordId: ""
15
+ });
16
+ assert.deepEqual(recordIdParamsValidator.normalize({ recordId: 42 }), {
17
+ recordId: ""
15
18
  });
16
19
  });
17
20
 
package/README.md DELETED
@@ -1,24 +0,0 @@
1
- # kernel
2
-
3
- Internal JSKIT framework runtime package.
4
-
5
- This package contains the merged runtime internals:
6
- - container
7
- - kernel
8
- - http fastify bridge
9
- - server runtime primitives
10
- - support primitives
11
- - surface routing primitives
12
- - platform runtime bootstrap
13
-
14
- ## Historical note
15
-
16
- kernel was assembled moving code from these legacy packages and then deleting them:
17
-
18
- - @jskit-ai/container-core
19
- - @jskit-ai/http-fastify-core
20
- - @jskit-ai/kernel
21
- - @jskit-ai/platform-server-runtime
22
- - @jskit-ai/server-runtime-core
23
- - @jskit-ai/support-core
24
- - @jskit-ai/surface-routing