@jskit-ai/console-core 0.1.122 → 0.1.124

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 CHANGED
@@ -1,17 +1,21 @@
1
1
  {
2
2
  "name": "@jskit-ai/console-core",
3
- "version": "0.1.122",
3
+ "version": "0.1.124",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
7
7
  },
8
+ "exports": {
9
+ "./server/ConsoleFeature": "./src/server/ConsoleFeature.js",
10
+ "./shared/resources/consoleSettingsResource": "./src/shared/resources/consoleSettingsResource.js"
11
+ },
8
12
  "dependencies": {
9
- "@jskit-ai/auth-core": "0.1.157",
10
- "@jskit-ai/database-runtime": "0.1.159",
11
- "@jskit-ai/http-runtime": "0.1.157",
12
- "@jskit-ai/kernel": "0.1.159",
13
- "@jskit-ai/resource-crud-core": "0.1.101",
14
- "@jskit-ai/users-core": "0.1.172",
13
+ "@jskit-ai/auth-core": "0.1.159",
14
+ "@jskit-ai/database-runtime": "0.1.161",
15
+ "@jskit-ai/http-runtime": "0.1.159",
16
+ "@jskit-ai/kernel": "0.1.161",
17
+ "@jskit-ai/resource-crud-core": "0.1.103",
18
+ "@jskit-ai/users-core": "0.1.174",
15
19
  "json-rest-schema": "^1.0.17"
16
20
  },
17
21
  "description": "Console runtime: console settings schema, bootstrap flags, actions, and HTTP routes.",
@@ -19,21 +23,22 @@
19
23
  "kind": "runtime",
20
24
  "capabilities": {
21
25
  "provides": [
22
- "console.core",
23
- "console.server-routes"
26
+ "console.core"
24
27
  ],
25
28
  "requires": [
29
+ "auth.extensions",
26
30
  "runtime.actions",
31
+ "runtime.bootstrap",
27
32
  "runtime.database",
28
- "users.core"
33
+ "runtime.http"
29
34
  ]
30
35
  },
31
36
  "runtime": {
32
37
  "server": {
33
38
  "providers": [
34
39
  {
35
- "entrypoint": "src/server/ConsoleCoreServiceProvider.js",
36
- "export": "ConsoleCoreServiceProvider"
40
+ "entrypoint": "src/server/ConsoleFeature.js",
41
+ "export": "ConsoleFeature"
37
42
  }
38
43
  ]
39
44
  },
@@ -46,9 +51,7 @@
46
51
  "tableOwnership": {
47
52
  "tables": [
48
53
  {
49
- "tableName": "console_settings",
50
- "provenance": "runtime-package",
51
- "ownerKind": "package-runtime"
54
+ "tableName": "console_settings"
52
55
  }
53
56
  ]
54
57
  }
@@ -57,7 +60,7 @@
57
60
  "surfaces": [
58
61
  {
59
62
  "subpath": "./server",
60
- "summary": "Exports ConsoleCoreServiceProvider plus console settings services, routes, and action definitions."
63
+ "summary": "Exports the explicit Console feature with owner access, settings actions, bootstrap, and routes."
61
64
  },
62
65
  {
63
66
  "subpath": "./shared",
@@ -68,10 +71,9 @@
68
71
  "summary": "Exports no runtime API today (reserved client entrypoint)."
69
72
  }
70
73
  ],
71
- "containerTokens": {
72
- "server": [],
73
- "client": []
74
- }
74
+ "capabilities": [
75
+ "console.core"
76
+ ]
75
77
  },
76
78
  "server": {
77
79
  "routes": [
@@ -88,34 +90,10 @@
88
90
  ]
89
91
  }
90
92
  },
91
- "mutations": {
92
- "dependencies": {
93
- "runtime": {
94
- "@jskit-ai/auth-core": "0.1.157",
95
- "@jskit-ai/database-runtime": "0.1.159",
96
- "@jskit-ai/http-runtime": "0.1.157",
97
- "@jskit-ai/kernel": "0.1.159",
98
- "@jskit-ai/resource-crud-core": "0.1.101",
99
- "@jskit-ai/users-core": "0.1.172"
100
- },
101
- "dev": {}
102
- },
103
- "packageJson": {
104
- "scripts": {}
105
- },
106
- "procfile": {},
107
- "files": [
108
- {
109
- "op": "install-migration",
110
- "from": "templates/migrations/console_core_generic_initial.cjs",
111
- "toDir": "migrations",
112
- "extension": ".cjs",
113
- "reason": "Install console settings schema migration.",
114
- "category": "migration",
115
- "id": "console-core-generic-initial-schema"
116
- }
117
- ],
118
- "text": []
93
+ "migrations": {
94
+ "directories": [
95
+ "migrations"
96
+ ]
119
97
  }
120
98
  }
121
99
  }
@@ -0,0 +1,67 @@
1
+ import { defineFeature } from "@jskit-ai/kernel/server/features";
2
+ import { createConsoleAuthServiceDecorator } from "./consoleAuthServiceDecorator.js";
3
+ import { createConsoleBootstrapContributor } from "./consoleBootstrapContributor.js";
4
+ import { registerConsoleSettingsRoutes } from "./consoleSettings/bootConsoleSettingsRoutes.js";
5
+ import { buildConsoleSettingsActions } from "./consoleSettings/consoleSettingsActions.js";
6
+ import { createService as createConsoleService } from "./consoleSettings/consoleService.js";
7
+ import { createRepository as createConsoleSettingsRepository } from "./consoleSettings/consoleSettingsRepository.js";
8
+ import { createService as createConsoleSettingsService } from "./consoleSettings/consoleSettingsService.js";
9
+
10
+ function createConsoleRuntime({ database } = {}) {
11
+ if (!database || typeof database.knex !== "function") {
12
+ throw new TypeError("ConsoleFeature requires runtime.database.knex.");
13
+ }
14
+
15
+ const consoleSettingsRepository = createConsoleSettingsRepository(database.knex);
16
+ const consoleService = createConsoleService({ consoleSettingsRepository });
17
+ const consoleSettingsService = createConsoleSettingsService({
18
+ consoleService,
19
+ consoleSettingsRepository
20
+ });
21
+
22
+ return Object.freeze({
23
+ repositories: Object.freeze({ settings: consoleSettingsRepository }),
24
+ services: Object.freeze({
25
+ access: consoleService,
26
+ settings: consoleSettingsService
27
+ })
28
+ });
29
+ }
30
+
31
+ const ConsoleFeature = defineFeature({
32
+ id: "console.core",
33
+ domain: "console",
34
+ requires: {
35
+ authExtensions: "auth.extensions",
36
+ bootstrap: "runtime.bootstrap",
37
+ database: "runtime.database",
38
+ http: "runtime.http"
39
+ },
40
+ provides: {
41
+ console: "console.core"
42
+ },
43
+ setup({ authExtensions, bootstrap, database, http }) {
44
+ const console = createConsoleRuntime({ database });
45
+
46
+ authExtensions.registerServiceDecorator(
47
+ createConsoleAuthServiceDecorator({ consoleService: console.services.access })
48
+ );
49
+ bootstrap.register({
50
+ id: "console.bootstrap",
51
+ order: 300,
52
+ contribute: createConsoleBootstrapContributor({
53
+ consoleService: console.services.access
54
+ }).contribute
55
+ });
56
+ registerConsoleSettingsRoutes(http.router);
57
+
58
+ return { console };
59
+ },
60
+ actions({ console }) {
61
+ return buildConsoleSettingsActions({
62
+ consoleSettingsService: console.services.settings
63
+ });
64
+ }
65
+ });
66
+
67
+ export { ConsoleFeature, createConsoleRuntime };
@@ -5,13 +5,11 @@ function resolveConsoleSettingsRecordId() {
5
5
  return "console-settings";
6
6
  }
7
7
 
8
- function bootConsoleSettingsRoutes(app) {
9
- if (!app || typeof app.make !== "function") {
10
- throw new Error("bootConsoleSettingsRoutes requires application make().");
8
+ function registerConsoleSettingsRoutes(router) {
9
+ if (!router || typeof router.register !== "function") {
10
+ throw new TypeError("registerConsoleSettingsRoutes requires router.register().");
11
11
  }
12
12
 
13
- const router = app.make("jskit.http.router");
14
-
15
13
  router.register(
16
14
  "GET",
17
15
  "/api/console/settings",
@@ -68,4 +66,4 @@ function bootConsoleSettingsRoutes(app) {
68
66
  );
69
67
  }
70
68
 
71
- export { bootConsoleSettingsRoutes };
69
+ export { registerConsoleSettingsRoutes };
@@ -2,15 +2,16 @@ import {
2
2
  emptyInputValidator
3
3
  } from "@jskit-ai/kernel/shared/actions/actionContributorHelpers";
4
4
  import { returnJsonApiData } from "@jskit-ai/http-runtime/shared";
5
+ import { createEntityChangedActionEvent } from "@jskit-ai/kernel/server/actions";
5
6
  import { consoleSettingsResource } from "../../shared/resources/consoleSettingsResource.js";
6
7
 
7
- const consoleSettingsActions = Object.freeze([
8
+ const consoleSettingsActionSpecifications = Object.freeze([
8
9
  {
9
10
  id: "console.settings.read",
10
11
  version: 1,
11
12
  kind: "query",
12
13
  channels: ["api", "automation", "internal"],
13
- surfacesFrom: "console",
14
+ surfaces: ["console"],
14
15
  permission: {
15
16
  require: "authenticated"
16
17
  },
@@ -21,8 +22,8 @@ const consoleSettingsActions = Object.freeze([
21
22
  actionName: "console.settings.read"
22
23
  },
23
24
  observability: {},
24
- async execute(_input, context, deps) {
25
- return returnJsonApiData(await deps.consoleSettingsService.getSettings({
25
+ async run(consoleSettingsService, _input, context) {
26
+ return returnJsonApiData(await consoleSettingsService.getSettings({
26
27
  context
27
28
  }));
28
29
  }
@@ -32,7 +33,7 @@ const consoleSettingsActions = Object.freeze([
32
33
  version: 1,
33
34
  kind: "command",
34
35
  channels: ["api", "automation", "internal"],
35
- surfacesFrom: "console",
36
+ surfaces: ["console"],
36
37
  permission: {
37
38
  require: "authenticated"
38
39
  },
@@ -43,12 +44,40 @@ const consoleSettingsActions = Object.freeze([
43
44
  actionName: "console.settings.update"
44
45
  },
45
46
  observability: {},
46
- async execute(input, context, deps) {
47
- return returnJsonApiData(await deps.consoleSettingsService.updateSettings(input, {
47
+ extensions: {
48
+ realtime: {
49
+ event: "console.settings.changed",
50
+ audience: "all_users"
51
+ }
52
+ },
53
+ events: [createEntityChangedActionEvent({
54
+ source: "console",
55
+ entity: "settings",
56
+ operation: "updated",
57
+ entityId: 1,
58
+ realtime: {
59
+ event: "console.settings.changed",
60
+ audience: "all_users"
61
+ }
62
+ })],
63
+ async run(consoleSettingsService, input, context) {
64
+ return returnJsonApiData(await consoleSettingsService.updateSettings(input, {
48
65
  context
49
66
  }));
50
67
  }
51
68
  }
52
69
  ]);
53
70
 
54
- export { consoleSettingsActions };
71
+ function buildConsoleSettingsActions({ consoleSettingsService } = {}) {
72
+ if (!consoleSettingsService) {
73
+ throw new TypeError("buildConsoleSettingsActions requires consoleSettingsService.");
74
+ }
75
+ return consoleSettingsActionSpecifications.map(({ run, ...definition }) => Object.freeze({
76
+ ...definition,
77
+ execute(input, context) {
78
+ return run(consoleSettingsService, input, context);
79
+ }
80
+ }));
81
+ }
82
+
83
+ export { consoleSettingsActionSpecifications, buildConsoleSettingsActions };
@@ -1,6 +1,6 @@
1
1
  import assert from "node:assert/strict";
2
2
  import test from "node:test";
3
- import { ConsoleCoreServiceProvider } from "../src/server/ConsoleCoreServiceProvider.js";
3
+ import { registerConsoleSettingsRoutes } from "../src/server/consoleSettings/bootConsoleSettingsRoutes.js";
4
4
 
5
5
  function createReplyDouble() {
6
6
  return {
@@ -26,9 +26,7 @@ function findRoute(routes, { method, path }) {
26
26
  return routes.find((route) => route.method === method && route.path === path) || null;
27
27
  }
28
28
 
29
- async function registerRoutes({
30
- consoleService = {}
31
- } = {}) {
29
+ async function registerRoutes() {
32
30
  const registeredRoutes = [];
33
31
  const router = {
34
32
  register(method, path, route, handler) {
@@ -41,27 +39,7 @@ async function registerRoutes({
41
39
  }
42
40
  };
43
41
 
44
- const bindings = new Map([
45
- ["jskit.http.router", router],
46
- ["actionExecutor", {}]
47
- ]);
48
-
49
- bindings.set("consoleService", consoleService);
50
-
51
- const app = {
52
- has(token) {
53
- return bindings.has(token);
54
- },
55
- make(token) {
56
- if (!bindings.has(token)) {
57
- throw new Error(`Missing test binding for token: ${String(token)}`);
58
- }
59
- return bindings.get(token);
60
- }
61
- };
62
-
63
- const provider = new ConsoleCoreServiceProvider();
64
- await provider.boot(app);
42
+ registerConsoleSettingsRoutes(router);
65
43
 
66
44
  return registeredRoutes;
67
45
  }
@@ -12,7 +12,11 @@ test("console-core exports are explicit and aligned with production/template usa
12
12
  const result = evaluatePackageExportsContract({
13
13
  repoRoot: REPO_ROOT,
14
14
  packageDir: PACKAGE_DIR,
15
- packageId: "@jskit-ai/console-core"
15
+ packageId: "@jskit-ai/console-core",
16
+ requiredExports: [
17
+ "./server/ConsoleFeature",
18
+ "./shared/resources/consoleSettingsResource"
19
+ ]
16
20
  });
17
21
 
18
22
  assert.deepEqual(result.wildcardExports, [], `console-core exports must be explicit. Remove wildcard keys: ${result.wildcardExports.join(", ")}`);
@@ -0,0 +1,59 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { createAuthExtensions } from "@jskit-ai/auth-core/server/authExtensions";
4
+ import { createActionProvider } from "@jskit-ai/kernel/server/actions";
5
+ import { createCapabilityRuntime, defineProvider } from "@jskit-ai/kernel/shared/capabilities";
6
+ import { createBootstrapRuntime } from "@jskit-ai/kernel/server/runtime";
7
+ import { ConsoleFeature } from "../src/server/ConsoleFeature.js";
8
+
9
+ test("ConsoleFeature assembles owner access, settings, routes, actions, and bootstrap explicitly", async () => {
10
+ const routes = [];
11
+ const authExtensions = createAuthExtensions();
12
+ const bootstrap = createBootstrapRuntime();
13
+ let actions = null;
14
+ let console = null;
15
+ const probe = defineProvider({
16
+ id: "test.console.probe",
17
+ requires: {
18
+ actionCatalogue: "runtime.actions",
19
+ consoleCapability: "console.core"
20
+ },
21
+ setup({ actionCatalogue, consoleCapability }) {
22
+ actions = actionCatalogue;
23
+ console = consoleCapability;
24
+ return {};
25
+ }
26
+ });
27
+ const runtime = createCapabilityRuntime({
28
+ inputs: {
29
+ "auth.extensions": authExtensions,
30
+ "runtime.bootstrap": bootstrap,
31
+ "runtime.database": { knex() {} },
32
+ "runtime.http": {
33
+ router: {
34
+ register(method, path) {
35
+ routes.push(`${method} ${path}`);
36
+ }
37
+ }
38
+ }
39
+ },
40
+ providers: [createActionProvider(), ConsoleFeature, probe]
41
+ });
42
+
43
+ await runtime.start();
44
+
45
+ assert.equal(typeof console.services.access.requireConsoleOwner, "function");
46
+ assert.equal(typeof console.services.settings.updateSettings, "function");
47
+ assert.deepEqual(routes, [
48
+ "GET /api/console/settings",
49
+ "PATCH /api/console/settings"
50
+ ]);
51
+ assert.deepEqual(
52
+ actions.listDefinitions().map((definition) => definition.id),
53
+ ["console.settings.read", "console.settings.update"]
54
+ );
55
+ assert.deepEqual(bootstrap.diagnostics().contributorIds, ["console.bootstrap"]);
56
+ assert.deepEqual(authExtensions.diagnostics().serviceDecoratorIds, [
57
+ "console.core.authServiceDecorator"
58
+ ]);
59
+ });
@@ -1,22 +0,0 @@
1
- import { bootConsoleSettingsRoutes } from "./consoleSettings/bootConsoleSettingsRoutes.js";
2
- import { registerConsoleCore } from "./registerConsoleCore.js";
3
- import { registerConsoleBootstrap } from "./registerConsoleBootstrap.js";
4
- import { registerConsoleSettings } from "./consoleSettings/registerConsoleSettings.js";
5
-
6
- class ConsoleCoreServiceProvider {
7
- static id = "console.core";
8
-
9
- static startsAfter = ["runtime.actions"];
10
-
11
- register(app) {
12
- registerConsoleCore(app);
13
- registerConsoleBootstrap(app);
14
- registerConsoleSettings(app);
15
- }
16
-
17
- async boot(app) {
18
- bootConsoleSettingsRoutes(app);
19
- }
20
- }
21
-
22
- export { ConsoleCoreServiceProvider };
@@ -1,56 +0,0 @@
1
- import { withActionDefaults } from "@jskit-ai/kernel/shared/actions";
2
- import { createService as createConsoleSettingsService } from "./consoleSettingsService.js";
3
- import { createService as createConsoleService } from "./consoleService.js";
4
- import { consoleSettingsActions } from "./consoleSettingsActions.js";
5
-
6
- function registerConsoleSettings(app) {
7
- if (!app || typeof app.singleton !== "function" || typeof app.service !== "function" || typeof app.actions !== "function") {
8
- throw new Error("registerConsoleSettings requires application singleton()/service()/actions().");
9
- }
10
-
11
- const hasConsoleService = typeof app.has === "function" ? app.has("consoleService") : false;
12
- if (!hasConsoleService) {
13
- app.singleton("consoleService", (scope) =>
14
- createConsoleService({
15
- consoleSettingsRepository: scope.make("consoleSettingsRepository")
16
- })
17
- );
18
- }
19
-
20
- app.service(
21
- "console.settings.service",
22
- (scope) =>
23
- createConsoleSettingsService({
24
- consoleSettingsRepository: scope.make("consoleSettingsRepository"),
25
- consoleService: scope.make("consoleService")
26
- }),
27
- {
28
- events: Object.freeze({
29
- updateSettings: Object.freeze([
30
- Object.freeze({
31
- type: "entity.changed",
32
- source: "console",
33
- entity: "settings",
34
- operation: "updated",
35
- entityId: 1,
36
- realtime: Object.freeze({
37
- event: "console.settings.changed",
38
- audience: "all_users"
39
- })
40
- })
41
- ])
42
- })
43
- }
44
- );
45
-
46
- app.actions(
47
- withActionDefaults(consoleSettingsActions, {
48
- domain: "console",
49
- dependencies: {
50
- consoleSettingsService: "console.settings.service"
51
- }
52
- })
53
- );
54
- }
55
-
56
- export { registerConsoleSettings };
@@ -1,16 +0,0 @@
1
- import { registerBootstrapPayloadContributor } from "@jskit-ai/kernel/server/runtime";
2
- import { createConsoleBootstrapContributor } from "./consoleBootstrapContributor.js";
3
-
4
- function registerConsoleBootstrap(app) {
5
- if (!app || typeof app.singleton !== "function") {
6
- throw new Error("registerConsoleBootstrap requires application singleton().");
7
- }
8
-
9
- registerBootstrapPayloadContributor(app, "console.core.bootstrap.payloadContributor", (scope) => {
10
- return createConsoleBootstrapContributor({
11
- consoleService: scope.make("consoleService")
12
- });
13
- });
14
- }
15
-
16
- export { registerConsoleBootstrap };
@@ -1,25 +0,0 @@
1
- import { registerAuthServiceDecorator } from "@jskit-ai/auth-core/server/authServiceDecoratorRegistry";
2
- import { createConsoleAuthServiceDecorator } from "./consoleAuthServiceDecorator.js";
3
- import { createRepository as createConsoleSettingsRepository } from "./consoleSettings/consoleSettingsRepository.js";
4
- import { registerConsoleCoreActionSurfaceSources } from "./support/consoleActionSurfaces.js";
5
-
6
- function registerConsoleCore(app) {
7
- if (!app || typeof app.singleton !== "function") {
8
- throw new Error("registerConsoleCore requires application singleton().");
9
- }
10
-
11
- registerConsoleCoreActionSurfaceSources(app);
12
-
13
- registerAuthServiceDecorator(app, "console.core.authServiceDecorator", (scope) =>
14
- createConsoleAuthServiceDecorator({
15
- consoleService: scope.make("consoleService")
16
- })
17
- );
18
-
19
- app.singleton("consoleSettingsRepository", (scope) => {
20
- const knex = scope.make("jskit.database.knex");
21
- return createConsoleSettingsRepository(knex);
22
- });
23
- }
24
-
25
- export { registerConsoleCore };
@@ -1,62 +0,0 @@
1
- import { normalizeSurfaceId } from "@jskit-ai/kernel/shared/surface/registry";
2
- import { isRecord, normalizeLowerText } from "@jskit-ai/kernel/shared/support/normalize";
3
-
4
- const CONSOLE_OWNER_ACCESS_POLICY_ID = "console_owner";
5
-
6
- function normalizeSurfaceIds(surfaceIds = []) {
7
- const source = Array.isArray(surfaceIds) ? surfaceIds : [];
8
- const seen = new Set();
9
- const normalized = [];
10
-
11
- for (const candidate of source) {
12
- const surfaceId = normalizeSurfaceId(candidate);
13
- if (!surfaceId || seen.has(surfaceId)) {
14
- continue;
15
- }
16
- seen.add(surfaceId);
17
- normalized.push(surfaceId);
18
- }
19
-
20
- return normalized;
21
- }
22
-
23
- function resolveConsoleSurfaceIdsFromAppConfig(appConfig = {}) {
24
- const source = isRecord(appConfig?.surfaceDefinitions) ? appConfig.surfaceDefinitions : {};
25
- const resolved = [];
26
-
27
- for (const [key, value] of Object.entries(source)) {
28
- const definition = isRecord(value) ? value : {};
29
- const surfaceId = normalizeSurfaceId(definition.id || key);
30
- if (!surfaceId) {
31
- continue;
32
- }
33
- if (definition.enabled === false) {
34
- continue;
35
- }
36
- if (definition.requiresWorkspace === true) {
37
- continue;
38
- }
39
- if (normalizeLowerText(definition.accessPolicyId) !== CONSOLE_OWNER_ACCESS_POLICY_ID) {
40
- continue;
41
- }
42
- resolved.push(surfaceId);
43
- }
44
-
45
- return normalizeSurfaceIds(resolved);
46
- }
47
-
48
- function registerConsoleCoreActionSurfaceSources(app) {
49
- if (!app || typeof app.actionSurfaceSource !== "function") {
50
- return;
51
- }
52
-
53
- app.actionSurfaceSource("console", ({ scope }) => {
54
- const appConfig = scope?.has?.("appConfig") ? scope.make("appConfig") : {};
55
- return resolveConsoleSurfaceIdsFromAppConfig(appConfig);
56
- });
57
- }
58
-
59
- export {
60
- resolveConsoleSurfaceIdsFromAppConfig,
61
- registerConsoleCoreActionSurfaceSources
62
- };
@@ -1,78 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import { createContainer } from "../../kernel/server/container/index.js";
4
- import { resolveBootstrapPayload } from "../../kernel/server/registries/bootstrapPayloadContributorRegistry.js";
5
- import { registerUsersBootstrap } from "../../users-core/src/server/registerUsersBootstrap.js";
6
- import { registerConsoleBootstrap } from "../src/server/registerConsoleBootstrap.js";
7
-
8
- function createAuthenticatedProfile(overrides = {}) {
9
- return {
10
- id: "12",
11
- authProvider: "local",
12
- authProviderUserSid: "user-12",
13
- username: "consoleowner",
14
- displayName: "Console Owner",
15
- email: "owner@example.com",
16
- ...overrides
17
- };
18
- }
19
-
20
- test("bootstrap payload preserves consoleowner for authenticated users after users bootstrap runs", async () => {
21
- const profile = createAuthenticatedProfile();
22
- const app = createContainer();
23
-
24
- app.instance("internal.repository.user-profiles", {
25
- async findById(userId) {
26
- return String(userId || "") === profile.id ? profile : null;
27
- }
28
- });
29
- app.instance("internal.repository.user-settings", {
30
- async ensureForUserId() {
31
- return {};
32
- }
33
- });
34
- app.instance("authService", {
35
- getOAuthProviderCatalog() {
36
- return {
37
- providers: [],
38
- defaultProvider: null
39
- };
40
- },
41
- writeSessionCookies() {},
42
- clearSessionCookies() {}
43
- });
44
- app.instance("consoleService", {
45
- async isConsoleOwnerUserId(userId) {
46
- return String(userId || "") === profile.id;
47
- }
48
- });
49
-
50
- registerConsoleBootstrap(app);
51
- registerUsersBootstrap(app);
52
-
53
- const payload = await resolveBootstrapPayload(app, {
54
- request: {
55
- async executeAction({ actionId }) {
56
- assert.equal(actionId, "auth.session.read");
57
- return {
58
- authenticated: true,
59
- actor: {
60
- id: profile.id,
61
- displayName: profile.displayName,
62
- email: profile.email
63
- },
64
- session: {
65
- csrfToken: "csrf-1"
66
- }
67
- };
68
- }
69
- },
70
- reply: {}
71
- });
72
-
73
- assert.equal(payload.session.authenticated, true);
74
- assert.equal(payload.session.userId, "12");
75
- assert.deepEqual(payload.surfaceAccess, {
76
- consoleowner: true
77
- });
78
- });
@@ -1,24 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import {
4
- resolveConsoleSurfaceIdsFromAppConfig
5
- } from "../src/server/support/consoleActionSurfaces.js";
6
-
7
- test("resolveConsoleSurfaceIdsFromAppConfig resolves all enabled console-owner surfaces", () => {
8
- const surfaceIds = resolveConsoleSurfaceIdsFromAppConfig({
9
- surfaceDefinitions: {
10
- home: { id: "home", enabled: true, requiresWorkspace: false, accessPolicyId: "public" },
11
- console: { id: "console", enabled: true, requiresWorkspace: false, accessPolicyId: "console_owner" },
12
- opsConsole: { id: "opsConsole", enabled: true, requiresWorkspace: false, accessPolicyId: "console_owner" },
13
- app: { id: "app", enabled: true, requiresWorkspace: true, accessPolicyId: "workspace_member" },
14
- disabledConsole: {
15
- id: "disabledConsole",
16
- enabled: false,
17
- requiresWorkspace: false,
18
- accessPolicyId: "console_owner"
19
- }
20
- }
21
- });
22
-
23
- assert.deepEqual(surfaceIds, ["console", "opsconsole"]);
24
- });
@@ -1,55 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import { registerConsoleCore } from "../src/server/registerConsoleCore.js";
4
-
5
- test("registerConsoleCore registers the console action surface alias when action runtime is available", () => {
6
- const calls = [];
7
- const tags = [];
8
- const app = {
9
- singleton() {
10
- return this;
11
- },
12
- tag(token, tagName) {
13
- tags.push({
14
- token: String(token || ""),
15
- tagName: String(tagName || "")
16
- });
17
- return this;
18
- },
19
- actionSurfaceSource(sourceName, resolver) {
20
- calls.push({
21
- sourceName: String(sourceName || ""),
22
- resolverType: typeof resolver
23
- });
24
- return this;
25
- }
26
- };
27
-
28
- registerConsoleCore(app);
29
-
30
- assert.deepEqual(calls, [
31
- {
32
- sourceName: "console",
33
- resolverType: "function"
34
- }
35
- ]);
36
- assert.deepEqual(tags, [
37
- {
38
- token: "console.core.authServiceDecorator",
39
- tagName: "jskit.auth.service.decorators"
40
- }
41
- ]);
42
- });
43
-
44
- test("registerConsoleCore still works when action runtime has not installed actionSurfaceSource yet", () => {
45
- const app = {
46
- singleton() {
47
- return this;
48
- },
49
- tag() {
50
- return this;
51
- }
52
- };
53
-
54
- assert.doesNotThrow(() => registerConsoleCore(app));
55
- });
@@ -1,38 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import { registerConsoleSettings } from "../src/server/consoleSettings/registerConsoleSettings.js";
4
-
5
- function createAppDouble() {
6
- const serviceCalls = [];
7
-
8
- return {
9
- serviceCalls,
10
- app: {
11
- singleton() {
12
- return this;
13
- },
14
- service(token, factory, metadata) {
15
- serviceCalls.push({
16
- token,
17
- factory,
18
- metadata
19
- });
20
- return this;
21
- },
22
- actions() {
23
- return this;
24
- }
25
- }
26
- };
27
- }
28
-
29
- function findServiceCall(serviceCalls, token) {
30
- return serviceCalls.find((entry) => entry.token === token) || null;
31
- }
32
-
33
- test("console settings register publishes console.settings.changed", () => {
34
- const payload = createAppDouble();
35
- registerConsoleSettings(payload.app);
36
- const consoleSettings = findServiceCall(payload.serviceCalls, "console.settings.service");
37
- assert.equal(consoleSettings?.metadata?.events?.updateSettings?.[0]?.realtime?.event, "console.settings.changed");
38
- });