@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.
- package/package.json +2 -1
- package/server/http/lib/kernel.test.js +5 -5
- package/server/runtime/entityChangeEvents.js +5 -5
- package/server/runtime/entityChangeEvents.test.js +5 -5
- package/server/runtime/serviceAuthorization.test.js +1 -1
- package/server/support/importFreshModuleFromAbsolutePath.js +23 -0
- package/server/support/importFreshModuleFromAbsolutePath.test.js +36 -0
- package/server/support/index.js +1 -0
- package/server/support/pageTargets.js +55 -35
- package/server/support/pageTargets.test.js +133 -31
- package/server/support/shellOutlets.js +62 -30
- package/server/support/shellOutlets.test.js +86 -27
- package/shared/support/normalize.js +31 -1
- package/shared/support/normalize.test.js +21 -2
- package/shared/support/shellLayoutTargets.js +68 -25
- package/shared/support/shellLayoutTargets.test.js +27 -9
- package/shared/support/visibility.js +1 -1
- package/shared/support/visibility.test.js +5 -5
- package/shared/validators/cursorPaginationQueryValidator.js +3 -4
- package/shared/validators/cursorPaginationQueryValidator.test.js +2 -3
- package/shared/validators/index.js +11 -1
- package/shared/validators/recordIdParamsValidator.js +47 -9
- package/shared/validators/recordIdParamsValidator.test.js +7 -4
- package/README.md +0 -24
|
@@ -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
|
|
22
|
-
<ShellOutlet
|
|
23
|
-
|
|
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
|
|
50
|
-
<ShellOutlet
|
|
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
|
|
64
|
-
<ShellOutlet
|
|
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
|
|
78
|
-
<ShellOutlet
|
|
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
|
-
|
|
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",
|
|
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
|
-
|
|
27
|
+
userId: "7"
|
|
28
28
|
});
|
|
29
29
|
|
|
30
|
-
assert.deepEqual(normalizeVisibilityContext({ visibility: "workspace_user", scopeOwnerId: "4",
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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(
|
|
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.
|
|
15
|
-
|
|
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 {
|
|
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,
|
|
3
|
+
import { normalizePositiveInteger, normalizeRecordId } from "../support/normalize.js";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
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:
|
|
20
|
+
Type.String({ minLength: 1, pattern: RECORD_ID_PATTERN })
|
|
13
21
|
]),
|
|
14
|
-
normalize
|
|
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(
|
|
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 =
|
|
57
|
+
normalized.recordId = recordIdValidator.normalize(source.recordId);
|
|
30
58
|
}
|
|
31
59
|
|
|
32
60
|
return normalized;
|
|
33
61
|
}
|
|
34
62
|
});
|
|
35
63
|
|
|
36
|
-
export {
|
|
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
|
|
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
|
|
12
|
+
test("recordIdParamsValidator rejects invalid ids", () => {
|
|
13
13
|
assert.deepEqual(recordIdParamsValidator.normalize({ recordId: "nope" }), {
|
|
14
|
-
recordId:
|
|
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
|