@jskit-ai/agent-docs 0.1.14 → 0.1.16

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.
@@ -181,6 +181,16 @@ In JSKIT's file-based routing, a page file can act as a layout if it renders a `
181
181
  - `src/pages/home/settings/general/index.vue` is the first real child page created by the starter shell.
182
182
  - `src/pages/home/settings/profile/index.vue` becomes `/home/settings/profile` and still renders inside the layout from `settings.vue`.
183
183
 
184
+ JSKIT uses a small helper for that redirect instead of hand-building the child path:
185
+
186
+ ```js
187
+ import { redirectToChild } from "@jskit-ai/kernel/client/pageRedirects";
188
+
189
+ definePage({
190
+ redirect: redirectToChild("general")
191
+ });
192
+ ```
193
+
184
194
  This is why the `home-settings:primary-menu` outlet from `list-placements` is such a useful clue: it tells you which page is acting as the host.
185
195
 
186
196
  Even an `index.vue` page can have children. If you want an index page to stay visible while child routes render underneath it, put those children under an `index/` directory such as `src/pages/home/settings/profile/index/details.vue`.
@@ -623,6 +633,16 @@ The starter shell now uses a real child-page structure right away:
623
633
  - `src/pages/home/settings/general/index.vue` is the first real settings page
624
634
  - `src/placement.js` already seeds a `General` link into `home-settings:primary-menu`
625
635
 
636
+ When you need that landing redirect yourself, use the same helper pattern:
637
+
638
+ ```js
639
+ import { redirectToChild } from "@jskit-ai/kernel/client/pageRedirects";
640
+
641
+ definePage({
642
+ redirect: redirectToChild("general")
643
+ });
644
+ ```
645
+
626
646
  That is what makes the page-generation examples in this chapter important. They are not inventing a new pattern. They are extending the exact same host-and-child-page structure that `shell-web` already uses for its own starter `General` page.
627
647
 
628
648
  ### What did not change
@@ -535,7 +535,7 @@ addPlacement({
535
535
 
536
536
  addPlacement({
537
537
  id: "workspaces.workspace.menu.workspace-settings",
538
- target: "workspace-tools:primary-menu",
538
+ target: "admin-cog:primary-menu",
539
539
  surfaces: ["admin"],
540
540
  order: 100,
541
541
  componentToken: "workspaces.web.workspace-settings.menu-item"
@@ -543,7 +543,7 @@ addPlacement({
543
543
 
544
544
  addPlacement({
545
545
  id: "workspaces.workspace.menu.members",
546
- target: "workspace-tools:primary-menu",
546
+ target: "admin-cog:primary-menu",
547
547
  surfaces: ["admin"],
548
548
  order: 200,
549
549
  componentToken: "workspaces.web.workspace-members.menu-item"
@@ -847,6 +847,8 @@ In JSKIT CRUD:
847
847
  Use these rules:
848
848
 
849
849
  - for explicit DB column overrides, use `repository.column`
850
+ - standard writable `date-time` fields are serialized automatically during CRUD writes
851
+ - use `repository.writeSerializer` only for non-default DB write serialization
850
852
  - for computed output fields, use `repository.storage: "virtual"`
851
853
  - do not put computed fields in create/patch write schemas
852
854
 
@@ -892,6 +894,8 @@ Once registered there:
892
894
  - generic CRUD `listByIds`
893
895
  - generic CRUD `listByForeignIds`
894
896
 
897
+ and generic CRUD writes automatically serialize standard writable `date-time` fields during create/update payload mapping, so normal datetime DB formatting does not need per-field metadata or repository-specific `preparePayload` hooks. Keep `repository.writeSerializer` for non-default cases only.
898
+
895
899
  all pick up the projection automatically, so you should not hand-patch `clearSelect()` / re-select logic into each method.
896
900
 
897
901
  Important limits:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/agent-docs",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "description": "Distributed JSKIT agent workflows, guides, and generated reference maps.",
5
5
  "type": "module",
6
6
  "files": [
package/patterns/INDEX.md CHANGED
@@ -18,6 +18,8 @@ How to use it:
18
18
  - `child-cruds.md`
19
19
  - CRUD links, record placeholders, `paths.page()`, `resolveViewUrl`, `resolveEditUrl`, `resolveParams`
20
20
  - `crud-links.md`
21
+ - `definePage`, redirect, child redirect, settings landing, `redirectToChild`
22
+ - `page-redirects.md`
21
23
  - live actions, checkbox, toggle, patch button, inline action, `useCommand()`
22
24
  - `live-actions.md`
23
25
  - ajax, fetch, API call, request, endpoint, HTTP client, `useList()`, `useView()`, `useAddEdit()`, `useEndpointResource()`, `usersWebHttpClient`
@@ -26,7 +28,7 @@ How to use it:
26
28
  - `ui-testing.md`
27
29
  - filter, filters, search facets, chips, date range, enum filter, lookup filter, `useCrudListFilters`, `createCrudListFilters`
28
30
  - `filters.md`
29
- - fieldMeta, `repository.column`, computed field, virtual field, projection, `createCrudResourceRuntime`, `remainingBatchWeight`
31
+ - fieldMeta, `repository.column`, `repository.writeSerializer`, computed field, virtual field, projection, `createCrudResourceRuntime`, `remainingBatchWeight`, datetime write serialization
30
32
  - `crud-repository-mapping.md`
31
33
 
32
34
  ## Current Patterns
@@ -35,6 +37,7 @@ How to use it:
35
37
  - [surfaces.md](./surfaces.md)
36
38
  - [child-cruds.md](./child-cruds.md)
37
39
  - [crud-links.md](./crud-links.md)
40
+ - [page-redirects.md](./page-redirects.md)
38
41
  - [live-actions.md](./live-actions.md)
39
42
  - [client-requests.md](./client-requests.md)
40
43
  - [ui-testing.md](./ui-testing.md)
@@ -9,9 +9,11 @@ Default JSKIT pattern:
9
9
  1. Treat the schema as the API contract only.
10
10
  2. Put persistence mapping in `resource.fieldMeta`.
11
11
  3. Use `repository.column` for explicit DB column overrides.
12
- 4. Use `repository.storage: "virtual"` for computed output fields.
13
- 5. Register computed SQL projections once in the repository runtime with `virtualFields`.
14
- 6. Let generic CRUD read paths apply those projections automatically.
12
+ 4. Let generic CRUD runtime handle standard writable `date-time` fields automatically at the DB write seam.
13
+ 5. Use `repository.writeSerializer` only for non-default write serialization.
14
+ 6. Use `repository.storage: "virtual"` for computed output fields.
15
+ 7. Register computed SQL projections once in the repository runtime with `virtualFields`.
16
+ 8. Let generic CRUD read paths apply those projections automatically.
15
17
 
16
18
  Field meta rules:
17
19
  - for a normal override, write:
@@ -36,14 +38,29 @@ RESOURCE_FIELD_META.push({
36
38
  });
37
39
  ```
38
40
 
41
+ - for a non-default write serializer override, write:
42
+
43
+ ```js
44
+ RESOURCE_FIELD_META.push({
45
+ key: "arrivalDatetime",
46
+ repository: {
47
+ writeSerializer: "datetime-utc"
48
+ }
49
+ });
50
+ ```
51
+
39
52
  - omit `repository` entirely when the field is column-backed and the default snake_case mapping is correct
53
+ - standard writable `format: "date-time"` fields do not need explicit `repository.writeSerializer`
54
+ - use `repository.writeSerializer` only for non-default DB write behavior; keep `bodyValidator.normalize(...)` in API shape
40
55
  - `repository.storage: "virtual"` cannot also define `repository.column`
56
+ - `repository.storage: "virtual"` cannot also define `repository.writeSerializer`
41
57
  - `repository.storage: "virtual"` fields must not appear in create/patch write schemas
42
58
 
43
59
  Repository pattern:
44
60
  - build the runtime with `createCrudResourceRuntime(resource, { ... })`
45
61
  - register computed projections in `virtualFields`
46
62
  - keep SQL in the repository, not in shared metadata
63
+ - let generic CRUD runtime apply `repository.writeSerializer` during create/update writes
47
64
 
48
65
  Example:
49
66
 
@@ -64,6 +81,8 @@ const repositoryRuntime = createCrudResourceRuntime(resource, {
64
81
 
65
82
  What CRUD core now does for you:
66
83
  - default select columns include only column-backed output fields
84
+ - create/update write payloads serialize standard writable `date-time` fields centrally
85
+ - create/update write payloads also apply any explicit field write serializers centrally
67
86
  - `list`, `findById`, `listByIds`, and `listByForeignIds` apply registered virtual projections automatically
68
87
  - search and parent-filter fallback derivation only use column-backed fields
69
88
  - `listByIds(..., { valueKey })` requires that `valueKey` be column-backed
@@ -76,6 +95,8 @@ Avoid:
76
95
  Review checks:
77
96
  - schema defines contract, not storage
78
97
  - `fieldMeta.repository` owns mapping
98
+ - standard datetime DB write serialization stays automatic and runtime-owned
99
+ - any non-default DB write serialization lives in `repository.writeSerializer`, not in per-repository hooks
79
100
  - computed fields use `repository.storage: "virtual"`
80
101
  - repository runtime registers matching `virtualFields`
81
102
  - no per-method projection duplication when generic CRUD reads already cover the field
@@ -0,0 +1,41 @@
1
+ # Page Redirect Patterns
2
+
3
+ Use when:
4
+
5
+ - redirecting a page index route to a child page
6
+ - writing `definePage({ redirect: ... })`
7
+ - seeding settings landing pages such as `/home/settings`
8
+ - wiring a section shell that should land on a real child page first
9
+
10
+ Check first:
11
+
12
+ - whether the page is only a landing route for child pages
13
+ - whether the destination child route is explicit and stable
14
+ - whether the redirect should preserve incoming query and hash
15
+
16
+ Rules:
17
+
18
+ - For “index page lands on child page” redirects, use `redirectToChild()` from `@jskit-ai/kernel/client/pageRedirects`.
19
+ - Do not hand-build child redirects with string surgery such as `` `${String(to.path || "").replace(/\\/$/, "")}/general` ``.
20
+ - Keep the destination explicit. Do not infer it from placements, menu order, or “first child page wins” behavior.
21
+ - If the redirect is just “go to this child page”, prefer:
22
+
23
+ ```js
24
+ import { redirectToChild } from "@jskit-ai/kernel/client/pageRedirects";
25
+
26
+ definePage({
27
+ redirect: redirectToChild("general")
28
+ });
29
+ ```
30
+
31
+ Why:
32
+
33
+ - the helper centralizes slash handling
34
+ - it preserves incoming query and hash unless the child target overrides them
35
+ - templates, guides, and apps all stay on one obvious pattern
36
+
37
+ Avoid:
38
+
39
+ - copying redirect lambdas between apps and templates
40
+ - building implicit redirect behavior from placements
41
+ - inventing page-local helper utilities for the same pattern
@@ -35,6 +35,24 @@ Exports
35
35
  Exports
36
36
  - `runAuthSignOutFlow`
37
37
 
38
+ ### `src/server/authPolicyContextResolverRegistry.js`
39
+ Exports
40
+ - `AUTH_POLICY_CONTEXT_RESOLVER_TAG`
41
+ - `registerAuthPolicyContextResolver(app, token, factory)`
42
+ - `resolveAuthPolicyContextResolvers(scope)`
43
+ - `mergeAuthPolicyContexts(contexts = [])`
44
+ - `composeAuthPolicyContextResolvers(resolvers = [])`
45
+ Local functions
46
+ - `normalizeAuthPolicyContextResolver(entry)`
47
+
48
+ ### `src/server/authServiceDecoratorRegistry.js`
49
+ Exports
50
+ - `AUTH_SERVICE_DECORATOR_TAG`
51
+ - `registerAuthServiceDecorator(app, token, factory)`
52
+ - `resolveAuthServiceDecorators(scope)`
53
+ Local functions
54
+ - `normalizeAuthServiceDecorator(entry)`
55
+
38
56
  ### `src/server/inviteTokens.js`
39
57
  Exports
40
58
  - `OPAQUE_INVITE_TOKEN_HASH_PREFIX`
@@ -110,13 +110,13 @@ Exports
110
110
 
111
111
  ### `src/server/lib/devAuthBootstrap.js`
112
112
  Exports
113
- - `assertDevAuthBootstrapConfig(config, { usersRepository = null } = {})`
114
- - `authenticateDevAuthRequest({ request, accessToken = "", refreshToken = "" }, { config, usersRepository = null } = {})`
113
+ - `assertDevAuthBootstrapConfig(config, { userProfilesRepository = null } = {})`
114
+ - `authenticateDevAuthRequest({ request, accessToken = "", refreshToken = "" }, { config, userProfilesRepository = null } = {})`
115
115
  - `createDevAuthSession(profile, config)`
116
116
  - `ensureDevAuthBootstrapAvailable(config, request)`
117
117
  - `isDevAuthToken(token)`
118
118
  - `resolveDevAuthConfig({ enabled = false, secret = "", nodeEnv = "development", jwtAudience = "authenticated", accessTtlSeconds = DEFAULT_DEV_AUTH_ACCESS_TTL_SECONDS, refreshTtlSeconds = DEFAULT_DEV_AUTH_REFRESH_TTL_SECONDS } = {})`
119
- - `resolveDevAuthProfile(input = {}, { usersRepository = null, validationError } = {})`
119
+ - `resolveDevAuthProfile(input = {}, { userProfilesRepository = null, validationError } = {})`
120
120
  Local functions
121
121
  - `parseBoolean(value, fallback = false)`
122
122
  - `normalizePositiveInteger(value, fallback)`
@@ -128,7 +128,7 @@ Local functions
128
128
  - `isLocalDevAuthRequest(request)`
129
129
  - `stripDevAuthTokenPrefix(token)`
130
130
  - `buildProfileFromTokenClaims(payload)`
131
- - `resolveProfileFromTokenClaims(payload, { usersRepository = null } = {})`
131
+ - `resolveProfileFromTokenClaims(payload, { userProfilesRepository = null } = {})`
132
132
  - `signDevAuthToken(kind, profile, config)`
133
133
  - `verifyDevAuthToken(token, kind, config)`
134
134
 
@@ -247,6 +247,7 @@ Local functions
247
247
  - `resolveCommonDependencies(scope)`
248
248
  - `resolveRuntimeEnv(scope)`
249
249
  - `resolveOptionalRepositories(scope)`
250
+ - `applyAuthServiceDecorators(scope, authService)`
250
251
 
251
252
  ### root
252
253
 
@@ -68,10 +68,6 @@ Exports
68
68
  - `createCrudClientSupport`
69
69
  - `useCrudRealtimeInvalidation`
70
70
 
71
- ### `src/server/createCrudRepositoryFromResource.js`
72
- Exports
73
- - `createCrudRepositoryFromResource(resource = {}, { context = "crudRepository", list = {}, virtualFields = {} } = {})`
74
-
75
71
  ### `src/server/createCrudServiceFromResource.js`
76
72
  Exports
77
73
  - `createCrudServiceFromResource(resource = {}, { context = "crudService" } = {})`
@@ -205,19 +201,35 @@ Exports
205
201
  Local functions
206
202
  - `normalizeLookupOwnershipFilter(value, { context = "crudLookup ownershipFilter" } = {})`
207
203
 
208
- ### `src/server/repositoryMethods.js`
204
+ ### `src/server/repositorySupport.js`
209
205
  Exports
210
- - `createCrudResourceRuntime(resource = {}, { context = "crudRepository", list = {}, virtualFields = {} } = {})`
211
- - `crudRepositoryList(runtime, knex, query = {}, repositoryOptions = {}, callOptions = {}, hooks = null)`
212
- - `crudRepositoryFindById(runtime, knex, recordId, repositoryOptions = {}, callOptions = {}, hooks = null)`
213
- - `crudRepositoryListByIds(runtime, knex, ids = [], repositoryOptions = {}, callOptions = {}, hooks = null)`
214
- - `crudRepositoryListByForeignIds(runtime, knex, ids = [], foreignKey = "", repositoryOptions = {}, callOptions = {}, hooks = null)`
215
- - `crudRepositoryCreate(runtime, knex, payload = {}, repositoryOptions = {}, callOptions = {}, hooks = null)`
216
- - `crudRepositoryUpdateById(runtime, knex, recordId, patch = {}, repositoryOptions = {}, callOptions = {}, hooks = null)`
217
- - `crudRepositoryDeleteById(runtime, knex, recordId, repositoryOptions = {}, callOptions = {}, hooks = null)`
206
+ - `DEFAULT_LIST_LIMIT`
207
+ - `MAX_LIST_LIMIT`
208
+ - `normalizeCrudListLimit(value, { fallback = DEFAULT_LIST_LIMIT, max = MAX_LIST_LIMIT } = {})`
209
+ - `normalizeCrudListCursor(cursor = null, { allowEmpty = true } = {})`
210
+ - `requireCrudTableName(tableName, { context = "crudRepository" } = {})`
211
+ - `deriveRepositoryMappingFromResource(resource = {}, { context = "crudRepository" } = {})`
212
+ - `applyCrudListQueryFilters(query, { idColumn = "id", cursor = "", applyCursor = true, q = "", searchColumns = [], parentFilters = {}, parentFilterColumns = {} } = {})`
213
+ - `mapRecordRow(row, fieldKeys = [], overrides = {}, { recordIdKeys = [] } = {})`
214
+ - `buildWritePayload(sourcePayload = {}, fieldKeys = [], overrides = {}, { serializerByKey = {} } = {})`
215
+ - `resolveColumnName(fieldKey, overrides = {})`
216
+ - `resolveCrudIdColumn(idColumn, { fallback = "id" } = {})`
217
+ - `buildRepositoryColumnMetadata({ outputKeys = [], writeKeys = [], columnOverrides = {}, fieldStorageByKey = {} } = {})`
218
+ Local functions
219
+ - `resolveOptionalObjectSchemaProperties(schema, options = {})`
220
+ - `requireObjectSchemaProperties(schema, { context = "crudRepository", schemaLabel = "schema" } = {})`
221
+ - `normalizeResourceFieldMetaEntries(fieldMeta = [])`
222
+ - `schemaIncludesStringType(schema = {})`
223
+ - `schemaIncludesDateTimeFormat(schema = {})`
224
+ - `schemaIncludesRecordIdType(schema = {})`
225
+
226
+ ### `src/server/resourceRuntime/index.js`
227
+ Exports
228
+ - `createCrudResourceRuntime(resource = {}, knex, repositoryOptions = {})`
218
229
  Local functions
219
230
  - `requireCrudRecordId(value, { context = "crudRepository" } = {})`
220
- - `resolveRepositoryDefaults(resource = {}, repositoryMapping = {})`
231
+ - `requireCrudRepositoryOptions(value = {}, { context = "crudRepository" } = {})`
232
+ - `resolveRepositoryDefaults(resource = {}, repositoryMapping = {}, { context = "crudRepository" } = {})`
221
233
  - `normalizeCrudVirtualFieldHandlers(virtualFields = {}, repositoryMapping = {}, { context = "crudRepository" } = {})`
222
234
  - `applyCrudRepositoryVirtualProjections(dbQuery, runtime = {}, { knex, tableName } = {})`
223
235
  - `normalizeSearchColumns(searchColumns = [], fallbackColumns = [])`
@@ -225,6 +237,12 @@ Local functions
225
237
  - `normalizeListOrderNulls(value = LIST_ORDER_NULLS_LAST)`
226
238
  - `normalizeListOrderBy(orderBy = [], { idColumn = "id" } = {})`
227
239
  - `resolveListRuntimeConfig(list = {}, fallbackSearchColumns = [], { idColumn = "id" } = {})`
240
+ - `formatOutputValidationError(issue = {})`
241
+ - `resolveRecordOutputValidator(resource = {}, { context = "crudRepository" } = {})`
242
+ - `resolveOperationBodyValidator(resource = {}, operationKey = "", { context = "crudRepository" } = {})`
243
+ - `extractExplicitFieldErrors(error)`
244
+ - `normalizeRepositoryInputPayload(runtime = {}, payload = {}, { operationKey = "create", phase = "crudCreate", action = "create", recordId = null, existingRecord = null, actionContextBase = {} } = {})`
245
+ - `normalizeRepositoryOutputRecord(runtime = {}, record = {}, { operation = "list" } = {})`
228
246
  - `encodeOrderedListCursorValue(value = null)`
229
247
  - `decodeOrderedListCursorValue(value = null)`
230
248
  - `encodeOrderedListCursor(row = null, orderBy = [])`
@@ -234,43 +252,51 @@ Local functions
234
252
  - `canApplyOrderedListCursorAfterBranch(descriptor = {}, value = null)`
235
253
  - `appendOrderedListCursorBranches(query, orderBy = [], cursorValues = [], index = 0, { useOr = false } = {})`
236
254
  - `applyOrderedListCursorFilter(query, { orderBy = [], cursor = "" } = {})`
237
- - `resolveRecordOutputValidator(resource = {}, { context = "crudRepository" } = {})`
238
- - `formatOutputValidationError(error = {})`
239
- - `normalizeRepositoryOutputRecord(runtime, record = {}, { operation = "read" } = {})`
240
- - `resolveCrudRepositoryCall(runtime, knex, repositoryOptions = {}, callOptions = {})`
241
- - `normalizeCrudRepositoryHooks(hooks = null, allowedHookKeys = [], { context = "crudRepository" } = {})`
242
- - `resolveOptionalCrudRepositoryHook(hooks = {}, hookKey = "", { context = "crudRepository" } = {})`
243
- - `applyCrudRepositoryQueryHook(dbQuery, hook = null, hookContext = {}, { context = "crudRepository", hookKey = "modifyQuery" } = {})`
255
+ - `normalizeCrudRepositoryOperationStage(stage = null, stageLabel = "", { context = "crudRepository" } = {})`
256
+ - `normalizeCrudRepositoryOperationConfig(config = {}, operationKey = "", { context = "crudRepository" } = {})`
257
+ - `normalizeCrudRepositoryOperations(sourceOperations = {}, { context = "crudRepository" } = {})`
258
+ - `applyConfiguredQueryStage(dbQuery, stage = null, stageContext = {}, { context = "crudRepository", stageKey = "applyQuery" } = {})`
259
+ - `isCrudRepositoryQueryBuilder(value)`
244
260
  - `normalizeCrudRepositoryObjectInput(value = {})`
245
- - `applyCrudRepositoryPayloadHook(payload = {}, hook = null, hookContext = {}, { context = "crudRepository", hookKey = "modifyPayload" } = {})`
246
- - `applyCrudRepositoryRecordsHook(items = [], hook = null, hookContext = {}, { context = "crudRepository", hookKey = "afterQuery" } = {})`
247
- - `applyCrudRepositoryRecordHook(record = null, hook = null, hookContext = {}, { context = "crudRepository", hookKey = "transformReturnedRecord" } = {})`
248
- - `applyCrudRepositoryOutputHook(output, hook = null, hookContext = {}, { context = "crudRepository", hookKey = "finalizeOutput", validateOutput = null } = {})`
249
- - `applyCrudRepositoryAfterWriteHook(meta = {}, hook = null, hookContext = {}, { context = "crudRepository", hookKey = "afterWrite" } = {})`
261
+ - `applyConfiguredObjectStage(payload = {}, stage = null, stageContext = {}, { context = "crudRepository", stageKey = "preparePayload" } = {})`
250
262
  - `applyOrderedListControls(dbQuery, orderBy = [])`
251
263
  - `enforceCrudRepositoryListControls(dbQuery, { idColumn = "id", limit = DEFAULT_LIST_LIMIT + 1, orderBy = [] } = {})`
252
- - `createCrudRepositoryHookContextBase(runtime, repositoryOptions = {}, callOptions = {})`
264
+ - `createCrudRepositoryActionContextBase(runtime, callOptions = {})`
265
+ - `createCompiledCrudRepositoryRuntime(resource = {}, repositoryOptions = {})`
266
+ - `resolveCrudRepositoryCall(runtime, knex, callOptions = {})`
267
+ - `applyCrudRepositoryReadLock(dbQuery, callOptions = {})`
268
+ - `listRecords(runtime, knex, query = {}, callOptions = {})`
269
+ - `findRecordById(runtime, knex, recordId, callOptions = {})`
270
+ - `listRecordsByIds(runtime, knex, ids = [], callOptions = {})`
271
+ - `createRecord(runtime, knex, payload = {}, callOptions = {})`
272
+ - `updateRecordById(runtime, knex, recordId, patch = {}, callOptions = {})`
273
+ - `deleteRecordById(runtime, knex, recordId, callOptions = {})`
253
274
 
254
- ### `src/server/repositorySupport.js`
275
+ ### `src/server/resourceRuntime/lookupHydration.js`
255
276
  Exports
256
- - `DEFAULT_LIST_LIMIT`
257
- - `MAX_LIST_LIMIT`
258
- - `normalizeCrudListLimit(value, { fallback = DEFAULT_LIST_LIMIT, max = MAX_LIST_LIMIT } = {})`
259
- - `normalizeCrudListCursor(cursor = null, { allowEmpty = true } = {})`
260
- - `requireCrudTableName(tableName, { context = "crudRepository" } = {})`
261
- - `deriveRepositoryMappingFromResource(resource = {}, { context = "crudRepository" } = {})`
262
- - `applyCrudListQueryFilters(query, { idColumn = "id", cursor = "", applyCursor = true, q = "", searchColumns = [], parentFilters = {}, parentFilterColumns = {} } = {})`
263
- - `mapRecordRow(row, fieldKeys = [], overrides = {}, { recordIdKeys = [] } = {})`
264
- - `buildWritePayload(sourcePayload = {}, fieldKeys = [], overrides = {})`
265
- - `resolveColumnName(fieldKey, overrides = {})`
266
- - `resolveCrudIdColumn(idColumn, { fallback = "id" } = {})`
267
- - `buildRepositoryColumnMetadata({ outputKeys = [], writeKeys = [], columnOverrides = {}, fieldStorageByKey = {} } = {})`
277
+ - `createCrudLookupRuntime(resource = {}, { outputKeys = [] } = {})`
278
+ - `hydrateCrudLookupRecords(records = [], runtime = {}, { include, mode = "list", repositoryOptions = {}, callOptions = {} } = {})`
268
279
  Local functions
269
- - `resolveOptionalObjectSchemaProperties(schema, options = {})`
270
- - `requireObjectSchemaProperties(schema, { context = "crudRepository", schemaLabel = "schema" } = {})`
271
- - `normalizeResourceFieldMetaEntries(fieldMeta = [])`
272
- - `schemaIncludesStringType(schema = {})`
273
- - `schemaIncludesRecordIdType(schema = {})`
280
+ - `normalizeLookupRelationEntry(entry = {}, outputKeys = new Set())`
281
+ - `normalizeLookupDefaultInclude(value)`
282
+ - `normalizeLookupMaxDepth(value)`
283
+ - `resolveLookupRuntimeDefaults(resource = {})`
284
+ - `normalizeLookupIdentifier(value)`
285
+ - `normalizeIncludePaths(include, { defaultInclude = DEFAULT_LOOKUP_INCLUDE } = {})`
286
+ - `resolveChildIncludeFromPaths(paths = [])`
287
+ - `shouldHydrateByMode(entry = {}, mode = "list")`
288
+ - `buildLookupHydrationPlan(runtime = {}, include, { mode = "list", context = "crudRepository", includeWasExplicit = false, skippedNamespaces = new Set() } = {})`
289
+ - `resolveLookupResolver(repositoryOptions = {}, callOptions = {}, { context = "crudRepository" } = {})`
290
+ - `resolveLookupDepthRuntime(runtime = {}, repositoryOptions = {}, callOptions = {})`
291
+ - `buildLookupGroupKey(relation = {})`
292
+ - `normalizeLookupRelationValues(records = [], entries = [], childIncludeByKey = {})`
293
+ - `resolveGroupChildInclude(group = {})`
294
+ - `normalizeLookup(provider, relation = {}, { context = "crudRepository" } = {})`
295
+ - `resolveLookupOwnershipFilter(provider = {}, { context = "crudRepository" } = {})`
296
+ - `resolveLookupVisibilityContext(provider = {}, relation = {}, callOptions = {}, { context = "crudRepository" } = {})`
297
+ - `buildLookupRecordMap(records = [], valueKey = "")`
298
+ - `buildLookupCollectionMap(records = [], foreignKey = "")`
299
+ - `resolveLookupVisitedNamespaces(runtime = {}, callOptions = {})`
274
300
 
275
301
  ### `src/server/serviceEvents.js`
276
302
  Exports
@@ -286,17 +312,20 @@ Exports
286
312
  - `crudServiceDeleteRecord(runtime, repository, fieldAccess = {}, recordId, options = {})`
287
313
  Local functions
288
314
  - `requireCrudServiceRepository(runtime = {}, repository = null)`
315
+ - `splitCrudListRepositoryCall(query = {}, options = {})`
289
316
 
290
317
  ### `src/shared/crudFieldMetaSupport.js`
291
318
  Exports
292
319
  - `CRUD_FIELD_REPOSITORY_STORAGE_COLUMN`
293
320
  - `CRUD_FIELD_REPOSITORY_STORAGE_VIRTUAL`
321
+ - `CRUD_FIELD_REPOSITORY_WRITE_SERIALIZER_DATETIME_UTC`
294
322
  - `CRUD_LOOKUP_FORM_CONTROL_AUTOCOMPLETE`
295
323
  - `CRUD_LOOKUP_FORM_CONTROL_SELECT`
296
324
  - `CRUD_RUNTIME_LOOKUPS_FIELD_KEY`
297
325
  - `checkCrudLookupFormControl(value, { context = "crud fieldMeta ui.formControl", defaultValue = CRUD_LOOKUP_FORM_CONTROL_AUTOCOMPLETE } = {})`
298
326
  - `isCrudRuntimeOutputOnlyFieldKey(value = "", { lookupContainerKey = CRUD_RUNTIME_LOOKUPS_FIELD_KEY } = {})`
299
327
  - `normalizeCrudFieldRepositoryConfig(fieldMetaEntry = {}, { context = "crud fieldMeta repository", fieldKey = "" } = {})`
328
+ - `normalizeCrudFieldRepositoryWriteSerializer(value, { context = "crud fieldMeta repository", fieldKey = "" } = {})`
300
329
 
301
330
  ### `src/shared/crudNamespaceSupport.js`
302
331
  Exports
@@ -45,11 +45,19 @@ Local functions
45
45
  - `resolveKnexFactory(moduleNamespace)`
46
46
  - `resolveMysqlSnapshotFromDatabase({ appRoot, tableName, idColumn } = {})`
47
47
  - `resolveColumnKey(column, idColumn)`
48
+ - `normalizeNumericBoundValue(value, scale = null)`
49
+ - `resolveNumericExclusiveStep(column)`
50
+ - `applyLowerBound(current = null, candidate = null)`
51
+ - `applyUpperBound(current = null, candidate = null)`
52
+ - `applyNumericConstraintBound(target = {}, column = null, operator = "", rawValue = null)`
53
+ - `resolveColumnNumericBounds(snapshot = {})`
48
54
  - `isIdentifier(value)`
49
55
  - `renderObjectPropertyKey(value)`
50
56
  - `renderIntegerSchema(column)`
51
57
  - `renderStringSchema(column, { forOutput = false } = {})`
52
- - `renderResourceValidatorsImport({ needsHtmlTimeSchemas = false, needsRecordIdSchemas = false } = {})`
58
+ - `renderResourceValidatorsImport({ htmlTimeSchemaImports = [], recordIdValidatorImports = [] } = {})`
59
+ - `resolveHtmlTimeSchemaImports(columns = [])`
60
+ - `resolveRecordIdValidatorImports(...sources)`
53
61
  - `renderResourceSchemaPropertyLines(columns, { forOutput = false } = {})`
54
62
  - `renderResourceInputNormalizationLines(columns)`
55
63
  - `renderResourceOutputNormalizationLines(columns)`
@@ -207,6 +215,39 @@ Exports
207
215
  Exports
208
216
  - None
209
217
 
218
+ ### .tmp-crud-server-template-fixture-FNbPfi
219
+
220
+ ### `.tmp-crud-server-template-fixture-FNbPfi/src/server/actionIds.js`
221
+ Exports
222
+ - `actionIds`
223
+
224
+ ### `.tmp-crud-server-template-fixture-FNbPfi/src/server/actions.js`
225
+ Exports
226
+ - `createActions({ surface = "" } = {})`
227
+ Local functions
228
+ - `requireActionSurface(surface = "")`
229
+
230
+ ### `.tmp-crud-server-template-fixture-FNbPfi/src/server/listConfig.js`
231
+ Exports
232
+ - `LIST_CONFIG`
233
+
234
+ ### `.tmp-crud-server-template-fixture-FNbPfi/src/server/registerRoutes.js`
235
+ Exports
236
+ - `registerRoutes(app, { routeOwnershipFilter = "public", routeSurface = "", routeRelativePath = "" } = {})`
237
+
238
+ ### `.tmp-crud-server-template-fixture-FNbPfi/src/server/repository.js`
239
+ Exports
240
+ - `createRepository(knex, options = {})`
241
+
242
+ ### `.tmp-crud-server-template-fixture-FNbPfi/src/server/service.js`
243
+ Exports
244
+ - `createService({ customersRepository, fieldAccess = DEFAULT_FIELD_ACCESS } = {})`
245
+ - `serviceEvents`
246
+
247
+ ### `.tmp-crud-server-template-fixture-FNbPfi/src/shared/customerResource.js`
248
+ Exports
249
+ - `resource`
250
+
210
251
  ### test-support
211
252
 
212
253
  ### `test-support/templateServerFixture.js`
@@ -32,6 +32,12 @@ Local functions
32
32
  - `parseDisplayFieldsOption(options)`
33
33
  - `validateDisplayFieldsForOperation(selectedFieldKeys, fields, operationName)`
34
34
  - `filterDisplayFields(selectedFieldKeys, fields)`
35
+ - `rewriteGeneratedBlockIndent(source = "", { trimPrefix = "", addPrefix = "" } = {})`
36
+ - `hasLookupFormFields(fields = [])`
37
+ - `buildLookupImportLine(fields = [])`
38
+ - `buildLookupRuntimeSetup(fields = [], { formFieldsVariable = "", resourceNamespace = "", mode = "" } = {})`
39
+ - `buildLookupFormProps(fields = [])`
40
+ - `buildLookupFormPropDefinitions({ createFields = [], editFields = [] } = {})`
35
41
  - `filterDefaultHiddenListFields(selectedFieldKeys, fields, { recordIdFieldKey = "" } = {})`
36
42
  - `ensureFields(fields, fallbackFields = createFieldDefinitions({}))`
37
43
  - `resolveViewTitleFallbackFieldKey(fields = [])`
@@ -88,6 +94,7 @@ Local functions
88
94
  - `toOptionalAccessorExpression(baseName, fieldKey)`
89
95
  - `escapeHtml(value)`
90
96
  - `serializeTemplateBindingValue(value)`
97
+ - `renderTemplateJsStringLiteral(value)`
91
98
  - `isLookupField(field = {})`
92
99
  - `toLookupDisplayFieldDescriptor(field = {})`
93
100
  - `toLookupDisplayFieldExpression(field = {})`
@@ -117,6 +124,7 @@ Local functions
117
124
  Exports
118
125
  - None
119
126
  Local functions
127
+ - `resolveFieldErrors(fieldKey)`
120
128
  - `resolveCancelTo(target)`
121
129
 
122
130
  ### `templates/src/pages/admin/ui-generator/AddEditFormFields.js`
@@ -127,6 +135,8 @@ Exports
127
135
  ### `templates/src/pages/admin/ui-generator/EditElement.vue`
128
136
  Exports
129
137
  - None
138
+ Local functions
139
+ - `resolveFieldErrors(fieldKey)`
130
140
 
131
141
  ### `templates/src/pages/admin/ui-generator/EditWrapperElement.vue`
132
142
  Exports
@@ -139,6 +149,8 @@ Exports
139
149
  ### `templates/src/pages/admin/ui-generator/NewElement.vue`
140
150
  Exports
141
151
  - None
152
+ Local functions
153
+ - `resolveFieldErrors(fieldKey)`
142
154
 
143
155
  ### `templates/src/pages/admin/ui-generator/NewWrapperElement.vue`
144
156
  Exports
@@ -600,6 +600,12 @@ Local functions
600
600
  - `normalizeClientModuleEntries(clientModules)`
601
601
  - `createClientRuntimeApp({ profile = "client", app, pinia = null, router, env, logger, surfaceRuntime, surfaceMode } = {})`
602
602
 
603
+ ### `client/pageRedirects.js`
604
+ Exports
605
+ - `redirectToChild(childTarget = "")`
606
+ Local functions
607
+ - `queryStringToObject(queryString = "")`
608
+
603
609
  ### `client/shellBootstrap.js`
604
610
  Exports
605
611
  - `resolveClientBootstrapDebugEnabled({ env = {}, debugEnabled = undefined, debugEnvKey = "VITE_JSKIT_CLIENT_DEBUG" } = {})`
@@ -20,7 +20,7 @@ Exports
20
20
 
21
21
  ### `src/server/accountNotifications/accountNotificationsService.js`
22
22
  Exports
23
- - `createService({ userSettingsRepository, usersRepository, authService } = {})`
23
+ - `createService({ userSettingsRepository, userProfilesRepository, authService } = {})`
24
24
 
25
25
  ### `src/server/accountNotifications/bootAccountNotificationsRoutes.js`
26
26
  Exports
@@ -36,7 +36,7 @@ Exports
36
36
 
37
37
  ### `src/server/accountPreferences/accountPreferencesService.js`
38
38
  Exports
39
- - `createService({ userSettingsRepository, usersRepository, authService } = {})`
39
+ - `createService({ userSettingsRepository, userProfilesRepository, authService } = {})`
40
40
 
41
41
  ### `src/server/accountPreferences/bootAccountPreferencesRoutes.js`
42
42
  Exports
@@ -52,11 +52,11 @@ Exports
52
52
 
53
53
  ### `src/server/accountProfile/accountProfileService.js`
54
54
  Exports
55
- - `createService({ userSettingsRepository, usersRepository, authService, avatarService } = {})`
55
+ - `createService({ userSettingsRepository, userProfilesRepository, authService, avatarService } = {})`
56
56
 
57
57
  ### `src/server/accountProfile/avatarService.js`
58
58
  Exports
59
- - `createService({ usersRepository, avatarStorageService, avatarPolicy } = {})`
59
+ - `createService({ userProfilesRepository, avatarStorageService, avatarPolicy } = {})`
60
60
  - `__testables`
61
61
  Local functions
62
62
  - `resolveAvatarPolicy(policy = {})`
@@ -83,7 +83,7 @@ Exports
83
83
 
84
84
  ### `src/server/accountSecurity/accountSecurityService.js`
85
85
  Exports
86
- - `createService({ userSettingsRepository, usersRepository, authService } = {})`
86
+ - `createService({ userSettingsRepository, userProfilesRepository, authService } = {})`
87
87
 
88
88
  ### `src/server/accountSecurity/bootAccountSecurityRoutes.js`
89
89
  Exports
@@ -138,6 +138,20 @@ Exports
138
138
  - `toDbJson(value, fallback = {})`
139
139
  - `createWithTransaction`
140
140
 
141
+ ### `src/server/common/repositories/userProfilesRepository.js`
142
+ Exports
143
+ - `createRepository(knex)`
144
+ Local functions
145
+ - `normalizeProfileRecord(payload)`
146
+ - `normalizeCreatePayload(payload = {})`
147
+ - `normalizeUsername(value)`
148
+ - `usernameBaseFromEmail(email)`
149
+ - `buildUsernameCandidate(baseUsername, suffix)`
150
+ - `duplicateTargetsEmail(error)`
151
+ - `duplicateTargetsUsername(error)`
152
+ - `createDuplicateEmailConflictError()`
153
+ - `resolveUniqueUsername(client, baseUsername, { excludeUserId = null } = {})`
154
+
141
155
  ### `src/server/common/repositories/userSettingsRepository.js`
142
156
  Exports
143
157
  - `createRepository(knex)`
@@ -146,28 +160,24 @@ Local functions
146
160
  - `normalizeBoolean(value, fallback = false)`
147
161
  - `createInsertPayload(userId)`
148
162
 
149
- ### `src/server/common/repositories/usersRepository.js`
163
+ ### `src/server/common/resources/userProfilesResource.js`
150
164
  Exports
151
- - `createRepository(knex)`
152
- - `mapProfileRow(row)`
153
- - `normalizeIdentity(identityLike)`
165
+ - `resource`
154
166
  Local functions
155
167
  - `normalizeUsername(value)`
156
- - `usernameBaseFromEmail(email)`
157
- - `buildUsernameCandidate(baseUsername, suffix)`
158
- - `duplicateTargetsEmail(error)`
159
- - `duplicateTargetsUsername(error)`
160
- - `createDuplicateEmailConflictError()`
161
- - `resolveUniqueUsername(client, baseUsername, { excludeUserId = null } = {})`
168
+ - `normalizeNullableString(value)`
169
+ - `normalizeNullableVersion(value)`
170
+ - `normalizeProfileRecord(payload = {})`
171
+ - `normalizeCreatePayload(payload = {})`
162
172
 
163
173
  ### `src/server/common/services/accountContextService.js`
164
174
  Exports
165
- - `resolveUserProfile(usersRepository, user)`
175
+ - `resolveUserProfile(userProfilesRepository, user)`
166
176
  - `resolveSecurityStatus(authService, request)`
167
177
 
168
178
  ### `src/server/common/services/authProfileSyncService.js`
169
179
  Exports
170
- - `createService({ usersRepository, lifecycleContributors = [], userSettingsRepository = null } = {})`
180
+ - `createService({ userProfilesRepository, lifecycleContributors = [], userSettingsRepository = null } = {})`
171
181
  Local functions
172
182
  - `buildNormalizedIdentityKey(identityLike)`
173
183
  - `buildNormalizedIdentityProfile(profileLike)`
@@ -179,6 +189,10 @@ Local functions
179
189
  Exports
180
190
  - `deepFreeze`
181
191
 
192
+ ### `src/server/common/support/identity.js`
193
+ Exports
194
+ - `normalizeIdentity(identityLike)`
195
+
182
196
  ### `src/server/common/support/realtimeServiceEvents.js`
183
197
  Exports
184
198
  - `ACCOUNT_SETTINGS_AND_BOOTSTRAP_EVENTS`
@@ -213,7 +227,7 @@ Exports
213
227
 
214
228
  ### `src/server/usersBootstrapContributor.js`
215
229
  Exports
216
- - `createUsersBootstrapContributor({ usersRepository, userSettingsRepository, appConfig = {}, authService } = {})`
230
+ - `createUsersBootstrapContributor({ userProfilesRepository, userSettingsRepository, appConfig = {}, authService } = {})`
217
231
  Local functions
218
232
  - `getOAuthProviderCatalogPayload(authService)`
219
233
  - `normalizeBoolean(value, fallback)`
@@ -294,6 +308,71 @@ Exports
294
308
  Local functions
295
309
  - `normalizePositiveInteger(value, fallback)`
296
310
 
311
+ ### `templates/packages/users-workspace/package.descriptor.mjs`
312
+ Exports
313
+ - None
314
+
315
+ ### `templates/packages/users-workspace/src/server/actions.js`
316
+ Exports
317
+ - `createActions({ surface = "" } = {})`
318
+ Local functions
319
+ - `requireActionSurface(surface = "")`
320
+
321
+ ### `templates/packages/users-workspace/src/server/registerRoutes.js`
322
+ Exports
323
+ - `registerRoutes(app, { routeOwnershipFilter = "public", routeSurface = "", routeSurfaceRequiresWorkspace = false, routeRelativePath = "" } = {})`
324
+
325
+ ### `templates/packages/users-workspace/src/server/UsersProvider.js`
326
+ Exports
327
+ - `UsersProvider`
328
+ Local functions
329
+ - `resolveCrudPolicyFromApp(app)`
330
+
331
+ ### `templates/packages/users/package.descriptor.mjs`
332
+ Exports
333
+ - None
334
+
335
+ ### `templates/packages/users/src/server/actionIds.js`
336
+ Exports
337
+ - `actionIds`
338
+
339
+ ### `templates/packages/users/src/server/actions.js`
340
+ Exports
341
+ - `createActions({ surface = "" } = {})`
342
+ Local functions
343
+ - `requireActionSurface(surface = "")`
344
+
345
+ ### `templates/packages/users/src/server/listConfig.js`
346
+ Exports
347
+ - `LIST_CONFIG`
348
+
349
+ ### `templates/packages/users/src/server/registerRoutes.js`
350
+ Exports
351
+ - `registerRoutes(app, { routeOwnershipFilter = "public", routeSurface = "", routeRelativePath = "" } = {})`
352
+
353
+ ### `templates/packages/users/src/server/repository.js`
354
+ Exports
355
+ - `createRepository(knex, options = {})`
356
+
357
+ ### `templates/packages/users/src/server/service.js`
358
+ Exports
359
+ - `createService({ usersRepository } = {})`
360
+ - `serviceEvents`
361
+
362
+ ### `templates/packages/users/src/server/UsersProvider.js`
363
+ Exports
364
+ - `UsersProvider`
365
+ Local functions
366
+ - `resolveCrudPolicyFromApp(app)`
367
+
368
+ ### `templates/packages/users/src/shared/index.js`
369
+ Exports
370
+ - `resource`
371
+
372
+ ### `templates/packages/users/src/shared/userResource.js`
373
+ Exports
374
+ - `resource`
375
+
297
376
  ### root
298
377
 
299
378
  ### `package.descriptor.mjs`
@@ -16,8 +16,7 @@ Use this on demand; do not load the full index at startup.
16
16
 
17
17
  ### `src/client/account-settings/sections.js`
18
18
  Exports
19
- - `ACCOUNT_SETTINGS_SECTIONS_INJECTION_KEY`
20
- - `ACCOUNT_SETTINGS_SECTION_REGISTRY_TAG`
19
+ - `ACCOUNT_SETTINGS_SECTION_TARGET`
21
20
  - `EMPTY_ACCOUNT_SETTINGS_SECTIONS`
22
21
  - `RESERVED_ACCOUNT_SETTINGS_SECTION_VALUES`
23
22
  - `normalizeAccountSettingsSectionEntry(entry = null)`
@@ -171,7 +170,7 @@ Exports
171
170
 
172
171
  ### `src/client/composables/records/useView.js`
173
172
  Exports
174
- - `useView({ ownershipFilter = ROUTE_VISIBILITY_WORKSPACE, surfaceId = "", access = "auto", apiSuffix = "", queryKeyFactory = null, viewPermissions = [], readMethod = "GET", readEnabled = true, placementSource = "users-web.view", fallbackLoadError = "Unable to load resource.", notFoundStatuses = [404], notFoundMessage = "Record not found.", model, mapLoadedToModel, recordIdParam = "recordId", routeParams = null, routeRecordId = null, apiUrlTemplate = "", listUrlTemplate = "", editUrlTemplate = "", includeRecordIdInQueryKey = false, realtime = null, adapter = null } = {})`
173
+ - `useView({ ownershipFilter = ROUTE_VISIBILITY_WORKSPACE, surfaceId = "", access = "auto", apiSuffix = "", queryKeyFactory = null, viewPermissions = [], readMethod = "GET", readEnabled = true, placementSource = "users-web.view", fallbackLoadError = "Unable to load resource.", notFoundStatuses = [404], notFoundMessage = "Record not found.", model, mapLoadedToModel, requestQueryParams = null, recordIdParam = "recordId", routeParams = null, routeRecordId = null, apiUrlTemplate = "", listUrlTemplate = "", editUrlTemplate = "", includeRecordIdInQueryKey = false, realtime = null, adapter = null } = {})`
175
174
 
176
175
  ### `src/client/composables/runtime/addEditUiRuntime.js`
177
176
  Exports
@@ -298,6 +297,10 @@ Exports
298
297
  - `resolveEnabledRef(value)`
299
298
  - `resolveTextRef(value)`
300
299
 
300
+ ### `src/client/composables/support/requestQueryPathSupport.js`
301
+ Exports
302
+ - `appendRequestQueryEntriesToPath(path = "", entries = [])`
303
+
301
304
  ### `src/client/composables/support/resourceLoadStateHelpers.js`
302
305
  Exports
303
306
  - `hasResolvedQueryData({ query = null, data = null } = {})`
@@ -457,10 +460,6 @@ Local functions
457
460
  - `resolveSystemThemeName({ prefersDark } = {})`
458
461
  - `resolveThemePreferenceStorage(options = {})`
459
462
 
460
- ### `src/client/providers/bootUsersWebClientProvider.js`
461
- Exports
462
- - `bootUsersWebClientProvider(app)`
463
-
464
463
  ### `src/client/providers/UsersWebClientProvider.js`
465
464
  Exports
466
465
  - `UsersWebClientProvider`
@@ -473,8 +472,8 @@ Exports
473
472
 
474
473
  ### `src/shared/toolsOutletContracts.js`
475
474
  Exports
476
- - `DEFAULT_TOOLS_LINK_COMPONENT_TOKEN`
477
- - `HOME_TOOLS_OUTLET`
475
+ - `DEFAULT_COG_LINK_COMPONENT_TOKEN`
476
+ - `HOME_COG_OUTLET`
478
477
 
479
478
  ### templates
480
479
 
@@ -55,19 +55,47 @@ Exports
55
55
  ### `src/server/common/repositories/workspaceInvitesRepository.js`
56
56
  Exports
57
57
  - `createRepository(knex)`
58
- - `mapRow(row)`
58
+ - `normalizeInviteRecord(payload)`
59
+ - `normalizeInviteWithWorkspace(payload = {})`
60
+ Local functions
61
+ - `normalizeInvitePatchPayload(payload = {})`
59
62
 
60
63
  ### `src/server/common/repositories/workspaceMembershipsRepository.js`
61
64
  Exports
62
65
  - `createRepository(knex)`
63
- - `mapRow(row)`
64
- - `mapMemberSummaryRow(row)`
66
+ - `normalizeMembershipRecord(payload)`
67
+ - `normalizeMemberSummaryRow(row)`
68
+ Local functions
69
+ - `normalizeMembershipPatchPayload(payload = {})`
65
70
 
66
71
  ### `src/server/common/repositories/workspacesRepository.js`
67
72
  Exports
68
73
  - `createRepository(knex)`
69
- - `mapRow(row)`
70
- - `mapMembershipWorkspaceRow(row)`
74
+ - `normalizeWorkspaceRecord(payload)`
75
+ - `normalizeMembershipWorkspaceRow(row)`
76
+ Local functions
77
+ - `normalizeCreatePayload(payload = {})`
78
+
79
+ ### `src/server/common/resources/workspaceInvitesResource.js`
80
+ Exports
81
+ - `workspaceInvitesResource`
82
+ Local functions
83
+ - `normalizeInviteRecord(payload = {})`
84
+ - `normalizeInviteInput(payload = {})`
85
+
86
+ ### `src/server/common/resources/workspaceMembershipsResource.js`
87
+ Exports
88
+ - `workspaceMembershipsResource`
89
+ Local functions
90
+ - `normalizeMembershipRecord(payload = {})`
91
+ - `normalizeMembershipInput(payload = {})`
92
+
93
+ ### `src/server/common/resources/workspacesResource.js`
94
+ Exports
95
+ - `workspacesResource`
96
+ Local functions
97
+ - `normalizeWorkspaceRecord(payload = {})`
98
+ - `normalizeWorkspaceInput(payload = {})`
71
99
 
72
100
  ### `src/server/common/services/workspaceContextService.js`
73
101
  Exports
@@ -160,7 +188,7 @@ Exports
160
188
 
161
189
  ### `src/server/workspaceBootstrapContributor.js`
162
190
  Exports
163
- - `createWorkspaceBootstrapContributor({ workspaceService, workspacePendingInvitationsService, usersRepository, workspaceInvitationsEnabled = false, appConfig = {}, tenancyProfile = null } = {})`
191
+ - `createWorkspaceBootstrapContributor({ workspaceService, workspacePendingInvitationsService, userProfilesRepository, workspaceInvitationsEnabled = false, appConfig = {}, tenancyProfile = null } = {})`
164
192
  Local functions
165
193
  - `normalizePendingInvites(invites)`
166
194
  - `normalizeQueryPayload(value = {})`
@@ -323,8 +323,8 @@ Local functions
323
323
 
324
324
  ### `src/shared/toolsOutletContracts.js`
325
325
  Exports
326
- - `DEFAULT_TOOLS_LINK_COMPONENT_TOKEN`
327
- - `WORKSPACE_TOOLS_OUTLET`
326
+ - `DEFAULT_COG_LINK_COMPONENT_TOKEN`
327
+ - `ADMIN_COG_OUTLET`
328
328
 
329
329
  ### templates
330
330
 
@@ -337,6 +337,10 @@ Local functions
337
337
  - `resolveReturnToHref()`
338
338
  - `countPendingInvites(entries = [])`
339
339
 
340
+ ### `templates/packages/main/src/client/components/AccountSettingsInvitesSection.vue`
341
+ Exports
342
+ - None
343
+
340
344
  ### `templates/src/components/WorkspaceNotFoundCard.vue`
341
345
  Exports
342
346
  - None