@jskit-ai/users-core 0.1.47 → 0.1.48
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.descriptor.mjs +8 -45
- package/package.json +7 -8
- package/src/server/UsersCoreServiceProvider.js +0 -4
- package/src/server/common/registerCommonRepositories.js +0 -5
- package/src/server/registerUsersBootstrap.js +1 -2
- package/src/server/support/workspaceActionSurfaces.js +1 -18
- package/src/server/usersBootstrapContributor.js +10 -23
- package/src/server/workspaceBootstrapContributor.js +1 -0
- package/templates/migrations/users_core_generic_initial.cjs +0 -16
- package/test/registerServiceRealtimeEvents.test.js +0 -8
- package/test/registerUsersCore.test.js +1 -5
- package/test/repositoryContracts.test.js +0 -2
- package/test/resourcesCanonical.test.js +1 -3
- package/test/settingsFieldRegistriesSingleton.test.js +0 -5
- package/test/usersBootstrapContributor.test.js +18 -12
- package/test/usersRouteRequestInputValidator.test.js +2 -43
- package/test/usersRouteResources.test.js +2 -4
- package/test/workspaceActionSurfaces.test.js +3 -23
- package/test-support/registerDefaultSettingsFields.js +0 -1
- package/src/server/consoleSettings/bootConsoleSettingsRoutes.js +0 -63
- package/src/server/consoleSettings/consoleService.js +0 -36
- package/src/server/consoleSettings/consoleSettingsActions.js +0 -55
- package/src/server/consoleSettings/consoleSettingsRepository.js +0 -115
- package/src/server/consoleSettings/consoleSettingsService.js +0 -40
- package/src/server/consoleSettings/registerConsoleSettings.js +0 -56
- package/src/shared/resources/consoleSettingsFields.js +0 -54
- package/src/shared/resources/consoleSettingsResource.js +0 -119
- package/templates/migrations/users_core_console_owner.cjs +0 -37
- package/templates/packages/main/src/shared/resources/consoleSettingsFields.js +0 -11
- package/test/consoleService.test.js +0 -57
- package/test/consoleSettingsService.test.js +0 -86
|
@@ -2,7 +2,6 @@ import assert from "node:assert/strict";
|
|
|
2
2
|
import test from "node:test";
|
|
3
3
|
import {
|
|
4
4
|
materializeWorkspaceActionSurfacesFromAppConfig,
|
|
5
|
-
resolveConsoleSurfaceIdsFromAppConfig,
|
|
6
5
|
resolveDefaultWorkspaceRouteSurfaceIdFromAppConfig
|
|
7
6
|
} from "../src/server/support/workspaceActionSurfaces.js";
|
|
8
7
|
|
|
@@ -23,7 +22,7 @@ test("materializeWorkspaceActionSurfacesFromAppConfig resolves workspace surface
|
|
|
23
22
|
surfaceDefinitions: {
|
|
24
23
|
app: { id: "app", enabled: true, requiresWorkspace: true },
|
|
25
24
|
admin: { id: "admin", enabled: true, requiresWorkspace: true },
|
|
26
|
-
|
|
25
|
+
ops: { id: "ops", enabled: true, requiresWorkspace: false }
|
|
27
26
|
}
|
|
28
27
|
}
|
|
29
28
|
});
|
|
@@ -52,7 +51,7 @@ test("materializeWorkspaceActionSurfacesFromAppConfig drops workspace actions wh
|
|
|
52
51
|
appConfig: {
|
|
53
52
|
surfaceDefinitions: {
|
|
54
53
|
app: { id: "app", enabled: true, requiresWorkspace: false },
|
|
55
|
-
|
|
54
|
+
ops: { id: "ops", enabled: true, requiresWorkspace: false }
|
|
56
55
|
}
|
|
57
56
|
}
|
|
58
57
|
});
|
|
@@ -78,28 +77,9 @@ test("resolveDefaultWorkspaceRouteSurfaceIdFromAppConfig falls back to app defau
|
|
|
78
77
|
surfaceDefaultId: "home",
|
|
79
78
|
surfaceDefinitions: {
|
|
80
79
|
home: { id: "home", enabled: true, requiresWorkspace: false },
|
|
81
|
-
|
|
80
|
+
ops: { id: "ops", enabled: true, requiresWorkspace: false }
|
|
82
81
|
}
|
|
83
82
|
});
|
|
84
83
|
|
|
85
84
|
assert.equal(surfaceId, "home");
|
|
86
85
|
});
|
|
87
|
-
|
|
88
|
-
test("resolveConsoleSurfaceIdsFromAppConfig resolves all enabled console-owner surfaces", () => {
|
|
89
|
-
const surfaceIds = resolveConsoleSurfaceIdsFromAppConfig({
|
|
90
|
-
surfaceDefinitions: {
|
|
91
|
-
home: { id: "home", enabled: true, requiresWorkspace: false, accessPolicyId: "public" },
|
|
92
|
-
console: { id: "console", enabled: true, requiresWorkspace: false, accessPolicyId: "console_owner" },
|
|
93
|
-
opsConsole: { id: "opsConsole", enabled: true, requiresWorkspace: false, accessPolicyId: "console_owner" },
|
|
94
|
-
app: { id: "app", enabled: true, requiresWorkspace: true, accessPolicyId: "workspace_member" },
|
|
95
|
-
disabledConsole: {
|
|
96
|
-
id: "disabledConsole",
|
|
97
|
-
enabled: false,
|
|
98
|
-
requiresWorkspace: false,
|
|
99
|
-
accessPolicyId: "console_owner"
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
assert.deepEqual(surfaceIds, ["console", "opsconsole"]);
|
|
105
|
-
});
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { withStandardErrorResponses } from "@jskit-ai/http-runtime/shared/validators/errorResponses";
|
|
2
|
-
import { consoleSettingsResource } from "../../shared/resources/consoleSettingsResource.js";
|
|
3
|
-
|
|
4
|
-
function bootConsoleSettingsRoutes(app) {
|
|
5
|
-
if (!app || typeof app.make !== "function") {
|
|
6
|
-
throw new Error("bootConsoleSettingsRoutes requires application make().");
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const router = app.make("jskit.http.router");
|
|
10
|
-
|
|
11
|
-
router.register(
|
|
12
|
-
"GET",
|
|
13
|
-
"/api/console/settings",
|
|
14
|
-
{
|
|
15
|
-
auth: "required",
|
|
16
|
-
surface: "console",
|
|
17
|
-
meta: {
|
|
18
|
-
tags: ["console", "settings"],
|
|
19
|
-
summary: "Get console settings"
|
|
20
|
-
},
|
|
21
|
-
responseValidators: withStandardErrorResponses({
|
|
22
|
-
200: consoleSettingsResource.operations.view.outputValidator
|
|
23
|
-
})
|
|
24
|
-
},
|
|
25
|
-
async function (request, reply) {
|
|
26
|
-
const response = await request.executeAction({
|
|
27
|
-
actionId: "console.settings.read"
|
|
28
|
-
});
|
|
29
|
-
reply.code(200).send(response);
|
|
30
|
-
}
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
router.register(
|
|
34
|
-
"PATCH",
|
|
35
|
-
"/api/console/settings",
|
|
36
|
-
{
|
|
37
|
-
auth: "required",
|
|
38
|
-
surface: "console",
|
|
39
|
-
meta: {
|
|
40
|
-
tags: ["console", "settings"],
|
|
41
|
-
summary: "Update console settings"
|
|
42
|
-
},
|
|
43
|
-
bodyValidator: consoleSettingsResource.operations.replace.bodyValidator,
|
|
44
|
-
responseValidators: withStandardErrorResponses(
|
|
45
|
-
{
|
|
46
|
-
200: consoleSettingsResource.operations.view.outputValidator
|
|
47
|
-
},
|
|
48
|
-
{ includeValidation400: true }
|
|
49
|
-
)
|
|
50
|
-
},
|
|
51
|
-
async function (request, reply) {
|
|
52
|
-
const response = await request.executeAction({
|
|
53
|
-
actionId: "console.settings.update",
|
|
54
|
-
input: {
|
|
55
|
-
payload: request.input.body
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
reply.code(200).send(response);
|
|
59
|
-
}
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export { bootConsoleSettingsRoutes };
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { AppError } from "@jskit-ai/kernel/server/runtime/errors";
|
|
2
|
-
import { normalizeRecordId } from "@jskit-ai/kernel/shared/support/normalize";
|
|
3
|
-
|
|
4
|
-
function createService({ consoleSettingsRepository } = {}) {
|
|
5
|
-
if (!consoleSettingsRepository || typeof consoleSettingsRepository.ensureOwnerUserId !== "function") {
|
|
6
|
-
throw new Error("consoleService requires consoleSettingsRepository.ensureOwnerUserId().");
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
async function ensureInitialConsoleMember(userId, options = {}) {
|
|
10
|
-
const normalizedUserId = normalizeRecordId(userId, { fallback: null });
|
|
11
|
-
if (!normalizedUserId) {
|
|
12
|
-
throw new AppError(400, "Invalid console user.");
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
return consoleSettingsRepository.ensureOwnerUserId(normalizedUserId, options);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
async function requireConsoleOwner(context = {}, options = {}) {
|
|
19
|
-
const actorUserId = normalizeRecordId(context?.actor?.id, { fallback: null });
|
|
20
|
-
if (!actorUserId) {
|
|
21
|
-
throw new AppError(401, "Authentication required.");
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const ownerUserId = await ensureInitialConsoleMember(actorUserId, options);
|
|
25
|
-
if (actorUserId !== ownerUserId) {
|
|
26
|
-
throw new AppError(403, "Forbidden.");
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return Object.freeze({
|
|
31
|
-
ensureInitialConsoleMember,
|
|
32
|
-
requireConsoleOwner
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export { createService };
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
EMPTY_INPUT_VALIDATOR
|
|
3
|
-
} from "@jskit-ai/kernel/shared/actions/actionContributorHelpers";
|
|
4
|
-
import { consoleSettingsResource } from "../../shared/resources/consoleSettingsResource.js";
|
|
5
|
-
|
|
6
|
-
const consoleSettingsActions = Object.freeze([
|
|
7
|
-
{
|
|
8
|
-
id: "console.settings.read",
|
|
9
|
-
version: 1,
|
|
10
|
-
kind: "query",
|
|
11
|
-
channels: ["api", "automation", "internal"],
|
|
12
|
-
surfacesFrom: "console",
|
|
13
|
-
permission: {
|
|
14
|
-
require: "authenticated"
|
|
15
|
-
},
|
|
16
|
-
inputValidator: EMPTY_INPUT_VALIDATOR,
|
|
17
|
-
outputValidator: consoleSettingsResource.operations.view.outputValidator,
|
|
18
|
-
idempotency: "none",
|
|
19
|
-
audit: {
|
|
20
|
-
actionName: "console.settings.read"
|
|
21
|
-
},
|
|
22
|
-
observability: {},
|
|
23
|
-
async execute(_input, context, deps) {
|
|
24
|
-
return deps.consoleSettingsService.getSettings({
|
|
25
|
-
context
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
id: "console.settings.update",
|
|
31
|
-
version: 1,
|
|
32
|
-
kind: "command",
|
|
33
|
-
channels: ["api", "automation", "internal"],
|
|
34
|
-
surfacesFrom: "console",
|
|
35
|
-
permission: {
|
|
36
|
-
require: "authenticated"
|
|
37
|
-
},
|
|
38
|
-
inputValidator: {
|
|
39
|
-
payload: consoleSettingsResource.operations.replace.bodyValidator
|
|
40
|
-
},
|
|
41
|
-
outputValidator: consoleSettingsResource.operations.replace.outputValidator,
|
|
42
|
-
idempotency: "optional",
|
|
43
|
-
audit: {
|
|
44
|
-
actionName: "console.settings.update"
|
|
45
|
-
},
|
|
46
|
-
observability: {},
|
|
47
|
-
async execute(input, context, deps) {
|
|
48
|
-
return deps.consoleSettingsService.updateSettings(input.payload, {
|
|
49
|
-
context
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
]);
|
|
54
|
-
|
|
55
|
-
export { consoleSettingsActions };
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
normalizeDbRecordId,
|
|
3
|
-
normalizeRecordId,
|
|
4
|
-
nowDb,
|
|
5
|
-
toIsoString,
|
|
6
|
-
createWithTransaction
|
|
7
|
-
} from "../common/repositories/repositoryUtils.js";
|
|
8
|
-
import { normalizeObjectInput } from "@jskit-ai/kernel/shared/validators/inputNormalization";
|
|
9
|
-
import { consoleSettingsFields } from "../../shared/resources/consoleSettingsFields.js";
|
|
10
|
-
|
|
11
|
-
function mapSettings(row = {}) {
|
|
12
|
-
const settings = {};
|
|
13
|
-
for (const field of consoleSettingsFields) {
|
|
14
|
-
const rawValue = Object.hasOwn(row, field.dbColumn)
|
|
15
|
-
? row[field.dbColumn]
|
|
16
|
-
: field.resolveDefault({
|
|
17
|
-
settings: row
|
|
18
|
-
});
|
|
19
|
-
settings[field.key] = field.normalizeOutput(rawValue, {
|
|
20
|
-
settings: row
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
return settings;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function mapSingletonRow(row) {
|
|
27
|
-
if (!row) {
|
|
28
|
-
throw new Error("console_settings singleton row is missing.");
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const ownerUserId = normalizeDbRecordId(row.owner_user_id, { fallback: null });
|
|
32
|
-
return {
|
|
33
|
-
id: normalizeDbRecordId(row.id, { fallback: "1" }),
|
|
34
|
-
ownerUserId,
|
|
35
|
-
settings: mapSettings(row),
|
|
36
|
-
createdAt: toIsoString(row.created_at),
|
|
37
|
-
updatedAt: toIsoString(row.updated_at)
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function createRepository(knex) {
|
|
42
|
-
if (typeof knex !== "function") {
|
|
43
|
-
throw new TypeError("consoleSettingsRepository requires knex.");
|
|
44
|
-
}
|
|
45
|
-
const withTransaction = createWithTransaction(knex);
|
|
46
|
-
|
|
47
|
-
async function readSingleton(client) {
|
|
48
|
-
return client("console_settings").where({ id: 1 }).first();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async function getSingleton(options = {}) {
|
|
52
|
-
const client = options?.trx || knex;
|
|
53
|
-
return mapSingletonRow(await readSingleton(client));
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async function ensureOwnerUserId(userId, options = {}) {
|
|
57
|
-
const client = options?.trx || knex;
|
|
58
|
-
const candidateOwnerUserId = normalizeRecordId(userId, { fallback: null });
|
|
59
|
-
if (!candidateOwnerUserId) {
|
|
60
|
-
throw new TypeError("consoleSettingsRepository.ensureOwnerUserId requires a positive user id.");
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const current = mapSingletonRow(await readSingleton(client));
|
|
64
|
-
if (current.ownerUserId) {
|
|
65
|
-
return current.ownerUserId;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
await client("console_settings")
|
|
69
|
-
.where({ id: 1 })
|
|
70
|
-
.whereNull("owner_user_id")
|
|
71
|
-
.update({
|
|
72
|
-
owner_user_id: candidateOwnerUserId,
|
|
73
|
-
updated_at: nowDb()
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
const reloaded = mapSingletonRow(await readSingleton(client));
|
|
77
|
-
if (!reloaded.ownerUserId) {
|
|
78
|
-
throw new Error("console_settings owner_user_id could not be resolved.");
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return reloaded.ownerUserId;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async function updateSingleton(patch, options = {}) {
|
|
85
|
-
const client = options?.trx || knex;
|
|
86
|
-
const source = normalizeObjectInput(patch);
|
|
87
|
-
const dbPatch = {
|
|
88
|
-
updated_at: nowDb()
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
for (const field of consoleSettingsFields) {
|
|
92
|
-
if (!Object.hasOwn(source, field.key)) {
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
dbPatch[field.dbColumn] = field.normalizeInput(source[field.key], {
|
|
96
|
-
payload: source
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
await client("console_settings")
|
|
101
|
-
.where({ id: 1 })
|
|
102
|
-
.update(dbPatch);
|
|
103
|
-
|
|
104
|
-
return getSingleton({ trx: client });
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return Object.freeze({
|
|
108
|
-
withTransaction,
|
|
109
|
-
getSingleton,
|
|
110
|
-
ensureOwnerUserId,
|
|
111
|
-
updateSingleton
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export { createRepository };
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
function buildSettingsResponse(record = {}) {
|
|
2
|
-
return {
|
|
3
|
-
settings: {
|
|
4
|
-
...(record?.settings && typeof record.settings === "object" ? record.settings : {})
|
|
5
|
-
}
|
|
6
|
-
};
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
function createService({ consoleSettingsRepository, consoleService } = {}) {
|
|
10
|
-
if (!consoleSettingsRepository || typeof consoleSettingsRepository.getSingleton !== "function") {
|
|
11
|
-
throw new Error("consoleSettingsService requires consoleSettingsRepository.getSingleton().");
|
|
12
|
-
}
|
|
13
|
-
if (!consoleSettingsRepository || typeof consoleSettingsRepository.updateSingleton !== "function") {
|
|
14
|
-
throw new Error("consoleSettingsService requires consoleSettingsRepository.updateSingleton().");
|
|
15
|
-
}
|
|
16
|
-
if (!consoleService || typeof consoleService.requireConsoleOwner !== "function") {
|
|
17
|
-
throw new Error("consoleSettingsService requires consoleService.requireConsoleOwner().");
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async function getSettings(options = {}) {
|
|
21
|
-
await consoleService.requireConsoleOwner(options?.context, options);
|
|
22
|
-
const settings = await consoleSettingsRepository.getSingleton();
|
|
23
|
-
|
|
24
|
-
return buildSettingsResponse(settings);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async function updateSettings(input = {}, options = {}) {
|
|
28
|
-
await consoleService.requireConsoleOwner(options?.context, options);
|
|
29
|
-
const settings = await consoleSettingsRepository.updateSingleton(input);
|
|
30
|
-
|
|
31
|
-
return buildSettingsResponse(settings);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return Object.freeze({
|
|
35
|
-
getSettings,
|
|
36
|
-
updateSettings
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export { createService };
|
|
@@ -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
|
-
"users.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: "users.console.settings.service"
|
|
51
|
-
}
|
|
52
|
-
})
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export { registerConsoleSettings };
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { normalizeText } from "@jskit-ai/kernel/shared/actions/textNormalization";
|
|
2
|
-
import { resolveGlobalArrayRegistry } from "./resolveGlobalArrayRegistry.js";
|
|
3
|
-
|
|
4
|
-
const consoleSettingsFields = resolveGlobalArrayRegistry("jskit.users-core.consoleSettingsFields");
|
|
5
|
-
|
|
6
|
-
function defineField(field = {}) {
|
|
7
|
-
const key = normalizeText(field.key);
|
|
8
|
-
if (!key) {
|
|
9
|
-
throw new TypeError("consoleSettingsFields.defineField requires field.key.");
|
|
10
|
-
}
|
|
11
|
-
if (consoleSettingsFields.some((entry) => entry.key === key)) {
|
|
12
|
-
throw new Error(`consoleSettingsFields.defineField duplicate key: ${key}`);
|
|
13
|
-
}
|
|
14
|
-
if (!field.inputSchema || typeof field.inputSchema !== "object") {
|
|
15
|
-
throw new TypeError(`consoleSettingsFields.defineField("${key}") requires inputSchema.`);
|
|
16
|
-
}
|
|
17
|
-
if (!field.outputSchema || typeof field.outputSchema !== "object") {
|
|
18
|
-
throw new TypeError(`consoleSettingsFields.defineField("${key}") requires outputSchema.`);
|
|
19
|
-
}
|
|
20
|
-
const dbColumn = normalizeText(field.dbColumn);
|
|
21
|
-
if (!dbColumn) {
|
|
22
|
-
throw new TypeError(`consoleSettingsFields.defineField("${key}") requires dbColumn.`);
|
|
23
|
-
}
|
|
24
|
-
if (typeof field.normalizeInput !== "function") {
|
|
25
|
-
throw new TypeError(`consoleSettingsFields.defineField("${key}") requires normalizeInput.`);
|
|
26
|
-
}
|
|
27
|
-
if (typeof field.normalizeOutput !== "function") {
|
|
28
|
-
throw new TypeError(`consoleSettingsFields.defineField("${key}") requires normalizeOutput.`);
|
|
29
|
-
}
|
|
30
|
-
if (typeof field.resolveDefault !== "function") {
|
|
31
|
-
throw new TypeError(`consoleSettingsFields.defineField("${key}") requires resolveDefault.`);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
consoleSettingsFields.push({
|
|
35
|
-
key,
|
|
36
|
-
dbColumn,
|
|
37
|
-
required: field.required !== false,
|
|
38
|
-
inputSchema: field.inputSchema,
|
|
39
|
-
outputSchema: field.outputSchema,
|
|
40
|
-
normalizeInput: field.normalizeInput,
|
|
41
|
-
normalizeOutput: field.normalizeOutput,
|
|
42
|
-
resolveDefault: field.resolveDefault
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function resetConsoleSettingsFields() {
|
|
47
|
-
consoleSettingsFields.splice(0, consoleSettingsFields.length);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export {
|
|
51
|
-
defineField,
|
|
52
|
-
resetConsoleSettingsFields,
|
|
53
|
-
consoleSettingsFields
|
|
54
|
-
};
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { Type } from "typebox";
|
|
2
|
-
import { createOperationMessages } from "../operationMessages.js";
|
|
3
|
-
import {
|
|
4
|
-
createCursorListValidator,
|
|
5
|
-
normalizeObjectInput,
|
|
6
|
-
normalizeSettingsFieldInput,
|
|
7
|
-
normalizeSettingsFieldOutput
|
|
8
|
-
} from "@jskit-ai/kernel/shared/validators";
|
|
9
|
-
import { consoleSettingsFields } from "./consoleSettingsFields.js";
|
|
10
|
-
|
|
11
|
-
function buildCreateSchema() {
|
|
12
|
-
const properties = {};
|
|
13
|
-
for (const field of consoleSettingsFields) {
|
|
14
|
-
properties[field.key] = field.required === false ? Type.Optional(field.inputSchema) : field.inputSchema;
|
|
15
|
-
}
|
|
16
|
-
return Type.Object(properties, { additionalProperties: false });
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function buildOutputSchema() {
|
|
20
|
-
const properties = {};
|
|
21
|
-
for (const field of consoleSettingsFields) {
|
|
22
|
-
properties[field.key] = field.outputSchema;
|
|
23
|
-
}
|
|
24
|
-
return Type.Object(properties, { additionalProperties: false });
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function buildConsoleSettingsRecordSchema() {
|
|
28
|
-
return Type.Object(
|
|
29
|
-
{
|
|
30
|
-
settings: buildOutputSchema()
|
|
31
|
-
},
|
|
32
|
-
{ additionalProperties: false }
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function buildConsoleSettingsCreateSchema() {
|
|
37
|
-
return buildCreateSchema();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function buildConsoleSettingsReplaceSchema() {
|
|
41
|
-
return buildConsoleSettingsCreateSchema();
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function buildConsoleSettingsPatchSchema() {
|
|
45
|
-
return Type.Partial(buildConsoleSettingsCreateSchema(), {
|
|
46
|
-
additionalProperties: false
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function normalizeConsoleSettingsInput(payload = {}) {
|
|
51
|
-
return normalizeSettingsFieldInput(payload, consoleSettingsFields);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const consoleSettingsOutputValidator = Object.freeze({
|
|
55
|
-
get schema() {
|
|
56
|
-
return buildConsoleSettingsRecordSchema();
|
|
57
|
-
},
|
|
58
|
-
normalize(payload = {}) {
|
|
59
|
-
const source = normalizeObjectInput(payload);
|
|
60
|
-
const settingsSource = normalizeObjectInput(source.settings);
|
|
61
|
-
|
|
62
|
-
return {
|
|
63
|
-
settings: normalizeSettingsFieldOutput(settingsSource, consoleSettingsFields)
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
const CONSOLE_SETTINGS_OPERATION_MESSAGES = createOperationMessages();
|
|
69
|
-
|
|
70
|
-
const consoleSettingsResource = Object.freeze({
|
|
71
|
-
resource: "consoleSettings",
|
|
72
|
-
operations: Object.freeze({
|
|
73
|
-
view: Object.freeze({
|
|
74
|
-
method: "GET",
|
|
75
|
-
messages: CONSOLE_SETTINGS_OPERATION_MESSAGES,
|
|
76
|
-
outputValidator: consoleSettingsOutputValidator
|
|
77
|
-
}),
|
|
78
|
-
list: Object.freeze({
|
|
79
|
-
method: "GET",
|
|
80
|
-
messages: CONSOLE_SETTINGS_OPERATION_MESSAGES,
|
|
81
|
-
outputValidator: createCursorListValidator(consoleSettingsOutputValidator)
|
|
82
|
-
}),
|
|
83
|
-
create: Object.freeze({
|
|
84
|
-
method: "POST",
|
|
85
|
-
messages: CONSOLE_SETTINGS_OPERATION_MESSAGES,
|
|
86
|
-
bodyValidator: Object.freeze({
|
|
87
|
-
get schema() {
|
|
88
|
-
return buildConsoleSettingsCreateSchema();
|
|
89
|
-
},
|
|
90
|
-
normalize: normalizeConsoleSettingsInput
|
|
91
|
-
}),
|
|
92
|
-
outputValidator: consoleSettingsOutputValidator
|
|
93
|
-
}),
|
|
94
|
-
replace: Object.freeze({
|
|
95
|
-
method: "PUT",
|
|
96
|
-
messages: CONSOLE_SETTINGS_OPERATION_MESSAGES,
|
|
97
|
-
bodyValidator: Object.freeze({
|
|
98
|
-
get schema() {
|
|
99
|
-
return buildConsoleSettingsReplaceSchema();
|
|
100
|
-
},
|
|
101
|
-
normalize: normalizeConsoleSettingsInput
|
|
102
|
-
}),
|
|
103
|
-
outputValidator: consoleSettingsOutputValidator
|
|
104
|
-
}),
|
|
105
|
-
patch: Object.freeze({
|
|
106
|
-
method: "PATCH",
|
|
107
|
-
messages: CONSOLE_SETTINGS_OPERATION_MESSAGES,
|
|
108
|
-
bodyValidator: Object.freeze({
|
|
109
|
-
get schema() {
|
|
110
|
-
return buildConsoleSettingsPatchSchema();
|
|
111
|
-
},
|
|
112
|
-
normalize: normalizeConsoleSettingsInput
|
|
113
|
-
}),
|
|
114
|
-
outputValidator: consoleSettingsOutputValidator
|
|
115
|
-
})
|
|
116
|
-
})
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
export { consoleSettingsResource };
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @param {import('knex').Knex} knex
|
|
3
|
-
*/
|
|
4
|
-
exports.up = async function up(knex) {
|
|
5
|
-
const hasConsoleSettingsTable = await knex.schema.hasTable("console_settings");
|
|
6
|
-
if (!hasConsoleSettingsTable) {
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const hasOwnerUserId = await knex.schema.hasColumn("console_settings", "owner_user_id");
|
|
11
|
-
if (hasOwnerUserId) {
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
await knex.schema.alterTable("console_settings", (table) => {
|
|
16
|
-
table.bigInteger("owner_user_id").unsigned().nullable();
|
|
17
|
-
});
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* @param {import('knex').Knex} knex
|
|
22
|
-
*/
|
|
23
|
-
exports.down = async function down(knex) {
|
|
24
|
-
const hasConsoleSettingsTable = await knex.schema.hasTable("console_settings");
|
|
25
|
-
if (!hasConsoleSettingsTable) {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const hasOwnerUserId = await knex.schema.hasColumn("console_settings", "owner_user_id");
|
|
30
|
-
if (!hasOwnerUserId) {
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
await knex.schema.alterTable("console_settings", (table) => {
|
|
35
|
-
table.dropColumn("owner_user_id");
|
|
36
|
-
});
|
|
37
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
// @jskit-contract users.settings-fields.console.v1
|
|
2
|
-
// Append-only settings field registrations for console settings.
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
defineField,
|
|
6
|
-
resetConsoleSettingsFields
|
|
7
|
-
} from "@jskit-ai/users-core/shared/resources/consoleSettingsFields";
|
|
8
|
-
|
|
9
|
-
resetConsoleSettingsFields();
|
|
10
|
-
|
|
11
|
-
void defineField;
|