@jskit-ai/users-core 0.1.172 → 0.1.174
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 +41 -253
- package/patterns/user-administration-server/PATTERN.md +64 -0
- package/patterns/user-administration-server/example/packages/users/package.json +42 -0
- package/patterns/user-administration-server/example/packages/users/src/server/UsersFeature.js +13 -0
- package/patterns/user-administration-server/example/packages/users/src/shared/index.js +1 -0
- package/patterns/user-administration-server/example/packages/users-workspace/package.json +43 -0
- package/patterns/user-administration-server/example/packages/users-workspace/src/server/UsersWorkspaceFeature.js +22 -0
- package/patterns/user-administration-server/example/packages/users-workspace/src/shared/userResource.js +56 -0
- package/src/server/UsersExtensionsProvider.js +14 -0
- package/src/server/UsersFeature.js +119 -0
- package/src/server/UsersIdentityProvider.js +57 -0
- package/src/server/accountNotifications/accountNotificationsActions.js +17 -5
- package/src/server/accountNotifications/bootAccountNotificationsRoutes.js +4 -6
- package/src/server/accountPreferences/accountPreferencesActions.js +17 -5
- package/src/server/accountPreferences/bootAccountPreferencesRoutes.js +4 -6
- package/src/server/accountProfile/accountProfileActions.js +28 -14
- package/src/server/accountProfile/bootAccountProfileRoutes.js +11 -10
- package/src/server/accountSecurity/accountSecurityActions.js +27 -17
- package/src/server/accountSecurity/bootAccountSecurityRoutes.js +4 -7
- package/src/server/common/services/authProfileSyncService.js +11 -4
- package/src/server/common/support/realtimeServiceEvents.js +8 -11
- package/src/server/usersBootstrapContributor.js +4 -28
- package/src/server/usersExtensions.js +65 -0
- package/test/authProfileSyncService.test.js +2 -2
- package/test/exportsContract.test.js +6 -1
- package/test/featureRuntime.test.js +78 -0
- package/test/usersBootstrapContributor.test.js +1 -43
- package/test/usersPackageScaffoldContract.test.js +58 -204
- package/test/usersRouteRequestInputValidator.test.js +19 -43
- package/src/server/UsersCoreServiceProvider.js +0 -56
- package/src/server/accountNotifications/registerAccountNotifications.js +0 -37
- package/src/server/accountPreferences/registerAccountPreferences.js +0 -37
- package/src/server/accountProfile/registerAccountProfile.js +0 -56
- package/src/server/accountSecurity/registerAccountSecurity.js +0 -29
- package/src/server/common/registerCommonRepositories.js +0 -23
- package/src/server/common/registerSharedApi.js +0 -9
- package/src/server/profileSyncLifecycleContributorRegistry.js +0 -56
- package/src/server/registerUsersBootstrap.js +0 -20
- package/src/server/registerUsersCore.js +0 -22
- package/templates/packages/users/package.json +0 -82
- package/templates/packages/users/src/server/UsersProvider.js +0 -90
- package/templates/packages/users/src/server/actions.js +0 -68
- package/templates/packages/users/src/server/registerRoutes.js +0 -101
- package/templates/packages/users/src/server/repository.js +0 -51
- package/templates/packages/users/src/server/service.js +0 -32
- package/templates/packages/users-workspace/package.json +0 -83
- package/templates/packages/users-workspace/src/server/UsersProvider.js +0 -91
- package/templates/packages/users-workspace/src/server/actions.js +0 -77
- package/templates/packages/users-workspace/src/server/registerRoutes.js +0 -111
- package/test/providerLifecycle.test.js +0 -63
- package/test/registerCommonRepositories.test.js +0 -57
- package/test/registerServiceRealtimeEvents.test.js +0 -57
- package/test/registerUsersCore.test.js +0 -53
- /package/{templates/migrations → migrations}/users_core_generic_initial.cjs +0 -0
- /package/{templates/migrations → migrations}/users_core_profile_updated_at.cjs +0 -0
- /package/{templates/migrations → migrations}/users_core_profile_username.cjs +0 -0
- /package/{templates → patterns/user-administration-server/example}/packages/users/src/shared/userResource.js +0 -0
- /package/{templates/packages/users → patterns/user-administration-server/example/packages/users-workspace}/src/shared/index.js +0 -0
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { resolveAppConfig } from "@jskit-ai/kernel/server/support";
|
|
2
|
-
import { resolveCrudSurfacePolicyFromAppConfig } from "@jskit-ai/crud-core/server/crudModuleConfig";
|
|
3
|
-
import {
|
|
4
|
-
INTERNAL_JSON_REST_API,
|
|
5
|
-
addResourceIfMissing,
|
|
6
|
-
createJsonRestResourceScopeOptions
|
|
7
|
-
} from "@jskit-ai/json-rest-api-core/server/jsonRestApiHost";
|
|
8
|
-
import { withActionDefaults } from "@jskit-ai/kernel/shared/actions";
|
|
9
|
-
import { toDatabaseDateTimeUtc } from "@jskit-ai/database-runtime/shared";
|
|
10
|
-
import { createRepository } from "./repository.js";
|
|
11
|
-
import { createService } from "./service.js";
|
|
12
|
-
import { createActions } from "./actions.js";
|
|
13
|
-
import { registerRoutes } from "./registerRoutes.js";
|
|
14
|
-
import { resource } from "../shared/userResource.js";
|
|
15
|
-
|
|
16
|
-
const CRUD_MODULE_CONFIG = Object.freeze({
|
|
17
|
-
namespace: "users",
|
|
18
|
-
surface: "admin",
|
|
19
|
-
ownershipFilter: "public",
|
|
20
|
-
relativePath: "/users"
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
function resolveCrudPolicyFromApp(app) {
|
|
24
|
-
return resolveCrudSurfacePolicyFromAppConfig(CRUD_MODULE_CONFIG, resolveAppConfig(app), {
|
|
25
|
-
context: "UsersProvider"
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
class UsersProvider {
|
|
30
|
-
static id = "crud.users";
|
|
31
|
-
|
|
32
|
-
static startsAfter = ["json-rest-api.core", "local.main", "runtime.actions"];
|
|
33
|
-
|
|
34
|
-
register(app) {
|
|
35
|
-
const crudPolicy = resolveCrudPolicyFromApp(app);
|
|
36
|
-
|
|
37
|
-
app.singleton("repository.users", (scope) => {
|
|
38
|
-
const api = scope.make(INTERNAL_JSON_REST_API);
|
|
39
|
-
const knex = scope.make("jskit.database.knex");
|
|
40
|
-
return createRepository({
|
|
41
|
-
api,
|
|
42
|
-
knex
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
app.service(
|
|
47
|
-
"crud.users",
|
|
48
|
-
(scope) => {
|
|
49
|
-
return createService({
|
|
50
|
-
usersRepository: scope.make("repository.users")
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
app.actions(
|
|
56
|
-
withActionDefaults(
|
|
57
|
-
createActions({
|
|
58
|
-
surface: crudPolicy.surfaceId
|
|
59
|
-
}),
|
|
60
|
-
{
|
|
61
|
-
domain: "crud",
|
|
62
|
-
dependencies: {
|
|
63
|
-
usersService: "crud.users"
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
)
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async boot(app) {
|
|
71
|
-
const crudPolicy = resolveCrudPolicyFromApp(app);
|
|
72
|
-
const api = app.make(INTERNAL_JSON_REST_API);
|
|
73
|
-
await addResourceIfMissing(
|
|
74
|
-
api,
|
|
75
|
-
"users",
|
|
76
|
-
createJsonRestResourceScopeOptions(resource, {
|
|
77
|
-
writeSerializers: {
|
|
78
|
-
"datetime-utc": toDatabaseDateTimeUtc
|
|
79
|
-
}
|
|
80
|
-
})
|
|
81
|
-
);
|
|
82
|
-
registerRoutes(app, {
|
|
83
|
-
routeOwnershipFilter: crudPolicy.ownershipFilter,
|
|
84
|
-
routeSurface: crudPolicy.surfaceId,
|
|
85
|
-
routeSurfaceRequiresWorkspace: crudPolicy.surfaceDefinition.requiresWorkspace === true,
|
|
86
|
-
routeRelativePath: crudPolicy.relativePath
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export { UsersProvider };
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
composeSchemaDefinitions,
|
|
3
|
-
recordIdParamsValidator
|
|
4
|
-
} from "@jskit-ai/kernel/shared/validators";
|
|
5
|
-
import {
|
|
6
|
-
createStandardCrudListQueryValidators,
|
|
7
|
-
createStandardCrudViewQueryValidators
|
|
8
|
-
} from "@jskit-ai/crud-core/server/listQueryValidators";
|
|
9
|
-
import { workspaceSlugParamsValidator } from "@jskit-ai/workspaces-core/server/validators/routeParamsValidator";
|
|
10
|
-
import { resource } from "../shared/userResource.js";
|
|
11
|
-
|
|
12
|
-
const authenticatedPermission = Object.freeze({
|
|
13
|
-
require: "authenticated"
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
function buildListQuery(input = {}) {
|
|
17
|
-
const query = { ...(input || {}) };
|
|
18
|
-
delete query.workspaceSlug;
|
|
19
|
-
return query;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function createActions({ surface } = {}) {
|
|
23
|
-
return Object.freeze([
|
|
24
|
-
{
|
|
25
|
-
id: "crud.users.list",
|
|
26
|
-
version: 1,
|
|
27
|
-
kind: "query",
|
|
28
|
-
channels: ["api", "automation", "internal"],
|
|
29
|
-
surfaces: [surface],
|
|
30
|
-
permission: authenticatedPermission,
|
|
31
|
-
input: composeSchemaDefinitions([
|
|
32
|
-
workspaceSlugParamsValidator,
|
|
33
|
-
...createStandardCrudListQueryValidators({ resource })
|
|
34
|
-
]),
|
|
35
|
-
output: null,
|
|
36
|
-
idempotency: "none",
|
|
37
|
-
audit: {
|
|
38
|
-
actionName: "crud.users.list"
|
|
39
|
-
},
|
|
40
|
-
observability: {},
|
|
41
|
-
async execute(input, context, deps) {
|
|
42
|
-
return deps.usersService.queryDocuments(buildListQuery(input), {
|
|
43
|
-
context,
|
|
44
|
-
visibilityContext: context?.visibilityContext
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
id: "crud.users.view",
|
|
50
|
-
version: 1,
|
|
51
|
-
kind: "query",
|
|
52
|
-
channels: ["api", "automation", "internal"],
|
|
53
|
-
surfaces: [surface],
|
|
54
|
-
permission: authenticatedPermission,
|
|
55
|
-
input: composeSchemaDefinitions([
|
|
56
|
-
workspaceSlugParamsValidator,
|
|
57
|
-
recordIdParamsValidator,
|
|
58
|
-
...createStandardCrudViewQueryValidators()
|
|
59
|
-
]),
|
|
60
|
-
output: null,
|
|
61
|
-
idempotency: "none",
|
|
62
|
-
audit: {
|
|
63
|
-
actionName: "crud.users.view"
|
|
64
|
-
},
|
|
65
|
-
observability: {},
|
|
66
|
-
async execute(input, context, deps) {
|
|
67
|
-
const { workspaceSlug, recordId, ...query } = input || {};
|
|
68
|
-
return deps.usersService.getDocumentById(recordId, query, {
|
|
69
|
-
context,
|
|
70
|
-
visibilityContext: context?.visibilityContext
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
]);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export { createActions };
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { createJsonApiResourceRouteContract } from "@jskit-ai/http-runtime/shared/validators/jsonApiRouteTransport";
|
|
2
|
-
import { normalizeSurfaceId } from "@jskit-ai/kernel/shared/surface/registry";
|
|
3
|
-
import {
|
|
4
|
-
createCrudCursorPaginationQueryValidator,
|
|
5
|
-
listSearchQueryValidator
|
|
6
|
-
} from "@jskit-ai/crud-core/server/listQueryValidators";
|
|
7
|
-
import { resolveScopedApiBasePath } from "@jskit-ai/kernel/shared/surface";
|
|
8
|
-
import { checkRouteVisibility } from "@jskit-ai/kernel/shared/support/visibility";
|
|
9
|
-
import {
|
|
10
|
-
composeSchemaDefinitions,
|
|
11
|
-
recordIdParamsValidator
|
|
12
|
-
} from "@jskit-ai/kernel/shared/validators";
|
|
13
|
-
import { routeParamsValidator } from "@jskit-ai/workspaces-core/server/validators/routeParamsValidator";
|
|
14
|
-
import { buildWorkspaceInputFromRouteParams } from "@jskit-ai/workspaces-core/server/support/workspaceRouteInput";
|
|
15
|
-
import { resource } from "../shared/userResource.js";
|
|
16
|
-
|
|
17
|
-
const listCursorPaginationQueryValidator = createCrudCursorPaginationQueryValidator({
|
|
18
|
-
orderBy: resource.defaultSort
|
|
19
|
-
});
|
|
20
|
-
const listRouteQueryValidator = composeSchemaDefinitions([
|
|
21
|
-
listCursorPaginationQueryValidator,
|
|
22
|
-
listSearchQueryValidator
|
|
23
|
-
]);
|
|
24
|
-
const RESOURCE_ROUTE_CONTRACT_TYPE = resource.namespace;
|
|
25
|
-
const listRouteContract = createJsonApiResourceRouteContract({
|
|
26
|
-
type: RESOURCE_ROUTE_CONTRACT_TYPE,
|
|
27
|
-
query: listRouteQueryValidator,
|
|
28
|
-
output: resource.operations.view.output,
|
|
29
|
-
outputKind: "collection"
|
|
30
|
-
});
|
|
31
|
-
const viewRouteContract = createJsonApiResourceRouteContract({
|
|
32
|
-
type: RESOURCE_ROUTE_CONTRACT_TYPE,
|
|
33
|
-
output: resource.operations.view.output,
|
|
34
|
-
outputKind: "record"
|
|
35
|
-
});
|
|
36
|
-
const viewRouteParamsValidator = composeSchemaDefinitions([
|
|
37
|
-
routeParamsValidator,
|
|
38
|
-
recordIdParamsValidator
|
|
39
|
-
]);
|
|
40
|
-
|
|
41
|
-
function registerRoutes(
|
|
42
|
-
app,
|
|
43
|
-
{
|
|
44
|
-
routeOwnershipFilter = "public",
|
|
45
|
-
routeSurface = "",
|
|
46
|
-
routeSurfaceRequiresWorkspace = false,
|
|
47
|
-
routeRelativePath = ""
|
|
48
|
-
} = {}
|
|
49
|
-
) {
|
|
50
|
-
const router = app.make("jskit.http.router");
|
|
51
|
-
const normalizedRouteSurface = normalizeSurfaceId(routeSurface);
|
|
52
|
-
const routeBase = resolveScopedApiBasePath({
|
|
53
|
-
routeBase: routeSurfaceRequiresWorkspace === true ? "/w/:workspaceSlug" : "/",
|
|
54
|
-
relativePath: routeRelativePath,
|
|
55
|
-
strictParams: false
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
router.register(
|
|
59
|
-
"GET",
|
|
60
|
-
routeBase,
|
|
61
|
-
{
|
|
62
|
-
auth: "required",
|
|
63
|
-
surface: normalizedRouteSurface,
|
|
64
|
-
visibility: checkRouteVisibility(routeOwnershipFilter),
|
|
65
|
-
meta: {
|
|
66
|
-
tags: ["crud"],
|
|
67
|
-
summary: "List users."
|
|
68
|
-
},
|
|
69
|
-
...listRouteContract,
|
|
70
|
-
params: routeParamsValidator
|
|
71
|
-
},
|
|
72
|
-
async function (request, reply) {
|
|
73
|
-
const response = await request.executeAction({
|
|
74
|
-
actionId: "crud.users.list",
|
|
75
|
-
input: {
|
|
76
|
-
...buildWorkspaceInputFromRouteParams(request.input.params),
|
|
77
|
-
...(request.input.query || {})
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
reply.code(200).send(response);
|
|
81
|
-
}
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
router.register(
|
|
85
|
-
"GET",
|
|
86
|
-
`${routeBase}/:recordId`,
|
|
87
|
-
{
|
|
88
|
-
auth: "required",
|
|
89
|
-
surface: normalizedRouteSurface,
|
|
90
|
-
visibility: checkRouteVisibility(routeOwnershipFilter),
|
|
91
|
-
meta: {
|
|
92
|
-
tags: ["crud"],
|
|
93
|
-
summary: "View a user."
|
|
94
|
-
},
|
|
95
|
-
...viewRouteContract,
|
|
96
|
-
params: viewRouteParamsValidator
|
|
97
|
-
},
|
|
98
|
-
async function (request, reply) {
|
|
99
|
-
const response = await request.executeAction({
|
|
100
|
-
actionId: "crud.users.view",
|
|
101
|
-
input: {
|
|
102
|
-
...buildWorkspaceInputFromRouteParams(request.input.params),
|
|
103
|
-
recordId: request.input.params.recordId
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
reply.code(200).send(response);
|
|
107
|
-
}
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export { registerRoutes };
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import { UsersCoreServiceProvider } from "../src/server/UsersCoreServiceProvider.js";
|
|
4
|
-
import { WorkspacesCoreServiceProvider } from "../../workspaces-core/src/server/WorkspacesCoreServiceProvider.js";
|
|
5
|
-
|
|
6
|
-
function createRegisterPhaseProbe() {
|
|
7
|
-
let makeCalls = 0;
|
|
8
|
-
|
|
9
|
-
const target = {
|
|
10
|
-
singleton() {
|
|
11
|
-
return proxy;
|
|
12
|
-
},
|
|
13
|
-
service() {
|
|
14
|
-
return proxy;
|
|
15
|
-
},
|
|
16
|
-
actions() {
|
|
17
|
-
return proxy;
|
|
18
|
-
},
|
|
19
|
-
instance() {
|
|
20
|
-
return proxy;
|
|
21
|
-
},
|
|
22
|
-
tag() {
|
|
23
|
-
return proxy;
|
|
24
|
-
},
|
|
25
|
-
has() {
|
|
26
|
-
return false;
|
|
27
|
-
},
|
|
28
|
-
make() {
|
|
29
|
-
makeCalls += 1;
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const proxy = new Proxy(target, {
|
|
35
|
-
get(source, property) {
|
|
36
|
-
if (property === "makeCalls") {
|
|
37
|
-
return makeCalls;
|
|
38
|
-
}
|
|
39
|
-
if (Object.prototype.hasOwnProperty.call(source, property)) {
|
|
40
|
-
return source[property];
|
|
41
|
-
}
|
|
42
|
-
return () => proxy;
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
return proxy;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
test("UsersCoreServiceProvider register phase does not resolve container services eagerly", async () => {
|
|
50
|
-
const app = createRegisterPhaseProbe();
|
|
51
|
-
|
|
52
|
-
await new UsersCoreServiceProvider().register(app);
|
|
53
|
-
|
|
54
|
-
assert.equal(app.makeCalls, 0);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
test("WorkspacesCoreServiceProvider register phase does not resolve container services eagerly", async () => {
|
|
58
|
-
const app = createRegisterPhaseProbe();
|
|
59
|
-
|
|
60
|
-
await new WorkspacesCoreServiceProvider().register(app);
|
|
61
|
-
|
|
62
|
-
assert.equal(app.makeCalls, 0);
|
|
63
|
-
});
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import { registerCommonRepositories } from "../src/server/common/registerCommonRepositories.js";
|
|
4
|
-
|
|
5
|
-
test("registerCommonRepositories exposes the shared users-core repositories", async () => {
|
|
6
|
-
const bindings = new Map();
|
|
7
|
-
const app = {
|
|
8
|
-
singleton(token, factory) {
|
|
9
|
-
bindings.set(token, factory);
|
|
10
|
-
return this;
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
registerCommonRepositories(app);
|
|
15
|
-
|
|
16
|
-
assert.equal(typeof bindings.get("internal.repository.user-settings"), "function");
|
|
17
|
-
assert.equal(typeof bindings.get("internal.repository.user-profiles"), "function");
|
|
18
|
-
|
|
19
|
-
const scope = {
|
|
20
|
-
make(token) {
|
|
21
|
-
if (token === "internal.json-rest-api") {
|
|
22
|
-
return {
|
|
23
|
-
resources: {
|
|
24
|
-
userSettings: {
|
|
25
|
-
query() {},
|
|
26
|
-
post() {},
|
|
27
|
-
patch() {}
|
|
28
|
-
},
|
|
29
|
-
userProfiles: {
|
|
30
|
-
query() {},
|
|
31
|
-
post() {},
|
|
32
|
-
patch() {}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (token === "jskit.database.knex") {
|
|
39
|
-
return Object.assign(() => {
|
|
40
|
-
throw new Error("query execution not expected");
|
|
41
|
-
}, {
|
|
42
|
-
async transaction(work) {
|
|
43
|
-
return work({ trxId: "trx-1" });
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
throw new Error(`Unexpected token: ${token}`);
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
const settingsRepository = bindings.get("internal.repository.user-settings")(scope);
|
|
53
|
-
const profileRepository = bindings.get("internal.repository.user-profiles")(scope);
|
|
54
|
-
|
|
55
|
-
assert.equal(typeof settingsRepository.findByUserId, "function");
|
|
56
|
-
assert.equal(typeof profileRepository.findById, "function");
|
|
57
|
-
});
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import { registerAccountProfile } from "../src/server/accountProfile/registerAccountProfile.js";
|
|
4
|
-
import { registerAccountPreferences } from "../src/server/accountPreferences/registerAccountPreferences.js";
|
|
5
|
-
import { registerAccountNotifications } from "../src/server/accountNotifications/registerAccountNotifications.js";
|
|
6
|
-
|
|
7
|
-
function createAppDouble() {
|
|
8
|
-
const serviceCalls = [];
|
|
9
|
-
|
|
10
|
-
return {
|
|
11
|
-
serviceCalls,
|
|
12
|
-
app: {
|
|
13
|
-
singleton() {
|
|
14
|
-
return this;
|
|
15
|
-
},
|
|
16
|
-
service(token, factory, metadata) {
|
|
17
|
-
serviceCalls.push({
|
|
18
|
-
token,
|
|
19
|
-
factory,
|
|
20
|
-
metadata
|
|
21
|
-
});
|
|
22
|
-
return this;
|
|
23
|
-
},
|
|
24
|
-
actions() {
|
|
25
|
-
return this;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function findServiceCall(serviceCalls, token) {
|
|
32
|
-
return serviceCalls.find((entry) => entry.token === token) || null;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
test("account register functions publish account.settings.changed for update operations", () => {
|
|
36
|
-
const profileApp = createAppDouble();
|
|
37
|
-
registerAccountProfile(profileApp.app);
|
|
38
|
-
const profile = findServiceCall(profileApp.serviceCalls, "users.accountProfile.service");
|
|
39
|
-
assert.equal(profile?.metadata?.events?.updateProfile?.[0]?.realtime?.event, "account.settings.changed");
|
|
40
|
-
assert.equal(profile?.metadata?.events?.updateProfile?.[1]?.realtime?.event, "users.bootstrap.changed");
|
|
41
|
-
assert.equal(profile?.metadata?.events?.uploadAvatar?.[0]?.realtime?.event, "account.settings.changed");
|
|
42
|
-
assert.equal(profile?.metadata?.events?.uploadAvatar?.[1]?.realtime?.event, "users.bootstrap.changed");
|
|
43
|
-
assert.equal(profile?.metadata?.events?.deleteAvatar?.[0]?.realtime?.event, "account.settings.changed");
|
|
44
|
-
assert.equal(profile?.metadata?.events?.deleteAvatar?.[1]?.realtime?.event, "users.bootstrap.changed");
|
|
45
|
-
|
|
46
|
-
const preferencesApp = createAppDouble();
|
|
47
|
-
registerAccountPreferences(preferencesApp.app);
|
|
48
|
-
const preferences = findServiceCall(preferencesApp.serviceCalls, "users.accountPreferences.service");
|
|
49
|
-
assert.equal(preferences?.metadata?.events?.updatePreferences?.[0]?.realtime?.event, "account.settings.changed");
|
|
50
|
-
assert.equal(preferences?.metadata?.events?.updatePreferences?.[1]?.realtime?.event, "users.bootstrap.changed");
|
|
51
|
-
|
|
52
|
-
const notificationsApp = createAppDouble();
|
|
53
|
-
registerAccountNotifications(notificationsApp.app);
|
|
54
|
-
const notifications = findServiceCall(notificationsApp.serviceCalls, "users.accountNotifications.service");
|
|
55
|
-
assert.equal(notifications?.metadata?.events?.updateNotifications?.[0]?.realtime?.event, "account.settings.changed");
|
|
56
|
-
assert.equal(notifications?.metadata?.events?.updateNotifications?.[1]?.realtime?.event, "users.bootstrap.changed");
|
|
57
|
-
});
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import { registerUsersCore } from "../src/server/registerUsersCore.js";
|
|
4
|
-
|
|
5
|
-
test("registerUsersCore only binds users-core singletons", () => {
|
|
6
|
-
const singletonTokens = [];
|
|
7
|
-
const app = {
|
|
8
|
-
has() {
|
|
9
|
-
return false;
|
|
10
|
-
},
|
|
11
|
-
singleton(token) {
|
|
12
|
-
singletonTokens.push(String(token || ""));
|
|
13
|
-
return this;
|
|
14
|
-
}
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
registerUsersCore(app);
|
|
18
|
-
|
|
19
|
-
assert.deepEqual(singletonTokens.sort(), [
|
|
20
|
-
"auth.profile.projector",
|
|
21
|
-
"users.profile.sync.service"
|
|
22
|
-
]);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
test("registerUsersCore still works when action runtime has not installed actionSurfaceSource yet", () => {
|
|
26
|
-
const app = {
|
|
27
|
-
has() {
|
|
28
|
-
return false;
|
|
29
|
-
},
|
|
30
|
-
singleton() {
|
|
31
|
-
return this;
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
assert.doesNotThrow(() => registerUsersCore(app));
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
test("registerUsersCore preserves an existing auth profile projector", () => {
|
|
39
|
-
const singletonTokens = [];
|
|
40
|
-
const app = {
|
|
41
|
-
has(token) {
|
|
42
|
-
return token === "auth.profile.projector";
|
|
43
|
-
},
|
|
44
|
-
singleton(token) {
|
|
45
|
-
singletonTokens.push(String(token || ""));
|
|
46
|
-
return this;
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
registerUsersCore(app);
|
|
51
|
-
|
|
52
|
-
assert.deepEqual(singletonTokens, ["users.profile.sync.service"]);
|
|
53
|
-
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|