@jskit-ai/workspaces-core 0.1.222 → 0.1.224
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 +9 -9
- package/src/server/WorkspacesIntegrationsProvider.js +22 -1
- package/src/server/common/contributors/workspaceActionContextContributor.js +2 -4
- package/src/server/common/formatters/workspaceFormatter.js +1 -1
- package/src/server/common/services/workspaceContextService.js +1 -1
- package/src/server/workspaceBootstrapContributor.js +2 -2
- package/src/server/workspaceDirectory/workspaceDirectoryActions.js +1 -17
- package/src/server/workspaceMembers/workspaceMembersActions.js +0 -28
- package/src/server/workspaceMembers/workspaceMembersService.js +1 -1
- package/src/server/workspacePendingInvitations/workspacePendingInvitationsActions.js +1 -13
- package/src/server/workspacePendingInvitations/workspacePendingInvitationsService.js +1 -1
- package/src/server/workspaceSettings/workspaceSettingsActions.js +0 -8
- package/test/featureRuntime.test.js +39 -0
- package/test/resourcesCanonical.test.js +2 -2
- package/test/usersRouteResources.test.js +3 -3
- package/test/workspaceInternalCrudResources.test.js +2 -2
- package/test/workspaceMembersResource.test.js +2 -2
- package/test/workspacePendingInvitationsResource.test.js +4 -4
- package/test/workspaceSettingsResource.test.js +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/workspaces-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.224",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test --test-concurrency=1"
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
"./shared/resources/workspaceSettingsResource": "./src/shared/resources/workspaceSettingsResource.js"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@jskit-ai/database-runtime": "0.1.
|
|
22
|
-
"@jskit-ai/json-rest-api-core": "0.1.
|
|
23
|
-
"@jskit-ai/resource-core": "0.1.
|
|
24
|
-
"@jskit-ai/resource-crud-core": "0.1.
|
|
25
|
-
"@jskit-ai/users-core": "0.1.
|
|
21
|
+
"@jskit-ai/database-runtime": "0.1.246",
|
|
22
|
+
"@jskit-ai/json-rest-api-core": "0.1.190",
|
|
23
|
+
"@jskit-ai/resource-core": "0.1.188",
|
|
24
|
+
"@jskit-ai/resource-crud-core": "0.1.188",
|
|
25
|
+
"@jskit-ai/users-core": "0.1.259",
|
|
26
26
|
"json-rest-schema": "^1.0.17"
|
|
27
27
|
},
|
|
28
28
|
"description": "Workspace tenancy runtime plus HTTP routes, role catalog, and workspace config scaffolding.",
|
|
@@ -169,8 +169,8 @@
|
|
|
169
169
|
}
|
|
170
170
|
},
|
|
171
171
|
"peerDependencies": {
|
|
172
|
-
"@jskit-ai/auth-core": "0.1.
|
|
173
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
174
|
-
"@jskit-ai/kernel": "0.1.
|
|
172
|
+
"@jskit-ai/auth-core": "0.1.244",
|
|
173
|
+
"@jskit-ai/http-runtime": "0.1.244",
|
|
174
|
+
"@jskit-ai/kernel": "0.1.246"
|
|
175
175
|
}
|
|
176
176
|
}
|
|
@@ -7,6 +7,16 @@ import {
|
|
|
7
7
|
resolveWorkspaceSurfaceIdsFromAppConfig
|
|
8
8
|
} from "./support/workspaceActionSurfaces.js";
|
|
9
9
|
|
|
10
|
+
// Every active membership puts the actor in the workspace audience and in its
|
|
11
|
+
// own workspace-user audience.
|
|
12
|
+
async function resolveWorkspaceRealtimeScopes(workspaceMemberships, actorId) {
|
|
13
|
+
const workspaceIds = await workspaceMemberships.listActiveWorkspaceIdsByUserId(actorId);
|
|
14
|
+
return workspaceIds.flatMap((workspaceId) => [
|
|
15
|
+
{ kind: "workspace", id: workspaceId },
|
|
16
|
+
{ kind: "workspace_user", workspaceId, userId: actorId }
|
|
17
|
+
]);
|
|
18
|
+
}
|
|
19
|
+
|
|
10
20
|
const WorkspacesIntegrationsProvider = defineProvider({
|
|
11
21
|
id: "workspaces.integrations",
|
|
12
22
|
requires: {
|
|
@@ -17,7 +27,10 @@ const WorkspacesIntegrationsProvider = defineProvider({
|
|
|
17
27
|
usersExtensions: "users.extensions",
|
|
18
28
|
workspaces: "workspaces.core"
|
|
19
29
|
},
|
|
20
|
-
|
|
30
|
+
optional: {
|
|
31
|
+
realtime: "runtime.realtime"
|
|
32
|
+
},
|
|
33
|
+
setup({ actions, authExtensions, config, http, realtime, usersExtensions, workspaces }) {
|
|
21
34
|
const workspaceService = workspaces.services.directory;
|
|
22
35
|
const membershipOptionalSurfaceIds = resolveWorkspaceMembershipOptionalSurfaceIdsFromAppConfig(config);
|
|
23
36
|
const workspaceSurfaceIds = resolveWorkspaceSurfaceIdsFromAppConfig(config);
|
|
@@ -58,6 +71,14 @@ const WorkspacesIntegrationsProvider = defineProvider({
|
|
|
58
71
|
}
|
|
59
72
|
});
|
|
60
73
|
|
|
74
|
+
realtime?.registerAudienceContributor({
|
|
75
|
+
id: "workspaces.memberships",
|
|
76
|
+
resolveActorScopes: (actorId) => resolveWorkspaceRealtimeScopes(
|
|
77
|
+
workspaces.repositories.workspaceMemberships,
|
|
78
|
+
actorId
|
|
79
|
+
)
|
|
80
|
+
});
|
|
81
|
+
|
|
61
82
|
if (workspaces.invitationsEnabled) {
|
|
62
83
|
authExtensions.registerInvitationContextResolver({
|
|
63
84
|
resolverId: "workspaces.invitation",
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
requireServiceMethod
|
|
4
|
-
} from "@jskit-ai/kernel/shared/actions/actionContributorHelpers";
|
|
1
|
+
import { requireServiceMethod } from "@jskit-ai/kernel/server/actions/actionContributorHelpers";
|
|
2
|
+
import { normalizeObject } from "@jskit-ai/kernel/shared/support/normalize";
|
|
5
3
|
import { normalizeSurfaceId } from "@jskit-ai/kernel/shared/surface/registry";
|
|
6
4
|
import {
|
|
7
5
|
checkRouteVisibility,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolveWorkspaceThemePalettes } from "@jskit-ai/workspaces-core/shared/settings";
|
|
2
|
-
import { normalizeLowerText, normalizeText } from "@jskit-ai/kernel/shared/
|
|
2
|
+
import { normalizeLowerText, normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
3
3
|
import { normalizeRecordId } from "@jskit-ai/kernel/shared/support/normalize";
|
|
4
4
|
|
|
5
5
|
function mapWorkspaceSummary(workspace, membership, roleCatalog = null) {
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import {
|
|
12
12
|
mapWorkspaceSummary
|
|
13
13
|
} from "../formatters/workspaceFormatter.js";
|
|
14
|
-
import { normalizeLowerText, normalizeText } from "@jskit-ai/kernel/shared/
|
|
14
|
+
import { normalizeLowerText, normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
15
15
|
import { normalizeRecordId } from "@jskit-ai/kernel/shared/support/normalize";
|
|
16
16
|
|
|
17
17
|
function toSlugPart(value) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { requireServiceMethod } from "@jskit-ai/kernel/
|
|
1
|
+
import { requireServiceMethod } from "@jskit-ai/kernel/server/actions/actionContributorHelpers";
|
|
2
2
|
import { normalizeRecordId } from "@jskit-ai/kernel/shared/support/normalize";
|
|
3
|
-
import { normalizeLowerText } from "@jskit-ai/kernel/shared/
|
|
3
|
+
import { normalizeLowerText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
4
4
|
import {
|
|
5
5
|
TENANCY_MODE_NONE,
|
|
6
6
|
resolveTenancyProfile
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
emptyInputValidator,
|
|
3
3
|
resolveRequest
|
|
4
|
-
} from "@jskit-ai/kernel/
|
|
4
|
+
} from "@jskit-ai/kernel/server/actions/actionContributorHelpers";
|
|
5
5
|
import { returnJsonApiData } from "@jskit-ai/http-runtime/shared";
|
|
6
6
|
import { composeSchemaDefinitions } from "@jskit-ai/kernel/shared/validators";
|
|
7
7
|
import { workspaceResource } from "../../shared/resources/workspaceResource.js";
|
|
@@ -40,10 +40,6 @@ const workspaceDirectoryActionSpecifications = Object.freeze([
|
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
idempotency: "none",
|
|
43
|
-
audit: {
|
|
44
|
-
actionName: "workspace.workspaces.create"
|
|
45
|
-
},
|
|
46
|
-
observability: {},
|
|
47
43
|
async run(workspaceService, input, context) {
|
|
48
44
|
return returnJsonApiData(await workspaceService.createWorkspaceForAuthenticatedUser(resolveActionUser(context, input), input, {
|
|
49
45
|
request: resolveRequest(context),
|
|
@@ -74,10 +70,6 @@ const workspaceDirectoryActionSpecifications = Object.freeze([
|
|
|
74
70
|
}
|
|
75
71
|
},
|
|
76
72
|
idempotency: "none",
|
|
77
|
-
audit: {
|
|
78
|
-
actionName: "workspace.workspaces.list"
|
|
79
|
-
},
|
|
80
|
-
observability: {},
|
|
81
73
|
async run(workspaceService, input, context) {
|
|
82
74
|
return returnJsonApiData({
|
|
83
75
|
items: await workspaceService.listWorkspacesForAuthenticatedUser(resolveActionUser(context, input), {
|
|
@@ -108,10 +100,6 @@ const workspaceDirectoryActionSpecifications = Object.freeze([
|
|
|
108
100
|
}
|
|
109
101
|
},
|
|
110
102
|
idempotency: "none",
|
|
111
|
-
audit: {
|
|
112
|
-
actionName: "workspace.workspaces.read"
|
|
113
|
-
},
|
|
114
|
-
observability: {},
|
|
115
103
|
async run(workspaceService, input, context) {
|
|
116
104
|
return returnJsonApiData(await workspaceService.getWorkspaceForAuthenticatedUser(
|
|
117
105
|
resolveActionUser(context, input),
|
|
@@ -143,10 +131,6 @@ const workspaceDirectoryActionSpecifications = Object.freeze([
|
|
|
143
131
|
}
|
|
144
132
|
},
|
|
145
133
|
idempotency: "optional",
|
|
146
|
-
audit: {
|
|
147
|
-
actionName: "workspace.workspaces.update"
|
|
148
|
-
},
|
|
149
|
-
observability: {},
|
|
150
134
|
async run(workspaceService, input, context) {
|
|
151
135
|
const { workspaceSlug, ...patch } = input;
|
|
152
136
|
return returnJsonApiData(await workspaceService.updateWorkspaceForAuthenticatedUser(
|
|
@@ -85,10 +85,6 @@ const workspaceMembersActionSpecifications = Object.freeze([
|
|
|
85
85
|
}
|
|
86
86
|
},
|
|
87
87
|
idempotency: "none",
|
|
88
|
-
audit: {
|
|
89
|
-
actionName: "workspace.roles.list"
|
|
90
|
-
},
|
|
91
|
-
observability: {},
|
|
92
88
|
async run(workspaceMembersService, _input, context) {
|
|
93
89
|
return returnJsonApiData(await workspaceMembersService.listRoles({ context }));
|
|
94
90
|
}
|
|
@@ -113,10 +109,6 @@ const workspaceMembersActionSpecifications = Object.freeze([
|
|
|
113
109
|
}
|
|
114
110
|
},
|
|
115
111
|
idempotency: "none",
|
|
116
|
-
audit: {
|
|
117
|
-
actionName: "workspace.members.list"
|
|
118
|
-
},
|
|
119
|
-
observability: {},
|
|
120
112
|
async run(workspaceMembersService, input, context) {
|
|
121
113
|
return returnJsonApiData(await workspaceMembersService.listMembers(resolveWorkspace(context, input), {
|
|
122
114
|
context
|
|
@@ -143,10 +135,6 @@ const workspaceMembersActionSpecifications = Object.freeze([
|
|
|
143
135
|
}
|
|
144
136
|
},
|
|
145
137
|
idempotency: "optional",
|
|
146
|
-
audit: {
|
|
147
|
-
actionName: "workspace.member.role.update"
|
|
148
|
-
},
|
|
149
|
-
observability: {},
|
|
150
138
|
events: WORKSPACE_MEMBER_CHANGED_EVENTS,
|
|
151
139
|
async run(workspaceMembersService, input, context) {
|
|
152
140
|
return returnJsonApiData(await workspaceMembersService.updateMemberRole(resolveWorkspace(context, input), {
|
|
@@ -177,10 +165,6 @@ const workspaceMembersActionSpecifications = Object.freeze([
|
|
|
177
165
|
}
|
|
178
166
|
},
|
|
179
167
|
idempotency: "optional",
|
|
180
|
-
audit: {
|
|
181
|
-
actionName: "workspace.member.remove"
|
|
182
|
-
},
|
|
183
|
-
observability: {},
|
|
184
168
|
events: WORKSPACE_MEMBER_CHANGED_EVENTS,
|
|
185
169
|
async run(workspaceMembersService, input, context) {
|
|
186
170
|
return returnJsonApiData(await workspaceMembersService.removeMember(resolveWorkspace(context, input), {
|
|
@@ -210,10 +194,6 @@ const workspaceMembersActionSpecifications = Object.freeze([
|
|
|
210
194
|
}
|
|
211
195
|
},
|
|
212
196
|
idempotency: "none",
|
|
213
|
-
audit: {
|
|
214
|
-
actionName: "workspace.invites.list"
|
|
215
|
-
},
|
|
216
|
-
observability: {},
|
|
217
197
|
async run(workspaceMembersService, input, context) {
|
|
218
198
|
return returnJsonApiData(await workspaceMembersService.listInvites(resolveWorkspace(context, input), {
|
|
219
199
|
context
|
|
@@ -245,10 +225,6 @@ const workspaceMembersActionSpecifications = Object.freeze([
|
|
|
245
225
|
}
|
|
246
226
|
},
|
|
247
227
|
idempotency: "optional",
|
|
248
|
-
audit: {
|
|
249
|
-
actionName: "workspace.invite.create"
|
|
250
|
-
},
|
|
251
|
-
observability: {},
|
|
252
228
|
events: WORKSPACE_INVITE_CREATED_EVENTS,
|
|
253
229
|
async run(workspaceMembersService, input, context) {
|
|
254
230
|
return returnJsonApiData(await workspaceMembersService.createInvite(
|
|
@@ -284,10 +260,6 @@ const workspaceMembersActionSpecifications = Object.freeze([
|
|
|
284
260
|
}
|
|
285
261
|
},
|
|
286
262
|
idempotency: "optional",
|
|
287
|
-
audit: {
|
|
288
|
-
actionName: "workspace.invite.revoke"
|
|
289
|
-
},
|
|
290
|
-
observability: {},
|
|
291
263
|
events: WORKSPACE_INVITE_REVOKED_EVENTS,
|
|
292
264
|
async run(workspaceMembersService, input, context) {
|
|
293
265
|
return returnJsonApiData(await workspaceMembersService.revokeInvite(resolveWorkspace(context, input), input.inviteId, {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { normalizeRecordId } from "@jskit-ai/kernel/shared/support/normalize";
|
|
2
|
-
import { normalizeLowerText, normalizeText } from "@jskit-ai/kernel/shared/
|
|
2
|
+
import { normalizeLowerText, normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
3
3
|
import { encodeInviteTokenHash } from "@jskit-ai/auth-core/shared/inviteTokens";
|
|
4
4
|
import { resolveInviteTokenHash, buildInviteToken, hashInviteToken } from "@jskit-ai/auth-core/server/inviteTokens";
|
|
5
5
|
import { AppError } from "@jskit-ai/kernel/server/runtime/errors";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { pendingInvitationsAssistantOutput } from "../../shared/resources/workspaceAssistantOutputs.js";
|
|
2
2
|
import {
|
|
3
3
|
emptyInputValidator
|
|
4
|
-
} from "@jskit-ai/kernel/
|
|
4
|
+
} from "@jskit-ai/kernel/server/actions/actionContributorHelpers";
|
|
5
5
|
import { returnJsonApiData } from "@jskit-ai/http-runtime/shared";
|
|
6
6
|
import { workspaceMembersResource } from "../../shared/resources/workspaceMembersResource.js";
|
|
7
7
|
import { workspacePendingInvitationsResource } from "../../shared/resources/workspacePendingInvitationsResource.js";
|
|
@@ -28,10 +28,6 @@ const workspacePendingInvitationsActionSpecifications = Object.freeze([
|
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
30
|
idempotency: "none",
|
|
31
|
-
audit: {
|
|
32
|
-
actionName: "workspace.invitation.resolve"
|
|
33
|
-
},
|
|
34
|
-
observability: {},
|
|
35
31
|
async run(workspacePendingInvitationsService, input, context) {
|
|
36
32
|
return returnJsonApiData(
|
|
37
33
|
await workspacePendingInvitationsService.resolveInviteByToken(input?.token, {
|
|
@@ -64,10 +60,6 @@ const workspacePendingInvitationsActionSpecifications = Object.freeze([
|
|
|
64
60
|
}
|
|
65
61
|
},
|
|
66
62
|
idempotency: "none",
|
|
67
|
-
audit: {
|
|
68
|
-
actionName: "workspace.invitations.pending.list"
|
|
69
|
-
},
|
|
70
|
-
observability: {},
|
|
71
63
|
async run(workspacePendingInvitationsService, input, context) {
|
|
72
64
|
return returnJsonApiData({
|
|
73
65
|
pendingInvites: await workspacePendingInvitationsService.listPendingInvitesForUser(resolveActionUser(context, input), {
|
|
@@ -93,10 +85,6 @@ const workspacePendingInvitationsActionSpecifications = Object.freeze([
|
|
|
93
85
|
}
|
|
94
86
|
},
|
|
95
87
|
idempotency: "optional",
|
|
96
|
-
audit: {
|
|
97
|
-
actionName: "workspace.invite.redeem"
|
|
98
|
-
},
|
|
99
|
-
observability: {},
|
|
100
88
|
events: WORKSPACE_INVITE_DECISION_EVENTS,
|
|
101
89
|
async run(workspacePendingInvitationsService, input, context) {
|
|
102
90
|
const payload = input || {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolveInviteTokenHash } from "@jskit-ai/auth-core/server/inviteTokens";
|
|
2
2
|
import { encodeInviteTokenHash } from "@jskit-ai/auth-core/shared/inviteTokens";
|
|
3
3
|
import { AppError } from "@jskit-ai/kernel/server/runtime/errors";
|
|
4
|
-
import { normalizeLowerText, normalizeText } from "@jskit-ai/kernel/shared/
|
|
4
|
+
import { normalizeLowerText, normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
5
5
|
import { normalizeRecordId } from "@jskit-ai/kernel/shared/support/normalize";
|
|
6
6
|
|
|
7
7
|
function createService({
|
|
@@ -40,10 +40,6 @@ const workspaceSettingsActionSpecifications = Object.freeze([
|
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
idempotency: "none",
|
|
43
|
-
audit: {
|
|
44
|
-
actionName: "workspace.settings.read"
|
|
45
|
-
},
|
|
46
|
-
observability: {},
|
|
47
43
|
async run(workspaceSettingsService, input, context) {
|
|
48
44
|
const response = await workspaceSettingsService.getWorkspaceSettings(resolveWorkspace(context, input), {
|
|
49
45
|
context
|
|
@@ -72,10 +68,6 @@ const workspaceSettingsActionSpecifications = Object.freeze([
|
|
|
72
68
|
}
|
|
73
69
|
},
|
|
74
70
|
idempotency: "optional",
|
|
75
|
-
audit: {
|
|
76
|
-
actionName: "workspace.settings.update"
|
|
77
|
-
},
|
|
78
|
-
observability: {},
|
|
79
71
|
events: WORKSPACE_SETTINGS_CHANGED_EVENTS,
|
|
80
72
|
async run(workspaceSettingsService, input, context) {
|
|
81
73
|
const { workspaceSlug, ...patch } = input;
|
|
@@ -50,6 +50,7 @@ function runtimeConfig() {
|
|
|
50
50
|
test("WorkspacesFeature assembles workspace behavior and explicit integrations", async () => {
|
|
51
51
|
const routes = [];
|
|
52
52
|
const visibilityResolvers = [];
|
|
53
|
+
const audienceContributors = [];
|
|
53
54
|
const bootstrap = createBootstrapRuntime();
|
|
54
55
|
const authExtensions = createAuthExtensions();
|
|
55
56
|
const usersExtensions = createUsersExtensions();
|
|
@@ -86,6 +87,11 @@ test("WorkspacesFeature assembles workspace behavior and explicit integrations",
|
|
|
86
87
|
}
|
|
87
88
|
},
|
|
88
89
|
"runtime.json-rest-api": jsonRestApi,
|
|
90
|
+
"runtime.realtime": {
|
|
91
|
+
registerAudienceContributor(contributor) {
|
|
92
|
+
audienceContributors.push(contributor);
|
|
93
|
+
}
|
|
94
|
+
},
|
|
89
95
|
"users.core": {
|
|
90
96
|
repositories: {
|
|
91
97
|
userProfiles: { async findById() { return null; } }
|
|
@@ -117,4 +123,37 @@ test("WorkspacesFeature assembles workspace behavior and explicit integrations",
|
|
|
117
123
|
assert.deepEqual(usersExtensions.diagnostics().profileSyncLifecycleContributorIds, ["workspaces.provisioning"]);
|
|
118
124
|
assert.deepEqual(authExtensions.diagnostics().invitationContextResolverIds, ["workspaces.invitation"]);
|
|
119
125
|
assert.deepEqual(authExtensions.diagnostics().policyContextResolverIds, ["workspaces.policy"]);
|
|
126
|
+
assert.deepEqual(audienceContributors.map((entry) => entry.id), ["workspaces.memberships"]);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test("workspace realtime audiences are the actor's active memberships", async () => {
|
|
130
|
+
const audienceContributors = [];
|
|
131
|
+
const noop = () => {};
|
|
132
|
+
WorkspacesIntegrationsProvider.setup({
|
|
133
|
+
actions: { registerContextContributor: noop },
|
|
134
|
+
authExtensions: { registerPolicyContextResolver: noop },
|
|
135
|
+
config: runtimeConfig(),
|
|
136
|
+
http: { registerVisibilityResolver: noop },
|
|
137
|
+
realtime: { registerAudienceContributor: (entry) => audienceContributors.push(entry) },
|
|
138
|
+
usersExtensions: { registerProfileSyncLifecycleContributor: noop },
|
|
139
|
+
workspaces: {
|
|
140
|
+
invitationsEnabled: false,
|
|
141
|
+
services: { directory: { async resolveWorkspaceContextForUserBySlug() { return null; } } },
|
|
142
|
+
repositories: {
|
|
143
|
+
workspaceMemberships: {
|
|
144
|
+
async listActiveWorkspaceIdsByUserId(userId) {
|
|
145
|
+
assert.equal(userId, "9");
|
|
146
|
+
return ["11", "12"];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
assert.equal(audienceContributors.length, 1);
|
|
153
|
+
assert.deepEqual(await audienceContributors[0].resolveActorScopes("9"), [
|
|
154
|
+
{ kind: "workspace", id: "11" },
|
|
155
|
+
{ kind: "workspace_user", workspaceId: "11", userId: "9" },
|
|
156
|
+
{ kind: "workspace", id: "12" },
|
|
157
|
+
{ kind: "workspace_user", workspaceId: "12", userId: "9" }
|
|
158
|
+
]);
|
|
120
159
|
});
|
|
@@ -3,7 +3,7 @@ import assert from "node:assert/strict";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
-
import {
|
|
6
|
+
import { resolveSchemaTransportSchemaDefinition } from "@jskit-ai/kernel/shared/validators";
|
|
7
7
|
import { workspaceMembersResource } from "../src/shared/resources/workspaceMembersResource.js";
|
|
8
8
|
import { workspacePendingInvitationsResource } from "../src/shared/resources/workspacePendingInvitationsResource.js";
|
|
9
9
|
import { workspaceInvitesResource } from "../src/shared/resources/workspaceInvitesResource.js";
|
|
@@ -87,7 +87,7 @@ test("workspaces-core specialized resource operations expose messages and valida
|
|
|
87
87
|
for (const { label, operation } of operationSpecs) {
|
|
88
88
|
assert.equal(typeof operation?.messages, "object", `${label}.messages must be an object.`);
|
|
89
89
|
assert.equal(
|
|
90
|
-
typeof
|
|
90
|
+
typeof resolveSchemaTransportSchemaDefinition(operation?.output, {
|
|
91
91
|
context: `${label}.output`,
|
|
92
92
|
defaultMode: "replace"
|
|
93
93
|
}),
|
|
@@ -4,7 +4,7 @@ import path from "node:path";
|
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { deriveResourceRequiredMetadata } from "@jskit-ai/kernel/_testable";
|
|
7
|
-
import {
|
|
7
|
+
import { resolveSchemaTransportSchemaDefinition } from "@jskit-ai/kernel/shared/validators";
|
|
8
8
|
import { workspaceMembersResource } from "../src/shared/resources/workspaceMembersResource.js";
|
|
9
9
|
import { workspacePendingInvitationsResource } from "../src/shared/resources/workspacePendingInvitationsResource.js";
|
|
10
10
|
import { workspaceResource } from "../src/shared/resources/workspaceResource.js";
|
|
@@ -29,7 +29,7 @@ function assertResourceShape(resource, label) {
|
|
|
29
29
|
`${label}.operations.${operationName} must resolve messages from operation.messages or resource.messages.`
|
|
30
30
|
);
|
|
31
31
|
assert.equal(
|
|
32
|
-
typeof
|
|
32
|
+
typeof resolveSchemaTransportSchemaDefinition(operation.output, {
|
|
33
33
|
context: `${label}.operations.${operationName}.output`,
|
|
34
34
|
defaultMode: "replace"
|
|
35
35
|
}),
|
|
@@ -76,7 +76,7 @@ test("workspace settings and invite operations expose canonical validators", ()
|
|
|
76
76
|
for (const { label, operation } of operationSpecs) {
|
|
77
77
|
assert.equal(typeof operation?.method, "string", `${label}.method must exist.`);
|
|
78
78
|
assert.equal(
|
|
79
|
-
typeof
|
|
79
|
+
typeof resolveSchemaTransportSchemaDefinition(operation?.output, {
|
|
80
80
|
context: `${label}.output`,
|
|
81
81
|
defaultMode: "replace"
|
|
82
82
|
}),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import test from "node:test";
|
|
3
3
|
import { validateOperationSection } from "@jskit-ai/http-runtime/shared/validators/operationValidation";
|
|
4
|
-
import {
|
|
4
|
+
import { resolveSchemaTransportSchemaDefinition } from "@jskit-ai/kernel/shared/validators";
|
|
5
5
|
import { workspaceInvitesResource } from "../src/shared/resources/workspaceInvitesResource.js";
|
|
6
6
|
import { workspaceMembershipsResource } from "../src/shared/resources/workspaceMembershipsResource.js";
|
|
7
7
|
|
|
@@ -24,7 +24,7 @@ test("workspace internal CRUD resources expose canonical derived operation sets"
|
|
|
24
24
|
assert.equal(typeof resource.operations.create.body?.schema, "object", `${label}.operations.create.body.schema is required.`);
|
|
25
25
|
assert.equal(typeof resource.operations.patch.body?.schema, "object", `${label}.operations.patch.body.schema is required.`);
|
|
26
26
|
assert.equal(
|
|
27
|
-
typeof
|
|
27
|
+
typeof resolveSchemaTransportSchemaDefinition(resource.operations.view.output, {
|
|
28
28
|
context: `${label}.operations.view.output`,
|
|
29
29
|
defaultMode: "replace"
|
|
30
30
|
}),
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import {
|
|
3
|
+
import { resolveSchemaTransportSchemaDefinition } from "@jskit-ai/kernel/shared/validators";
|
|
4
4
|
import { workspaceMembersResource } from "../src/shared/resources/workspaceMembersResource.js";
|
|
5
5
|
|
|
6
6
|
function resolveOutputSchema(operationName) {
|
|
7
|
-
return
|
|
7
|
+
return resolveSchemaTransportSchemaDefinition(workspaceMembersResource.operations[operationName].output, {
|
|
8
8
|
context: `workspaceMembers.${operationName}.output`,
|
|
9
9
|
defaultMode: "replace"
|
|
10
10
|
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import {
|
|
3
|
+
import { resolveSchemaTransportSchemaDefinition } from "@jskit-ai/kernel/shared/validators";
|
|
4
4
|
import { workspacePendingInvitationsResource } from "../src/shared/resources/workspacePendingInvitationsResource.js";
|
|
5
5
|
|
|
6
6
|
test("workspacePendingInvitationsResource output schema accepts already-shaped invite payloads", () => {
|
|
7
|
-
const outputSchema =
|
|
7
|
+
const outputSchema = resolveSchemaTransportSchemaDefinition(workspacePendingInvitationsResource.operations.list.output, {
|
|
8
8
|
context: "workspacePendingInvitations.list.output",
|
|
9
9
|
defaultMode: "replace"
|
|
10
10
|
});
|
|
@@ -33,11 +33,11 @@ test("workspacePendingInvitationsResource output schema accepts already-shaped i
|
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
test("workspacePendingInvitationsResource exposes public resolve query and terminal statuses", () => {
|
|
36
|
-
const querySchema =
|
|
36
|
+
const querySchema = resolveSchemaTransportSchemaDefinition(workspacePendingInvitationsResource.operations.resolve.query, {
|
|
37
37
|
context: "workspacePendingInvitations.resolve.query",
|
|
38
38
|
defaultMode: "replace"
|
|
39
39
|
});
|
|
40
|
-
const outputSchema =
|
|
40
|
+
const outputSchema = resolveSchemaTransportSchemaDefinition(workspacePendingInvitationsResource.operations.resolve.output, {
|
|
41
41
|
context: "workspacePendingInvitations.resolve.output",
|
|
42
42
|
defaultMode: "replace"
|
|
43
43
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
3
|
import { validateOperationSection } from "@jskit-ai/http-runtime/shared/validators/operationValidation";
|
|
4
|
-
import {
|
|
4
|
+
import { resolveSchemaTransportSchemaDefinition } from "@jskit-ai/kernel/shared/validators";
|
|
5
5
|
import { resolveWorkspaceThemePalettes } from "@jskit-ai/workspaces-core/shared/settings";
|
|
6
6
|
import {
|
|
7
7
|
WORKSPACE_SETTINGS_FIELD_KEYS,
|
|
@@ -102,7 +102,7 @@ test("workspace settings create body requires full-write fields", async () => {
|
|
|
102
102
|
});
|
|
103
103
|
|
|
104
104
|
test("workspace settings output schema accepts already-shaped service payloads", () => {
|
|
105
|
-
const outputSchema =
|
|
105
|
+
const outputSchema = resolveSchemaTransportSchemaDefinition(workspaceSettingsResource.operations.view.output, {
|
|
106
106
|
context: "workspaceSettings.view.output",
|
|
107
107
|
defaultMode: "replace"
|
|
108
108
|
});
|