@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.
Files changed (58) hide show
  1. package/package.json +41 -253
  2. package/patterns/user-administration-server/PATTERN.md +64 -0
  3. package/patterns/user-administration-server/example/packages/users/package.json +42 -0
  4. package/patterns/user-administration-server/example/packages/users/src/server/UsersFeature.js +13 -0
  5. package/patterns/user-administration-server/example/packages/users/src/shared/index.js +1 -0
  6. package/patterns/user-administration-server/example/packages/users-workspace/package.json +43 -0
  7. package/patterns/user-administration-server/example/packages/users-workspace/src/server/UsersWorkspaceFeature.js +22 -0
  8. package/patterns/user-administration-server/example/packages/users-workspace/src/shared/userResource.js +56 -0
  9. package/src/server/UsersExtensionsProvider.js +14 -0
  10. package/src/server/UsersFeature.js +119 -0
  11. package/src/server/UsersIdentityProvider.js +57 -0
  12. package/src/server/accountNotifications/accountNotificationsActions.js +17 -5
  13. package/src/server/accountNotifications/bootAccountNotificationsRoutes.js +4 -6
  14. package/src/server/accountPreferences/accountPreferencesActions.js +17 -5
  15. package/src/server/accountPreferences/bootAccountPreferencesRoutes.js +4 -6
  16. package/src/server/accountProfile/accountProfileActions.js +28 -14
  17. package/src/server/accountProfile/bootAccountProfileRoutes.js +11 -10
  18. package/src/server/accountSecurity/accountSecurityActions.js +27 -17
  19. package/src/server/accountSecurity/bootAccountSecurityRoutes.js +4 -7
  20. package/src/server/common/services/authProfileSyncService.js +11 -4
  21. package/src/server/common/support/realtimeServiceEvents.js +8 -11
  22. package/src/server/usersBootstrapContributor.js +4 -28
  23. package/src/server/usersExtensions.js +65 -0
  24. package/test/authProfileSyncService.test.js +2 -2
  25. package/test/exportsContract.test.js +6 -1
  26. package/test/featureRuntime.test.js +78 -0
  27. package/test/usersBootstrapContributor.test.js +1 -43
  28. package/test/usersPackageScaffoldContract.test.js +58 -204
  29. package/test/usersRouteRequestInputValidator.test.js +19 -43
  30. package/src/server/UsersCoreServiceProvider.js +0 -56
  31. package/src/server/accountNotifications/registerAccountNotifications.js +0 -37
  32. package/src/server/accountPreferences/registerAccountPreferences.js +0 -37
  33. package/src/server/accountProfile/registerAccountProfile.js +0 -56
  34. package/src/server/accountSecurity/registerAccountSecurity.js +0 -29
  35. package/src/server/common/registerCommonRepositories.js +0 -23
  36. package/src/server/common/registerSharedApi.js +0 -9
  37. package/src/server/profileSyncLifecycleContributorRegistry.js +0 -56
  38. package/src/server/registerUsersBootstrap.js +0 -20
  39. package/src/server/registerUsersCore.js +0 -22
  40. package/templates/packages/users/package.json +0 -82
  41. package/templates/packages/users/src/server/UsersProvider.js +0 -90
  42. package/templates/packages/users/src/server/actions.js +0 -68
  43. package/templates/packages/users/src/server/registerRoutes.js +0 -101
  44. package/templates/packages/users/src/server/repository.js +0 -51
  45. package/templates/packages/users/src/server/service.js +0 -32
  46. package/templates/packages/users-workspace/package.json +0 -83
  47. package/templates/packages/users-workspace/src/server/UsersProvider.js +0 -91
  48. package/templates/packages/users-workspace/src/server/actions.js +0 -77
  49. package/templates/packages/users-workspace/src/server/registerRoutes.js +0 -111
  50. package/test/providerLifecycle.test.js +0 -63
  51. package/test/registerCommonRepositories.test.js +0 -57
  52. package/test/registerServiceRealtimeEvents.test.js +0 -57
  53. package/test/registerUsersCore.test.js +0 -53
  54. /package/{templates/migrations → migrations}/users_core_generic_initial.cjs +0 -0
  55. /package/{templates/migrations → migrations}/users_core_profile_updated_at.cjs +0 -0
  56. /package/{templates/migrations → migrations}/users_core_profile_username.cjs +0 -0
  57. /package/{templates → patterns/user-administration-server/example}/packages/users/src/shared/userResource.js +0 -0
  58. /package/{templates/packages/users → patterns/user-administration-server/example/packages/users-workspace}/src/shared/index.js +0 -0
package/package.json CHANGED
@@ -1,25 +1,27 @@
1
1
  {
2
2
  "name": "@jskit-ai/users-core",
3
- "version": "0.1.172",
3
+ "version": "0.1.174",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
7
7
  },
8
8
  "exports": {
9
- "./server/profileSyncLifecycleContributorRegistry": "./src/server/profileSyncLifecycleContributorRegistry.js",
9
+ "./server/UsersFeature": "./src/server/UsersFeature.js",
10
+ "./server/UsersIdentityProvider": "./src/server/UsersIdentityProvider.js",
11
+ "./server/usersExtensions": "./src/server/usersExtensions.js",
10
12
  "./shared/resources/userProfileResource": "./src/shared/resources/userProfileResource.js",
11
13
  "./shared/resources/userSettingsResource": "./src/shared/resources/userSettingsResource.js"
12
14
  },
13
15
  "dependencies": {
14
- "@jskit-ai/auth-core": "0.1.157",
15
- "@jskit-ai/database-runtime": "0.1.159",
16
- "@jskit-ai/http-runtime": "0.1.157",
17
- "@jskit-ai/json-rest-api-core": "0.1.103",
18
- "@jskit-ai/kernel": "0.1.159",
19
- "@jskit-ai/resource-core": "0.1.101",
20
- "@jskit-ai/resource-crud-core": "0.1.101",
21
- "@jskit-ai/storage-runtime": "0.1.156",
22
- "@jskit-ai/uploads-runtime": "0.1.134",
16
+ "@jskit-ai/auth-core": "0.1.159",
17
+ "@jskit-ai/database-runtime": "0.1.161",
18
+ "@jskit-ai/http-runtime": "0.1.159",
19
+ "@jskit-ai/json-rest-api-core": "0.1.105",
20
+ "@jskit-ai/kernel": "0.1.161",
21
+ "@jskit-ai/resource-core": "0.1.103",
22
+ "@jskit-ai/resource-crud-core": "0.1.103",
23
+ "@jskit-ai/storage-runtime": "0.1.158",
24
+ "@jskit-ai/uploads-runtime": "0.1.136",
23
25
  "json-rest-schema": "^1.0.17"
24
26
  },
25
27
  "description": "Users/account runtime plus HTTP routes for account features.",
@@ -28,24 +30,35 @@
28
30
  "capabilities": {
29
31
  "provides": [
30
32
  "users.core",
31
- "users.server-routes"
33
+ "users.identity",
34
+ "users.extensions"
32
35
  ],
33
36
  "requires": [
37
+ "auth.extensions",
38
+ "auth.service",
34
39
  "runtime.actions",
40
+ "runtime.bootstrap",
35
41
  "runtime.database",
36
- "json-rest-api.core",
42
+ "runtime.http",
43
+ "runtime.json-rest-api",
37
44
  "runtime.storage",
38
- "runtime.uploads",
39
- "auth.provider",
40
- "auth.policy"
45
+ "runtime.uploads"
41
46
  ]
42
47
  },
43
48
  "runtime": {
44
49
  "server": {
45
50
  "providers": [
46
51
  {
47
- "entrypoint": "src/server/UsersCoreServiceProvider.js",
48
- "export": "UsersCoreServiceProvider"
52
+ "entrypoint": "src/server/UsersExtensionsProvider.js",
53
+ "export": "UsersExtensionsProvider"
54
+ },
55
+ {
56
+ "entrypoint": "src/server/UsersIdentityProvider.js",
57
+ "export": "UsersIdentityProvider"
58
+ },
59
+ {
60
+ "entrypoint": "src/server/UsersFeature.js",
61
+ "export": "UsersFeature"
49
62
  }
50
63
  ]
51
64
  },
@@ -58,9 +71,7 @@
58
71
  "tableOwnership": {
59
72
  "tables": [
60
73
  {
61
- "tableName": "user_settings",
62
- "provenance": "runtime-package",
63
- "ownerKind": "package-runtime"
74
+ "tableName": "user_settings"
64
75
  }
65
76
  ]
66
77
  }
@@ -69,7 +80,7 @@
69
80
  "surfaces": [
70
81
  {
71
82
  "subpath": "./server",
72
- "summary": "Exports UsersCoreServiceProvider plus account feature route registration modules and action definitions."
83
+ "summary": "Exports the explicit users feature, account services, repositories, actions, and extension API."
73
84
  },
74
85
  {
75
86
  "subpath": "./shared",
@@ -80,13 +91,11 @@
80
91
  "summary": "Exports no runtime API today (reserved client entrypoint)."
81
92
  }
82
93
  ],
83
- "containerTokens": {
84
- "server": [
85
- "users.profile.sync.service",
86
- "auth.profile.projector"
87
- ],
88
- "client": []
89
- }
94
+ "capabilities": [
95
+ "users.core",
96
+ "users.identity",
97
+ "users.extensions"
98
+ ]
90
99
  },
91
100
  "server": {
92
101
  "routes": [
@@ -153,230 +162,9 @@
153
162
  ]
154
163
  }
155
164
  },
156
- "mutations": {
157
- "dependencies": {
158
- "runtime": {
159
- "@jskit-ai/auth-core": "0.1.157",
160
- "@jskit-ai/crud-core": "0.1.170",
161
- "@jskit-ai/database-runtime": "0.1.159",
162
- "@jskit-ai/http-runtime": "0.1.157",
163
- "@jskit-ai/json-rest-api-core": "0.1.103",
164
- "@jskit-ai/kernel": "0.1.159",
165
- "@jskit-ai/resource-core": "0.1.101",
166
- "@jskit-ai/resource-crud-core": "0.1.101",
167
- "@local/users": "file:packages/users",
168
- "@jskit-ai/uploads-runtime": "0.1.134"
169
- },
170
- "dev": {}
171
- },
172
- "packageJson": {
173
- "scripts": {}
174
- },
175
- "procfile": {},
176
- "files": [
177
- {
178
- "op": "install-migration",
179
- "from": "templates/migrations/users_core_generic_initial.cjs",
180
- "toDir": "migrations",
181
- "extension": ".cjs",
182
- "reason": "Install users/account core schema migration.",
183
- "category": "migration",
184
- "id": "users-core-generic-initial-schema"
185
- },
186
- {
187
- "op": "install-migration",
188
- "from": "templates/migrations/users_core_profile_username.cjs",
189
- "toDir": "migrations",
190
- "extension": ".cjs",
191
- "reason": "Install users profile username migration.",
192
- "category": "migration",
193
- "id": "users-core-profile-username-schema"
194
- },
195
- {
196
- "op": "install-migration",
197
- "from": "templates/migrations/users_core_profile_updated_at.cjs",
198
- "toDir": "migrations",
199
- "extension": ".cjs",
200
- "reason": "Install users profile updated-at migration.",
201
- "category": "migration",
202
- "id": "users-core-profile-updated-at-schema"
203
- },
204
- {
205
- "from": "templates/packages/users/package.json",
206
- "to": "packages/users/package.json",
207
- "ownership": "app",
208
- "preserveOnRemove": true,
209
- "reason": "Install app-owned users package manifest for non-workspace tenancy.",
210
- "category": "users-core",
211
- "id": "users-core-users-package-json-base",
212
- "when": {
213
- "config": "tenancyMode",
214
- "notIn": [
215
- "personal",
216
- "workspaces"
217
- ]
218
- }
219
- },
220
- {
221
- "from": "templates/packages/users-workspace/package.json",
222
- "to": "packages/users/package.json",
223
- "ownership": "app",
224
- "preserveOnRemove": true,
225
- "reason": "Install app-owned users package manifest for workspace tenancy.",
226
- "category": "users-core",
227
- "id": "users-core-users-package-json-workspace",
228
- "when": {
229
- "config": "tenancyMode",
230
- "in": [
231
- "personal",
232
- "workspaces"
233
- ]
234
- }
235
- },
236
- {
237
- "from": "templates/packages/users/src/server/UsersProvider.js",
238
- "to": "packages/users/src/server/UsersProvider.js",
239
- "ownership": "app",
240
- "preserveOnRemove": true,
241
- "reason": "Install app-owned users CRUD provider for non-workspace tenancy.",
242
- "category": "users-core",
243
- "id": "users-core-users-provider-base",
244
- "when": {
245
- "config": "tenancyMode",
246
- "notIn": [
247
- "personal",
248
- "workspaces"
249
- ]
250
- }
251
- },
252
- {
253
- "from": "templates/packages/users-workspace/src/server/UsersProvider.js",
254
- "to": "packages/users/src/server/UsersProvider.js",
255
- "ownership": "app",
256
- "preserveOnRemove": true,
257
- "reason": "Install app-owned users CRUD provider for workspace tenancy.",
258
- "category": "users-core",
259
- "id": "users-core-users-provider-workspace",
260
- "when": {
261
- "config": "tenancyMode",
262
- "in": [
263
- "personal",
264
- "workspaces"
265
- ]
266
- }
267
- },
268
- {
269
- "from": "templates/packages/users/src/server/actions.js",
270
- "to": "packages/users/src/server/actions.js",
271
- "ownership": "app",
272
- "preserveOnRemove": true,
273
- "reason": "Install app-owned users CRUD actions for non-workspace tenancy.",
274
- "category": "users-core",
275
- "id": "users-core-users-actions-base",
276
- "when": {
277
- "config": "tenancyMode",
278
- "notIn": [
279
- "personal",
280
- "workspaces"
281
- ]
282
- }
283
- },
284
- {
285
- "from": "templates/packages/users-workspace/src/server/actions.js",
286
- "to": "packages/users/src/server/actions.js",
287
- "ownership": "app",
288
- "preserveOnRemove": true,
289
- "reason": "Install app-owned users CRUD actions for workspace tenancy.",
290
- "category": "users-core",
291
- "id": "users-core-users-actions-workspace",
292
- "when": {
293
- "config": "tenancyMode",
294
- "in": [
295
- "personal",
296
- "workspaces"
297
- ]
298
- }
299
- },
300
- {
301
- "from": "templates/packages/users/src/server/registerRoutes.js",
302
- "to": "packages/users/src/server/registerRoutes.js",
303
- "ownership": "app",
304
- "preserveOnRemove": true,
305
- "reason": "Install app-owned users CRUD routes for non-workspace tenancy.",
306
- "category": "users-core",
307
- "id": "users-core-users-routes-base",
308
- "when": {
309
- "config": "tenancyMode",
310
- "notIn": [
311
- "personal",
312
- "workspaces"
313
- ]
314
- }
315
- },
316
- {
317
- "from": "templates/packages/users-workspace/src/server/registerRoutes.js",
318
- "to": "packages/users/src/server/registerRoutes.js",
319
- "ownership": "app",
320
- "preserveOnRemove": true,
321
- "reason": "Install app-owned users CRUD routes for workspace tenancy.",
322
- "category": "users-core",
323
- "id": "users-core-users-routes-workspace",
324
- "when": {
325
- "config": "tenancyMode",
326
- "in": [
327
- "personal",
328
- "workspaces"
329
- ]
330
- }
331
- },
332
- {
333
- "from": "templates/packages/users/src/server/repository.js",
334
- "to": "packages/users/src/server/repository.js",
335
- "ownership": "app",
336
- "preserveOnRemove": true,
337
- "reason": "Install app-owned users CRUD repository.",
338
- "category": "users-core",
339
- "id": "users-core-users-repository"
340
- },
341
- {
342
- "from": "templates/packages/users/src/server/service.js",
343
- "to": "packages/users/src/server/service.js",
344
- "ownership": "app",
345
- "preserveOnRemove": true,
346
- "reason": "Install app-owned users CRUD service.",
347
- "category": "users-core",
348
- "id": "users-core-users-service"
349
- },
350
- {
351
- "from": "templates/packages/users/src/shared/index.js",
352
- "to": "packages/users/src/shared/index.js",
353
- "ownership": "app",
354
- "preserveOnRemove": true,
355
- "reason": "Install app-owned users shared entrypoint.",
356
- "category": "users-core",
357
- "id": "users-core-users-shared-index"
358
- },
359
- {
360
- "from": "templates/packages/users/src/shared/userResource.js",
361
- "to": "packages/users/src/shared/userResource.js",
362
- "ownership": "app",
363
- "preserveOnRemove": true,
364
- "reason": "Install app-owned users shared resource.",
365
- "category": "users-core",
366
- "id": "users-core-users-resource"
367
- }
368
- ],
369
- "text": [
370
- {
371
- "op": "append-text",
372
- "file": "config/server.js",
373
- "position": "bottom",
374
- "skipIfContains": "config.auth.profileMode = \"users\";",
375
- "value": "\nconfig.auth ||= {};\nconfig.auth.profileMode = \"users\";\n",
376
- "reason": "Enable users-backed auth profile sync when users-core is installed.",
377
- "category": "runtime-config",
378
- "id": "users-core-auth-profile-mode"
379
- }
165
+ "migrations": {
166
+ "directories": [
167
+ "migrations"
380
168
  ]
381
169
  }
382
170
  }
@@ -0,0 +1,64 @@
1
+ ---
2
+ id: users/user-administration-server
3
+ title: User administration server package
4
+ summary: Expose user administration and workspace-scoped member operations through app-owned packages backed by JSKIT users runtime APIs.
5
+ keywords: account, admin, member, repository, resource, routes, service, user, workspace
6
+ requires: @jskit-ai/users-core, @jskit-ai/crud-core
7
+ ---
8
+
9
+ # User administration server package
10
+
11
+ ## Use when
12
+
13
+ Use this pattern when an application needs app-specific administration of user
14
+ profiles or workspace members beyond the built-in account runtime.
15
+
16
+ ## Do not use when
17
+
18
+ Do not use this pattern for self-service account settings, authentication
19
+ credentials, or an application that needs no administrative user listing.
20
+
21
+ ## Product decisions
22
+
23
+ Choose global versus workspace scope, visible and editable fields, permission
24
+ policy, route surface, filters, and whether account deletion is part of the
25
+ product. Do not expose password/session data through the resource.
26
+
27
+ ## Framework APIs
28
+
29
+ Use `@jskit-ai/users-core` for profile persistence and policies,
30
+ `defineCrudJsonApiFeature()` from `@jskit-ai/crud-core` for standard mechanics,
31
+ and the resource contracts from `@jskit-ai/resource-crud-core`.
32
+
33
+ ## Invariants
34
+
35
+ - The public user id is the resource identity.
36
+ - Workspace operations are scoped before repository access.
37
+ - Permission checks happen before records or record existence are disclosed.
38
+ - Shared profile persistence remains owned by `@jskit-ai/users-core`.
39
+ - The resource is the field contract; the feature projects its repository,
40
+ service, actions, and routes without app-local ceremony.
41
+
42
+ ## Example files
43
+
44
+ `example/packages/users/` is a global administration package.
45
+ `example/packages/users-workspace/` demonstrates the workspace route/action
46
+ boundary while reusing the same service contract. Copy only the composition
47
+ that matches the product and adapt it as ordinary application source.
48
+
49
+ ## Variation points
50
+
51
+ Change scope, route surface, visible fields, filters, sorting, permission
52
+ policy, and user-facing language. Retain the core user identity contract.
53
+
54
+ ## Verification
55
+
56
+ Test authorized and forbidden list/view/update operations, cross-workspace
57
+ isolation, missing records, null/cleared fields, filtering, and pagination.
58
+
59
+ ## Avoid
60
+
61
+ - copying authentication credential tables into the user resource
62
+ - trusting route scope without repository scope
63
+ - adding app-local mechanics already provided by `defineCrudJsonApiFeature()`
64
+ - generator metadata or field questionnaires
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@app/users",
3
+ "version": "0.0.0",
4
+ "description": "App-local read-only user administration feature.",
5
+ "private": true,
6
+ "type": "module",
7
+ "exports": {
8
+ "./server/UsersFeature": "./src/server/UsersFeature.js",
9
+ "./shared": "./src/shared/index.js"
10
+ },
11
+ "dependencies": {
12
+ "@jskit-ai/crud-core": "0.1.172",
13
+ "@jskit-ai/resource-crud-core": "0.1.103"
14
+ },
15
+ "jskit": {
16
+ "kind": "runtime",
17
+ "capabilities": {
18
+ "provides": [
19
+ "app.users"
20
+ ],
21
+ "requires": [
22
+ "runtime.http",
23
+ "runtime.json-rest-api",
24
+ "runtime.actions",
25
+ "runtime.database"
26
+ ]
27
+ },
28
+ "runtime": {
29
+ "server": {
30
+ "providers": [
31
+ {
32
+ "entrypoint": "src/server/UsersFeature.js",
33
+ "export": "UsersFeature"
34
+ }
35
+ ]
36
+ },
37
+ "client": {
38
+ "providers": []
39
+ }
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,13 @@
1
+ import { defineCrudJsonApiFeature } from "@jskit-ai/crud-core/server/defineCrudJsonApiFeature";
2
+ import { resource } from "../shared/userResource.js";
3
+
4
+ const UsersFeature = defineCrudJsonApiFeature({
5
+ resource,
6
+ id: "app.users",
7
+ capability: "app.users",
8
+ surface: "home",
9
+ ownershipFilter: "public",
10
+ relativePath: "/users"
11
+ });
12
+
13
+ export { UsersFeature };
@@ -0,0 +1 @@
1
+ export { resource } from "./userResource.js";
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@app/users-workspace",
3
+ "version": "0.0.0",
4
+ "description": "App-local workspace-scoped read-only user administration feature.",
5
+ "private": true,
6
+ "type": "module",
7
+ "exports": {
8
+ "./server/UsersWorkspaceFeature": "./src/server/UsersWorkspaceFeature.js",
9
+ "./shared": "./src/shared/index.js"
10
+ },
11
+ "dependencies": {
12
+ "@jskit-ai/crud-core": "0.1.172",
13
+ "@jskit-ai/resource-crud-core": "0.1.103",
14
+ "@jskit-ai/workspaces-core": "0.1.139"
15
+ },
16
+ "jskit": {
17
+ "kind": "runtime",
18
+ "capabilities": {
19
+ "provides": [
20
+ "app.users-workspace"
21
+ ],
22
+ "requires": [
23
+ "runtime.http",
24
+ "runtime.json-rest-api",
25
+ "runtime.actions",
26
+ "runtime.database"
27
+ ]
28
+ },
29
+ "runtime": {
30
+ "server": {
31
+ "providers": [
32
+ {
33
+ "entrypoint": "src/server/UsersWorkspaceFeature.js",
34
+ "export": "UsersWorkspaceFeature"
35
+ }
36
+ ]
37
+ },
38
+ "client": {
39
+ "providers": []
40
+ }
41
+ }
42
+ }
43
+ }
@@ -0,0 +1,22 @@
1
+ import { defineCrudJsonApiFeature } from "@jskit-ai/crud-core/server/defineCrudJsonApiFeature";
2
+ import { buildWorkspaceInputFromRouteParams } from "@jskit-ai/workspaces-core/server/support/workspaceRouteInput";
3
+ import { workspaceSlugParamsValidator } from "@jskit-ai/workspaces-core/server/validators/routeParamsValidator";
4
+ import { resource } from "../shared/userResource.js";
5
+
6
+ const UsersWorkspaceFeature = defineCrudJsonApiFeature({
7
+ resource,
8
+ id: "app.users-workspace",
9
+ capability: "app.users-workspace",
10
+ surface: "admin",
11
+ ownershipFilter: "workspace",
12
+ relativePath: "/users",
13
+ scope: {
14
+ routeBase: "/w/:workspaceSlug",
15
+ actionInputValidator: workspaceSlugParamsValidator,
16
+ routeParamsValidator: workspaceSlugParamsValidator,
17
+ inputKeys: ["workspaceSlug"],
18
+ input: (request) => buildWorkspaceInputFromRouteParams(request.input.params)
19
+ }
20
+ });
21
+
22
+ export { UsersWorkspaceFeature };
@@ -0,0 +1,56 @@
1
+ import { defineCrudResource } from "@jskit-ai/resource-crud-core/shared/crudResource";
2
+
3
+ const resource = defineCrudResource({
4
+ namespace: "users",
5
+ tableName: "users",
6
+ crudOperations: ["list", "view"],
7
+ schema: {
8
+ name: {
9
+ type: "string",
10
+ required: true,
11
+ minLength: 1,
12
+ maxLength: 160,
13
+ actualField: "display_name",
14
+ search: true,
15
+ operations: { output: { required: false } }
16
+ },
17
+ email: {
18
+ type: "string",
19
+ required: true,
20
+ search: true,
21
+ operations: { output: { required: false } }
22
+ },
23
+ username: {
24
+ type: "string",
25
+ required: true,
26
+ search: true,
27
+ operations: { output: { required: false } }
28
+ },
29
+ createdAt: {
30
+ type: "dateTime",
31
+ required: true,
32
+ storage: { writeSerializer: "datetime-utc" },
33
+ operations: { output: { required: true } }
34
+ },
35
+ updatedAt: {
36
+ type: "dateTime",
37
+ required: true,
38
+ storage: { writeSerializer: "datetime-utc" },
39
+ operations: { output: { required: true } }
40
+ }
41
+ },
42
+ searchSchema: {
43
+ id: { type: "id", actualField: "id" },
44
+ q: {
45
+ type: "string",
46
+ oneOf: ["name", "email", "username"],
47
+ filterOperator: "like",
48
+ splitBy: " ",
49
+ matchAll: true
50
+ }
51
+ },
52
+ defaultSort: ["name", "email"],
53
+ autofilter: "public"
54
+ });
55
+
56
+ export { resource };
@@ -0,0 +1,14 @@
1
+ import { defineProvider } from "@jskit-ai/kernel/shared/capabilities";
2
+ import { createUsersExtensions } from "./usersExtensions.js";
3
+
4
+ const UsersExtensionsProvider = defineProvider({
5
+ id: "users.extensions",
6
+ provides: {
7
+ extensions: "users.extensions"
8
+ },
9
+ setup() {
10
+ return { extensions: createUsersExtensions() };
11
+ }
12
+ });
13
+
14
+ export { UsersExtensionsProvider };