@nocobase/plugin-flow-engine 2.1.0-alpha.9 → 2.1.0-beta.10
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/dist/ai/docs/runjs/context/block-model.md +35 -35
- package/dist/ai/docs/runjs/context/collection-field.md +51 -53
- package/dist/ai/docs/runjs/context/collection.md +39 -39
- package/dist/ai/docs/runjs/context/data-source-manager.md +30 -40
- package/dist/ai/docs/runjs/context/data-source.md +44 -52
- package/dist/ai/docs/runjs/context/element.md +38 -44
- package/dist/ai/docs/runjs/context/exit-all.md +35 -37
- package/dist/ai/docs/runjs/context/exit.md +35 -38
- package/dist/ai/docs/runjs/context/filter-manager.md +30 -36
- package/dist/ai/docs/runjs/context/form.md +57 -57
- package/dist/ai/docs/runjs/context/get-model.md +21 -22
- package/dist/ai/docs/runjs/context/get-value.md +19 -20
- package/dist/ai/docs/runjs/context/get-var.md +55 -61
- package/dist/ai/docs/runjs/context/i18n.md +14 -17
- package/dist/ai/docs/runjs/context/import-async.md +45 -333
- package/dist/ai/docs/runjs/context/init-resource.md +20 -20
- package/dist/ai/docs/runjs/context/libs.md +31 -31
- package/dist/ai/docs/runjs/context/location.md +31 -34
- package/dist/ai/docs/runjs/context/logger.md +40 -41
- package/dist/ai/docs/runjs/context/make-resource.md +26 -27
- package/dist/ai/docs/runjs/context/message.md +41 -42
- package/dist/ai/docs/runjs/context/modal.md +44 -44
- package/dist/ai/docs/runjs/context/model.md +33 -36
- package/dist/ai/docs/runjs/context/notification.md +40 -41
- package/dist/ai/docs/runjs/context/off.md +14 -14
- package/dist/ai/docs/runjs/context/on.md +29 -30
- package/dist/ai/docs/runjs/context/open-view.md +40 -40
- package/dist/ai/docs/runjs/context/render.md +32 -37
- package/dist/ai/docs/runjs/context/request.md +45 -46
- package/dist/ai/docs/runjs/context/require-async.md +25 -28
- package/dist/ai/docs/runjs/context/resource.md +34 -34
- package/dist/ai/docs/runjs/context/route.md +34 -36
- package/dist/ai/docs/runjs/context/router.md +31 -43
- package/dist/ai/docs/runjs/context/set-value.md +17 -18
- package/dist/ai/docs/runjs/context/t.md +17 -20
- package/dist/ai/docs/runjs/context/view.md +46 -49
- package/dist/ai/docs/runjs/document.md +0 -1
- package/dist/ai/docs/runjs/import-modules.md +32 -32
- package/dist/ai/docs/runjs/index.md +13 -13
- package/dist/ai/docs/runjs/jsx.md +19 -19
- package/dist/ai/docs/runjs/model/form-block-model.md +3 -1
- package/dist/ai/docs/runjs/render.md +15 -15
- package/dist/ai/docs/runjs/resource/api-resource.md +53 -53
- package/dist/ai/docs/runjs/resource/multi-record-resource.md +64 -64
- package/dist/ai/docs/runjs/resource/single-record-resource.md +55 -55
- package/dist/ai/docs/runjs/resource/sql-resource.md +57 -57
- package/dist/ai/docs/runjs/window.md +5 -5
- package/dist/externalVersion.js +10 -10
- package/dist/node_modules/ses/package.json +1 -1
- package/dist/node_modules/zod/package.json +1 -1
- package/package.json +2 -2
|
@@ -1,83 +1,83 @@
|
|
|
1
1
|
# SingleRecordResource
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Resource for **single records**: data is one object; supports get by primary key, create/update (save), and destroy. Use for detail, form, and other "single record" scenarios. Unlike [MultiRecordResource](./multi-record-resource.md), SingleRecordResource's `getData()` returns a single object; use `setFilterByTk(id)` for primary key; `save()` auto-calls create or update based on `isNewRecord`.
|
|
4
4
|
|
|
5
5
|
**Inheritance**: FlowResource → APIResource → BaseRecordResource → SingleRecordResource.
|
|
6
6
|
|
|
7
|
-
**
|
|
7
|
+
**Create with**: `ctx.makeResource('SingleRecordResource')` or `ctx.initResource('SingleRecordResource')`. Before use call `setResourceName('collectionName')`; for operations by primary key call `setFilterByTk(id)`; RunJS injects `ctx.api`.
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
## Use
|
|
11
|
+
## Use cases
|
|
12
12
|
|
|
13
13
|
| Scenario | Description |
|
|
14
|
-
|
|
15
|
-
| **
|
|
16
|
-
| **Form
|
|
17
|
-
| **JSBlock
|
|
18
|
-
| **Association
|
|
14
|
+
|----------|-------------|
|
|
15
|
+
| **Detail block** | Detail block uses SingleRecordResource by default; loads single record by primary key |
|
|
16
|
+
| **Form block** | Create/edit forms use SingleRecordResource; `save()` auto-distinguishes create vs update |
|
|
17
|
+
| **JSBlock detail** | Load single user, order, etc. in JSBlock and render custom UI |
|
|
18
|
+
| **Association resources** | Load associated single record with `users.profile`; requires `setSourceId(parentRecordId)` |
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
-
## Data
|
|
22
|
+
## Data format
|
|
23
23
|
|
|
24
|
-
- `getData()` returns a **single record object**,
|
|
25
|
-
- `getMeta()` returns metadata (if
|
|
24
|
+
- `getData()` returns a **single record object**, i.e. the get API `data` field
|
|
25
|
+
- `getMeta()` returns metadata (if any)
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
29
|
-
## Resource
|
|
29
|
+
## Resource name and primary key
|
|
30
30
|
|
|
31
31
|
| Method | Description |
|
|
32
|
-
|
|
33
|
-
| `setResourceName(name)` / `getResourceName()` | Resource name, e.g
|
|
34
|
-
| `setSourceId(id)` / `getSourceId()` |
|
|
35
|
-
| `setDataSourceKey(key)` / `getDataSourceKey()` | Data source
|
|
36
|
-
| `setFilterByTk(tk)` / `getFilterByTk()` |
|
|
32
|
+
|--------|-------------|
|
|
33
|
+
| `setResourceName(name)` / `getResourceName()` | Resource name, e.g. `'users'`, `'users.profile'` (association) |
|
|
34
|
+
| `setSourceId(id)` / `getSourceId()` | Parent record id for association resources (e.g. `users.profile` needs users primary key) |
|
|
35
|
+
| `setDataSourceKey(key)` / `getDataSourceKey()` | Data source key (for multiple data sources) |
|
|
36
|
+
| `setFilterByTk(tk)` / `getFilterByTk()` | Current record primary key; after set, `isNewRecord` is false |
|
|
37
37
|
|
|
38
38
|
---
|
|
39
39
|
|
|
40
40
|
## State
|
|
41
41
|
|
|
42
42
|
| Property/Method | Description |
|
|
43
|
-
|
|
44
|
-
| `isNewRecord` | Whether
|
|
43
|
+
|-----------------|-------------|
|
|
44
|
+
| `isNewRecord` | Whether in "create" state (true when filterByTk not set or just created) |
|
|
45
45
|
|
|
46
46
|
---
|
|
47
47
|
|
|
48
|
-
## Request
|
|
48
|
+
## Request params (filter / fields)
|
|
49
49
|
|
|
50
50
|
| Method | Description |
|
|
51
|
-
|
|
52
|
-
| `setFilter(filter)` / `getFilter()` | Filter (
|
|
53
|
-
| `setFields(fields)` / `getFields()` | Requested fields
|
|
54
|
-
| `setAppends(appends)` / `getAppends()` / `addAppends` / `removeAppends` | Association
|
|
51
|
+
|--------|-------------|
|
|
52
|
+
| `setFilter(filter)` / `getFilter()` | Filter (when not new) |
|
|
53
|
+
| `setFields(fields)` / `getFields()` | Requested fields |
|
|
54
|
+
| `setAppends(appends)` / `getAppends()` / `addAppends` / `removeAppends` | Association expansion |
|
|
55
55
|
|
|
56
56
|
---
|
|
57
57
|
|
|
58
58
|
## CRUD
|
|
59
59
|
|
|
60
60
|
| Method | Description |
|
|
61
|
-
|
|
62
|
-
| `refresh()` |
|
|
63
|
-
| `save(data, options?)` |
|
|
64
|
-
| `destroy(options?)` |
|
|
65
|
-
| `runAction(actionName, options)` |
|
|
61
|
+
|--------|-------------|
|
|
62
|
+
| `refresh()` | Request get with current `filterByTk`; update `getData()`. No request when in new state. |
|
|
63
|
+
| `save(data, options?)` | Create when new, otherwise update; optional `{ refresh: false }` to skip auto refresh |
|
|
64
|
+
| `destroy(options?)` | Delete by current `filterByTk` and clear local data |
|
|
65
|
+
| `runAction(actionName, options)` | Call any resource action |
|
|
66
66
|
|
|
67
67
|
---
|
|
68
68
|
|
|
69
|
-
##
|
|
69
|
+
## Config and events
|
|
70
70
|
|
|
71
71
|
| Method | Description |
|
|
72
|
-
|
|
73
|
-
| `setSaveActionOptions(options)` | Request
|
|
74
|
-
| `on('refresh', fn)` / `on('saved', fn)` |
|
|
72
|
+
|--------|-------------|
|
|
73
|
+
| `setSaveActionOptions(options)` | Request config for save |
|
|
74
|
+
| `on('refresh', fn)` / `on('saved', fn)` | Fired when refresh completes or after save |
|
|
75
75
|
|
|
76
76
|
---
|
|
77
77
|
|
|
78
78
|
## Examples
|
|
79
79
|
|
|
80
|
-
### Basic
|
|
80
|
+
### Basic get and update
|
|
81
81
|
|
|
82
82
|
```js
|
|
83
83
|
ctx.initResource('SingleRecordResource');
|
|
@@ -87,27 +87,27 @@ await ctx.resource.refresh();
|
|
|
87
87
|
const user = ctx.resource.getData();
|
|
88
88
|
|
|
89
89
|
// Update
|
|
90
|
-
await ctx.resource.save({ name: '
|
|
90
|
+
await ctx.resource.save({ name: 'Jane' });
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
-
### Create
|
|
93
|
+
### Create record
|
|
94
94
|
|
|
95
95
|
```js
|
|
96
96
|
const newRes = ctx.makeResource('SingleRecordResource');
|
|
97
97
|
newRes.setResourceName('users');
|
|
98
|
-
await newRes.save({ name: '
|
|
98
|
+
await newRes.save({ name: 'Bob', email: 'bob@example.com' });
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
### Delete
|
|
101
|
+
### Delete record
|
|
102
102
|
|
|
103
103
|
```js
|
|
104
104
|
ctx.resource.setResourceName('users');
|
|
105
105
|
ctx.resource.setFilterByTk(1);
|
|
106
106
|
await ctx.resource.destroy();
|
|
107
|
-
// After destroy, getData()
|
|
107
|
+
// After destroy, getData() is null
|
|
108
108
|
```
|
|
109
109
|
|
|
110
|
-
### Association
|
|
110
|
+
### Association expansion and fields
|
|
111
111
|
|
|
112
112
|
```js
|
|
113
113
|
ctx.resource.setResourceName('users');
|
|
@@ -118,25 +118,25 @@ await ctx.resource.refresh();
|
|
|
118
118
|
const user = ctx.resource.getData();
|
|
119
119
|
```
|
|
120
120
|
|
|
121
|
-
### Association
|
|
121
|
+
### Association resource (e.g. users.profile)
|
|
122
122
|
|
|
123
123
|
```js
|
|
124
124
|
const res = ctx.makeResource('SingleRecordResource');
|
|
125
125
|
res.setResourceName('users.profile');
|
|
126
126
|
res.setSourceId(ctx.record?.id); // Parent record primary key
|
|
127
|
-
res.setFilterByTk(profileId); //
|
|
127
|
+
res.setFilterByTk(profileId); // Can omit filterByTk if profile is hasOne
|
|
128
128
|
await res.refresh();
|
|
129
129
|
const profile = res.getData();
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
-
###
|
|
132
|
+
### save without auto refresh
|
|
133
133
|
|
|
134
134
|
```js
|
|
135
135
|
await ctx.resource.save({ status: 'active' }, { refresh: false });
|
|
136
|
-
//
|
|
136
|
+
// After save, no refresh; getData() keeps previous value
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
-
###
|
|
139
|
+
### Listen to refresh / saved events
|
|
140
140
|
|
|
141
141
|
```js
|
|
142
142
|
ctx.resource?.on?.('refresh', () => {
|
|
@@ -144,7 +144,7 @@ ctx.resource?.on?.('refresh', () => {
|
|
|
144
144
|
ctx.render(<div>User: {data?.nickname}</div>);
|
|
145
145
|
});
|
|
146
146
|
ctx.resource?.on?.('saved', (savedData) => {
|
|
147
|
-
ctx.message.success('Saved
|
|
147
|
+
ctx.message.success('Saved');
|
|
148
148
|
});
|
|
149
149
|
await ctx.resource?.refresh?.();
|
|
150
150
|
```
|
|
@@ -153,17 +153,17 @@ await ctx.resource?.refresh?.();
|
|
|
153
153
|
|
|
154
154
|
## Notes
|
|
155
155
|
|
|
156
|
-
- **setResourceName
|
|
157
|
-
- **filterByTk and isNewRecord**:
|
|
158
|
-
- **Association
|
|
159
|
-
- **getData
|
|
156
|
+
- **setResourceName required**: Must call `setResourceName('collectionName')` before use; otherwise request URL cannot be built.
|
|
157
|
+
- **filterByTk and isNewRecord**: When `setFilterByTk` is not set, `isNewRecord` is true; `refresh()` does not send request; `save()` does create.
|
|
158
|
+
- **Association resources**: When resource name is `parent.child` (e.g. `users.profile`), call `setSourceId(parentPrimaryKey)` first.
|
|
159
|
+
- **getData is object**: Single record API returns `data` as record object; `getData()` returns that object; after `destroy()` it is null.
|
|
160
160
|
|
|
161
161
|
---
|
|
162
162
|
|
|
163
163
|
## Related
|
|
164
164
|
|
|
165
|
-
- [ctx.resource](../context/resource.md) -
|
|
166
|
-
- [ctx.initResource()](../context/init-resource.md) - Initialize and bind to
|
|
167
|
-
- [ctx.makeResource()](../context/make-resource.md) - Create
|
|
168
|
-
- [APIResource](./api-resource.md) -
|
|
169
|
-
- [MultiRecordResource](./multi-record-resource.md) -
|
|
165
|
+
- [ctx.resource](../context/resource.md) - Resource instance in current context
|
|
166
|
+
- [ctx.initResource()](../context/init-resource.md) - Initialize and bind to ctx.resource
|
|
167
|
+
- [ctx.makeResource()](../context/make-resource.md) - Create resource instance without binding
|
|
168
|
+
- [APIResource](./api-resource.md) - Generic API resource, request by URL
|
|
169
|
+
- [MultiRecordResource](./multi-record-resource.md) - For data tables/lists, CRUD, pagination
|
|
@@ -1,95 +1,95 @@
|
|
|
1
1
|
# SQLResource
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Resource that runs queries via **saved SQL config** or **dynamic SQL**; data comes from `flowSql:run` / `flowSql:runById`, etc. Use for reports, stats, custom SQL lists. Unlike [MultiRecordResource](./multi-record-resource.md), SQLResource does not depend on data tables and runs SQL directly; supports pagination, parameter binding, template variables (`{{ctx.xxx}}`), and result type control.
|
|
4
4
|
|
|
5
5
|
**Inheritance**: FlowResource → APIResource → BaseRecordResource → SQLResource.
|
|
6
6
|
|
|
7
|
-
**
|
|
7
|
+
**Create with**: `ctx.makeResource('SQLResource')` or `ctx.initResource('SQLResource')`. For saved-config execution call `setFilterByTk(uid)` (SQL template uid); for debugging use `setDebug(true)` + `setSQL(sql)` to run SQL directly; RunJS injects `ctx.api`.
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
## Use
|
|
11
|
+
## Use cases
|
|
12
12
|
|
|
13
13
|
| Scenario | Description |
|
|
14
|
-
|
|
15
|
-
| **Reports /
|
|
16
|
-
| **JSBlock
|
|
17
|
-
| **Chart
|
|
18
|
-
| **
|
|
14
|
+
|----------|-------------|
|
|
15
|
+
| **Reports / stats** | Complex aggregations, cross-table queries, custom metrics |
|
|
16
|
+
| **JSBlock custom list** | Use SQL for special filter, sort, or join; render custom UI |
|
|
17
|
+
| **Chart block** | Save SQL template to drive chart data source; supports pagination |
|
|
18
|
+
| **vs ctx.sql** | Use SQLResource when you need pagination, events, or reactive data; use `ctx.sql.run()` / `ctx.sql.runById()` for simple one-off queries |
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
-
## Data
|
|
22
|
+
## Data format
|
|
23
23
|
|
|
24
24
|
- `getData()` returns different formats based on `setSQLType()`:
|
|
25
|
-
- `selectRows` (default): **
|
|
26
|
-
- `selectRow`: **
|
|
27
|
-
- `selectVar`: **
|
|
28
|
-
- `getMeta()` returns
|
|
25
|
+
- `selectRows` (default): **array**, multiple rows
|
|
26
|
+
- `selectRow`: **single object**
|
|
27
|
+
- `selectVar`: **scalar value** (e.g. COUNT, SUM)
|
|
28
|
+
- `getMeta()` returns pagination meta: `page`, `pageSize`, `count`, `totalPage`, etc.
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
32
|
-
## SQL
|
|
32
|
+
## SQL config and execution mode
|
|
33
33
|
|
|
34
34
|
| Method | Description |
|
|
35
|
-
|
|
36
|
-
| `setFilterByTk(uid)` |
|
|
37
|
-
| `setSQL(sql)` |
|
|
38
|
-
| `setSQLType(type)` | Result type: `'selectVar'` / `'selectRow'` / `'selectRows'
|
|
39
|
-
| `setDebug(enabled)` | When
|
|
40
|
-
| `run()` | Calls `runBySQL()` or `runById()`
|
|
41
|
-
| `runBySQL()` |
|
|
42
|
-
| `runById()` |
|
|
35
|
+
|--------|-------------|
|
|
36
|
+
| `setFilterByTk(uid)` | SQL template uid to run (for runById; must be saved first) |
|
|
37
|
+
| `setSQL(sql)` | Raw SQL (only in debug mode `setDebug(true)` for runBySQL) |
|
|
38
|
+
| `setSQLType(type)` | Result type: `'selectVar'` / `'selectRow'` / `'selectRows'` |
|
|
39
|
+
| `setDebug(enabled)` | When true, refresh uses `runBySQL()`; otherwise `runById()` |
|
|
40
|
+
| `run()` | Calls `runBySQL()` or `runById()` depending on debug |
|
|
41
|
+
| `runBySQL()` | Run current `setSQL` SQL (requires setDebug(true)) |
|
|
42
|
+
| `runById()` | Run saved SQL template by current uid |
|
|
43
43
|
|
|
44
44
|
---
|
|
45
45
|
|
|
46
|
-
##
|
|
46
|
+
## Params and context
|
|
47
47
|
|
|
48
48
|
| Method | Description |
|
|
49
|
-
|
|
50
|
-
| `setBind(bind)` |
|
|
51
|
-
| `setLiquidContext(ctx)` | Template context (Liquid)
|
|
52
|
-
| `setFilter(filter)` |
|
|
53
|
-
| `setDataSourceKey(key)` | Data source
|
|
49
|
+
|--------|-------------|
|
|
50
|
+
| `setBind(bind)` | Bound variables; object with `:name`, array with `?` |
|
|
51
|
+
| `setLiquidContext(ctx)` | Template context (Liquid) for `{{ctx.xxx}}` |
|
|
52
|
+
| `setFilter(filter)` | Extra filter (passed in request data) |
|
|
53
|
+
| `setDataSourceKey(key)` | Data source key (for multiple data sources) |
|
|
54
54
|
|
|
55
55
|
---
|
|
56
56
|
|
|
57
57
|
## Pagination
|
|
58
58
|
|
|
59
59
|
| Method | Description |
|
|
60
|
-
|
|
61
|
-
| `setPage(page)` / `getPage()` | Current page (default
|
|
62
|
-
| `setPageSize(size)` / `getPageSize()` |
|
|
63
|
-
| `next()` / `previous()` / `goto(page)` |
|
|
60
|
+
|--------|-------------|
|
|
61
|
+
| `setPage(page)` / `getPage()` | Current page (default 1) |
|
|
62
|
+
| `setPageSize(size)` / `getPageSize()` | Page size (default 20) |
|
|
63
|
+
| `next()` / `previous()` / `goto(page)` | Change page and trigger refresh |
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
Use `{{ctx.limit}}` and `{{ctx.offset}}` in SQL for pagination; SQLResource injects `limit` and `offset` into context.
|
|
66
66
|
|
|
67
67
|
---
|
|
68
68
|
|
|
69
|
-
## Data
|
|
69
|
+
## Data fetch and events
|
|
70
70
|
|
|
71
71
|
| Method | Description |
|
|
72
|
-
|
|
73
|
-
| `refresh()` |
|
|
74
|
-
| `runAction(actionName, options)` |
|
|
75
|
-
| `on('refresh', fn)` / `on('loading', fn)` |
|
|
72
|
+
|--------|-------------|
|
|
73
|
+
| `refresh()` | Run SQL (runById or runBySQL); write result to `setData(data)` and update meta; emit `'refresh'` |
|
|
74
|
+
| `runAction(actionName, options)` | Call underlying APIs (e.g. `getBind`, `run`, `runById`) |
|
|
75
|
+
| `on('refresh', fn)` / `on('loading', fn)` | Fired when refresh completes or loading starts |
|
|
76
76
|
|
|
77
77
|
---
|
|
78
78
|
|
|
79
79
|
## Examples
|
|
80
80
|
|
|
81
|
-
###
|
|
81
|
+
### Run by saved template (runById)
|
|
82
82
|
|
|
83
83
|
```js
|
|
84
84
|
ctx.initResource('SQLResource');
|
|
85
|
-
ctx.resource.setFilterByTk('active-users-report'); //
|
|
85
|
+
ctx.resource.setFilterByTk('active-users-report'); // Saved SQL template uid
|
|
86
86
|
ctx.resource.setBind({ status: 'active' });
|
|
87
87
|
await ctx.resource.refresh();
|
|
88
88
|
const data = ctx.resource.getData();
|
|
89
89
|
const meta = ctx.resource.getMeta(); // page, pageSize, count, etc.
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
### Debug
|
|
92
|
+
### Debug mode: run SQL directly (runBySQL)
|
|
93
93
|
|
|
94
94
|
```js
|
|
95
95
|
const res = ctx.makeResource('SQLResource');
|
|
@@ -100,20 +100,20 @@ await res.refresh();
|
|
|
100
100
|
const data = res.getData();
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
### Pagination and
|
|
103
|
+
### Pagination and navigation
|
|
104
104
|
|
|
105
105
|
```js
|
|
106
106
|
ctx.resource.setFilterByTk('user-list-sql');
|
|
107
107
|
ctx.resource.setPageSize(20);
|
|
108
108
|
await ctx.resource.refresh();
|
|
109
109
|
|
|
110
|
-
//
|
|
110
|
+
// Navigate pages
|
|
111
111
|
await ctx.resource.next();
|
|
112
112
|
await ctx.resource.previous();
|
|
113
113
|
await ctx.resource.goto(3);
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
-
### Result
|
|
116
|
+
### Result types
|
|
117
117
|
|
|
118
118
|
```js
|
|
119
119
|
// Multiple rows (default)
|
|
@@ -124,12 +124,12 @@ const rows = ctx.resource.getData(); // [{...}, {...}]
|
|
|
124
124
|
ctx.resource.setSQLType('selectRow');
|
|
125
125
|
const row = ctx.resource.getData(); // {...}
|
|
126
126
|
|
|
127
|
-
// Single value (e.g
|
|
127
|
+
// Single value (e.g. COUNT)
|
|
128
128
|
ctx.resource.setSQLType('selectVar');
|
|
129
129
|
const total = ctx.resource.getData(); // 42
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
-
###
|
|
132
|
+
### Use template variables
|
|
133
133
|
|
|
134
134
|
```js
|
|
135
135
|
ctx.defineProperty('minId', { get: () => 10 });
|
|
@@ -139,7 +139,7 @@ res.setSQL('SELECT * FROM users WHERE id > {{ctx.minId}} LIMIT {{ctx.limit}}');
|
|
|
139
139
|
await res.refresh();
|
|
140
140
|
```
|
|
141
141
|
|
|
142
|
-
###
|
|
142
|
+
### Listen to refresh event
|
|
143
143
|
|
|
144
144
|
```js
|
|
145
145
|
ctx.resource?.on?.('refresh', () => {
|
|
@@ -153,18 +153,18 @@ await ctx.resource?.refresh?.();
|
|
|
153
153
|
|
|
154
154
|
## Notes
|
|
155
155
|
|
|
156
|
-
- **runById requires
|
|
157
|
-
- **Debug mode
|
|
158
|
-
- **
|
|
159
|
-
- **Parameter
|
|
156
|
+
- **runById requires saved template**: `setFilterByTk(uid)` uid must be a saved SQL template ID; save via `ctx.sql.save({ uid, sql })`.
|
|
157
|
+
- **Debug mode needs permission**: `setDebug(true)` uses `flowSql:run`; requires SQL config permission. `runById` only needs login.
|
|
158
|
+
- **refresh debounce**: Multiple `refresh()` calls in the same event loop only run the last one to avoid duplicate requests.
|
|
159
|
+
- **Parameter binding prevents injection**: Use `setBind()` with `:name` / `?` placeholders; avoid string concatenation to prevent SQL injection.
|
|
160
160
|
|
|
161
161
|
---
|
|
162
162
|
|
|
163
163
|
## Related
|
|
164
164
|
|
|
165
|
-
- [ctx.sql](../context/sql.md) - SQL execution and management; `ctx.sql.runById`
|
|
166
|
-
- [ctx.resource](../context/resource.md) -
|
|
167
|
-
- [ctx.initResource()](../context/init-resource.md) -
|
|
168
|
-
- [ctx.makeResource()](../context/make-resource.md) -
|
|
169
|
-
- [APIResource](./api-resource.md) -
|
|
170
|
-
- [MultiRecordResource](./multi-record-resource.md) -
|
|
165
|
+
- [ctx.sql](../context/sql.md) - SQL execution and management; `ctx.sql.runById` for simple one-off queries
|
|
166
|
+
- [ctx.resource](../context/resource.md) - Resource instance in current context
|
|
167
|
+
- [ctx.initResource()](../context/init-resource.md) - Initialize and bind to ctx.resource
|
|
168
|
+
- [ctx.makeResource()](../context/make-resource.md) - Create resource instance without binding
|
|
169
|
+
- [APIResource](./api-resource.md) - Generic API resource
|
|
170
|
+
- [MultiRecordResource](./multi-record-resource.md) - For data tables/lists
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# window
|
|
2
2
|
|
|
3
|
-
The following
|
|
3
|
+
The following are available on `window`:
|
|
4
4
|
|
|
5
5
|
* `setTimeout` / `clearTimeout`
|
|
6
6
|
* `setInterval` / `clearInterval`
|
|
@@ -9,12 +9,12 @@ The following properties can be accessed directly via `window`:
|
|
|
9
9
|
* `Date`
|
|
10
10
|
* `FormData`
|
|
11
11
|
* `addEventListener`
|
|
12
|
-
* `open` (
|
|
13
|
-
* `location` (
|
|
12
|
+
* `open` (only `http:`, `https:`, or `about:blank` allowed)
|
|
13
|
+
* `location` (read-only, safe navigation)
|
|
14
14
|
* `navigator`
|
|
15
15
|
|
|
16
|
-
Only basic
|
|
16
|
+
Only basic, safe DOM query and creation are supported:
|
|
17
17
|
|
|
18
18
|
* `createElement(tagName)`
|
|
19
19
|
* `querySelector(selectors)`
|
|
20
|
-
* `querySelectorAll(selectors)`
|
|
20
|
+
* `querySelectorAll(selectors)`
|
package/dist/externalVersion.js
CHANGED
|
@@ -8,15 +8,15 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
module.exports = {
|
|
11
|
-
"@nocobase/client": "2.1.0-
|
|
11
|
+
"@nocobase/client": "2.1.0-beta.10",
|
|
12
12
|
"lodash": "4.17.21",
|
|
13
|
-
"@nocobase/database": "2.1.0-
|
|
14
|
-
"@nocobase/data-source-manager": "2.1.0-
|
|
15
|
-
"@nocobase/resourcer": "2.1.0-
|
|
16
|
-
"@nocobase/server": "2.1.0-
|
|
17
|
-
"@nocobase/utils": "2.1.0-
|
|
18
|
-
"@nocobase/cache": "2.1.0-
|
|
19
|
-
"@nocobase/plugin-localization": "2.1.0-
|
|
20
|
-
"@nocobase/ai": "2.1.0-
|
|
21
|
-
"@nocobase/actions": "2.1.0-
|
|
13
|
+
"@nocobase/database": "2.1.0-beta.10",
|
|
14
|
+
"@nocobase/data-source-manager": "2.1.0-beta.10",
|
|
15
|
+
"@nocobase/resourcer": "2.1.0-beta.10",
|
|
16
|
+
"@nocobase/server": "2.1.0-beta.10",
|
|
17
|
+
"@nocobase/utils": "2.1.0-beta.10",
|
|
18
|
+
"@nocobase/cache": "2.1.0-beta.10",
|
|
19
|
+
"@nocobase/plugin-localization": "2.1.0-beta.10",
|
|
20
|
+
"@nocobase/ai": "2.1.0-beta.10",
|
|
21
|
+
"@nocobase/actions": "2.1.0-beta.10"
|
|
22
22
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"ses","version":"1.14.0","description":"Hardened JavaScript for Fearless Cooperation","keywords":["lockdown","harden","Compartment","assert","security","confinement","isolation","object capabilities","ocaps","secure execution","third-party code","prototype pollution","supply-chain attack","plugin"],"author":"Agoric","license":"Apache-2.0","homepage":"https://github.com/Agoric/SES-shim/tree/master/packages/ses#readme","repository":{"type":"git","url":"git+https://github.com/endojs/endo.git","directory":"packages/ses"},"bugs":{"url":"https://github.com/endojs/endo/issues"},"type":"module","main":"./dist/ses.cjs","module":"./index.js","unpkg":"./dist/ses.umd.js","types":"./types.d.ts","exports":{".":{"import":{"types":"./types.d.ts","xs":"./src-xs/index.js","default":"./index.js"},"require":{"types":"./dist/types.d.cts","default":"./dist/ses.cjs"}},"./lockdown":{"import":{"types":"./types.d.ts","default":"./index.js"},"require":{"types":"./dist/types.d.cts","default":"./dist/ses.cjs"}},"./hermes":{"require":{"types":"./dist/types.d.cts","default":"./dist/ses-hermes.cjs"}},"./tools.js":"./tools.js","./assert-shim.js":"./assert-shim.js","./lockdown-shim.js":{"xs":"./src-xs/lockdown-shim.js","default":"./lockdown-shim.js"},"./compartment-shim.js":{"xs":"./src-xs/compartment-shim.js","default":"./compartment-shim.js"},"./console-shim.js":"./console-shim.js","./package.json":"./package.json"},"scripts":{"build:vanilla":"node scripts/bundle.js","build:hermes":"node scripts/bundle.js hermes","build":"yarn build:vanilla && yarn build:hermes","clean":"rm -rf dist","cover":"c8 ava","demo":"python3 -m http.server","lint":"yarn lint:types && yarn lint:eslint","lint-fix":"eslint --fix .","lint:eslint":"eslint .","lint:types":"tsc","prepare":"npm run clean && npm run build","qt":"ava","test":"tsd && ava","test:hermes":"./scripts/hermes-test.sh","test:xs":"xst dist/ses.umd.js test/_lockdown-safe.js && node scripts/generate-test-xs.js && xst tmp/test-xs.js && rm -rf tmp","postpack":"git clean -fX \"*.d.ts*\" \"*.d.cts*\" \"*.d.mts*\" \"*.tsbuildinfo\""},"dependencies":{"@endo/cache-map":"^1.1.0","@endo/env-options":"^1.1.11","@endo/immutable-arraybuffer":"^1.1.2"},"devDependencies":{"@babel/generator":"^7.26.3","@babel/parser":"~7.26.2","@babel/traverse":"~7.25.9","@babel/types":"~7.26.0","@endo/compartment-mapper":"^1.6.3","@endo/module-source":"^1.3.3","@endo/test262-runner":"^0.1.48","@types/babel__traverse":"^7.20.5","ava":"^6.1.3","babel-eslint":"^10.1.0","c8":"^7.14.0","core-js":"^3.31.0","eslint":"^8.57.1","eslint-config-airbnb-base":"^15.0.0","eslint-config-prettier":"^9.1.0","eslint-plugin-eslint-comments":"^3.2.0","eslint-plugin-import":"^2.31.0","hermes-engine-cli":"^0.12.0","prettier":"^3.5.3","terser":"^5.16.6","tsd":"^0.31.2","typescript":"~5.8.3"},"files":["./*.d.ts","./*.js","./*.map","LICENSE*","SECURITY*","dist","lib","src","tools"],"publishConfig":{"access":"public"},"eslintConfig":{"extends":["plugin:@endo/ses"]},"ava":{"files":["test/**/*.test.*"],"timeout":"2m"},"typeCoverage":{"atLeast":81.17},"gitHead":"9815aea9541f241389d2135c6097a7442bdffa17","_lastModified":"2026-03-
|
|
1
|
+
{"name":"ses","version":"1.14.0","description":"Hardened JavaScript for Fearless Cooperation","keywords":["lockdown","harden","Compartment","assert","security","confinement","isolation","object capabilities","ocaps","secure execution","third-party code","prototype pollution","supply-chain attack","plugin"],"author":"Agoric","license":"Apache-2.0","homepage":"https://github.com/Agoric/SES-shim/tree/master/packages/ses#readme","repository":{"type":"git","url":"git+https://github.com/endojs/endo.git","directory":"packages/ses"},"bugs":{"url":"https://github.com/endojs/endo/issues"},"type":"module","main":"./dist/ses.cjs","module":"./index.js","unpkg":"./dist/ses.umd.js","types":"./types.d.ts","exports":{".":{"import":{"types":"./types.d.ts","xs":"./src-xs/index.js","default":"./index.js"},"require":{"types":"./dist/types.d.cts","default":"./dist/ses.cjs"}},"./lockdown":{"import":{"types":"./types.d.ts","default":"./index.js"},"require":{"types":"./dist/types.d.cts","default":"./dist/ses.cjs"}},"./hermes":{"require":{"types":"./dist/types.d.cts","default":"./dist/ses-hermes.cjs"}},"./tools.js":"./tools.js","./assert-shim.js":"./assert-shim.js","./lockdown-shim.js":{"xs":"./src-xs/lockdown-shim.js","default":"./lockdown-shim.js"},"./compartment-shim.js":{"xs":"./src-xs/compartment-shim.js","default":"./compartment-shim.js"},"./console-shim.js":"./console-shim.js","./package.json":"./package.json"},"scripts":{"build:vanilla":"node scripts/bundle.js","build:hermes":"node scripts/bundle.js hermes","build":"yarn build:vanilla && yarn build:hermes","clean":"rm -rf dist","cover":"c8 ava","demo":"python3 -m http.server","lint":"yarn lint:types && yarn lint:eslint","lint-fix":"eslint --fix .","lint:eslint":"eslint .","lint:types":"tsc","prepare":"npm run clean && npm run build","qt":"ava","test":"tsd && ava","test:hermes":"./scripts/hermes-test.sh","test:xs":"xst dist/ses.umd.js test/_lockdown-safe.js && node scripts/generate-test-xs.js && xst tmp/test-xs.js && rm -rf tmp","postpack":"git clean -fX \"*.d.ts*\" \"*.d.cts*\" \"*.d.mts*\" \"*.tsbuildinfo\""},"dependencies":{"@endo/cache-map":"^1.1.0","@endo/env-options":"^1.1.11","@endo/immutable-arraybuffer":"^1.1.2"},"devDependencies":{"@babel/generator":"^7.26.3","@babel/parser":"~7.26.2","@babel/traverse":"~7.25.9","@babel/types":"~7.26.0","@endo/compartment-mapper":"^1.6.3","@endo/module-source":"^1.3.3","@endo/test262-runner":"^0.1.48","@types/babel__traverse":"^7.20.5","ava":"^6.1.3","babel-eslint":"^10.1.0","c8":"^7.14.0","core-js":"^3.31.0","eslint":"^8.57.1","eslint-config-airbnb-base":"^15.0.0","eslint-config-prettier":"^9.1.0","eslint-plugin-eslint-comments":"^3.2.0","eslint-plugin-import":"^2.31.0","hermes-engine-cli":"^0.12.0","prettier":"^3.5.3","terser":"^5.16.6","tsd":"^0.31.2","typescript":"~5.8.3"},"files":["./*.d.ts","./*.js","./*.map","LICENSE*","SECURITY*","dist","lib","src","tools"],"publishConfig":{"access":"public"},"eslintConfig":{"extends":["plugin:@endo/ses"]},"ava":{"files":["test/**/*.test.*"],"timeout":"2m"},"typeCoverage":{"atLeast":81.17},"gitHead":"9815aea9541f241389d2135c6097a7442bdffa17","_lastModified":"2026-03-19T03:13:36.833Z"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"zod","version":"4.3.5","type":"module","license":"MIT","author":"Colin McDonnell <zod@colinhacks.com>","description":"TypeScript-first schema declaration and validation library with static type inference","homepage":"https://zod.dev","llms":"https://zod.dev/llms.txt","llmsFull":"https://zod.dev/llms-full.txt","mcpServer":"https://mcp.inkeep.com/zod/mcp","funding":"https://github.com/sponsors/colinhacks","sideEffects":false,"files":["src","**/*.js","**/*.mjs","**/*.cjs","**/*.d.ts","**/*.d.mts","**/*.d.cts","**/package.json"],"keywords":["typescript","schema","validation","type","inference"],"main":"./index.cjs","types":"./index.d.cts","module":"./index.js","zshy":{"exports":{"./package.json":"./package.json",".":"./src/index.ts","./mini":"./src/mini/index.ts","./locales":"./src/locales/index.ts","./v3":"./src/v3/index.ts","./v4":"./src/v4/index.ts","./v4-mini":"./src/v4-mini/index.ts","./v4/mini":"./src/v4/mini/index.ts","./v4/core":"./src/v4/core/index.ts","./v4/locales":"./src/v4/locales/index.ts","./v4/locales/*":"./src/v4/locales/*"},"conditions":{"@zod/source":"src"}},"exports":{"./package.json":"./package.json",".":{"@zod/source":"./src/index.ts","types":"./index.d.cts","import":"./index.js","require":"./index.cjs"},"./mini":{"@zod/source":"./src/mini/index.ts","types":"./mini/index.d.cts","import":"./mini/index.js","require":"./mini/index.cjs"},"./locales":{"@zod/source":"./src/locales/index.ts","types":"./locales/index.d.cts","import":"./locales/index.js","require":"./locales/index.cjs"},"./v3":{"@zod/source":"./src/v3/index.ts","types":"./v3/index.d.cts","import":"./v3/index.js","require":"./v3/index.cjs"},"./v4":{"@zod/source":"./src/v4/index.ts","types":"./v4/index.d.cts","import":"./v4/index.js","require":"./v4/index.cjs"},"./v4-mini":{"@zod/source":"./src/v4-mini/index.ts","types":"./v4-mini/index.d.cts","import":"./v4-mini/index.js","require":"./v4-mini/index.cjs"},"./v4/mini":{"@zod/source":"./src/v4/mini/index.ts","types":"./v4/mini/index.d.cts","import":"./v4/mini/index.js","require":"./v4/mini/index.cjs"},"./v4/core":{"@zod/source":"./src/v4/core/index.ts","types":"./v4/core/index.d.cts","import":"./v4/core/index.js","require":"./v4/core/index.cjs"},"./v4/locales":{"@zod/source":"./src/v4/locales/index.ts","types":"./v4/locales/index.d.cts","import":"./v4/locales/index.js","require":"./v4/locales/index.cjs"},"./v4/locales/*":{"@zod/source":"./src/v4/locales/*","types":"./v4/locales/*","import":"./v4/locales/*","require":"./v4/locales/*"}},"repository":{"type":"git","url":"git+https://github.com/colinhacks/zod.git"},"bugs":{"url":"https://github.com/colinhacks/zod/issues"},"support":{"backing":{"npm-funding":true}},"scripts":{"clean":"git clean -xdf . -e node_modules","build":"zshy --project tsconfig.build.json","postbuild":"tsx ../../scripts/write-stub-package-jsons.ts && pnpm biome check --write .","test:watch":"pnpm vitest","test":"pnpm vitest run","prepublishOnly":"tsx ../../scripts/check-versions.ts"},"_lastModified":"2026-03-
|
|
1
|
+
{"name":"zod","version":"4.3.5","type":"module","license":"MIT","author":"Colin McDonnell <zod@colinhacks.com>","description":"TypeScript-first schema declaration and validation library with static type inference","homepage":"https://zod.dev","llms":"https://zod.dev/llms.txt","llmsFull":"https://zod.dev/llms-full.txt","mcpServer":"https://mcp.inkeep.com/zod/mcp","funding":"https://github.com/sponsors/colinhacks","sideEffects":false,"files":["src","**/*.js","**/*.mjs","**/*.cjs","**/*.d.ts","**/*.d.mts","**/*.d.cts","**/package.json"],"keywords":["typescript","schema","validation","type","inference"],"main":"./index.cjs","types":"./index.d.cts","module":"./index.js","zshy":{"exports":{"./package.json":"./package.json",".":"./src/index.ts","./mini":"./src/mini/index.ts","./locales":"./src/locales/index.ts","./v3":"./src/v3/index.ts","./v4":"./src/v4/index.ts","./v4-mini":"./src/v4-mini/index.ts","./v4/mini":"./src/v4/mini/index.ts","./v4/core":"./src/v4/core/index.ts","./v4/locales":"./src/v4/locales/index.ts","./v4/locales/*":"./src/v4/locales/*"},"conditions":{"@zod/source":"src"}},"exports":{"./package.json":"./package.json",".":{"@zod/source":"./src/index.ts","types":"./index.d.cts","import":"./index.js","require":"./index.cjs"},"./mini":{"@zod/source":"./src/mini/index.ts","types":"./mini/index.d.cts","import":"./mini/index.js","require":"./mini/index.cjs"},"./locales":{"@zod/source":"./src/locales/index.ts","types":"./locales/index.d.cts","import":"./locales/index.js","require":"./locales/index.cjs"},"./v3":{"@zod/source":"./src/v3/index.ts","types":"./v3/index.d.cts","import":"./v3/index.js","require":"./v3/index.cjs"},"./v4":{"@zod/source":"./src/v4/index.ts","types":"./v4/index.d.cts","import":"./v4/index.js","require":"./v4/index.cjs"},"./v4-mini":{"@zod/source":"./src/v4-mini/index.ts","types":"./v4-mini/index.d.cts","import":"./v4-mini/index.js","require":"./v4-mini/index.cjs"},"./v4/mini":{"@zod/source":"./src/v4/mini/index.ts","types":"./v4/mini/index.d.cts","import":"./v4/mini/index.js","require":"./v4/mini/index.cjs"},"./v4/core":{"@zod/source":"./src/v4/core/index.ts","types":"./v4/core/index.d.cts","import":"./v4/core/index.js","require":"./v4/core/index.cjs"},"./v4/locales":{"@zod/source":"./src/v4/locales/index.ts","types":"./v4/locales/index.d.cts","import":"./v4/locales/index.js","require":"./v4/locales/index.cjs"},"./v4/locales/*":{"@zod/source":"./src/v4/locales/*","types":"./v4/locales/*","import":"./v4/locales/*","require":"./v4/locales/*"}},"repository":{"type":"git","url":"git+https://github.com/colinhacks/zod.git"},"bugs":{"url":"https://github.com/colinhacks/zod/issues"},"support":{"backing":{"npm-funding":true}},"scripts":{"clean":"git clean -xdf . -e node_modules","build":"zshy --project tsconfig.build.json","postbuild":"tsx ../../scripts/write-stub-package-jsons.ts && pnpm biome check --write .","test:watch":"pnpm vitest","test":"pnpm vitest run","prepublishOnly":"tsx ../../scripts/check-versions.ts"},"_lastModified":"2026-03-19T03:13:36.363Z"}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"displayName.zh-CN": "前端流引擎",
|
|
5
5
|
"description": "",
|
|
6
6
|
"description.zh-CN": "",
|
|
7
|
-
"version": "2.1.0-
|
|
7
|
+
"version": "2.1.0-beta.10",
|
|
8
8
|
"main": "./dist/server/index.js",
|
|
9
9
|
"license": "Apache-2.0",
|
|
10
10
|
"devDependencies": {
|
|
@@ -24,5 +24,5 @@
|
|
|
24
24
|
"@nocobase/test": "2.x",
|
|
25
25
|
"@nocobase/utils": "2.x"
|
|
26
26
|
},
|
|
27
|
-
"gitHead": "
|
|
27
|
+
"gitHead": "f7e467710d4748f7089b779494b220025b39bc02"
|
|
28
28
|
}
|