@jskit-ai/workspaces-core 0.1.126 → 0.1.128
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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/workspaces-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.128",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -17,14 +17,358 @@
|
|
|
17
17
|
"./shared/resources/workspaceSettingsResource": "./src/shared/resources/workspaceSettingsResource.js"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@jskit-ai/auth-core": "0.1.
|
|
21
|
-
"@jskit-ai/database-runtime": "0.1.
|
|
22
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
23
|
-
"@jskit-ai/json-rest-api-core": "0.1.
|
|
24
|
-
"@jskit-ai/kernel": "0.1.
|
|
25
|
-
"@jskit-ai/resource-
|
|
26
|
-
"@jskit-ai/resource-core": "0.1.
|
|
27
|
-
"@jskit-ai/users-core": "0.1.
|
|
20
|
+
"@jskit-ai/auth-core": "0.1.148",
|
|
21
|
+
"@jskit-ai/database-runtime": "0.1.150",
|
|
22
|
+
"@jskit-ai/http-runtime": "0.1.148",
|
|
23
|
+
"@jskit-ai/json-rest-api-core": "0.1.94",
|
|
24
|
+
"@jskit-ai/kernel": "0.1.150",
|
|
25
|
+
"@jskit-ai/resource-core": "0.1.92",
|
|
26
|
+
"@jskit-ai/resource-crud-core": "0.1.92",
|
|
27
|
+
"@jskit-ai/users-core": "0.1.163",
|
|
28
28
|
"json-rest-schema": "^1.0.17"
|
|
29
|
+
},
|
|
30
|
+
"description": "Workspace tenancy runtime plus HTTP routes, role catalog, and workspace config scaffolding.",
|
|
31
|
+
"jskit": {
|
|
32
|
+
"kind": "runtime",
|
|
33
|
+
"capabilities": {
|
|
34
|
+
"provides": [
|
|
35
|
+
"workspaces.core",
|
|
36
|
+
"workspaces.server-routes"
|
|
37
|
+
],
|
|
38
|
+
"requires": [
|
|
39
|
+
"users.core",
|
|
40
|
+
"json-rest-api.core"
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
"runtime": {
|
|
44
|
+
"server": {
|
|
45
|
+
"providers": [
|
|
46
|
+
{
|
|
47
|
+
"entrypoint": "src/server/WorkspacesCoreServiceProvider.js",
|
|
48
|
+
"export": "WorkspacesCoreServiceProvider"
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"client": {
|
|
53
|
+
"providers": []
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"metadata": {
|
|
57
|
+
"jskit": {
|
|
58
|
+
"tableOwnership": {
|
|
59
|
+
"tables": [
|
|
60
|
+
{
|
|
61
|
+
"tableName": "workspaces",
|
|
62
|
+
"provenance": "runtime-package",
|
|
63
|
+
"ownerKind": "package-runtime"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"tableName": "workspace_memberships",
|
|
67
|
+
"provenance": "runtime-package",
|
|
68
|
+
"ownerKind": "package-runtime"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"tableName": "workspace_settings",
|
|
72
|
+
"provenance": "runtime-package",
|
|
73
|
+
"ownerKind": "package-runtime"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"tableName": "workspace_invites",
|
|
77
|
+
"provenance": "runtime-package",
|
|
78
|
+
"ownerKind": "package-runtime"
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"apiSummary": {
|
|
84
|
+
"surfaces": [
|
|
85
|
+
{
|
|
86
|
+
"subpath": "./server",
|
|
87
|
+
"summary": "Exports the workspace runtime provider and workspace route registration surface."
|
|
88
|
+
}
|
|
89
|
+
],
|
|
90
|
+
"containerTokens": {
|
|
91
|
+
"server": [
|
|
92
|
+
"workspaces.server.scope-support"
|
|
93
|
+
],
|
|
94
|
+
"client": []
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"server": {
|
|
98
|
+
"routes": [
|
|
99
|
+
{
|
|
100
|
+
"method": "POST",
|
|
101
|
+
"path": "/api/workspaces",
|
|
102
|
+
"summary": "Create a workspace for the authenticated user."
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"method": "GET",
|
|
106
|
+
"path": "/api/workspaces",
|
|
107
|
+
"summary": "List workspaces visible to authenticated user."
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"method": "GET",
|
|
111
|
+
"path": "/api/workspace/invitations/resolve",
|
|
112
|
+
"summary": "Resolve safe public workspace invitation metadata."
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"method": "GET",
|
|
116
|
+
"path": "/api/workspace/invitations/pending",
|
|
117
|
+
"summary": "List pending workspace invitations for authenticated user."
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"method": "POST",
|
|
121
|
+
"path": "/api/workspace/invitations/redeem",
|
|
122
|
+
"summary": "Accept or refuse a workspace invitation using an invite token."
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"method": "GET",
|
|
126
|
+
"path": "/api/w/:workspaceSlug/settings",
|
|
127
|
+
"summary": "Get workspace settings and role catalog by workspace slug."
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"method": "PATCH",
|
|
131
|
+
"path": "/api/w/:workspaceSlug/settings",
|
|
132
|
+
"summary": "Update workspace settings by workspace slug."
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"method": "GET",
|
|
136
|
+
"path": "/api/w/:workspaceSlug/roles",
|
|
137
|
+
"summary": "Get role catalog by workspace slug."
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"method": "GET",
|
|
141
|
+
"path": "/api/w/:workspaceSlug/members",
|
|
142
|
+
"summary": "List members by workspace slug."
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"method": "PATCH",
|
|
146
|
+
"path": "/api/w/:workspaceSlug/members/:memberUserId/role",
|
|
147
|
+
"summary": "Update workspace member role by workspace slug."
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"method": "GET",
|
|
151
|
+
"path": "/api/w/:workspaceSlug/invites",
|
|
152
|
+
"summary": "List workspace invites by workspace slug."
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"method": "POST",
|
|
156
|
+
"path": "/api/w/:workspaceSlug/invites",
|
|
157
|
+
"summary": "Create workspace invite by workspace slug."
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"method": "DELETE",
|
|
161
|
+
"path": "/api/w/:workspaceSlug/invites/:inviteId",
|
|
162
|
+
"summary": "Revoke workspace invite by workspace slug."
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"mutations": {
|
|
168
|
+
"dependencies": {
|
|
169
|
+
"runtime": {
|
|
170
|
+
"@jskit-ai/json-rest-api-core": "0.1.94",
|
|
171
|
+
"@jskit-ai/resource-core": "0.1.92",
|
|
172
|
+
"@jskit-ai/resource-crud-core": "0.1.92",
|
|
173
|
+
"@jskit-ai/users-core": "0.1.163"
|
|
174
|
+
},
|
|
175
|
+
"dev": {}
|
|
176
|
+
},
|
|
177
|
+
"packageJson": {
|
|
178
|
+
"scripts": {
|
|
179
|
+
"server:app": "SERVER_SURFACE=app node ./bin/server.js",
|
|
180
|
+
"server:admin": "SERVER_SURFACE=admin node ./bin/server.js"
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
"procfile": {},
|
|
184
|
+
"files": [
|
|
185
|
+
{
|
|
186
|
+
"op": "install-migration",
|
|
187
|
+
"from": "templates/migrations/workspaces_core_initial.cjs",
|
|
188
|
+
"toDir": "migrations",
|
|
189
|
+
"extension": ".cjs",
|
|
190
|
+
"reason": "Install workspace tenancy schema migration.",
|
|
191
|
+
"category": "migration",
|
|
192
|
+
"id": "workspaces-core-initial-schema"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"op": "install-migration",
|
|
196
|
+
"from": "templates/migrations/workspaces_core_workspace_settings_single_name_source.cjs",
|
|
197
|
+
"toDir": "migrations",
|
|
198
|
+
"extension": ".cjs",
|
|
199
|
+
"reason": "Remove workspace_settings name/avatar fields so workspace identity data comes from workspaces only.",
|
|
200
|
+
"category": "migration",
|
|
201
|
+
"id": "users-core-workspace-settings-single-name-source"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"op": "install-migration",
|
|
205
|
+
"from": "templates/migrations/workspaces_core_workspaces_drop_color.cjs",
|
|
206
|
+
"toDir": "migrations",
|
|
207
|
+
"extension": ".cjs",
|
|
208
|
+
"reason": "Drop workspaces.color now that workspace theme colors live in workspace_settings.",
|
|
209
|
+
"category": "migration",
|
|
210
|
+
"id": "users-core-workspaces-drop-color"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"from": "templates/config/roles.js",
|
|
214
|
+
"to": "config/roles.js",
|
|
215
|
+
"ownership": "app",
|
|
216
|
+
"preserveOnRemove": true,
|
|
217
|
+
"reason": "Install app-owned role catalog in a dedicated config file.",
|
|
218
|
+
"category": "workspaces-core",
|
|
219
|
+
"id": "users-core-app-owned-role-catalog-config"
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"from": "templates/packages/main/src/server/email/workspaceInviteEmail.js",
|
|
223
|
+
"to": "packages/main/src/server/email/workspaceInviteEmail.js",
|
|
224
|
+
"ownership": "app",
|
|
225
|
+
"preserveOnRemove": true,
|
|
226
|
+
"reason": "Install app-owned editable workspace invite email template.",
|
|
227
|
+
"category": "workspaces-core",
|
|
228
|
+
"id": "workspaces-core-main-workspace-invite-email-template"
|
|
229
|
+
}
|
|
230
|
+
],
|
|
231
|
+
"source": [
|
|
232
|
+
{
|
|
233
|
+
"op": "ensure-import",
|
|
234
|
+
"file": "config/server.js",
|
|
235
|
+
"namedImports": [
|
|
236
|
+
"renderWorkspaceInviteEmail"
|
|
237
|
+
],
|
|
238
|
+
"from": "../packages/main/src/server/email/workspaceInviteEmail.js",
|
|
239
|
+
"reason": "Load app-owned workspace invite email renderer from packages/main.",
|
|
240
|
+
"category": "workspaces-core",
|
|
241
|
+
"id": "workspaces-core-server-config-workspace-invite-email-import"
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"op": "ensure-assignment",
|
|
245
|
+
"file": "config/server.js",
|
|
246
|
+
"target": "config.workspaceInviteEmailTemplate",
|
|
247
|
+
"value": "renderWorkspaceInviteEmail",
|
|
248
|
+
"reason": "Bind app-owned workspace invite email renderer into server config.",
|
|
249
|
+
"category": "workspaces-core",
|
|
250
|
+
"id": "workspaces-core-server-config-workspace-invite-email-template"
|
|
251
|
+
}
|
|
252
|
+
],
|
|
253
|
+
"text": [
|
|
254
|
+
{
|
|
255
|
+
"op": "append-text",
|
|
256
|
+
"file": "config/public.js",
|
|
257
|
+
"position": "top",
|
|
258
|
+
"skipIfContains": "import { roleCatalog } from \"./roles.js\";",
|
|
259
|
+
"value": "import { roleCatalog } from \"./roles.js\";\n",
|
|
260
|
+
"reason": "Load app-owned role catalog from dedicated config file.",
|
|
261
|
+
"category": "workspaces-core",
|
|
262
|
+
"id": "users-core-role-catalog-public-import"
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"op": "append-text",
|
|
266
|
+
"file": "config/public.js",
|
|
267
|
+
"position": "top",
|
|
268
|
+
"skipIfContains": "import { surfaceAccessPolicies } from \"./surfaceAccessPolicies.js\";",
|
|
269
|
+
"value": "import { surfaceAccessPolicies } from \"./surfaceAccessPolicies.js\";\n",
|
|
270
|
+
"reason": "Load app-owned surface access policy catalog from dedicated config file.",
|
|
271
|
+
"category": "workspaces-core",
|
|
272
|
+
"id": "users-core-surface-access-policies-public-import"
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"op": "append-text",
|
|
276
|
+
"file": "config/surfaceAccessPolicies.js",
|
|
277
|
+
"position": "top",
|
|
278
|
+
"skipIfContains": "export const surfaceAccessPolicies = {};",
|
|
279
|
+
"value": "export const surfaceAccessPolicies = {};\n\n",
|
|
280
|
+
"reason": "Initialize app-owned surface access policy config if missing.",
|
|
281
|
+
"category": "workspaces-core",
|
|
282
|
+
"id": "users-core-surface-access-policies-config-init"
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
"op": "append-text",
|
|
286
|
+
"file": "config/surfaceAccessPolicies.js",
|
|
287
|
+
"position": "bottom",
|
|
288
|
+
"skipIfContains": "surfaceAccessPolicies.workspace_member = {",
|
|
289
|
+
"value": "\nsurfaceAccessPolicies.workspace_member = {\n requireAuth: true,\n requireWorkspaceMembership: true\n};\n",
|
|
290
|
+
"reason": "Register workspace-member surface access policy for workspace surfaces.",
|
|
291
|
+
"category": "workspaces-core",
|
|
292
|
+
"id": "users-core-surface-access-policies-workspace-member"
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
"op": "append-text",
|
|
296
|
+
"file": "config/public.js",
|
|
297
|
+
"position": "bottom",
|
|
298
|
+
"skipIfContains": "config.surfaceDefinitions.app = {",
|
|
299
|
+
"value": "\nconfig.surfaceDefinitions.app = {\n id: \"app\",\n label: \"App\",\n pagesRoot: \"w/[workspaceSlug]\",\n enabled: true,\n requiresAuth: true,\n requiresWorkspace: true,\n accessPolicyId: \"workspace_member\",\n origin: \"\"\n};\n\nconfig.surfaceDefinitions.admin = {\n id: \"admin\",\n label: \"Admin\",\n pagesRoot: \"w/[workspaceSlug]/admin\",\n enabled: true,\n requiresAuth: true,\n requiresWorkspace: true,\n accessPolicyId: \"workspace_member\",\n origin: \"\"\n};\n",
|
|
300
|
+
"reason": "Append workspace surface topology when tenancy enables workspace routing.",
|
|
301
|
+
"category": "workspaces-core",
|
|
302
|
+
"id": "users-core-surface-config-workspace",
|
|
303
|
+
"when": {
|
|
304
|
+
"config": "tenancyMode",
|
|
305
|
+
"in": [
|
|
306
|
+
"personal",
|
|
307
|
+
"workspaces"
|
|
308
|
+
]
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"op": "append-text",
|
|
313
|
+
"file": "config/public.js",
|
|
314
|
+
"position": "bottom",
|
|
315
|
+
"skipIfContains": "config.workspaceSwitching =",
|
|
316
|
+
"value": "\nconfig.workspaceSwitching = true;\nconfig.workspaceInvitations = {\n enabled: true,\n allowInPersonalMode: true\n};\n",
|
|
317
|
+
"reason": "Append default workspace feature toggles into app-owned config.",
|
|
318
|
+
"category": "workspaces-core",
|
|
319
|
+
"id": "users-core-public-config"
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
"op": "append-text",
|
|
323
|
+
"file": "config/public.js",
|
|
324
|
+
"position": "bottom",
|
|
325
|
+
"skipIfContains": "config.roleCatalog = roleCatalog;",
|
|
326
|
+
"value": "\nconfig.roleCatalog = roleCatalog;\n",
|
|
327
|
+
"reason": "Bind app-owned role catalog onto public config.",
|
|
328
|
+
"category": "workspaces-core",
|
|
329
|
+
"id": "users-core-role-catalog-public-config"
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
"op": "append-text",
|
|
333
|
+
"file": "config/public.js",
|
|
334
|
+
"position": "bottom",
|
|
335
|
+
"skipIfContains": "config.surfaceAccessPolicies = surfaceAccessPolicies;",
|
|
336
|
+
"value": "\nconfig.surfaceAccessPolicies = surfaceAccessPolicies;\n",
|
|
337
|
+
"reason": "Bind app-owned surface access policies onto public config.",
|
|
338
|
+
"category": "workspaces-core",
|
|
339
|
+
"id": "users-core-surface-access-policies-public-config"
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
"op": "append-text",
|
|
343
|
+
"file": "config/server.js",
|
|
344
|
+
"position": "bottom",
|
|
345
|
+
"skipIfContains": "config.workspaceColor =",
|
|
346
|
+
"value": "\nconfig.workspaceColor = \"#1867C0\";\n",
|
|
347
|
+
"reason": "Append default workspace server settings into app-owned config.",
|
|
348
|
+
"category": "workspaces-core",
|
|
349
|
+
"id": "users-core-server-config"
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
"op": "append-text",
|
|
353
|
+
"file": "config/server.js",
|
|
354
|
+
"position": "bottom",
|
|
355
|
+
"skipIfContains": "config.workspaceSettings =",
|
|
356
|
+
"value": "\nconfig.workspaceSettings = {\n defaults: {\n invitesEnabled: true\n }\n};\n",
|
|
357
|
+
"reason": "Append app-owned workspace settings defaults into the server config.",
|
|
358
|
+
"category": "workspaces-core",
|
|
359
|
+
"id": "users-core-workspace-settings-server-config"
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
"op": "append-text",
|
|
363
|
+
"file": "config/server.js",
|
|
364
|
+
"position": "bottom",
|
|
365
|
+
"skipIfContains": "config.workspaceMembers =",
|
|
366
|
+
"value": "\nconfig.workspaceMembers = {\n defaults: {\n inviteExpiresInMs: 604800000\n }\n};\n",
|
|
367
|
+
"reason": "Append app-owned workspace member invite policy defaults into the server config.",
|
|
368
|
+
"category": "workspaces-core",
|
|
369
|
+
"id": "users-core-workspace-members-server-config"
|
|
370
|
+
}
|
|
371
|
+
]
|
|
372
|
+
}
|
|
29
373
|
}
|
|
30
374
|
}
|
|
@@ -3,33 +3,35 @@ import path from "node:path";
|
|
|
3
3
|
import test from "node:test";
|
|
4
4
|
import { readFile } from "node:fs/promises";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
-
import
|
|
6
|
+
import packageJson from "../package.json" with { type: "json" };
|
|
7
|
+
|
|
8
|
+
const packageMetadata = packageJson.jskit;
|
|
7
9
|
|
|
8
10
|
const TEST_DIRECTORY = path.dirname(fileURLToPath(import.meta.url));
|
|
9
11
|
const PACKAGE_DIR = path.resolve(TEST_DIRECTORY, "..");
|
|
10
12
|
|
|
11
13
|
function findRoute(method, routePath) {
|
|
12
|
-
const routes =
|
|
14
|
+
const routes = packageMetadata?.metadata?.server?.routes;
|
|
13
15
|
return Array.isArray(routes)
|
|
14
16
|
? routes.find((entry) => entry?.method === method && entry?.path === routePath) || null
|
|
15
17
|
: null;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
function findFileMutation(id) {
|
|
19
|
-
const fileMutations =
|
|
21
|
+
const fileMutations = packageMetadata?.mutations?.files;
|
|
20
22
|
return Array.isArray(fileMutations)
|
|
21
23
|
? fileMutations.find((entry) => String(entry?.id || "").trim() === id) || null
|
|
22
24
|
: null;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
function findSourceMutation(id) {
|
|
26
|
-
const sourceMutations =
|
|
28
|
+
const sourceMutations = packageMetadata?.mutations?.source;
|
|
27
29
|
return Array.isArray(sourceMutations)
|
|
28
30
|
? sourceMutations.find((entry) => String(entry?.id || "").trim() === id) || null
|
|
29
31
|
: null;
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
test("workspaces-core
|
|
34
|
+
test("workspaces-core packageMetadata advertises public invite resolution route metadata", () => {
|
|
33
35
|
assert.deepEqual(findRoute("GET", "/api/workspace/invitations/resolve"), {
|
|
34
36
|
method: "GET",
|
|
35
37
|
path: "/api/workspace/invitations/resolve",
|
package/package.descriptor.mjs
DELETED
|
@@ -1,352 +0,0 @@
|
|
|
1
|
-
export default Object.freeze({
|
|
2
|
-
packageVersion: 1,
|
|
3
|
-
packageId: "@jskit-ai/workspaces-core",
|
|
4
|
-
version: "0.1.126",
|
|
5
|
-
kind: "runtime",
|
|
6
|
-
description: "Workspace tenancy runtime plus HTTP routes, role catalog, and workspace config scaffolding.",
|
|
7
|
-
dependsOn: [
|
|
8
|
-
"@jskit-ai/json-rest-api-core",
|
|
9
|
-
"@jskit-ai/resource-core",
|
|
10
|
-
"@jskit-ai/resource-crud-core",
|
|
11
|
-
"@jskit-ai/users-core"
|
|
12
|
-
],
|
|
13
|
-
capabilities: {
|
|
14
|
-
provides: [
|
|
15
|
-
"workspaces.core",
|
|
16
|
-
"workspaces.server-routes"
|
|
17
|
-
],
|
|
18
|
-
requires: [
|
|
19
|
-
"users.core",
|
|
20
|
-
"json-rest-api.core"
|
|
21
|
-
]
|
|
22
|
-
},
|
|
23
|
-
runtime: {
|
|
24
|
-
server: {
|
|
25
|
-
providers: [
|
|
26
|
-
{
|
|
27
|
-
entrypoint: "src/server/WorkspacesCoreServiceProvider.js",
|
|
28
|
-
export: "WorkspacesCoreServiceProvider"
|
|
29
|
-
}
|
|
30
|
-
]
|
|
31
|
-
},
|
|
32
|
-
client: {
|
|
33
|
-
providers: []
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
metadata: {
|
|
37
|
-
jskit: {
|
|
38
|
-
tableOwnership: {
|
|
39
|
-
tables: [
|
|
40
|
-
{
|
|
41
|
-
tableName: "workspaces",
|
|
42
|
-
provenance: "runtime-package",
|
|
43
|
-
ownerKind: "package-runtime"
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
tableName: "workspace_memberships",
|
|
47
|
-
provenance: "runtime-package",
|
|
48
|
-
ownerKind: "package-runtime"
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
tableName: "workspace_settings",
|
|
52
|
-
provenance: "runtime-package",
|
|
53
|
-
ownerKind: "package-runtime"
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
tableName: "workspace_invites",
|
|
57
|
-
provenance: "runtime-package",
|
|
58
|
-
ownerKind: "package-runtime"
|
|
59
|
-
}
|
|
60
|
-
]
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
apiSummary: {
|
|
64
|
-
surfaces: [
|
|
65
|
-
{
|
|
66
|
-
subpath: "./server",
|
|
67
|
-
summary: "Exports the workspace runtime provider and workspace route registration surface."
|
|
68
|
-
}
|
|
69
|
-
],
|
|
70
|
-
containerTokens: {
|
|
71
|
-
server: [
|
|
72
|
-
"workspaces.server.scope-support"
|
|
73
|
-
],
|
|
74
|
-
client: []
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
|
-
server: {
|
|
78
|
-
routes: [
|
|
79
|
-
{
|
|
80
|
-
method: "POST",
|
|
81
|
-
path: "/api/workspaces",
|
|
82
|
-
summary: "Create a workspace for the authenticated user."
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
method: "GET",
|
|
86
|
-
path: "/api/workspaces",
|
|
87
|
-
summary: "List workspaces visible to authenticated user."
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
method: "GET",
|
|
91
|
-
path: "/api/workspace/invitations/resolve",
|
|
92
|
-
summary: "Resolve safe public workspace invitation metadata."
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
method: "GET",
|
|
96
|
-
path: "/api/workspace/invitations/pending",
|
|
97
|
-
summary: "List pending workspace invitations for authenticated user."
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
method: "POST",
|
|
101
|
-
path: "/api/workspace/invitations/redeem",
|
|
102
|
-
summary: "Accept or refuse a workspace invitation using an invite token."
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
method: "GET",
|
|
106
|
-
path: "/api/w/:workspaceSlug/settings",
|
|
107
|
-
summary: "Get workspace settings and role catalog by workspace slug."
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
method: "PATCH",
|
|
111
|
-
path: "/api/w/:workspaceSlug/settings",
|
|
112
|
-
summary: "Update workspace settings by workspace slug."
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
method: "GET",
|
|
116
|
-
path: "/api/w/:workspaceSlug/roles",
|
|
117
|
-
summary: "Get role catalog by workspace slug."
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
method: "GET",
|
|
121
|
-
path: "/api/w/:workspaceSlug/members",
|
|
122
|
-
summary: "List members by workspace slug."
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
method: "PATCH",
|
|
126
|
-
path: "/api/w/:workspaceSlug/members/:memberUserId/role",
|
|
127
|
-
summary: "Update workspace member role by workspace slug."
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
method: "GET",
|
|
131
|
-
path: "/api/w/:workspaceSlug/invites",
|
|
132
|
-
summary: "List workspace invites by workspace slug."
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
method: "POST",
|
|
136
|
-
path: "/api/w/:workspaceSlug/invites",
|
|
137
|
-
summary: "Create workspace invite by workspace slug."
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
method: "DELETE",
|
|
141
|
-
path: "/api/w/:workspaceSlug/invites/:inviteId",
|
|
142
|
-
summary: "Revoke workspace invite by workspace slug."
|
|
143
|
-
}
|
|
144
|
-
]
|
|
145
|
-
}
|
|
146
|
-
},
|
|
147
|
-
mutations: {
|
|
148
|
-
dependencies: {
|
|
149
|
-
runtime: {
|
|
150
|
-
"@jskit-ai/json-rest-api-core": "0.1.92",
|
|
151
|
-
"@jskit-ai/resource-core": "0.1.90",
|
|
152
|
-
"@jskit-ai/resource-crud-core": "0.1.90",
|
|
153
|
-
"@jskit-ai/users-core": "0.1.161"
|
|
154
|
-
},
|
|
155
|
-
dev: {}
|
|
156
|
-
},
|
|
157
|
-
packageJson: {
|
|
158
|
-
scripts: {
|
|
159
|
-
"server:app": "SERVER_SURFACE=app node ./bin/server.js",
|
|
160
|
-
"server:admin": "SERVER_SURFACE=admin node ./bin/server.js"
|
|
161
|
-
}
|
|
162
|
-
},
|
|
163
|
-
procfile: {},
|
|
164
|
-
files: [
|
|
165
|
-
{
|
|
166
|
-
op: "install-migration",
|
|
167
|
-
from: "templates/migrations/workspaces_core_initial.cjs",
|
|
168
|
-
toDir: "migrations",
|
|
169
|
-
extension: ".cjs",
|
|
170
|
-
reason: "Install workspace tenancy schema migration.",
|
|
171
|
-
category: "migration",
|
|
172
|
-
id: "workspaces-core-initial-schema"
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
op: "install-migration",
|
|
176
|
-
from: "templates/migrations/workspaces_core_workspace_settings_single_name_source.cjs",
|
|
177
|
-
toDir: "migrations",
|
|
178
|
-
extension: ".cjs",
|
|
179
|
-
reason: "Remove workspace_settings name/avatar fields so workspace identity data comes from workspaces only.",
|
|
180
|
-
category: "migration",
|
|
181
|
-
id: "users-core-workspace-settings-single-name-source"
|
|
182
|
-
},
|
|
183
|
-
{
|
|
184
|
-
op: "install-migration",
|
|
185
|
-
from: "templates/migrations/workspaces_core_workspaces_drop_color.cjs",
|
|
186
|
-
toDir: "migrations",
|
|
187
|
-
extension: ".cjs",
|
|
188
|
-
reason: "Drop workspaces.color now that workspace theme colors live in workspace_settings.",
|
|
189
|
-
category: "migration",
|
|
190
|
-
id: "users-core-workspaces-drop-color"
|
|
191
|
-
},
|
|
192
|
-
{
|
|
193
|
-
from: "templates/config/roles.js",
|
|
194
|
-
to: "config/roles.js",
|
|
195
|
-
ownership: "app",
|
|
196
|
-
preserveOnRemove: true,
|
|
197
|
-
reason: "Install app-owned role catalog in a dedicated config file.",
|
|
198
|
-
category: "workspaces-core",
|
|
199
|
-
id: "users-core-app-owned-role-catalog-config"
|
|
200
|
-
},
|
|
201
|
-
{
|
|
202
|
-
from: "templates/packages/main/src/server/email/workspaceInviteEmail.js",
|
|
203
|
-
to: "packages/main/src/server/email/workspaceInviteEmail.js",
|
|
204
|
-
ownership: "app",
|
|
205
|
-
preserveOnRemove: true,
|
|
206
|
-
reason: "Install app-owned editable workspace invite email template.",
|
|
207
|
-
category: "workspaces-core",
|
|
208
|
-
id: "workspaces-core-main-workspace-invite-email-template"
|
|
209
|
-
}
|
|
210
|
-
],
|
|
211
|
-
source: [
|
|
212
|
-
{
|
|
213
|
-
op: "ensure-import",
|
|
214
|
-
file: "config/server.js",
|
|
215
|
-
namedImports: ["renderWorkspaceInviteEmail"],
|
|
216
|
-
from: "../packages/main/src/server/email/workspaceInviteEmail.js",
|
|
217
|
-
reason: "Load app-owned workspace invite email renderer from packages/main.",
|
|
218
|
-
category: "workspaces-core",
|
|
219
|
-
id: "workspaces-core-server-config-workspace-invite-email-import"
|
|
220
|
-
},
|
|
221
|
-
{
|
|
222
|
-
op: "ensure-assignment",
|
|
223
|
-
file: "config/server.js",
|
|
224
|
-
target: "config.workspaceInviteEmailTemplate",
|
|
225
|
-
value: "renderWorkspaceInviteEmail",
|
|
226
|
-
reason: "Bind app-owned workspace invite email renderer into server config.",
|
|
227
|
-
category: "workspaces-core",
|
|
228
|
-
id: "workspaces-core-server-config-workspace-invite-email-template"
|
|
229
|
-
}
|
|
230
|
-
],
|
|
231
|
-
text: [
|
|
232
|
-
{
|
|
233
|
-
op: "append-text",
|
|
234
|
-
file: "config/public.js",
|
|
235
|
-
position: "top",
|
|
236
|
-
skipIfContains: "import { roleCatalog } from \"./roles.js\";",
|
|
237
|
-
value: "import { roleCatalog } from \"./roles.js\";\n",
|
|
238
|
-
reason: "Load app-owned role catalog from dedicated config file.",
|
|
239
|
-
category: "workspaces-core",
|
|
240
|
-
id: "users-core-role-catalog-public-import"
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
op: "append-text",
|
|
244
|
-
file: "config/public.js",
|
|
245
|
-
position: "top",
|
|
246
|
-
skipIfContains: "import { surfaceAccessPolicies } from \"./surfaceAccessPolicies.js\";",
|
|
247
|
-
value: "import { surfaceAccessPolicies } from \"./surfaceAccessPolicies.js\";\n",
|
|
248
|
-
reason: "Load app-owned surface access policy catalog from dedicated config file.",
|
|
249
|
-
category: "workspaces-core",
|
|
250
|
-
id: "users-core-surface-access-policies-public-import"
|
|
251
|
-
},
|
|
252
|
-
{
|
|
253
|
-
op: "append-text",
|
|
254
|
-
file: "config/surfaceAccessPolicies.js",
|
|
255
|
-
position: "top",
|
|
256
|
-
skipIfContains: "export const surfaceAccessPolicies = {};",
|
|
257
|
-
value: "export const surfaceAccessPolicies = {};\n\n",
|
|
258
|
-
reason: "Initialize app-owned surface access policy config if missing.",
|
|
259
|
-
category: "workspaces-core",
|
|
260
|
-
id: "users-core-surface-access-policies-config-init"
|
|
261
|
-
},
|
|
262
|
-
{
|
|
263
|
-
op: "append-text",
|
|
264
|
-
file: "config/surfaceAccessPolicies.js",
|
|
265
|
-
position: "bottom",
|
|
266
|
-
skipIfContains: "surfaceAccessPolicies.workspace_member = {",
|
|
267
|
-
value: "\nsurfaceAccessPolicies.workspace_member = {\n requireAuth: true,\n requireWorkspaceMembership: true\n};\n",
|
|
268
|
-
reason: "Register workspace-member surface access policy for workspace surfaces.",
|
|
269
|
-
category: "workspaces-core",
|
|
270
|
-
id: "users-core-surface-access-policies-workspace-member"
|
|
271
|
-
},
|
|
272
|
-
{
|
|
273
|
-
op: "append-text",
|
|
274
|
-
file: "config/public.js",
|
|
275
|
-
position: "bottom",
|
|
276
|
-
skipIfContains: "config.surfaceDefinitions.app = {",
|
|
277
|
-
value:
|
|
278
|
-
"\nconfig.surfaceDefinitions.app = {\n id: \"app\",\n label: \"App\",\n pagesRoot: \"w/[workspaceSlug]\",\n enabled: true,\n requiresAuth: true,\n requiresWorkspace: true,\n accessPolicyId: \"workspace_member\",\n origin: \"\"\n};\n\nconfig.surfaceDefinitions.admin = {\n id: \"admin\",\n label: \"Admin\",\n pagesRoot: \"w/[workspaceSlug]/admin\",\n enabled: true,\n requiresAuth: true,\n requiresWorkspace: true,\n accessPolicyId: \"workspace_member\",\n origin: \"\"\n};\n",
|
|
279
|
-
reason: "Append workspace surface topology when tenancy enables workspace routing.",
|
|
280
|
-
category: "workspaces-core",
|
|
281
|
-
id: "users-core-surface-config-workspace",
|
|
282
|
-
when: {
|
|
283
|
-
config: "tenancyMode",
|
|
284
|
-
in: ["personal", "workspaces"]
|
|
285
|
-
}
|
|
286
|
-
},
|
|
287
|
-
{
|
|
288
|
-
op: "append-text",
|
|
289
|
-
file: "config/public.js",
|
|
290
|
-
position: "bottom",
|
|
291
|
-
skipIfContains: "config.workspaceSwitching =",
|
|
292
|
-
value:
|
|
293
|
-
"\nconfig.workspaceSwitching = true;\nconfig.workspaceInvitations = {\n enabled: true,\n allowInPersonalMode: true\n};\n",
|
|
294
|
-
reason: "Append default workspace feature toggles into app-owned config.",
|
|
295
|
-
category: "workspaces-core",
|
|
296
|
-
id: "users-core-public-config"
|
|
297
|
-
},
|
|
298
|
-
{
|
|
299
|
-
op: "append-text",
|
|
300
|
-
file: "config/public.js",
|
|
301
|
-
position: "bottom",
|
|
302
|
-
skipIfContains: "config.roleCatalog = roleCatalog;",
|
|
303
|
-
value: "\nconfig.roleCatalog = roleCatalog;\n",
|
|
304
|
-
reason: "Bind app-owned role catalog onto public config.",
|
|
305
|
-
category: "workspaces-core",
|
|
306
|
-
id: "users-core-role-catalog-public-config"
|
|
307
|
-
},
|
|
308
|
-
{
|
|
309
|
-
op: "append-text",
|
|
310
|
-
file: "config/public.js",
|
|
311
|
-
position: "bottom",
|
|
312
|
-
skipIfContains: "config.surfaceAccessPolicies = surfaceAccessPolicies;",
|
|
313
|
-
value: "\nconfig.surfaceAccessPolicies = surfaceAccessPolicies;\n",
|
|
314
|
-
reason: "Bind app-owned surface access policies onto public config.",
|
|
315
|
-
category: "workspaces-core",
|
|
316
|
-
id: "users-core-surface-access-policies-public-config"
|
|
317
|
-
},
|
|
318
|
-
{
|
|
319
|
-
op: "append-text",
|
|
320
|
-
file: "config/server.js",
|
|
321
|
-
position: "bottom",
|
|
322
|
-
skipIfContains: "config.workspaceColor =",
|
|
323
|
-
value: "\nconfig.workspaceColor = \"#1867C0\";\n",
|
|
324
|
-
reason: "Append default workspace server settings into app-owned config.",
|
|
325
|
-
category: "workspaces-core",
|
|
326
|
-
id: "users-core-server-config"
|
|
327
|
-
},
|
|
328
|
-
{
|
|
329
|
-
op: "append-text",
|
|
330
|
-
file: "config/server.js",
|
|
331
|
-
position: "bottom",
|
|
332
|
-
skipIfContains: "config.workspaceSettings =",
|
|
333
|
-
value:
|
|
334
|
-
"\nconfig.workspaceSettings = {\n defaults: {\n invitesEnabled: true\n }\n};\n",
|
|
335
|
-
reason: "Append app-owned workspace settings defaults into the server config.",
|
|
336
|
-
category: "workspaces-core",
|
|
337
|
-
id: "users-core-workspace-settings-server-config"
|
|
338
|
-
},
|
|
339
|
-
{
|
|
340
|
-
op: "append-text",
|
|
341
|
-
file: "config/server.js",
|
|
342
|
-
position: "bottom",
|
|
343
|
-
skipIfContains: "config.workspaceMembers =",
|
|
344
|
-
value:
|
|
345
|
-
"\nconfig.workspaceMembers = {\n defaults: {\n inviteExpiresInMs: 604800000\n }\n};\n",
|
|
346
|
-
reason: "Append app-owned workspace member invite policy defaults into the server config.",
|
|
347
|
-
category: "workspaces-core",
|
|
348
|
-
id: "users-core-workspace-members-server-config"
|
|
349
|
-
}
|
|
350
|
-
]
|
|
351
|
-
}
|
|
352
|
-
});
|