@jskit-ai/agent-docs 0.1.18 → 0.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/guide/agent/app-setup/users.md +11 -4
- package/guide/agent/app-setup/working-with-the-jskit-cli.md +1 -0
- package/package.json +1 -1
- package/patterns/INDEX.md +3 -0
- package/patterns/client-requests.md +5 -0
- package/patterns/filters.md +4 -0
- package/patterns/server-search.md +211 -0
- package/reference/autogen/packages/auth-provider-supabase-core.md +1 -0
- package/reference/autogen/packages/crud-core.md +8 -0
- package/reference/autogen/packages/crud-server-generator.md +1 -0
- package/reference/autogen/packages/http-runtime.md +12 -6
- package/reference/autogen/packages/json-rest-api-core.md +2 -1
- package/reference/autogen/packages/kernel.md +1 -0
- package/reference/autogen/packages/ui-generator.md +2 -2
- package/reference/autogen/packages/users-web.md +22 -9
- package/reference/autogen/packages/workspaces-web.md +0 -1
- package/reference/autogen/tooling/jskit-cli.md +4 -0
|
@@ -212,13 +212,17 @@ The account route itself is very small:
|
|
|
212
212
|
<template>
|
|
213
213
|
<AccountSettingsClientElement />
|
|
214
214
|
</template>
|
|
215
|
+
|
|
216
|
+
<script setup>
|
|
217
|
+
import AccountSettingsClientElement from "@jskit-ai/users-web/client/components/AccountSettingsClientElement";
|
|
218
|
+
</script>
|
|
215
219
|
```
|
|
216
220
|
|
|
217
221
|
That is a very JSKIT-style file.
|
|
218
222
|
|
|
219
223
|
- the route policy is app-owned
|
|
220
224
|
- the page wrapper is app-owned
|
|
221
|
-
- the heavy UI is delegated to a reusable client element
|
|
225
|
+
- the heavy UI is delegated to a package-owned reusable client element
|
|
222
226
|
|
|
223
227
|
So the route is simple, but it is already a real authenticated account screen rather than a placeholder card.
|
|
224
228
|
|
|
@@ -228,18 +232,21 @@ The account page is backed by:
|
|
|
228
232
|
|
|
229
233
|
```text
|
|
230
234
|
src/components/account/settings/
|
|
231
|
-
AccountSettingsClientElement.vue
|
|
232
235
|
AccountSettingsProfileSection.vue
|
|
233
236
|
AccountSettingsPreferencesSection.vue
|
|
234
237
|
AccountSettingsNotificationsSection.vue
|
|
235
238
|
```
|
|
236
239
|
|
|
237
|
-
|
|
240
|
+
Those three section components stay app-owned so you can reshape the actual UI freely.
|
|
241
|
+
|
|
242
|
+
The host itself now lives in `users-web` and resolves every account section through the `account-settings:sections` placement target, including the default `profile`, `preferences`, and `notifications` entries.
|
|
243
|
+
|
|
244
|
+
So the screen follows the same rule as the rest of JSKIT UI: sections are added by placement rather than being hardcoded into an app-owned host component.
|
|
238
245
|
|
|
239
246
|
That is worth noticing because the guide has now reached a new level of scaffolding:
|
|
240
247
|
|
|
241
248
|
- earlier chapters mostly introduced shells and routes
|
|
242
|
-
- this chapter introduces
|
|
249
|
+
- this chapter introduces app-owned leaf section UI while the generic section host stays in the package
|
|
243
250
|
|
|
244
251
|
## Under the hood
|
|
245
252
|
|
|
@@ -666,6 +666,7 @@ In the current CLI, that includes checks such as:
|
|
|
666
666
|
- installed package entries in `.jskit/lock.json`
|
|
667
667
|
- whether managed files recorded in the lock still exist
|
|
668
668
|
- whether installed packages are still visible in the package registry
|
|
669
|
+
- explicit `transport` passed to high-level CRUD hooks such as `useCrudList()`, `useCrudView()`, and `useCrudAddEdit()`, where the shared CRUD resource should derive the JSON:API transport automatically
|
|
669
670
|
- certain JSKIT-specific app checks, such as invalid raw `mdi-*` icon literals in Vue templates when the app uses Vuetify's `mdi-svg` iconset
|
|
670
671
|
- UI verification receipts for current dirty UI files in git, via `.jskit/verification/ui.json`
|
|
671
672
|
|
package/package.json
CHANGED
package/patterns/INDEX.md
CHANGED
|
@@ -28,6 +28,8 @@ How to use it:
|
|
|
28
28
|
- `ui-testing.md`
|
|
29
29
|
- filter, filters, search facets, chips, date range, enum filter, lookup filter, `useCrudListFilters`, `createCrudListFilters`
|
|
30
30
|
- `filters.md`
|
|
31
|
+
- `searchSchema`, `search: true`, `applyFilter`, server search, query validators, backend filters, internal JSON REST filters
|
|
32
|
+
- `server-search.md`
|
|
31
33
|
- `actualField`, `storage.writeSerializer`, `storage.virtual`, computed field, virtual field, projection, `createCrudResourceRuntime`, `remainingBatchWeight`, datetime write serialization
|
|
32
34
|
- `crud-repository-mapping.md`
|
|
33
35
|
|
|
@@ -42,4 +44,5 @@ How to use it:
|
|
|
42
44
|
- [client-requests.md](./client-requests.md)
|
|
43
45
|
- [ui-testing.md](./ui-testing.md)
|
|
44
46
|
- [filters.md](./filters.md)
|
|
47
|
+
- [server-search.md](./server-search.md)
|
|
45
48
|
- [crud-repository-mapping.md](./crud-repository-mapping.md)
|
|
@@ -41,6 +41,11 @@ Use the CRUD wrappers when they fit:
|
|
|
41
41
|
- `useCrudView()` for routed CRUD record loading
|
|
42
42
|
- `useCrudAddEdit()` for routed CRUD forms
|
|
43
43
|
|
|
44
|
+
CRUD hook transport defaults:
|
|
45
|
+
|
|
46
|
+
- CRUD hooks derive the standard JSON:API transport from the shared CRUD `resource` automatically.
|
|
47
|
+
- Do not pass `transport` to CRUD hooks. If you need a non-standard wire contract, drop to `useList()`, `useView()`, `useAddEdit()`, or `usersWebHttpClient.request(...)` instead of the CRUD wrappers.
|
|
48
|
+
|
|
44
49
|
Why this is the standard JSKIT shape:
|
|
45
50
|
|
|
46
51
|
- `useCommand()` resolves the scoped API path for the current route and surface.
|
package/patterns/filters.md
CHANGED
|
@@ -5,6 +5,10 @@ Use when:
|
|
|
5
5
|
- the user asks to "add a filter", "make the list filterable", or "keep filters in the URL"
|
|
6
6
|
- a screen mixes free-text search with structured facets
|
|
7
7
|
|
|
8
|
+
Server-side note:
|
|
9
|
+
- for the current CRUD server contract on the JSON REST path, see `server-search.md`
|
|
10
|
+
- this file is about the shared structured-filter runtime used by CRUD list pages and explicit list-filter modules
|
|
11
|
+
|
|
8
12
|
Ask first:
|
|
9
13
|
- which fields are filterable
|
|
10
14
|
- whether each filter is a flag, enum, multi-enum, date/date-range, number-range, record id, or lookup-backed record id
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# Server Search
|
|
2
|
+
|
|
3
|
+
Use when:
|
|
4
|
+
- a CRUD list accepts `q` or other server-side query params
|
|
5
|
+
- a resource needs alias filters such as `onlyArchived -> archived`
|
|
6
|
+
- a list needs access-scoped filters that the repository injects before querying
|
|
7
|
+
- the user asks where search belongs on the server in a current JSKIT app
|
|
8
|
+
|
|
9
|
+
Core rule:
|
|
10
|
+
- for current JSKIT CRUD apps, the server search contract lives in `resource.searchSchema` on the internal JSON REST path
|
|
11
|
+
- route validators decide which public query keys HTTP callers may send
|
|
12
|
+
- repositories may add internal-only filter keys before forwarding the query to JSON REST
|
|
13
|
+
|
|
14
|
+
Fresh generated CRUD repositories already follow this path:
|
|
15
|
+
|
|
16
|
+
```js
|
|
17
|
+
return api.resources.contacts.query({
|
|
18
|
+
queryParams: buildJsonRestQueryParams(RESOURCE_TYPE, query),
|
|
19
|
+
simplified: false
|
|
20
|
+
}, createJsonRestContext(context));
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The normal layer split is:
|
|
24
|
+
1. `actions.js` / `registerRoutes.js`: accept and validate public query keys
|
|
25
|
+
2. `repository.js`: add internal-only filter keys such as visibility scope
|
|
26
|
+
3. `*Resource.js`: define the backend filter behavior in `searchSchema`
|
|
27
|
+
|
|
28
|
+
## Decision Rules
|
|
29
|
+
|
|
30
|
+
Use `search: true` on a schema field when:
|
|
31
|
+
- the public filter key should be the same as the field name
|
|
32
|
+
- direct field filtering is enough
|
|
33
|
+
- you are happy with the generated/effective search entry for that one field
|
|
34
|
+
|
|
35
|
+
Example:
|
|
36
|
+
|
|
37
|
+
```js
|
|
38
|
+
schema: {
|
|
39
|
+
archived: {
|
|
40
|
+
type: "boolean",
|
|
41
|
+
search: true,
|
|
42
|
+
operations: {
|
|
43
|
+
output: { required: true }
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Good fit:
|
|
50
|
+
- `archived=true`
|
|
51
|
+
- `statusSid=active`
|
|
52
|
+
- direct field-by-field filtering with no aliasing
|
|
53
|
+
|
|
54
|
+
Do not use `search: true` when:
|
|
55
|
+
- you want a different public key than the storage field
|
|
56
|
+
- you need one key to search several fields
|
|
57
|
+
- you need custom SQL semantics
|
|
58
|
+
- you need an internal-only injected filter
|
|
59
|
+
|
|
60
|
+
Use explicit `searchSchema` when:
|
|
61
|
+
- the public key differs from the field name
|
|
62
|
+
- one key searches multiple fields
|
|
63
|
+
- the route/API contract should stay stable even if field names change
|
|
64
|
+
- the filter is internal-only and injected by the repository
|
|
65
|
+
- you need to override the simple `search: true` behavior
|
|
66
|
+
|
|
67
|
+
Example:
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
searchSchema: {
|
|
71
|
+
onlyArchived: {
|
|
72
|
+
type: "boolean",
|
|
73
|
+
actualField: "archived",
|
|
74
|
+
filterOperator: "="
|
|
75
|
+
},
|
|
76
|
+
q: {
|
|
77
|
+
type: "string",
|
|
78
|
+
oneOf: ["firstName", "lastName", "email"],
|
|
79
|
+
filterOperator: "like",
|
|
80
|
+
splitBy: " ",
|
|
81
|
+
matchAll: true
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Important merge rule:
|
|
87
|
+
- explicit `searchSchema` is the authored contract
|
|
88
|
+
- fields marked `search: true` are added to the effective search schema too
|
|
89
|
+
- if both define the same public key, explicit `searchSchema` wins
|
|
90
|
+
|
|
91
|
+
Use `applyFilter` when:
|
|
92
|
+
- `actualField`, `oneOf`, and normal operators are not enough
|
|
93
|
+
- the filter needs compound SQL
|
|
94
|
+
- the filter encodes visibility rules, status buckets, or null/not-null semantics that are more complex than a direct field comparison
|
|
95
|
+
|
|
96
|
+
Example:
|
|
97
|
+
|
|
98
|
+
```js
|
|
99
|
+
searchSchema: {
|
|
100
|
+
"__viewerAccess": {
|
|
101
|
+
type: "string",
|
|
102
|
+
applyFilter(query, rawValue) {
|
|
103
|
+
const value = String(rawValue || "").trim();
|
|
104
|
+
|
|
105
|
+
query.whereNull("deleted_at");
|
|
106
|
+
if (value === "privileged") {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const userId = value.startsWith("user:")
|
|
111
|
+
? String(value.slice(5) || "").trim()
|
|
112
|
+
: "";
|
|
113
|
+
|
|
114
|
+
query.where(function () {
|
|
115
|
+
this.where("user_added", 0);
|
|
116
|
+
if (userId) {
|
|
117
|
+
this.orWhere("added_by_user_id", userId);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Keep `applyFilter` focused on query semantics:
|
|
126
|
+
- build the SQL/knex filter there
|
|
127
|
+
- do not put permission checks there
|
|
128
|
+
- do not turn it into a second service layer
|
|
129
|
+
|
|
130
|
+
Add route validators when:
|
|
131
|
+
- the filter key is public and may arrive from HTTP query params
|
|
132
|
+
- the page/UI needs a stable, validated query contract
|
|
133
|
+
- malformed values should either be rejected or deliberately discarded
|
|
134
|
+
|
|
135
|
+
Example route layer:
|
|
136
|
+
|
|
137
|
+
```js
|
|
138
|
+
input: composeSchemaDefinitions([
|
|
139
|
+
workspaceSlugParamsValidator,
|
|
140
|
+
listCursorPaginationQueryValidator,
|
|
141
|
+
listSearchQueryValidator,
|
|
142
|
+
vetsListFiltersQueryValidator,
|
|
143
|
+
])
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
That means:
|
|
147
|
+
- `q` and the structured filter keys are accepted publicly
|
|
148
|
+
- the repository may still add internal-only keys later
|
|
149
|
+
|
|
150
|
+
Do not add route validators for:
|
|
151
|
+
- repository-injected internal keys such as `"__viewerAccess"`
|
|
152
|
+
- filters that must never be supplied by the client directly
|
|
153
|
+
|
|
154
|
+
## Recommended Shapes
|
|
155
|
+
|
|
156
|
+
Simple direct field exposure:
|
|
157
|
+
|
|
158
|
+
```js
|
|
159
|
+
schema: {
|
|
160
|
+
vip: { type: "boolean", search: true }
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Public alias for a real field:
|
|
165
|
+
|
|
166
|
+
```js
|
|
167
|
+
searchSchema: {
|
|
168
|
+
onlyVip: { type: "boolean", actualField: "vip", filterOperator: "=" }
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Grouped text search:
|
|
173
|
+
|
|
174
|
+
```js
|
|
175
|
+
searchSchema: {
|
|
176
|
+
q: {
|
|
177
|
+
type: "string",
|
|
178
|
+
oneOf: ["name", "email", "phone"],
|
|
179
|
+
filterOperator: "like",
|
|
180
|
+
splitBy: " ",
|
|
181
|
+
matchAll: true
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Repository-injected internal filter:
|
|
187
|
+
|
|
188
|
+
```js
|
|
189
|
+
function buildScopedQuery(query = {}, context = null) {
|
|
190
|
+
return {
|
|
191
|
+
...(query || {}),
|
|
192
|
+
"__viewerAccess": resolveViewerAccess(context)
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Keep These Boundaries Clean
|
|
198
|
+
|
|
199
|
+
- Put backend filter behavior in `searchSchema`, not in page code.
|
|
200
|
+
- Put permission checks in the action/service layer, not in `applyFilter`.
|
|
201
|
+
- Put repository-only scoping in the repository, not in route query validation.
|
|
202
|
+
- Do not expose a query key publicly just because the repository uses it internally.
|
|
203
|
+
- Do not rely on route validators alone; a public key still needs a matching backend search definition.
|
|
204
|
+
|
|
205
|
+
## Quick Rule Of Thumb
|
|
206
|
+
|
|
207
|
+
- Same key, same field, simple behavior: `search: true`
|
|
208
|
+
- Public alias or multi-field search: `searchSchema`
|
|
209
|
+
- Complex SQL semantics: `searchSchema` + `applyFilter`
|
|
210
|
+
- Public HTTP query key: add a route validator
|
|
211
|
+
- Internal-only repository key: inject it in `repository.js`, skip the public validator
|
|
@@ -296,6 +296,14 @@ Local functions
|
|
|
296
296
|
### `src/server/routeContracts.js`
|
|
297
297
|
Exports
|
|
298
298
|
- `createCrudJsonApiRouteContracts({ resource = {}, routeParamsValidator = null, listSearchQueryValidator = defaultListSearchQueryValidator, lookupIncludeQueryValidator = defaultLookupIncludeQueryValidator } = {})`
|
|
299
|
+
Local functions
|
|
300
|
+
- `isRecord(value)`
|
|
301
|
+
- `resolveSchemaFieldDefinitions(definition = null)`
|
|
302
|
+
- `resolveJsonApiRelationshipEntries(definition = null)`
|
|
303
|
+
- `createRecordAttributesResolver(definition = null, { excludeKeys = [] } = {})`
|
|
304
|
+
- `createRecordRelationshipsResolver(definition = null)`
|
|
305
|
+
- `createRequestRelationshipMapper(definition = null)`
|
|
306
|
+
- `resolveOutputAttributeExcludeKeys(resource = {})`
|
|
299
307
|
|
|
300
308
|
### `src/server/serviceEvents.js`
|
|
301
309
|
Exports
|
|
@@ -132,6 +132,7 @@ Local functions
|
|
|
132
132
|
- `requireVariableDeclarator(programNode, variableName = "", context = "crud-server-generator scaffold-field")`
|
|
133
133
|
- `requireCrudResourceConfigObject(programNode, context = "crud-server-generator scaffold-field")`
|
|
134
134
|
- `requireResourceSchemaObject(programNode, context = "crud-server-generator scaffold-field")`
|
|
135
|
+
- `assertNoExplicitCrudSchemaOverrides(resourceObject, context = "crud-server-generator scaffold-field")`
|
|
135
136
|
- `findObjectPropertyByName(objectNode, propertyName = "")`
|
|
136
137
|
- `hasObjectProperty(objectNode, propertyName = "")`
|
|
137
138
|
- `insertObjectProperty(objectNode, propertyName = "", valueExpressionSource = "", { context = "crud-server-generator scaffold-field", insertBeforeComputed = false } = {})`
|
|
@@ -111,7 +111,10 @@ Local functions
|
|
|
111
111
|
- `isRecord(value)`
|
|
112
112
|
- `normalizeTransportKind(transport = null)`
|
|
113
113
|
- `defaultEncodeAttributes(body = {})`
|
|
114
|
-
- `
|
|
114
|
+
- `resolveRelationshipFieldKey(relationshipName = "", lookupFieldMap = null)`
|
|
115
|
+
- `createIncludedResourceIndex(document = {})`
|
|
116
|
+
- `simplifyRelationshipResource(linkage = {}, options = {})`
|
|
117
|
+
- `simplifyResourceObject(resource = {}, options = {})`
|
|
115
118
|
- `assertPrimaryDataType(resource = {}, expectedType = "")`
|
|
116
119
|
- `resolveCollectionPageMeta(document = {})`
|
|
117
120
|
|
|
@@ -262,18 +265,21 @@ Local functions
|
|
|
262
265
|
### `src/shared/validators/jsonApiRouteTransport.js`
|
|
263
266
|
Exports
|
|
264
267
|
- `JSON_API_ERROR_DOCUMENT_SCHEMA`
|
|
265
|
-
- `createJsonApiResourceObjectTransportSchema({ type = "", attributes, requireId = true, includeLinks = false, includeMeta = false } = {})`
|
|
266
|
-
- `createJsonApiResourceRequestBodyTransportSchema({ type = "", attributes, requireId = false } = {})`
|
|
267
|
-
- `createJsonApiResourceSuccessTransportSchema({ type = "", attributes, kind = "record", includeLinks = false, includeMeta = false, includeIncluded = false } = {})`
|
|
268
|
+
- `createJsonApiResourceObjectTransportSchema({ type = "", attributes, requireId = true, includeLinks = false, includeMeta = false, excludeAttributeKeys = [], relationshipEntries = [], relationshipMembersRequired = false } = {})`
|
|
269
|
+
- `createJsonApiResourceRequestBodyTransportSchema({ type = "", attributes, requireId = false, excludeAttributeKeys = [], relationshipEntries = [] } = {})`
|
|
270
|
+
- `createJsonApiResourceSuccessTransportSchema({ type = "", attributes, kind = "record", includeLinks = false, includeMeta = false, includeIncluded = false, excludeAttributeKeys = [], relationshipEntries = [] } = {})`
|
|
268
271
|
- `withJsonApiErrorResponses(successResponses, { includeValidation400 = false } = {})`
|
|
269
272
|
- `createJsonApiResourceRouteTransport({ type = "", requestType = "", responseType = "", query = null, allowBodyId = false, successKind = "record", pointerPrefix = "/data/attributes", mapRequestRelationships = null, getRecordType = null, getRecordId = null, getRecordAttributes = null, getRecordRelationships = null, getRecordLinks = null, getRecordMeta = null, getIncluded = null, getDocumentLinks = null, getDocumentMeta = null, getCollectionItems = null } = {})`
|
|
270
|
-
- `createJsonApiResourceRouteContract({ type = "", requestType = "", responseType = "", body = null, query = null, output = null, outputKind = "record", successStatus = 200, includeValidation400 = false, allowBodyId = false, pointerPrefix = "/data/attributes", getRecordType = null, getRecordId = null, getRecordAttributes = null, getRecordRelationships = null, getRecordLinks = null, getRecordMeta = null, getIncluded = null, getDocumentLinks = null, getDocumentMeta = null, getCollectionItems = null, mapRequestRelationships = null } = {})`
|
|
273
|
+
- `createJsonApiResourceRouteContract({ type = "", requestType = "", responseType = "", body = null, query = null, output = null, outputKind = "record", successStatus = 200, includeValidation400 = false, allowBodyId = false, pointerPrefix = "/data/attributes", bodyAttributeExcludeKeys = [], outputAttributeExcludeKeys = [], bodyRelationshipEntries = [], outputRelationshipEntries = [], getRecordType = null, getRecordId = null, getRecordAttributes = null, getRecordRelationships = null, getRecordLinks = null, getRecordMeta = null, getIncluded = null, getDocumentLinks = null, getDocumentMeta = null, getCollectionItems = null, mapRequestRelationships = null } = {})`
|
|
271
274
|
Local functions
|
|
272
275
|
- `isRecord(value)`
|
|
273
276
|
- `createJsonApiTransportError(statusCode, message, code)`
|
|
274
277
|
- `resolveRouteType(type = "")`
|
|
275
278
|
- `resolveRouteTypes(value = {})`
|
|
276
|
-
- `resolveEmbeddedAttributesTransportSchema(definition, { context = "JSON:API resource", defaultMode = "replace", removeId = false } = {})`
|
|
279
|
+
- `resolveEmbeddedAttributesTransportSchema(definition, { context = "JSON:API resource", defaultMode = "replace", removeId = false, removeKeys = [] } = {})`
|
|
280
|
+
- `normalizeRelationshipSchemaEntries(entries = [])`
|
|
281
|
+
- `createJsonApiRelationshipDataSchema(relationshipType = "", { nullable = false } = {})`
|
|
282
|
+
- `createJsonApiRelationshipsTransportSchema(entries = [], { includeRequired = false } = {})`
|
|
277
283
|
- `createJsonApiMetaSuccessTransportSchema({ meta } = {})`
|
|
278
284
|
- `defaultRecordTypeResolver(type)`
|
|
279
285
|
- `defaultRecordIdResolver(record = {})`
|
|
@@ -24,7 +24,7 @@ Exports
|
|
|
24
24
|
- `JSON_REST_AUTOFILTER_PRESETS`
|
|
25
25
|
- `addResourceIfMissing(api, scopeName, resourceConfig)`
|
|
26
26
|
- `buildJsonRestQueryParams(resourceType = "", query = {}, { include = undefined } = {})`
|
|
27
|
-
- `createJsonApiInputRecord(resourceType = "", attributes = {}, { id = null, relationships = null } = {})`
|
|
27
|
+
- `createJsonApiInputRecord(resourceType = "", attributes = {}, { id = null, relationships = null, resource = null } = {})`
|
|
28
28
|
- `createJsonApiRelationship(resourceType = "", id = null)`
|
|
29
29
|
- `createJsonRestResourceScopeOptions(resource = {}, { writeSerializers = {}, normalizeId = null } = {})`
|
|
30
30
|
- `createJsonRestContext(context = null)`
|
|
@@ -42,6 +42,7 @@ Local functions
|
|
|
42
42
|
- `normalizeJsonRestText(value, { fallback = "" } = {})`
|
|
43
43
|
- `normalizeJsonRestObject(value)`
|
|
44
44
|
- `normalizeJsonRestList(value)`
|
|
45
|
+
- `extractJsonApiInputRelationships(attributes = {}, resource = null, relationships = null)`
|
|
45
46
|
- `normalizeJsonApiResourceObject(resource = {})`
|
|
46
47
|
- `buildJsonApiIncludedIndex(payload = {})`
|
|
47
48
|
- `simplifyJsonApiRelationshipData(data, { includedIndex = null, seen = null } = {})`
|
|
@@ -878,6 +878,7 @@ Exports
|
|
|
878
878
|
- `registerRoutes(fastify, { routes = [], app = null, applyRoutePolicy = defaultApplyRoutePolicy, missingHandler = defaultMissingHandler, enableRequestScope = true, requestScopeProperty = "scope", requestActionExecutorProperty = "executeAction", actionExecutorToken = "actionExecutor", requestActionDefaultChannel = "api", requestActionDefaultSurface = "", requestScopeIdPrefix = "http", requestIdResolver = null, middleware = {} } = {})`
|
|
879
879
|
Local functions
|
|
880
880
|
- `toFastifyRouteOptions(route)`
|
|
881
|
+
- `shouldStripFastifyBodySchema(route = null, schema = null)`
|
|
881
882
|
- `normalizeHeaderValue(value)`
|
|
882
883
|
- `normalizeMediaType(value = "")`
|
|
883
884
|
- `routeDefinesRequestBody(route = null)`
|
|
@@ -54,8 +54,8 @@ Exports
|
|
|
54
54
|
- `DEFAULT_SUBPAGES_POSITION`
|
|
55
55
|
- `DEFAULT_COMPONENT_DIRECTORY`
|
|
56
56
|
- `SECTION_CONTAINER_SHELL_COMPONENT`
|
|
57
|
-
- `
|
|
58
|
-
- `
|
|
57
|
+
- `SUBPAGES_LINK_COMPONENT`
|
|
58
|
+
- `SUBPAGES_LINK_COMPONENT_TOKEN`
|
|
59
59
|
- `resolvePageTargetDetails`
|
|
60
60
|
- `resolveNearestParentSubpagesHost`
|
|
61
61
|
- `deriveDefaultSubpagesHost`
|
|
@@ -18,7 +18,6 @@ Use this on demand; do not load the full index at startup.
|
|
|
18
18
|
Exports
|
|
19
19
|
- `ACCOUNT_SETTINGS_SECTION_TARGET`
|
|
20
20
|
- `EMPTY_ACCOUNT_SETTINGS_SECTIONS`
|
|
21
|
-
- `RESERVED_ACCOUNT_SETTINGS_SECTION_VALUES`
|
|
22
21
|
- `normalizeAccountSettingsSectionEntry(entry = null)`
|
|
23
22
|
- `resolveAccountSettingsSections(entries = [])`
|
|
24
23
|
- `sortAccountSettingsSections(entries = [])`
|
|
@@ -29,6 +28,13 @@ Exports
|
|
|
29
28
|
- `createUsersBootstrapUserHandler()`
|
|
30
29
|
- `registerUsersBootstrapPayloadHandlers(app)`
|
|
31
30
|
|
|
31
|
+
### `src/client/components/AccountSettingsClientElement.vue`
|
|
32
|
+
Exports
|
|
33
|
+
- None
|
|
34
|
+
Local functions
|
|
35
|
+
- `normalizeSection(value)`
|
|
36
|
+
- `readRouteSection()`
|
|
37
|
+
|
|
32
38
|
### `src/client/components/ProfileClientElement.vue`
|
|
33
39
|
Exports
|
|
34
40
|
- None
|
|
@@ -75,6 +81,17 @@ Exports
|
|
|
75
81
|
- `resolveCrudBindingValues(values, context = {})`
|
|
76
82
|
- `resolveCrudBoundValues({ binding = {}, routeValues = {}, context = {} } = {})`
|
|
77
83
|
|
|
84
|
+
### `src/client/composables/crud/crudJsonApiTransportSupport.js`
|
|
85
|
+
Exports
|
|
86
|
+
- `inferCrudJsonApiTransport(resource = null, { mode = "", operationName = "" } = {})`
|
|
87
|
+
- `resolveCrudJsonApiTransport(transport = null, resource = null, options = {})`
|
|
88
|
+
- `resolveLookupFieldMap(resource = null)`
|
|
89
|
+
Local functions
|
|
90
|
+
- `isRecord(value)`
|
|
91
|
+
- `resolveSchemaFieldDefinitions(definition = null)`
|
|
92
|
+
- `isJsonApiResourceTransport(transport = null)`
|
|
93
|
+
- `resolveCrudJsonApiResourceType(resource = null)`
|
|
94
|
+
|
|
78
95
|
### `src/client/composables/crud/crudLookupFieldLabelSupport.js`
|
|
79
96
|
Exports
|
|
80
97
|
- `resolveLookupItemLabel(item = {}, labelKey = "")`
|
|
@@ -84,6 +101,7 @@ Local functions
|
|
|
84
101
|
- `hasDisplayValue(value)`
|
|
85
102
|
- `resolveComposedLabel(source = {}, candidates = LOOKUP_LABEL_COMPOSITION_CANDIDATES)`
|
|
86
103
|
- `resolveLookupFieldDescriptor(field = {}, relationKind = "", valueKey = "", labelKey = "")`
|
|
104
|
+
- `resolveFallbackLookupKey(key = "")`
|
|
87
105
|
|
|
88
106
|
### `src/client/composables/crud/crudLookupFieldRuntime.js`
|
|
89
107
|
Exports
|
|
@@ -108,6 +126,7 @@ Local functions
|
|
|
108
126
|
- `resolveFormFieldType(field = {})`
|
|
109
127
|
- `resolveFormFieldFormat(field = {})`
|
|
110
128
|
- `isNullableFormField(field = {})`
|
|
129
|
+
- `isLookupFormField(field = {})`
|
|
111
130
|
- `padDateTimePart(value)`
|
|
112
131
|
- `normalizeTimeWhitespace(value)`
|
|
113
132
|
- `toTimeInputValue(value)`
|
|
@@ -166,7 +185,7 @@ Local functions
|
|
|
166
185
|
|
|
167
186
|
### `src/client/composables/records/useCrudView.js`
|
|
168
187
|
Exports
|
|
169
|
-
- `useCrudView({ paramBinding = null, route = null, ...viewOptions } = {})`
|
|
188
|
+
- `useCrudView({ resource = null, paramBinding = null, route = null, ...viewOptions } = {})`
|
|
170
189
|
|
|
171
190
|
### `src/client/composables/records/useList.js`
|
|
172
191
|
Exports
|
|
@@ -433,6 +452,7 @@ Exports
|
|
|
433
452
|
### `src/client/index.js`
|
|
434
453
|
Exports
|
|
435
454
|
- `UsersWebClientProvider`
|
|
455
|
+
- `AccountSettingsClientElement`
|
|
436
456
|
- `clientProviders`
|
|
437
457
|
|
|
438
458
|
### `src/client/lib/bootstrap.js`
|
|
@@ -486,13 +506,6 @@ Exports
|
|
|
486
506
|
|
|
487
507
|
### templates
|
|
488
508
|
|
|
489
|
-
### `templates/src/components/account/settings/AccountSettingsClientElement.vue`
|
|
490
|
-
Exports
|
|
491
|
-
- None
|
|
492
|
-
Local functions
|
|
493
|
-
- `normalizeSection(value)`
|
|
494
|
-
- `readRouteSection()`
|
|
495
|
-
|
|
496
509
|
### `templates/src/components/account/settings/AccountSettingsNotificationsSection.vue`
|
|
497
510
|
Exports
|
|
498
511
|
- None
|
|
@@ -333,7 +333,6 @@ Local functions
|
|
|
333
333
|
- `normalizePendingInvitesCount(value)`
|
|
334
334
|
- `resolveReturnTo()`
|
|
335
335
|
- `resolveReturnToHref()`
|
|
336
|
-
- `countPendingInvites(entries = [])`
|
|
337
336
|
|
|
338
337
|
### `templates/packages/main/src/client/components/AccountSettingsInvitesSection.vue`
|
|
339
338
|
Exports
|
|
@@ -368,6 +368,10 @@ Local functions
|
|
|
368
368
|
### `src/server/commandHandlers/appCommands/linkLocalPackages.js`
|
|
369
369
|
Exports
|
|
370
370
|
- `runAppLinkLocalPackagesCommand(ctx = {}, { appRoot = "", options = {}, stdout })`
|
|
371
|
+
Local functions
|
|
372
|
+
- `collectDeclaredPackageNames(packageJson = {})`
|
|
373
|
+
- `verifySymlinkTarget(targetPath = "", sourceDir = "", { packageName = "" } = {})`
|
|
374
|
+
- `maybeLinkCompanionPackages({ appRoot = "", repoRoot = "", stdout, createCliError })`
|
|
371
375
|
|
|
372
376
|
### `src/server/commandHandlers/appCommands/release.js`
|
|
373
377
|
Exports
|