@jskit-ai/agent-docs 0.1.14 → 0.1.15

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"
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.15",
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`
@@ -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)
@@ -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,34 @@ Exports
205
201
  Local functions
206
202
  - `normalizeLookupOwnershipFilter(value, { context = "crudLookup ownershipFilter" } = {})`
207
203
 
208
- ### `src/server/repositoryMethods.js`
204
+ ### `src/server/repositorySupport.js`
205
+ Exports
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 = {})`
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
+ - `schemaIncludesRecordIdType(schema = {})`
224
+
225
+ ### `src/server/resourceRuntime/index.js`
209
226
  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)`
227
+ - `createCrudResourceRuntime(resource = {}, knex, repositoryOptions = {})`
218
228
  Local functions
219
229
  - `requireCrudRecordId(value, { context = "crudRepository" } = {})`
220
- - `resolveRepositoryDefaults(resource = {}, repositoryMapping = {})`
230
+ - `requireCrudRepositoryOptions(value = {}, { context = "crudRepository" } = {})`
231
+ - `resolveRepositoryDefaults(resource = {}, repositoryMapping = {}, { context = "crudRepository" } = {})`
221
232
  - `normalizeCrudVirtualFieldHandlers(virtualFields = {}, repositoryMapping = {}, { context = "crudRepository" } = {})`
222
233
  - `applyCrudRepositoryVirtualProjections(dbQuery, runtime = {}, { knex, tableName } = {})`
223
234
  - `normalizeSearchColumns(searchColumns = [], fallbackColumns = [])`
@@ -225,6 +236,12 @@ Local functions
225
236
  - `normalizeListOrderNulls(value = LIST_ORDER_NULLS_LAST)`
226
237
  - `normalizeListOrderBy(orderBy = [], { idColumn = "id" } = {})`
227
238
  - `resolveListRuntimeConfig(list = {}, fallbackSearchColumns = [], { idColumn = "id" } = {})`
239
+ - `formatOutputValidationError(issue = {})`
240
+ - `resolveRecordOutputValidator(resource = {}, { context = "crudRepository" } = {})`
241
+ - `resolveOperationBodyValidator(resource = {}, operationKey = "", { context = "crudRepository" } = {})`
242
+ - `extractExplicitFieldErrors(error)`
243
+ - `normalizeRepositoryInputPayload(runtime = {}, payload = {}, { operationKey = "create", phase = "crudCreate", action = "create", recordId = null, existingRecord = null, actionContextBase = {} } = {})`
244
+ - `normalizeRepositoryOutputRecord(runtime = {}, record = {}, { operation = "list" } = {})`
228
245
  - `encodeOrderedListCursorValue(value = null)`
229
246
  - `decodeOrderedListCursorValue(value = null)`
230
247
  - `encodeOrderedListCursor(row = null, orderBy = [])`
@@ -234,43 +251,51 @@ Local functions
234
251
  - `canApplyOrderedListCursorAfterBranch(descriptor = {}, value = null)`
235
252
  - `appendOrderedListCursorBranches(query, orderBy = [], cursorValues = [], index = 0, { useOr = false } = {})`
236
253
  - `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" } = {})`
254
+ - `normalizeCrudRepositoryOperationStage(stage = null, stageLabel = "", { context = "crudRepository" } = {})`
255
+ - `normalizeCrudRepositoryOperationConfig(config = {}, operationKey = "", { context = "crudRepository" } = {})`
256
+ - `normalizeCrudRepositoryOperations(sourceOperations = {}, { context = "crudRepository" } = {})`
257
+ - `applyConfiguredQueryStage(dbQuery, stage = null, stageContext = {}, { context = "crudRepository", stageKey = "applyQuery" } = {})`
258
+ - `isCrudRepositoryQueryBuilder(value)`
244
259
  - `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" } = {})`
260
+ - `applyConfiguredObjectStage(payload = {}, stage = null, stageContext = {}, { context = "crudRepository", stageKey = "preparePayload" } = {})`
250
261
  - `applyOrderedListControls(dbQuery, orderBy = [])`
251
262
  - `enforceCrudRepositoryListControls(dbQuery, { idColumn = "id", limit = DEFAULT_LIST_LIMIT + 1, orderBy = [] } = {})`
252
- - `createCrudRepositoryHookContextBase(runtime, repositoryOptions = {}, callOptions = {})`
263
+ - `createCrudRepositoryActionContextBase(runtime, callOptions = {})`
264
+ - `createCompiledCrudRepositoryRuntime(resource = {}, repositoryOptions = {})`
265
+ - `resolveCrudRepositoryCall(runtime, knex, callOptions = {})`
266
+ - `applyCrudRepositoryReadLock(dbQuery, callOptions = {})`
267
+ - `listRecords(runtime, knex, query = {}, callOptions = {})`
268
+ - `findRecordById(runtime, knex, recordId, callOptions = {})`
269
+ - `listRecordsByIds(runtime, knex, ids = [], callOptions = {})`
270
+ - `createRecord(runtime, knex, payload = {}, callOptions = {})`
271
+ - `updateRecordById(runtime, knex, recordId, patch = {}, callOptions = {})`
272
+ - `deleteRecordById(runtime, knex, recordId, callOptions = {})`
253
273
 
254
- ### `src/server/repositorySupport.js`
274
+ ### `src/server/resourceRuntime/lookupHydration.js`
255
275
  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 = {} } = {})`
276
+ - `createCrudLookupRuntime(resource = {}, { outputKeys = [] } = {})`
277
+ - `hydrateCrudLookupRecords(records = [], runtime = {}, { include, mode = "list", repositoryOptions = {}, callOptions = {} } = {})`
268
278
  Local functions
269
- - `resolveOptionalObjectSchemaProperties(schema, options = {})`
270
- - `requireObjectSchemaProperties(schema, { context = "crudRepository", schemaLabel = "schema" } = {})`
271
- - `normalizeResourceFieldMetaEntries(fieldMeta = [])`
272
- - `schemaIncludesStringType(schema = {})`
273
- - `schemaIncludesRecordIdType(schema = {})`
279
+ - `normalizeLookupRelationEntry(entry = {}, outputKeys = new Set())`
280
+ - `normalizeLookupDefaultInclude(value)`
281
+ - `normalizeLookupMaxDepth(value)`
282
+ - `resolveLookupRuntimeDefaults(resource = {})`
283
+ - `normalizeLookupIdentifier(value)`
284
+ - `normalizeIncludePaths(include, { defaultInclude = DEFAULT_LOOKUP_INCLUDE } = {})`
285
+ - `resolveChildIncludeFromPaths(paths = [])`
286
+ - `shouldHydrateByMode(entry = {}, mode = "list")`
287
+ - `buildLookupHydrationPlan(runtime = {}, include, { mode = "list", context = "crudRepository", includeWasExplicit = false, skippedNamespaces = new Set() } = {})`
288
+ - `resolveLookupResolver(repositoryOptions = {}, callOptions = {}, { context = "crudRepository" } = {})`
289
+ - `resolveLookupDepthRuntime(runtime = {}, repositoryOptions = {}, callOptions = {})`
290
+ - `buildLookupGroupKey(relation = {})`
291
+ - `normalizeLookupRelationValues(records = [], entries = [], childIncludeByKey = {})`
292
+ - `resolveGroupChildInclude(group = {})`
293
+ - `normalizeLookup(provider, relation = {}, { context = "crudRepository" } = {})`
294
+ - `resolveLookupOwnershipFilter(provider = {}, { context = "crudRepository" } = {})`
295
+ - `resolveLookupVisibilityContext(provider = {}, relation = {}, callOptions = {}, { context = "crudRepository" } = {})`
296
+ - `buildLookupRecordMap(records = [], valueKey = "")`
297
+ - `buildLookupCollectionMap(records = [], foreignKey = "")`
298
+ - `resolveLookupVisitedNamespaces(runtime = {}, callOptions = {})`
274
299
 
275
300
  ### `src/server/serviceEvents.js`
276
301
  Exports
@@ -286,6 +311,7 @@ Exports
286
311
  - `crudServiceDeleteRecord(runtime, repository, fieldAccess = {}, recordId, options = {})`
287
312
  Local functions
288
313
  - `requireCrudServiceRepository(runtime = {}, repository = null)`
314
+ - `splitCrudListRepositoryCall(query = {}, options = {})`
289
315
 
290
316
  ### `src/shared/crudFieldMetaSupport.js`
291
317
  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)`
@@ -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