@jskit-ai/agent-docs 0.1.293 → 0.1.295
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-extras/realtime.md +14 -4
- package/guide/agent/app-setup/multi-homing.md +12 -3
- package/guide/agent/framework/client-features.md +28 -0
- package/guide/agent/framework/crud-operations.md +7 -0
- package/guide/agent/framework/data-access.md +75 -9
- package/guide/agent/framework/sanity-checks.md +4 -4
- package/guide/agent/framework/typed-features.md +12 -3
- package/package.json +1 -1
- package/patterns/minimal-foundation/example/package.json +2 -2
- package/patterns/shell-foundation/example/package.json +3 -3
- package/reference/autogen/PATTERN_INDEX.md +35 -35
- package/reference/autogen/packages/agent.md +4 -2
- package/reference/autogen/packages/assistant-core.md +1 -1
- package/reference/autogen/packages/assistant-runtime.md +1 -0
- package/reference/autogen/packages/crud-core.md +2 -0
- package/reference/autogen/packages/http-web.md +9 -6
- package/reference/autogen/packages/realtime.md +1 -0
- package/reference/autogen/packages/resource-runtime.md +1 -0
- package/reference/autogen/packages/users-core.md +3 -0
- package/reference/autogen/packages/workspaces-core.md +11 -2
- package/reference/autogen/packages/workspaces-web.md +1 -1
- package/reference/autogen/tooling/config-eslint.md +26 -0
- package/reference/autogen/tooling/jskit-catalog.md +27 -13
- package/skills/jskit/references/client-features.md +28 -0
- package/skills/jskit/references/crud-operations.md +7 -0
- package/skills/jskit/references/data-access.md +75 -9
- package/skills/jskit/references/heuristics/INDEX.md +1 -1
- package/skills/jskit/references/heuristics/data-access.md +1 -0
- package/skills/jskit/references/heuristics/filters.md +14 -0
- package/skills/jskit/references/heuristics/server-search.md +2 -0
- package/skills/jskit/references/multi-homing.md +12 -3
- package/skills/jskit/references/pattern-index.md +35 -35
- package/skills/jskit/references/patterns/app/minimal-foundation/example/package.json +2 -2
- package/skills/jskit/references/patterns/app/shell-foundation/example/package.json +3 -3
- package/skills/jskit/references/patterns/auth/accounts-hub/example/package.json +1 -1
- package/skills/jskit/references/patterns/auth/oidc-sign-in/example/package.json +2 -2
- package/skills/jskit/references/patterns/auth/supabase-auth/example/package.json +1 -1
- package/skills/jskit/references/patterns/connectors/calendar-cli/example/package.json +2 -2
- package/skills/jskit/references/patterns/crud/crud-feature-package/example/packages/books/package.json +2 -2
- package/skills/jskit/references/patterns/crud/crud-screen-set/PATTERN.md +9 -0
- package/skills/jskit/references/patterns/realtime/realtime-application/example/package.json +2 -2
- package/skills/jskit/references/patterns/users/user-administration-server/PATTERN.md +7 -3
- package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users/package.json +3 -3
- package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users-workspace/package.json +5 -5
- package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users-workspace/src/server/workspaceMembersOnly.js +69 -17
- package/skills/jskit/references/sanity-checks.md +4 -4
- package/skills/jskit/references/typed-features.md +12 -3
|
@@ -250,6 +250,13 @@ mapping in the resource; do not add page-local filtering or duplicate request
|
|
|
250
250
|
code. The full Books source example maps `q` to title, author and notes; narrow
|
|
251
251
|
it when adapting the example to fewer fields.
|
|
252
252
|
|
|
253
|
+
Every CRUD list also takes `id`, one record id or a list of them
|
|
254
|
+
(`filter[id]` on the JSON:API transport), and answers only those of its rows,
|
|
255
|
+
in the caller's scope. A picker whose selected values are not on the page it
|
|
256
|
+
loaded reads them this way, all in one request, instead of showing their raw
|
|
257
|
+
ids or reading pages until it finds them; `useCrudListFilterLookups()` does it
|
|
258
|
+
for a lookup filter's chips and options.
|
|
259
|
+
|
|
253
260
|
The browser page's route query and internal CRUD query use plain `q`. The
|
|
254
261
|
JSON:API HTTP transport uses `filter[q]`. Shared CRUD clients encode and decode
|
|
255
262
|
this automatically. Raw HTTP/API tests must send the transport key themselves:
|
|
@@ -60,7 +60,9 @@ A grouped `aggregate` answers its groups from one statement, at most
|
|
|
60
60
|
`pageLimits().request` of them (the resource's `queryMaxLimit`). When there
|
|
61
61
|
are more it throws a 400 coded `RESOURCE_GROUP_LIMIT` instead of answering
|
|
62
62
|
part of them. Narrow the filters, or read the groups in pages, `page: { size,
|
|
63
|
-
number }` with `number` from 1
|
|
63
|
+
number }` with `number` from 1. A page answers as a `query` page does, `{ rows,
|
|
64
|
+
page: { size, number, hasMore, next } }`, never a bare array that could pass
|
|
65
|
+
for every group: read the next while `page.hasMore`.
|
|
64
66
|
Page numbers are offsets, so read every page before work that changes what
|
|
65
67
|
the filters match.
|
|
66
68
|
|
|
@@ -710,12 +712,12 @@ takes first.
|
|
|
710
712
|
// good: the lock is the transaction's first read, so the bookings read after it are current
|
|
711
713
|
const reserve = (seatId, options) => seats.withTransaction(options, async (txOptions) => {
|
|
712
714
|
await seats.lock(seatId, { ...txOptions, fields: ["status"] });
|
|
713
|
-
const taken = await bookings.queryAll({ filters: { seatIds: [seatId] } }, txOptions);
|
|
714
|
-
return taken
|
|
715
|
+
const [taken] = await bookings.queryAll({ filters: { seatIds: [seatId] }, take: 1 }, txOptions);
|
|
716
|
+
return taken ? null : bookings.create({ seatId }, { ...txOptions, returning: "id" });
|
|
715
717
|
});
|
|
716
718
|
|
|
717
719
|
// bad: the read before the lock fixed the snapshot, so a booking committed while the lock waited is missed
|
|
718
|
-
const
|
|
720
|
+
const [booked] = await bookings.queryAll({ filters: { seatIds: [seatId] }, take: 1 }, txOptions);
|
|
719
721
|
await seats.lock(seatId, txOptions);
|
|
720
722
|
```
|
|
721
723
|
|
|
@@ -926,7 +928,11 @@ async function activeDays(memberIds, options) {
|
|
|
926
928
|
`page.number` reads with OFFSET, which slows as the rows grow, so anything
|
|
927
929
|
that grows pages with `page.after`. Each page is one statement, with no
|
|
928
930
|
count: never walk pages to reach one.
|
|
929
|
-
- A screen list never uses `queryAll
|
|
931
|
+
- A screen list never uses `queryAll`, and neither does a picker: it reads
|
|
932
|
+
one page searched on the server as the person types (`q`), narrowed in the
|
|
933
|
+
query by what it depends on (the parent record, `active`), and reads its
|
|
934
|
+
selected values past that page by id. Reading every row for a dropdown, or
|
|
935
|
+
narrowing a page in code, either grows with the table or misses rows.
|
|
930
936
|
- Related rows come by id list (`filters: { id: ids }`, or an `in` filter on
|
|
931
937
|
another field) or `include`, grouped in memory. Never a query per row, however
|
|
932
938
|
the loop is spelled (`for`, `map` with `Promise.all`, a helper called per
|
|
@@ -982,6 +988,66 @@ const { records: firstPage } = await subscriptions.query({ filters: { newsletter
|
|
|
982
988
|
|
|
983
989
|
Bad: a list read 100-row pages in a loop for each of 40 related sets.
|
|
984
990
|
|
|
991
|
+
## Narrow in the query
|
|
992
|
+
|
|
993
|
+
A read asks the store for exactly the rows the code uses. The filter, sort,
|
|
994
|
+
limit, existence check and count go in the read, never in code over the rows
|
|
995
|
+
it answered: a read of every row then narrowed is slow, and a page or a `take`
|
|
996
|
+
then narrowed is also wrong, since the row wanted can sit past it.
|
|
997
|
+
|
|
998
|
+
- Filter with the resource's searchSchema: a field
|
|
999
|
+
(`filters: { status: "open" }`), an id list (`filters: { id: ids }`, or an
|
|
1000
|
+
`in` filter on another field), or `q` for typed text, whose `oneOf` names the
|
|
1001
|
+
fields it searches.
|
|
1002
|
+
- One row: a unique filter with `take: 1` or `page: { size: 1 }`, which also
|
|
1003
|
+
answers whether one exists. A count: `aggregate()`.
|
|
1004
|
+
- Never filter, find, slice or count the rows a read answered, nor skip some
|
|
1005
|
+
in a loop. Mapping them and grouping them by a key (`Map.groupBy`) narrow
|
|
1006
|
+
nothing, and neither does code that needs every row it read: rows handed on
|
|
1007
|
+
whole (returned, passed, stored, mapped or walked in full) with a subset
|
|
1008
|
+
derived beside them, and rows matched against other items in a loop or a
|
|
1009
|
+
callback (an in-memory join, one read instead of one per item).
|
|
1010
|
+
- A lookup field's picker and a list's Search box send what the person types
|
|
1011
|
+
as `q` to the server, which searches every row; `useList` does with
|
|
1012
|
+
`search: { enabled: true }`. The table resource defines `searchSchema.q`.
|
|
1013
|
+
Never search the page a list loaded in the browser: it misses every row past
|
|
1014
|
+
it.
|
|
1015
|
+
- A CRUD list refuses a query key it does not take with a 400
|
|
1016
|
+
(`crud.query.undeclaredKeys`). A list filter is declared in the feature's
|
|
1017
|
+
`listFilterQueryValidator` and the resource's searchSchema.
|
|
1018
|
+
- Prove a capped read with a test that seeds past the cap and makes the row
|
|
1019
|
+
the cap leaves out (the oldest, for a newest-first read) the one that
|
|
1020
|
+
matches: the read that asks for it finds it; a read narrowed in code does
|
|
1021
|
+
not.
|
|
1022
|
+
|
|
1023
|
+
```js
|
|
1024
|
+
// good: the store answers one module's sections
|
|
1025
|
+
const { records } = await sections.query({ filters: { moduleId }, sort: ["-createdAt"], page: { size: 50 } }, options);
|
|
1026
|
+
|
|
1027
|
+
// bad: the newest 200 sections of every module, then one module's kept in code
|
|
1028
|
+
const { records: recent } = await sections.query({ sort: ["-createdAt"], page: { size: 200 } }, options);
|
|
1029
|
+
const moduleSections = recent.filter((section) => section.moduleId === moduleId);
|
|
1030
|
+
|
|
1031
|
+
// good: one row says who holds a unique username
|
|
1032
|
+
const [holder] = await profiles.queryAll({ filters: { usernames: [username] }, take: 1 }, options);
|
|
1033
|
+
```
|
|
1034
|
+
|
|
1035
|
+
`jskit/narrow-in-query` reports `.filter()`, `.find()`, `.some()`,
|
|
1036
|
+
`.every()`, `.slice()`, a lone `.length` and a loop that skips rows with
|
|
1037
|
+
`continue` over the rows a read answered in the same function, unless the
|
|
1038
|
+
code also uses those rows whole, runs the narrowing once per item of
|
|
1039
|
+
something else, read at most one row, or slices a read that asked for one row
|
|
1040
|
+
more than it keeps (`limit(size + 1)`) to learn whether more follow.
|
|
1041
|
+
`jskit/search-on-server` reports a client search over a list's loaded items.
|
|
1042
|
+
`jskit check` fails a lookup field or a CRUD list screen whose app table
|
|
1043
|
+
resource has no `searchSchema.q`, on the resource or its owns entry
|
|
1044
|
+
(`data/search-q`). Other code that needs every row a read answers says why on
|
|
1045
|
+
the line above the read or the narrowing:
|
|
1046
|
+
|
|
1047
|
+
```js
|
|
1048
|
+
// readable-check: allow narrow-in-query - every row: a conversation holds at most keep + 1 summaries, since each save deletes the older ones
|
|
1049
|
+
```
|
|
1050
|
+
|
|
985
1051
|
## What changed since
|
|
986
1052
|
|
|
987
1053
|
A page that catches up on a chat, a watch that acts on changes and a sync to
|
|
@@ -1077,10 +1143,10 @@ const SettlementFeature = defineFeature({
|
|
|
1077
1143
|
async function settleDue(options) {
|
|
1078
1144
|
const size = cohorts.pageLimits().request;
|
|
1079
1145
|
const due = [];
|
|
1080
|
-
for (let number = 1; ;
|
|
1081
|
-
const page = await cohorts.aggregate({ measures: { cohorts: { count: "id" } }, groupBy: ["workspaceId"], filters: { status: "finished" }, page: { size, number } }, options);
|
|
1082
|
-
due.push(...
|
|
1083
|
-
|
|
1146
|
+
for (let number = 1; number; ) {
|
|
1147
|
+
const { rows, page } = await cohorts.aggregate({ measures: { cohorts: { count: "id" } }, groupBy: ["workspaceId"], filters: { status: "finished" }, page: { size, number } }, options);
|
|
1148
|
+
due.push(...rows);
|
|
1149
|
+
number = page.next;
|
|
1084
1150
|
}
|
|
1085
1151
|
for (const { workspaceId } of due) {
|
|
1086
1152
|
await settleWorkspace({ context: systemContext("settle finished weekly leagues for every user").forWorkspace(workspaceId) });
|
|
@@ -38,7 +38,7 @@ How to use it:
|
|
|
38
38
|
- [ui-contract.md](./ui-contract.md)
|
|
39
39
|
- filter, filters, search facets, chips, date range, enum filter, lookup filter, `useCrudListFilters`, `createCrudListFilters`
|
|
40
40
|
- [filters.md](./filters.md)
|
|
41
|
-
- `searchSchema`, `search: true`, `applyFilter`, server search, query validators, backend filters, internal JSON REST filters
|
|
41
|
+
- `searchSchema`, `search: true`, `applyFilter`, server search, query validators, backend filters, internal JSON REST filters, picker search, `q`, filtering rows in code, `jskit/narrow-in-query`, `jskit/search-on-server`, `data/search-q`, `crud.query.undeclaredKeys`
|
|
42
42
|
- [server-search.md](./server-search.md)
|
|
43
43
|
- `actualField`, `storage.column`, `storage.writeSerializer`, `storage.virtual`, `queryFields`, computed field, virtual field, projection, `defaultTo`, datetime write serialization, temporalPrecision, json-rest-schema dates
|
|
44
44
|
- [table-resource-fields.md](./table-resource-fields.md)
|
|
@@ -13,6 +13,7 @@ Pick the layer ([Data access](../data-access.md)):
|
|
|
13
13
|
- Two requests could change the same rows: `lockMany` inside `withTransaction`, rows in id order.
|
|
14
14
|
- Work inside `withTransaction`: `txOptions` is only `{ context, trx }`, so a key the work needs, the app's own included, comes from the method's `options`, and a write on the method's own table gets `{ ...options, ...txOptions }` so the caller's `returning`, `missing` or `format` reaches it.
|
|
15
15
|
- A change only while a row still holds a value (open to booked, once): `patch` with `onlyIf`, or `patchWhere` with that value in its filters (a compare-and-set on every database, so of two concurrent writers one wins); a filter on a related table is refused on MySQL and MariaDB (`selection_cross_table`), so filter on the row's own columns, after locking the related rows with `lockMany`, or use `claim`.
|
|
16
|
+
- Only some of the rows, one row, whether one exists: in the read (a searchSchema filter, `take: 1` or a page of size 1), never `.filter()`, `.find()`, `.some()`, `.slice()` or `.length` over the rows it answered ([Narrow in the query](../data-access.md#narrow-in-the-query)).
|
|
16
17
|
- Counts, sums, buckets: `aggregate`; newest per group: a window include; anything else: one `scopedQuery()` method under `// Knex: <kind> - <reason>`.
|
|
17
18
|
- Every workspace or user at once: a job with `systemScope`, finding its units with an `aggregate` grouped by the ownership field and looping over them, never rows.
|
|
18
19
|
- A table another feature owns: its service or owner API, never its table. A report that joins it joins the `{ query, column }` its owner API answers from `scopedQuery({ alias })`, as a subquery: one statement, both scopes kept.
|
|
@@ -132,6 +132,20 @@ Use `useCrudListFilterLookups(...)` when:
|
|
|
132
132
|
- the UI needs remote autocomplete search
|
|
133
133
|
- chips should show readable labels instead of raw ids
|
|
134
134
|
|
|
135
|
+
A lookup filter's options are one server page, searched on the server as the
|
|
136
|
+
person types (`setSearch`, sent as `q`):
|
|
137
|
+
- the page keeps the server's order while more rows remain (`hasMore`), and is
|
|
138
|
+
sorted by label only once every row is loaded; `loadMore()` (or
|
|
139
|
+
`loadMoreLookup(key)`) reads the next page, so never present the first page
|
|
140
|
+
as the complete list
|
|
141
|
+
- a selected value past the loaded page (from the URL or a bookmark) is read by
|
|
142
|
+
id, every such value in one request, so its chip shows its label
|
|
143
|
+
- the options load when something shows them (the open filter sheet's
|
|
144
|
+
control, or a search), not with every list page
|
|
145
|
+
- a lookup narrowed by another value (only active suppliers, only one
|
|
146
|
+
region's) passes it in `requestQueryParams[filterKey]`, which the lookup's
|
|
147
|
+
list must accept as a filter
|
|
148
|
+
|
|
135
149
|
Use built-in `presence` when:
|
|
136
150
|
- a filter means null vs not-null, such as assigned vs unassigned storage
|
|
137
151
|
- the UI wants custom labels like "Assigned" / "Unassigned" but the transport contract can stay `present` / `missing`
|
|
@@ -243,6 +243,8 @@ owns: [{ resource: contactResource, rowPolicy: ownContactsOrShared }]
|
|
|
243
243
|
- Put visibility in the owner's row policy, never in a search key or route query validation.
|
|
244
244
|
- Do not expose a query key publicly just because the service maps to it internally.
|
|
245
245
|
- Do not rely on route validators alone; a public key still needs a matching backend search definition.
|
|
246
|
+
- A CRUD list refuses a query key its route does not declare with a 400 (`crud.query.undeclaredKeys`), so an undeclared filter fails loudly instead of answering every row.
|
|
247
|
+
- Never narrow the rows a read answered in code, and never search a list's loaded page in the browser: the filter goes in the read, and a picker or Search box sends `q` ([Narrow in the query](../data-access.md#narrow-in-the-query); `jskit/narrow-in-query`, `jskit/search-on-server`, and `jskit check`'s `data/search-q` for a lookup or list screen whose resource has no `searchSchema.q`).
|
|
246
248
|
|
|
247
249
|
## Quick Rule Of Thumb
|
|
248
250
|
|
|
@@ -196,12 +196,21 @@ method takes the call's `options` last and joins the transaction of the
|
|
|
196
196
|
| Capability | Methods |
|
|
197
197
|
| --- | --- |
|
|
198
198
|
| `workspaces` | `findById(id, options)`, `findBySlug(slug, options)` (a deleted workspace is not found, though its slug stays taken), `listSlugsIn`, `findPersonalByOwnerUserId`, `listForUserId(userId, options)`, `insert`, `updateById`, `lock(workspaceId, options)` |
|
|
199
|
-
| `workspaces.memberships` | `findByWorkspaceIdAndUserId`, `ensureOwnerMembership`, `upsertMembership(workspaceId, userId, patch, options)`, `addMember({ workspaceId, userId, roleSid }, options)`, `activeMemberIds(workspaceId, options)`, `listActiveByWorkspaceId`, `findActiveByWorkspaceIdAndUserId`, `listActiveWorkspaceIdsByUserId`, `listActiveWorkspaceIdsByUserIds` |
|
|
199
|
+
| `workspaces.memberships` | `findByWorkspaceIdAndUserId`, `ensureOwnerMembership`, `upsertMembership(workspaceId, userId, patch, options)`, `addMember({ workspaceId, userId, roleSid }, options)`, `activeMemberIds(workspaceId, options)`, `listActiveByWorkspaceId`, `findActiveByWorkspaceIdAndUserId`, `listActiveWorkspaceIdsByUserId`, `listActiveWorkspaceIdsByUserIds`, `listActiveWorkspaceIdsByUserIdsAmong(userIds, workspaceIds, options)`, `joinSource({ alias, filters }, options)` |
|
|
200
200
|
|
|
201
201
|
`addMember` makes the user an active member with the role (`member` when none
|
|
202
202
|
is given), adding the membership or reactivating it. `activeMemberIds` answers
|
|
203
|
-
|
|
204
|
-
|
|
203
|
+
every active member's user id, without their profiles: it reads all of the
|
|
204
|
+
workspace's active memberships, so its cost grows with the workspace, and so
|
|
205
|
+
do `listActiveByWorkspaceId`'s and
|
|
206
|
+
`workspaces.services.members.listMembers(workspace, options)`'s. Use them where
|
|
207
|
+
the work needs every member, such as a job, a delivery's recipients or a
|
|
208
|
+
realtime audience. A screen or list reads a page instead:
|
|
209
|
+
`workspaces.services.members.listMembersPage(workspace, { cursor, limit }, options)`
|
|
210
|
+
answers one page of active members by display name (`limit`, 20 when none)
|
|
211
|
+
with the `nextCursor` that asks for the next, null on the last, and an app's
|
|
212
|
+
own list of members pages them in SQL with one report over the memberships'
|
|
213
|
+
`joinSource`. `lock` takes
|
|
205
214
|
the workspace's row lock until the caller's transaction ends, so work that must
|
|
206
215
|
not interleave for one workspace takes turns; it runs only inside a
|
|
207
216
|
transaction, given its `txOptions`, and answers `{ id }`, or `null` when there
|
|
@@ -15,7 +15,7 @@ A concrete Fastify, Vue, and JSKIT application foundation for products that do n
|
|
|
15
15
|
|
|
16
16
|
- Id: `app/minimal-foundation`
|
|
17
17
|
- Keywords: `app`, `fastify`, `foundation`, `minimal`, `server`, `vite`, `vue`
|
|
18
|
-
- Owner: `@jskit-ai/agent-docs@0.1.
|
|
18
|
+
- Owner: `@jskit-ai/agent-docs@0.1.295`
|
|
19
19
|
- Read: [PATTERN.md](patterns/app/minimal-foundation/PATTERN.md)
|
|
20
20
|
- Examples: [example/](patterns/app/minimal-foundation/example/)
|
|
21
21
|
- Requires: `@jskit-ai/http-runtime`, `@jskit-ai/kernel`
|
|
@@ -26,7 +26,7 @@ A concrete JSKIT web application foundation with responsive shell navigation, se
|
|
|
26
26
|
|
|
27
27
|
- Id: `app/shell-foundation`
|
|
28
28
|
- Keywords: `app`, `foundation`, `material`, `navigation`, `placements`, `shell`, `vite`, `vue`
|
|
29
|
-
- Owner: `@jskit-ai/agent-docs@0.1.
|
|
29
|
+
- Owner: `@jskit-ai/agent-docs@0.1.295`
|
|
30
30
|
- Read: [PATTERN.md](patterns/app/shell-foundation/PATTERN.md)
|
|
31
31
|
- Examples: [example/](patterns/app/shell-foundation/example/)
|
|
32
32
|
- Requires: `@jskit-ai/http-runtime`, `@jskit-ai/kernel`, `@jskit-ai/shell-web`
|
|
@@ -37,7 +37,7 @@ Configure an assistant runtime for one application surface and expose its chat a
|
|
|
37
37
|
|
|
38
38
|
- Id: `assistant/assistant-surface`
|
|
39
39
|
- Keywords: `ai`, `assistant`, `chat`, `config`, `environment`, `page`, `placement`, `settings`, `surface`
|
|
40
|
-
- Owner: `@jskit-ai/assistant-runtime@0.2.
|
|
40
|
+
- Owner: `@jskit-ai/assistant-runtime@0.2.41`
|
|
41
41
|
- Read: [PATTERN.md](patterns/assistant/assistant-surface/PATTERN.md)
|
|
42
42
|
- Examples: [example/](patterns/assistant/assistant-surface/example/)
|
|
43
43
|
- Requires: `@jskit-ai/assistant-runtime`, `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`, `@jskit-ai/shell-web`
|
|
@@ -48,7 +48,7 @@ Run one OpenID Connect sign-in for all of an owner's apps as its own JSKIT proje
|
|
|
48
48
|
|
|
49
49
|
- Id: `auth/accounts-hub`
|
|
50
50
|
- Keywords: `accounts hub`, `auth`, `authentication`, `issuer`, `master login`, `oidc`, `openid connect`, `single sign-on`, `sso`
|
|
51
|
-
- Owner: `@jskit-ai/oidc-issuer-core@0.1.
|
|
51
|
+
- Owner: `@jskit-ai/oidc-issuer-core@0.1.27`
|
|
52
52
|
- Read: [PATTERN.md](patterns/auth/accounts-hub/PATTERN.md)
|
|
53
53
|
- Examples: [example/](patterns/auth/accounts-hub/example/)
|
|
54
54
|
- Requires: `@jskit-ai/oidc-issuer-core`
|
|
@@ -59,7 +59,7 @@ Compose JSKIT authentication routes, views, profile controls, and public surface
|
|
|
59
59
|
|
|
60
60
|
- Id: `auth/auth-surface`
|
|
61
61
|
- Keywords: `account`, `auth`, `login`, `logout`, `password`, `placement`, `profile`, `reset`, `surface`
|
|
62
|
-
- Owner: `@jskit-ai/auth-web@0.2.
|
|
62
|
+
- Owner: `@jskit-ai/auth-web@0.2.25`
|
|
63
63
|
- Read: [PATTERN.md](patterns/auth/auth-surface/PATTERN.md)
|
|
64
64
|
- Examples: [example/](patterns/auth/auth-surface/example/)
|
|
65
65
|
- Requires: `@jskit-ai/auth-core`, `@jskit-ai/auth-web`, `@jskit-ai/shell-web`
|
|
@@ -70,7 +70,7 @@ Let people sign in with the accounts they already have in an accounts hub or ano
|
|
|
70
70
|
|
|
71
71
|
- Id: `auth/oidc-sign-in`
|
|
72
72
|
- Keywords: `accounts hub`, `auth`, `authentication`, `back-channel logout`, `dynamic client registration`, `issuer`, `master login`, `oidc`, `openid connect`, `single sign-on`, `sso`
|
|
73
|
-
- Owner: `@jskit-ai/auth-provider-oidc-core@0.2.
|
|
73
|
+
- Owner: `@jskit-ai/auth-provider-oidc-core@0.2.27`
|
|
74
74
|
- Read: [PATTERN.md](patterns/auth/oidc-sign-in/PATTERN.md)
|
|
75
75
|
- Examples: [example/](patterns/auth/oidc-sign-in/example/)
|
|
76
76
|
- Requires: `@jskit-ai/auth-provider-oidc-core`, `@jskit-ai/auth-web`
|
|
@@ -81,7 +81,7 @@ Add Supabase authentication through normal npm composition, explicit environment
|
|
|
81
81
|
|
|
82
82
|
- Id: `auth/supabase-auth`
|
|
83
83
|
- Keywords: `auth`, `authentication`, `oauth`, `sessions`, `supabase`
|
|
84
|
-
- Owner: `@jskit-ai/auth-provider-supabase-core@0.2.
|
|
84
|
+
- Owner: `@jskit-ai/auth-provider-supabase-core@0.2.21`
|
|
85
85
|
- Read: [PATTERN.md](patterns/auth/supabase-auth/PATTERN.md)
|
|
86
86
|
- Examples: [example/](patterns/auth/supabase-auth/example/)
|
|
87
87
|
- Requires: `@jskit-ai/auth-provider-supabase-core`
|
|
@@ -92,7 +92,7 @@ Resolve an administrator environment key or an individual user's grant, then use
|
|
|
92
92
|
|
|
93
93
|
- Id: `connectors/ai-connections`
|
|
94
94
|
- Keywords: `ai`, `api-key`, `cli`, `environment`, `free`, `models`, `ownership`, `zai`, `zen`
|
|
95
|
-
- Owner: `@jskit-ai/connectors-catalog@0.2.
|
|
95
|
+
- Owner: `@jskit-ai/connectors-catalog@0.2.25`
|
|
96
96
|
- Read: [PATTERN.md](patterns/connectors/ai-connections/PATTERN.md)
|
|
97
97
|
- Examples: [example/](patterns/connectors/ai-connections/example/)
|
|
98
98
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -103,7 +103,7 @@ Compose provider operations, authorization and encrypted file storage from a CLI
|
|
|
103
103
|
|
|
104
104
|
- Id: `connectors/api-key-connection`
|
|
105
105
|
- Keywords: `api-key`, `clay`, `cli`, `clickhouse`, `connectors`, `dbt`, `files`, `firecrawl`, `granola`, `integrations`, `metrics`, `prestashop`, `resend`, `semantic-layer`, `semrush`, `x-twitter`
|
|
106
|
-
- Owner: `@jskit-ai/connectors-catalog@0.2.
|
|
106
|
+
- Owner: `@jskit-ai/connectors-catalog@0.2.25`
|
|
107
107
|
- Read: [PATTERN.md](patterns/connectors/api-key-connection/PATTERN.md)
|
|
108
108
|
- Examples: [example/](patterns/connectors/api-key-connection/example/)
|
|
109
109
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -114,7 +114,7 @@ Compose token-based MCP discovery and explicitly authorized tool calls using the
|
|
|
114
114
|
|
|
115
115
|
- Id: `connectors/assistant-mcp`
|
|
116
116
|
- Keywords: `assistant`, `cli`, `connectors`, `files`, `integrations`, `mcp`, `n8n`, `sanity`
|
|
117
|
-
- Owner: `@jskit-ai/connectors-catalog@0.2.
|
|
117
|
+
- Owner: `@jskit-ai/connectors-catalog@0.2.25`
|
|
118
118
|
- Read: [PATTERN.md](patterns/connectors/assistant-mcp/PATTERN.md)
|
|
119
119
|
- Examples: [example/](patterns/connectors/assistant-mcp/example/)
|
|
120
120
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -125,7 +125,7 @@ Configure assistant OAuth clients, then compose existing state, encrypted file g
|
|
|
125
125
|
|
|
126
126
|
- Id: `connectors/assistant-mcp-oauth`
|
|
127
127
|
- Keywords: `amplitude`, `assistant`, `atlassian`, `canva`, `cli`, `client metadata`, `confidence`, `connectors`, `figma`, `files`, `granola`, `hex`, `mcp`, `miro`, `oauth`
|
|
128
|
-
- Owner: `@jskit-ai/connectors-catalog@0.2.
|
|
128
|
+
- Owner: `@jskit-ai/connectors-catalog@0.2.25`
|
|
129
129
|
- Read: [PATTERN.md](patterns/connectors/assistant-mcp-oauth/PATTERN.md)
|
|
130
130
|
- Examples: [example/](patterns/connectors/assistant-mcp-oauth/example/)
|
|
131
131
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -136,7 +136,7 @@ Compose signed AWS operations, file configuration and application authorization
|
|
|
136
136
|
|
|
137
137
|
- Id: `connectors/aws-storage-queries`
|
|
138
138
|
- Keywords: `athena`, `aws`, `cli`, `connectors`, `files`, `iam`, `queries`, `s3`, `storage`, `sts`
|
|
139
|
-
- Owner: `@jskit-ai/connectors-catalog@0.2.
|
|
139
|
+
- Owner: `@jskit-ai/connectors-catalog@0.2.25`
|
|
140
140
|
- Read: [PATTERN.md](patterns/connectors/aws-storage-queries/PATTERN.md)
|
|
141
141
|
- Examples: [example/](patterns/connectors/aws-storage-queries/example/)
|
|
142
142
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -147,7 +147,7 @@ Compose reusable connection libraries with portable configuration, application o
|
|
|
147
147
|
|
|
148
148
|
- Id: `connectors/calendar-cli`
|
|
149
149
|
- Keywords: `calendar`, `cli`, `connectors`, `google`, `integrations`, `oauth`, `permissions`
|
|
150
|
-
- Owner: `@jskit-ai/connector-google-calendar@0.2.
|
|
150
|
+
- Owner: `@jskit-ai/connector-google-calendar@0.2.25`
|
|
151
151
|
- Read: [PATTERN.md](patterns/connectors/calendar-cli/PATTERN.md)
|
|
152
152
|
- Examples: [example/](patterns/connectors/calendar-cli/example/)
|
|
153
153
|
- Requires: `@jskit-ai/connector-google-calendar`, `@jskit-ai/connectors-core`, `@jskit-ai/database-runtime-mysql`
|
|
@@ -158,7 +158,7 @@ Compose the shared connector runtime for event delivery while leaving workflow c
|
|
|
158
158
|
|
|
159
159
|
- Id: `connectors/event-delivery`
|
|
160
160
|
- Keywords: `cli`, `connectors`, `events`, `files`, `inngest`, `integrations`, `workflows`
|
|
161
|
-
- Owner: `@jskit-ai/connectors-catalog@0.2.
|
|
161
|
+
- Owner: `@jskit-ai/connectors-catalog@0.2.25`
|
|
162
162
|
- Read: [PATTERN.md](patterns/connectors/event-delivery/PATTERN.md)
|
|
163
163
|
- Examples: [example/](patterns/connectors/event-delivery/example/)
|
|
164
164
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -169,7 +169,7 @@ Wire service-account grants, file storage, explicit message actions and public b
|
|
|
169
169
|
|
|
170
170
|
- Id: `connectors/firebase-messaging`
|
|
171
171
|
- Keywords: `cli`, `connectors`, `fcm`, `files`, `firebase`, `integrations`, `jwt`, `notifications`, `push`, `service-account`, `vapid`
|
|
172
|
-
- Owner: `@jskit-ai/connectors-catalog@0.2.
|
|
172
|
+
- Owner: `@jskit-ai/connectors-catalog@0.2.25`
|
|
173
173
|
- Read: [PATTERN.md](patterns/connectors/firebase-messaging/PATTERN.md)
|
|
174
174
|
- Examples: [example/](patterns/connectors/firebase-messaging/example/)
|
|
175
175
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -180,7 +180,7 @@ Compose reviewed Search campaigns with project-owned Google OAuth and portable s
|
|
|
180
180
|
|
|
181
181
|
- Id: `connectors/google-ads-search`
|
|
182
182
|
- Keywords: `ads`, `campaigns`, `cli`, `connectors`, `conversion`, `google`, `search`
|
|
183
|
-
- Owner: `@jskit-ai/connectors-catalog@0.2.
|
|
183
|
+
- Owner: `@jskit-ai/connectors-catalog@0.2.25`
|
|
184
184
|
- Read: [PATTERN.md](patterns/connectors/google-ads-search/PATTERN.md)
|
|
185
185
|
- Examples: [example/](patterns/connectors/google-ads-search/example/)
|
|
186
186
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -191,7 +191,7 @@ Compose provider consent, verification and encrypted file persistence from an ap
|
|
|
191
191
|
|
|
192
192
|
- Id: `connectors/oauth-connection`
|
|
193
193
|
- Keywords: `accounting`, `assistant permissions`, `books`, `cli`, `client credentials`, `connectors`, `consent`, `crm`, `databricks`, `developer token`, `fabric`, `files`, `gaql`, `google ads`, `graphql`, `integrations`, `linkedin`, `microsoft`, `oauth`, `powerpoint`, `salesforce`, `service principal`, `shopify`, `soql`, `staffing`, `tiktok`, `twitch`, `wave`, `word`, `wordpress`, `workday`, `xero`, `zoho`
|
|
194
|
-
- Owner: `@jskit-ai/connectors-catalog@0.2.
|
|
194
|
+
- Owner: `@jskit-ai/connectors-catalog@0.2.25`
|
|
195
195
|
- Read: [PATTERN.md](patterns/connectors/oauth-connection/PATTERN.md)
|
|
196
196
|
- Examples: [example/](patterns/connectors/oauth-connection/example/)
|
|
197
197
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -202,7 +202,7 @@ Compose a sequential catalogue batch and preserve partial success for applicatio
|
|
|
202
202
|
|
|
203
203
|
- Id: `connectors/paddle-catalogue`
|
|
204
204
|
- Keywords: `batch`, `paddle`, `payments`, `prices`, `products`
|
|
205
|
-
- Owner: `@jskit-ai/connectors-catalog@0.2.
|
|
205
|
+
- Owner: `@jskit-ai/connectors-catalog@0.2.25`
|
|
206
206
|
- Read: [PATTERN.md](patterns/connectors/paddle-catalogue/PATTERN.md)
|
|
207
207
|
- Examples: [example/](patterns/connectors/paddle-catalogue/example/)
|
|
208
208
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -213,7 +213,7 @@ Resolve a publishable image key deliberately and use the shared URL library in a
|
|
|
213
213
|
|
|
214
214
|
- Id: `connectors/public-image`
|
|
215
215
|
- Keywords: `cli`, `connectors`, `files`, `images`, `integrations`, `logo-dev`, `public-key`
|
|
216
|
-
- Owner: `@jskit-ai/connectors-catalog@0.2.
|
|
216
|
+
- Owner: `@jskit-ai/connectors-catalog@0.2.25`
|
|
217
217
|
- Read: [PATTERN.md](patterns/connectors/public-image/PATTERN.md)
|
|
218
218
|
- Examples: [example/](patterns/connectors/public-image/example/)
|
|
219
219
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -224,7 +224,7 @@ Compose file configuration, Redshift Data API operations and application query o
|
|
|
224
224
|
|
|
225
225
|
- Id: `connectors/redshift-queries`
|
|
226
226
|
- Keywords: `aws`, `cli`, `connectors`, `files`, `iam`, `provisioned`, `redshift`, `serverless`, `sql`, `warehouse`
|
|
227
|
-
- Owner: `@jskit-ai/connectors-catalog@0.2.
|
|
227
|
+
- Owner: `@jskit-ai/connectors-catalog@0.2.25`
|
|
228
228
|
- Read: [PATTERN.md](patterns/connectors/redshift-queries/PATTERN.md)
|
|
229
229
|
- Examples: [example/](patterns/connectors/redshift-queries/example/)
|
|
230
230
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -235,7 +235,7 @@ Use the shared scanner runtime from a CLI or a host worker with portable configu
|
|
|
235
235
|
|
|
236
236
|
- Id: `connectors/source-scanning`
|
|
237
237
|
- Keywords: `cancellation`, `cli`, `connectors`, `integrations`, `scanning`, `security`, `source`, `wiz`, `worker`
|
|
238
|
-
- Owner: `@jskit-ai/connectors-catalog@0.2.
|
|
238
|
+
- Owner: `@jskit-ai/connectors-catalog@0.2.25`
|
|
239
239
|
- Read: [PATTERN.md](patterns/connectors/source-scanning/PATTERN.md)
|
|
240
240
|
- Examples: [example/](patterns/connectors/source-scanning/example/)
|
|
241
241
|
- Requires: `@jskit-ai/connectors-catalog`, `@jskit-ai/connectors-core`
|
|
@@ -246,7 +246,7 @@ Add a protected administration surface, settings shell, and semantic navigation
|
|
|
246
246
|
|
|
247
247
|
- Id: `console/console-surface`
|
|
248
248
|
- Keywords: `admin`, `console`, `navigation`, `owner`, `placement`, `settings`, `surface`
|
|
249
|
-
- Owner: `@jskit-ai/console-web@0.1.
|
|
249
|
+
- Owner: `@jskit-ai/console-web@0.1.252`
|
|
250
250
|
- Read: [PATTERN.md](patterns/console/console-surface/PATTERN.md)
|
|
251
251
|
- Examples: [example/](patterns/console/console-surface/example/)
|
|
252
252
|
- Requires: `@jskit-ai/console-core`, `@jskit-ai/console-web`, `@jskit-ai/shell-web`
|
|
@@ -257,7 +257,7 @@ Define an application table resource whose records belong to the current user, a
|
|
|
257
257
|
|
|
258
258
|
- Id: `crud/crud-contract`
|
|
259
259
|
- Keywords: `authenticated`, `crud`, `database`, `owner-scoped`, `resource`, `table`, `user`
|
|
260
|
-
- Owner: `@jskit-ai/resource-crud-core@0.1.
|
|
260
|
+
- Owner: `@jskit-ai/resource-crud-core@0.1.210`
|
|
261
261
|
- Read: [PATTERN.md](patterns/crud/crud-contract/PATTERN.md)
|
|
262
262
|
- Examples: [example/](patterns/crud/crud-contract/example/)
|
|
263
263
|
- Requires: `@jskit-ai/resource-core`, `@jskit-ai/resource-crud-core`
|
|
@@ -268,7 +268,7 @@ Build a complete application-owned CRUD server package from a migration, a table
|
|
|
268
268
|
|
|
269
269
|
- Id: `crud/crud-feature-package`
|
|
270
270
|
- Keywords: `actions`, `crud`, `database`, `defineCrudFeature`, `json-api`, `migration`, `owns`, `permissions`, `repository`, `routes`, `service`, `table resource`
|
|
271
|
-
- Owner: `@jskit-ai/crud-core@0.2.
|
|
271
|
+
- Owner: `@jskit-ai/crud-core@0.2.25`
|
|
272
272
|
- Read: [PATTERN.md](patterns/crud/crud-feature-package/PATTERN.md)
|
|
273
273
|
- Examples: [example/](patterns/crud/crud-feature-package/example/)
|
|
274
274
|
- Requires: `@jskit-ai/crud-core`, `@jskit-ai/resource-core`, `@jskit-ai/resource-crud-core`
|
|
@@ -279,7 +279,7 @@ Build a routed CRUD user interface as thin application pages over JSKIT's shared
|
|
|
279
279
|
|
|
280
280
|
- Id: `crud/crud-screen-set`
|
|
281
281
|
- Keywords: `actions`, `add`, `crud`, `delete`, `edit`, `filters`, `list`, `material`, `routes`, `view`, `vue`
|
|
282
|
-
- Owner: `@jskit-ai/http-web@0.2.
|
|
282
|
+
- Owner: `@jskit-ai/http-web@0.2.28`
|
|
283
283
|
- Read: [PATTERN.md](patterns/crud/crud-screen-set/PATTERN.md)
|
|
284
284
|
- Examples: [example/](patterns/crud/crud-screen-set/example/)
|
|
285
285
|
- Requires: `@jskit-ai/http-web`, `@jskit-ai/resource-core`, `@jskit-ai/resource-crud-core`
|
|
@@ -323,7 +323,7 @@ Wrap a JSKIT web application in a Capacitor Android shell using native Capacitor
|
|
|
323
323
|
|
|
324
324
|
- Id: `mobile/android-application`
|
|
325
325
|
- Keywords: `android`, `capacitor`, `device`, `mobile`, `native`, `shell`, `webview`
|
|
326
|
-
- Owner: `@jskit-ai/mobile-capacitor@0.2.
|
|
326
|
+
- Owner: `@jskit-ai/mobile-capacitor@0.2.23`
|
|
327
327
|
- Read: [PATTERN.md](patterns/mobile/android-application/PATTERN.md)
|
|
328
328
|
- Examples: [example/](patterns/mobile/android-application/example/)
|
|
329
329
|
- Requires: `@capacitor/android`, `@capacitor/app`, `@capacitor/cli`, `@jskit-ai/mobile-capacitor`
|
|
@@ -334,7 +334,7 @@ Add JSKIT realtime events with an optional Redis backplane and an explicit shell
|
|
|
334
334
|
|
|
335
335
|
- Id: `realtime/realtime-application`
|
|
336
336
|
- Keywords: `realtime`, `redis`, `socket.io`, `sockets`, `status`, `websocket`
|
|
337
|
-
- Owner: `@jskit-ai/realtime@0.2.
|
|
337
|
+
- Owner: `@jskit-ai/realtime@0.2.26`
|
|
338
338
|
- Read: [PATTERN.md](patterns/realtime/realtime-application/PATTERN.md)
|
|
339
339
|
- Examples: [example/](patterns/realtime/realtime-application/example/)
|
|
340
340
|
- Requires: `@jskit-ai/realtime`, `@jskit-ai/shell-web`
|
|
@@ -345,7 +345,7 @@ Compose application-owned Google Publisher Tag delivery with the generic rewarde
|
|
|
345
345
|
|
|
346
346
|
- Id: `rewards/google-rewarded`
|
|
347
347
|
- Keywords: `ads`, `google`, `publisher tag`, `rewarded`, `unlock`
|
|
348
|
-
- Owner: `@jskit-ai/rewarded-web@0.2.
|
|
348
|
+
- Owner: `@jskit-ai/rewarded-web@0.2.30`
|
|
349
349
|
- Read: [PATTERN.md](patterns/rewards/google-rewarded/PATTERN.md)
|
|
350
350
|
- Examples: [example/](patterns/rewards/google-rewarded/example/)
|
|
351
351
|
- Requires: `@jskit-ai/rewarded-web`
|
|
@@ -356,7 +356,7 @@ Define a server feature through explicit capabilities and first-class actions, a
|
|
|
356
356
|
|
|
357
357
|
- Id: `server/feature-package`
|
|
358
358
|
- Keywords: `actions`, `aggregate`, `feature`, `handle`, `orchestration`, `owns`, `package`, `provider`, `repository`, `routes`, `server`, `table resource`
|
|
359
|
-
- Owner: `@jskit-ai/agent-docs@0.1.
|
|
359
|
+
- Owner: `@jskit-ai/agent-docs@0.1.295`
|
|
360
360
|
- Read: [PATTERN.md](patterns/server/feature-package/PATTERN.md)
|
|
361
361
|
- Examples: [example/](patterns/server/feature-package/example/)
|
|
362
362
|
- Requires: `@jskit-ai/kernel`
|
|
@@ -367,7 +367,7 @@ Compose the JSKIT responsive shell, semantic placements, settings navigation, an
|
|
|
367
367
|
|
|
368
368
|
- Id: `shell/application-shell`
|
|
369
369
|
- Keywords: `adaptive`, `app`, `layout`, `navigation`, `placement`, `responsive`, `settings`, `shell`
|
|
370
|
-
- Owner: `@jskit-ai/shell-web@0.2.
|
|
370
|
+
- Owner: `@jskit-ai/shell-web@0.2.23`
|
|
371
371
|
- Read: [PATTERN.md](patterns/shell/application-shell/PATTERN.md)
|
|
372
372
|
- Examples: [example/](patterns/shell/application-shell/example/)
|
|
373
373
|
- Requires: `@jskit-ai/kernel`, `@jskit-ai/shell-web`
|
|
@@ -378,7 +378,7 @@ Add product routes and shell extensions through file routing, semantic placement
|
|
|
378
378
|
|
|
379
379
|
- Id: `ui/page-and-placement`
|
|
380
380
|
- Keywords: `component`, `navigation`, `outlet`, `page`, `placement`, `routes`, `section`, `shell`, `subpages`, `vue`
|
|
381
|
-
- Owner: `@jskit-ai/shell-web@0.2.
|
|
381
|
+
- Owner: `@jskit-ai/shell-web@0.2.23`
|
|
382
382
|
- Read: [PATTERN.md](patterns/ui/page-and-placement/PATTERN.md)
|
|
383
383
|
- Examples: [example/](patterns/ui/page-and-placement/example/)
|
|
384
384
|
- Requires: `@jskit-ai/kernel`, `@jskit-ai/shell-web`
|
|
@@ -389,7 +389,7 @@ Compose an account settings route and profile, preference, notification, and sig
|
|
|
389
389
|
|
|
390
390
|
- Id: `users/account-settings`
|
|
391
391
|
- Keywords: `account`, `link provider`, `notifications`, `oauth`, `preferences`, `profile`, `settings`, `sign-in methods`, `user`, `vue`
|
|
392
|
-
- Owner: `@jskit-ai/users-web@0.2.
|
|
392
|
+
- Owner: `@jskit-ai/users-web@0.2.35`
|
|
393
393
|
- Read: [PATTERN.md](patterns/users/account-settings/PATTERN.md)
|
|
394
394
|
- Examples: [example/](patterns/users/account-settings/example/)
|
|
395
395
|
- Requires: `@jskit-ai/shell-web`, `@jskit-ai/users-core`, `@jskit-ai/users-web`
|
|
@@ -400,7 +400,7 @@ Expose user administration and workspace-scoped member operations through app-ow
|
|
|
400
400
|
|
|
401
401
|
- Id: `users/user-administration-server`
|
|
402
402
|
- Keywords: `account`, `admin`, `member`, `repository`, `resource`, `routes`, `service`, `user`, `workspace`
|
|
403
|
-
- Owner: `@jskit-ai/users-core@0.2.
|
|
403
|
+
- Owner: `@jskit-ai/users-core@0.2.26`
|
|
404
404
|
- Read: [PATTERN.md](patterns/users/user-administration-server/PATTERN.md)
|
|
405
405
|
- Examples: [example/](patterns/users/user-administration-server/example/)
|
|
406
406
|
- Requires: `@jskit-ai/crud-core`, `@jskit-ai/users-core`
|
|
@@ -411,7 +411,7 @@ Configure roles, workspace access policy, invitations, and app-owned invitation
|
|
|
411
411
|
|
|
412
412
|
- Id: `workspaces/workspace-server`
|
|
413
413
|
- Keywords: `access`, `invite`, `membership`, `multitenancy`, `policy`, `role`, `tenancy`, `workspace`
|
|
414
|
-
- Owner: `@jskit-ai/workspaces-core@0.2.
|
|
414
|
+
- Owner: `@jskit-ai/workspaces-core@0.2.26`
|
|
415
415
|
- Read: [PATTERN.md](patterns/workspaces/workspace-server/PATTERN.md)
|
|
416
416
|
- Examples: [example/](patterns/workspaces/workspace-server/example/)
|
|
417
417
|
- Requires: `@jskit-ai/users-core`, `@jskit-ai/workspaces-core`
|
|
@@ -422,7 +422,7 @@ Compose workspace selection, invitation, member administration, settings, and re
|
|
|
422
422
|
|
|
423
423
|
- Id: `workspaces/workspace-surfaces`
|
|
424
424
|
- Keywords: `admin`, `invite`, `member`, `navigation`, `settings`, `surface`, `switcher`, `workspace`
|
|
425
|
-
- Owner: `@jskit-ai/workspaces-web@0.2.
|
|
425
|
+
- Owner: `@jskit-ai/workspaces-web@0.2.35`
|
|
426
426
|
- Read: [PATTERN.md](patterns/workspaces/workspace-surfaces/PATTERN.md)
|
|
427
427
|
- Examples: [example/](patterns/workspaces/workspace-surfaces/example/)
|
|
428
428
|
- Requires: `@jskit-ai/shell-web`, `@jskit-ai/workspaces-core`, `@jskit-ai/workspaces-web`
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
"@vue/devtools-api": "^8.2.1"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@jskit-ai/config-eslint": "0.1.
|
|
53
|
-
"@jskit-ai/jskit-catalog": "0.2.
|
|
52
|
+
"@jskit-ai/config-eslint": "0.1.250",
|
|
53
|
+
"@jskit-ai/jskit-catalog": "0.2.47",
|
|
54
54
|
"@playwright/test": "1.61.1",
|
|
55
55
|
"@vitejs/plugin-vue": "^6.0.7",
|
|
56
56
|
"eslint": "^10.8.0",
|
|
@@ -45,13 +45,13 @@
|
|
|
45
45
|
"vue-router": "^5.3.1",
|
|
46
46
|
"vuetify": "^4.3.0",
|
|
47
47
|
"@jskit-ai/http-runtime": "0.2.18",
|
|
48
|
-
"@jskit-ai/shell-web": "0.2.
|
|
48
|
+
"@jskit-ai/shell-web": "0.2.23",
|
|
49
49
|
"@fastify/fast-json-stringify-compiler": "^5.1.0",
|
|
50
50
|
"@vue/devtools-api": "^8.2.1"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@jskit-ai/config-eslint": "0.1.
|
|
54
|
-
"@jskit-ai/jskit-catalog": "0.2.
|
|
53
|
+
"@jskit-ai/config-eslint": "0.1.250",
|
|
54
|
+
"@jskit-ai/jskit-catalog": "0.2.47",
|
|
55
55
|
"@playwright/test": "1.61.1",
|
|
56
56
|
"@vitejs/plugin-vue": "^6.0.7",
|
|
57
57
|
"eslint": "^10.8.0",
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
"db:migrate:status": "knex --knexfile ./knexfile.js migrate:list"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@jskit-ai/connectors-core": "0.2.
|
|
11
|
-
"@jskit-ai/connector-google-calendar": "0.2.
|
|
10
|
+
"@jskit-ai/connectors-core": "0.2.25",
|
|
11
|
+
"@jskit-ai/connector-google-calendar": "0.2.25",
|
|
12
12
|
"@jskit-ai/database-runtime": "0.1.267",
|
|
13
13
|
"@jskit-ai/database-runtime-mysql": "0.1.265",
|
|
14
14
|
"knex": "^3.1.0"
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
"./shared": "./src/shared/index.js"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@jskit-ai/crud-core": "0.2.
|
|
12
|
+
"@jskit-ai/crud-core": "0.2.25",
|
|
13
13
|
"@jskit-ai/resource-core": "0.1.209",
|
|
14
|
-
"@jskit-ai/resource-crud-core": "0.1.
|
|
14
|
+
"@jskit-ai/resource-crud-core": "0.1.210"
|
|
15
15
|
},
|
|
16
16
|
"jskit": {
|
|
17
17
|
"kind": "runtime",
|
|
@@ -134,6 +134,15 @@ A form field whose `relation` is a `lookup` takes its options from
|
|
|
134
134
|
lookup label for a selected value missing from the current options, that option
|
|
135
135
|
is listed first; a selected value without a label is not listed.
|
|
136
136
|
|
|
137
|
+
A lookup whose options depend on another field of the form (the rooms of the
|
|
138
|
+
chosen building, only bookable ones) narrows them on the server: pass
|
|
139
|
+
`requestQueryParams` keyed by the field, `createCrudLookupFieldRuntime({
|
|
140
|
+
formFields, requestQueryParams: { roomId: () => ({ buildingId:
|
|
141
|
+
formState.buildingId, bookable: true }) } })`. The function runs again when what
|
|
142
|
+
it reads changes, so the options follow the building. Each value is a filter the lookup's list accepts
|
|
143
|
+
(its `searchSchema` and list filter validator), never a page of every row
|
|
144
|
+
narrowed in the browser.
|
|
145
|
+
|
|
137
146
|
Render selection fields whose options load from the server, or whose value is a
|
|
138
147
|
record id, with `SelectField` from
|
|
139
148
|
`@jskit-ai/http-web/client/components/SelectField`, not a raw `v-select`,
|