@lowdefy/docs-content 0.0.0-experimental-20260909201552 → 6.0.0
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/README.md +0 -1
- package/content/actions/login.md +5 -23
- package/content/actions/logout.md +5 -5
- package/content/agents/agentchat.md +1 -13
- package/content/concepts/ai-agent-docs.md +4 -90
- package/content/concepts/custom-styling.md +5 -50
- package/content/concepts/events-and-actions.md +2 -64
- package/content/concepts/i18n.md +1 -1
- package/content/connections/mongodb.md +3 -109
- package/content/container-blocks/modal.md +1 -1
- package/content/container-blocks/pagesidebarlayout.md +0 -1
- package/content/controls/reject.md +1 -3
- package/content/controls/throw.md +0 -1
- package/content/controls/try.md +2 -3
- package/content/display-blocks/difflist.md +1 -1
- package/content/display-blocks/difftimeline.md +1 -1
- package/content/display-blocks/s3download.md +1 -1
- package/content/display-blocks/search.md +0 -1
- package/content/input-blocks/checkboxselector.md +4 -80
- package/content/input-blocks/radioselector.md +3 -65
- package/content/input-blocks/s3uploadbutton.md +1 -1
- package/content/input-blocks/s3uploaddragger.md +1 -1
- package/content/input-blocks/s3uploadphoto.md +1 -1
- package/content/input-blocks/tiptapmentioninput.md +1 -1
- package/content/list-blocks/masonrylist.md +1 -1
- package/content/operators/_type.md +3 -14
- package/content/operators/_user.md +3 -3
- package/content/user-authentication/login-and-logout.md +8 -158
- package/content/user-authentication/users-introduction.md +0 -8
- package/index.json +1 -99
- package/package.json +1 -3
- package/content/actions/emailotpsend.md +0 -58
- package/content/actions/emailotpverify.md +0 -77
- package/content/actions/magiclinkverify.md +0 -113
- package/content/controls/while.md +0 -46
- package/content/input-blocks/captcha.md +0 -40
- package/content/input-blocks/tagmultipleselector.md +0 -101
- package/content/input-blocks/tagselector.md +0 -101
- package/content/migration/auth-upgrade.md +0 -315
- package/content/other/mongodbadapter.md +0 -3
- package/content/user-authentication/auth-steps.md +0 -111
- package/content/user-authentication/mcp-oauth.md +0 -289
- package/content/user-authentication/organizations.md +0 -134
- package/content/user-authentication/two-factor.md +0 -225
- package/content/user-authentication/user-object.md +0 -58
- package/hazards.json +0 -44
package/README.md
CHANGED
|
@@ -6,7 +6,6 @@ Lowdefy documentation extracted as markdown, for serving to AI coding agents via
|
|
|
6
6
|
|
|
7
7
|
- `content/<section>/<slug>.md` — one markdown file per docs page (concepts, tutorial, operators, actions, connections, blocks, ...).
|
|
8
8
|
- `index.json` — manifest of all docs: `{ version, docs: [{ slug, title, section, path, kind?, typeName? }] }`. `kind`/`typeName` map a plugin type (e.g. operator `_get`) to its doc.
|
|
9
|
-
- `hazards.json` — framework-level hazards served by the dev MCP alongside schemas, docs and config lookups: `[{ id, appliesTo: { kinds?, types?, when? }, message, see }]`. This file is hand-authored and committed, not generated — `pnpm docs:content` wipes `content/` but leaves it untouched. Add an entry only for a behaviour verified in the framework source.
|
|
10
9
|
|
|
11
10
|
## Regenerating content
|
|
12
11
|
|
package/content/actions/login.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
pageId?: string
|
|
11
11
|
url?: string
|
|
12
12
|
urlQuery?: object
|
|
13
|
-
}
|
|
13
|
+
}
|
|
14
14
|
providerId?: string,
|
|
15
15
|
}): void
|
|
16
16
|
```
|
|
@@ -19,46 +19,28 @@ The `Login` action is used to start the user login flow. If only one provider is
|
|
|
19
19
|
|
|
20
20
|
The authorization url usually hosts a page where the user can input their credentials. After the user has logged in successfully, the user is redirected to the `api/auth/callback/[provider_id]` route in the Lowdefy app, where the rest of the authorization code flow is completed.
|
|
21
21
|
|
|
22
|
-
The `callbackUrl`
|
|
23
|
-
|
|
24
|
-
1. The `callbackUrl` param, if given.
|
|
25
|
-
2. The `?callbackUrl=` query parameter, which Lowdefy sets when it redirects an unauthenticated user to the sign-in page - so a user who was bounced there returns to the page they asked for.
|
|
26
|
-
3. The app's home page.
|
|
27
|
-
|
|
28
|
-
If none of the three resolves - an app with no `homePageId` whose menu offers the signed-out user no page to fall back on - the action throws rather than staying silently on the sign-in page.
|
|
29
|
-
|
|
30
|
-
To sign in without navigating at all, set `callbackUrl: false`. This is for a login form in a modal or an embedded panel, where the session store re-renders the page with the new user in place. It is not valid for magic-link or social/OAuth sign-in, which redirect through a hop Lowdefy does not control.
|
|
31
|
-
|
|
32
|
-
A sign-in the auth server rejects - a wrong password, an expired or already-used link, an invalid code - is an expected outcome, not an app error. The action throws a `UserError`: `catch` actions on the event still run and the error message still displays, but it is logged to the browser console only and is never reported to the server. The auth server's response is available to `catch` actions as `_actions.<actionId>.error.metaData`, with a `code` (for example `INVALID_EMAIL_OR_PASSWORD`) and the HTTP `status`. A network failure or a server fault is still thrown as an action error and reported.
|
|
22
|
+
The `callbackUrl` parameters of the Login action specify where the user is redirected after login is complete. If `callbackUrl` parameters not set, the user will return to the page from which the action was called.
|
|
33
23
|
|
|
34
24
|
#### Parameters
|
|
35
25
|
|
|
36
26
|
###### object
|
|
37
27
|
- `authUrl: object`:
|
|
38
28
|
- `urlQuery: object`: Query parameters to set for the authorization URL.
|
|
39
|
-
- `callbackUrl: object
|
|
29
|
+
- `callbackUrl: object`:
|
|
40
30
|
- `home: boolean`: Redirect to the home page after the login flow is complete.
|
|
41
31
|
- `pageId: string`: The pageId of the page to redirect to after the login flow is complete.
|
|
42
|
-
- `url: string`: The URL to redirect to after the login flow is complete.
|
|
32
|
+
- `url: string`: The URL to redirect to after the login flow is complete.
|
|
43
33
|
- `urlQuery: object`: The urlQuery to set for the page the user is redirected to after login.
|
|
44
34
|
- `providerId: string`: The ID of the provider that should be used for login. If not set and only one provider is configured the configured provider will be used. Else the user will be redirected to a sign in page where they can choose a provider.
|
|
45
35
|
|
|
46
36
|
#### Examples
|
|
47
37
|
|
|
48
|
-
###### Login and
|
|
38
|
+
###### Login and return to the same page:
|
|
49
39
|
```yaml
|
|
50
40
|
- id: login
|
|
51
41
|
type: Login
|
|
52
42
|
```
|
|
53
43
|
|
|
54
|
-
###### Login in a modal, without navigating:
|
|
55
|
-
```yaml
|
|
56
|
-
- id: login
|
|
57
|
-
type: Login
|
|
58
|
-
params:
|
|
59
|
-
callbackUrl: false
|
|
60
|
-
```
|
|
61
|
-
|
|
62
44
|
###### Login with the google provider:
|
|
63
45
|
```yaml
|
|
64
46
|
- id: login_with_google
|
|
@@ -14,16 +14,16 @@
|
|
|
14
14
|
|
|
15
15
|
When the `Logout` action is called, the user data and authorization cookies are cleared by the app.
|
|
16
16
|
|
|
17
|
-
The `callbackUrl`
|
|
17
|
+
The `callbackUrl` parameters of the Logout action specify where the user is redirected after logout is complete. If `callbackUrl` parameters not set, the user will return to the page from which the action was called.
|
|
18
18
|
|
|
19
19
|
#### Parameters
|
|
20
20
|
|
|
21
21
|
###### object
|
|
22
22
|
- `callbackUrl: object`:
|
|
23
|
-
- `home: boolean`: Redirect to the home page after the
|
|
24
|
-
- `pageId: string`: The pageId of the page to redirect to after the
|
|
25
|
-
- `url: string`: The URL to redirect to after the
|
|
26
|
-
- `urlQuery: object`: The urlQuery to set for the page the user is redirected to after
|
|
23
|
+
- `home: boolean`: Redirect to the home page after the login flow is complete.
|
|
24
|
+
- `pageId: string`: The pageId of the page to redirect to after the login flow is complete.
|
|
25
|
+
- `url: string`: The URL to redirect to after the login flow is complete.
|
|
26
|
+
- `urlQuery: object`: The urlQuery to set for the page the user is redirected to after login.
|
|
27
27
|
- `redirect: boolean`: If set to `false` the user session will be cleared, but the page will not be reloaded.
|
|
28
28
|
|
|
29
29
|
#### Examples
|
|
@@ -68,7 +68,6 @@ The `AgentChat` block renders a streaming AI chat interface. It connects to a [L
|
|
|
68
68
|
| `agentId` | string | | __Required__ - The `id` of the agent to connect to. |
|
|
69
69
|
| `conversationId` | string | | Active conversation ID. When this changes, messages are cleared. If left empty, the block auto-mints a stable id for the session and surfaces it via `onConversationStart`, so every turn posts a consistent id. App-supplied ids are always authoritative. |
|
|
70
70
|
| `messages` | array | | Load messages externally. `undefined` = no sync, `null` = clear, array = load. |
|
|
71
|
-
| `feedbackValues` | object | | Ratings already recorded for messages in this conversation, keyed by message id, each `like` or `dislike`. The block does not persist a rating, so without this a reload or a conversation switch shows every message unrated even where your app stored it. A rating clicked this visit takes precedence, so the thumb still responds immediately and a rating the user has just withdrawn is not re-lit by a stale value. |
|
|
72
71
|
| `urlQuery` | object | | Query parameters sent with each request. Available server-side via `_payload`. |
|
|
73
72
|
| `sharedState` | object | | Two-way bridge between page state and the agent. See [Shared State](#shared-state). |
|
|
74
73
|
| `height` | string | `'calc(100dvh - 170px)'` | CSS height of the chat container. Only applies when `display` is `'inline'`. |
|
|
@@ -327,7 +326,7 @@ With the curated form above, the agent can read `legal_name` and `registration_n
|
|
|
327
326
|
| `onToolResult` | A tool returns a result. | `toolName`, `toolCallId`, `output`, `error` |
|
|
328
327
|
| `onError` | A streaming error occurs. | `message` |
|
|
329
328
|
| `onStop` | User stops generation. | `messages` |
|
|
330
|
-
| `onFeedback` | User clicks thumbs up/down.
|
|
329
|
+
| `onFeedback` | User clicks thumbs up/down. | `messageId`, `messageContent`, `rating` |
|
|
331
330
|
| `onRegenerate` | User clicks regenerate. | `messageId`, `messages` |
|
|
332
331
|
| `onDeleteMessage` | User deletes a message. | `messageId`, `content`, `messages` |
|
|
333
332
|
| `onEditMessage` | User edits and resubmits. | `messageId`, `originalContent`, `newContent`, `messages` |
|
|
@@ -335,7 +334,6 @@ With the curated form above, the agent can read `legal_name` and `registration_n
|
|
|
335
334
|
| `onSwitchChange` | User toggles a sender switch. | `key`, `checked` |
|
|
336
335
|
| `onTitleGenerated` | A `data-chat-title` data part arrives — emitted automatically when the agent's [`generateTitle`](/agent-properties) property is set, or manually from an `onFinish` hook. | `title` |
|
|
337
336
|
| `onDataPart` | Any data part arrives from the server. | `type`, `data`, `id` |
|
|
338
|
-
| `onLinkClick` | User clicks a link in a message. Wiring this event suppresses the default navigation for plain left clicks, so the app can open the target in place; modified clicks (new tab, middle click) always navigate. | `href`, `text` |
|
|
339
337
|
|
|
340
338
|
###### Validate messages before sending:
|
|
341
339
|
```yaml
|
|
@@ -367,16 +365,6 @@ events:
|
|
|
367
365
|
type: success
|
|
368
366
|
```
|
|
369
367
|
|
|
370
|
-
Saving is only half of it — the block does not persist a rating, so a
|
|
371
|
-
reload or a conversation switch shows the message unrated again. Pass
|
|
372
|
-
what you stored back through `feedbackValues`, keyed by message id:
|
|
373
|
-
|
|
374
|
-
```yaml
|
|
375
|
-
properties:
|
|
376
|
-
feedbackValues:
|
|
377
|
-
_request: saved_feedback_for_conversation
|
|
378
|
-
```
|
|
379
|
-
|
|
380
368
|
###### Adapt behavior based on sender switches:
|
|
381
369
|
```yaml
|
|
382
370
|
events:
|
|
@@ -29,7 +29,6 @@ It provides these tools:
|
|
|
29
29
|
| `lowdefy_build_status` | Current build errors and warnings (with source file locations) plus recent browser runtime errors — call after every edit |
|
|
30
30
|
| `lowdefy_get_page_config`| The fully built config for a page, or its structured build errors |
|
|
31
31
|
| `lowdefy_screenshot_page`| PNG screenshot of a rendered page (headless Chromium) for visual verification |
|
|
32
|
-
| `lowdefy_run_journey` | Drive a page headless through declarative steps (`click`, `fill`, `select`, `press`, `wait`, `screenshot`, `expect`) and assert state, visibility, text or url — verify behaviour, not just layout |
|
|
33
32
|
| `lowdefy_find_config` | Which yaml file (and line) defines a given page, block, or request id |
|
|
34
33
|
| `lowdefy_scaffold_page` | Create a new page yaml file with a canonical minimal structure |
|
|
35
34
|
| `lowdefy_app_map` | The whole-app graph: every page, menu, connection, endpoint, and agent in one call |
|
|
@@ -79,9 +78,9 @@ When you have a page open in your browser, the agent can read its **actual live
|
|
|
79
78
|
|
|
80
79
|
## Auth-protected pages
|
|
81
80
|
|
|
82
|
-
The headless renderer behind `lowdefy_screenshot_page` and `lowdefy_inspect_state` authenticates as a signed-in user, so pages with `auth.public: false` render for the agent instead of
|
|
81
|
+
The headless renderer behind `lowdefy_screenshot_page` and `lowdefy_inspect_state` authenticates as a signed-in user, so pages with `auth.public: false` render for the agent instead of returning a 404. That default user carries **no roles**, so a page or request gated on a role still comes back refused or empty.
|
|
83
82
|
|
|
84
|
-
To act as a specific caller, pass `user` — every tool that renders a page headless accepts it: `lowdefy_screenshot_page`, `
|
|
83
|
+
To act as a specific caller, pass `user` — every tool that renders a page headless accepts it: `lowdefy_screenshot_page`, `lowdefy_inspect_state`, `lowdefy_eval_operator` and `lowdefy_load_state`:
|
|
85
84
|
|
|
86
85
|
```json
|
|
87
86
|
{ "pageId": "users", "user": { "roles": ["admin"] } }
|
|
@@ -89,9 +88,9 @@ To act as a specific caller, pass `user` — every tool that renders a page head
|
|
|
89
88
|
|
|
90
89
|
It is merged over the default user, so `{"roles": [...]}` is usually all you need. No auth engine runs for an injected caller, so nothing derives the rest of the record — include `email`, `profile` or `attributes` in the object if the page reads them. Every call opens its own browser context, so one call can act as an admin and the next as a plain member.
|
|
91
90
|
|
|
92
|
-
`user` applies to the headless renderer only — it is never applied to a page you open in your own browser, which carries your real session and cannot be re-identified. `lowdefy_inspect_state` and `lowdefy_eval_operator` normally prefer your open tab, so passing `user` selects the headless source instead; combining it with `source: "tab"` is an error rather than a silently ignored role, as is combining it with `lowdefy_load_state`'s `mode: "registry-only"` (that mode hands you a URL to open yourself). The plain HTTP routes take the same param: `?user={"roles":["admin"]}` on the GET routes, a `user` key in the body of `POST /lowdefy-docs/
|
|
91
|
+
`user` applies to the headless renderer only — it is never applied to a page you open in your own browser, which carries your real session and cannot be re-identified. `lowdefy_inspect_state` and `lowdefy_eval_operator` normally prefer your open tab, so passing `user` selects the headless source instead; combining it with `source: "tab"` is an error rather than a silently ignored role, as is combining it with `lowdefy_load_state`'s `mode: "registry-only"` (that mode hands you a URL to open yourself). The plain HTTP routes take the same param: `?user={"roles":["admin"]}` on the GET routes, a `user` key in the body of `POST /lowdefy-docs/eval-operator` and `POST /lowdefy-docs/state-checkpoints/load`. They answer a malformed or contradictory `user` with a `400`, distinct from the `502` a failed render returns.
|
|
93
92
|
|
|
94
|
-
To bypass login for the whole dev server — your own browser included — start it with a mock user instead: `lowdefy dev --mock-user '{"
|
|
93
|
+
To bypass login for the whole dev server — your own browser included — start it with a mock user instead: `lowdefy dev --mock-user '{"sub":"dev","roles":["admin"]}'` (or configure `auth.dev.mockUser`). See [Auth Configuration](/auth-configuration#mock-user-for-testing-dev-server-only).
|
|
95
94
|
|
|
96
95
|
## State checkpoints — put the app in a known state
|
|
97
96
|
|
|
@@ -124,90 +123,6 @@ cli:
|
|
|
124
123
|
|
|
125
124
|
This is dev-only — enable it when you're comfortable with the agent writing to your dev data.
|
|
126
125
|
|
|
127
|
-
## Journeys — verify behaviour, not just layout
|
|
128
|
-
|
|
129
|
-
A screenshot shows what rendered; it cannot tell the agent whether the form submits, the modal opens or the filter works. `lowdefy_run_journey` (or `POST /lowdefy-docs/journey`) opens a page headless and drives it through a declarative list of steps — a tiny Playwright — then reports what happened as data. Blocks are addressed by their `blockId`, through the same `#bl-<blockId>` DOM contract `@lowdefy/e2e-utils` uses, so a journey reads like the config it tests:
|
|
130
|
-
|
|
131
|
-
```json
|
|
132
|
-
{
|
|
133
|
-
"pageId": "new_customer",
|
|
134
|
-
"user": { "roles": ["admin"] },
|
|
135
|
-
"urlQuery": { "ref": "campaign-1" },
|
|
136
|
-
"steps": [
|
|
137
|
-
{ "fill": { "blockId": "name", "value": "Ada Lovelace" } },
|
|
138
|
-
{ "select": { "blockId": "country", "value": "United Kingdom" } },
|
|
139
|
-
{ "click": "submit" },
|
|
140
|
-
{ "wait": { "request": "create_customer" } },
|
|
141
|
-
{ "expect": { "state": { "path": "created", "equals": true } } },
|
|
142
|
-
{ "expect": { "visible": "success_modal" } },
|
|
143
|
-
{ "expect": { "text": { "blockId": "success_message", "contains": "Ada Lovelace" } } },
|
|
144
|
-
{ "screenshot": "after-submit" },
|
|
145
|
-
{ "press": "Escape" },
|
|
146
|
-
{ "click": "go_to_list" },
|
|
147
|
-
{ "expect": { "url": { "contains": "/customers" } } }
|
|
148
|
-
]
|
|
149
|
-
}
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
Every step is an object with exactly one key:
|
|
153
|
-
|
|
154
|
-
| Step | What it does |
|
|
155
|
-
| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
156
|
-
| `{ "click": blockId }` | Clicks the block — its interactive control (button, link, input, checkbox…) when it has one, otherwise the block itself |
|
|
157
|
-
| `{ "fill": { blockId, value } }` | Fills the block's `input` or `textarea` with `value` (converted to a string) |
|
|
158
|
-
| `{ "select": { blockId, value } }` | Opens the block's dropdown and clicks the option whose text is exactly `value`; a native `<select>` inside the block is set by label instead |
|
|
159
|
-
| `{ "press": key }` | Presses a key or chord, e.g. `"Enter"`, `"Escape"`, `"Mod+k"` — `Mod` becomes `Meta` or `Control` for the platform the page reports, the same way the app's shortcuts resolve it |
|
|
160
|
-
| `{ "wait": { "ms": n } }` | Sleeps `n` milliseconds |
|
|
161
|
-
| `{ "wait": { "request": requestId } }` | Waits until the request has finished loading |
|
|
162
|
-
| `{ "wait": { "state": path } }` | Waits until the state path is defined |
|
|
163
|
-
| `{ "screenshot": name? }` | Captures a PNG of the viewport; returned with the result (`true`, `null` or a missing name defaults to `step-<index>`) |
|
|
164
|
-
| `{ "expect": { "state": { path, equals } } }` | The state at `path` structurally equals `equals` (key order does not matter) |
|
|
165
|
-
| `{ "expect": { "visible": blockId } }` | The block is visible |
|
|
166
|
-
| `{ "expect": { "text": { blockId, contains } } }` | The block's text contains the string |
|
|
167
|
-
| `{ "expect": { "url": { contains } } }` | The page url contains the string |
|
|
168
|
-
|
|
169
|
-
Each step gets 5 seconds (Playwright's own auto-waiting — a `click` waits for the block to be attached, visible and enabled; nothing is retried). After an interaction the runner waits for the page to settle — the event the interaction fired, the requests it called — using the same readiness check the page open uses, so the next `expect` asserts against the outcome instead of racing it. The page opens with the same headless `user` and `urlQuery` handling as the other tools.
|
|
170
|
-
|
|
171
|
-
A step that fails **stops the journey and comes back as data**, never as a tool error — a failed journey is the answer, not a fault:
|
|
172
|
-
|
|
173
|
-
```json
|
|
174
|
-
{
|
|
175
|
-
"pageId": "new_customer",
|
|
176
|
-
"passed": false,
|
|
177
|
-
"steps": [
|
|
178
|
-
{
|
|
179
|
-
"index": 0,
|
|
180
|
-
"step": { "fill": { "blockId": "name", "value": "Ada Lovelace" } },
|
|
181
|
-
"status": "ok",
|
|
182
|
-
"durationMs": 18
|
|
183
|
-
},
|
|
184
|
-
{ "index": 1, "step": { "click": "submit" }, "status": "ok", "durationMs": 71 },
|
|
185
|
-
{
|
|
186
|
-
"index": 2,
|
|
187
|
-
"step": { "expect": { "state": { "path": "created", "equals": true } } },
|
|
188
|
-
"status": "failed",
|
|
189
|
-
"durationMs": 1
|
|
190
|
-
},
|
|
191
|
-
{ "index": 3, "step": { "screenshot": "after-submit" }, "status": "skipped", "durationMs": 0 }
|
|
192
|
-
],
|
|
193
|
-
"failure": {
|
|
194
|
-
"index": 2,
|
|
195
|
-
"step": { "expect": { "state": { "path": "created", "equals": true } } },
|
|
196
|
-
"expected": true,
|
|
197
|
-
"actual": null,
|
|
198
|
-
"message": "Expected state \"created\" to equal true but found undefined."
|
|
199
|
-
},
|
|
200
|
-
"screenshots": [],
|
|
201
|
-
"state": { "name": "Ada Lovelace", "country": null }
|
|
202
|
-
}
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
`expected` and `actual` hold the compared values for an `expect` step, and for an interaction step what the runner needed (`block "submit" to be actionable`, `option "Chile" in the dropdown of block "country"`) against Playwright's own message. The remaining steps are marked `skipped`. A passing journey returns `passed: true` and no `failure`. The final page `state` is always included, pass or fail — it is what the agent needs to write the next assertion. Screenshots taken before the failure are kept: over MCP they arrive as image content after the JSON (with the JSON listing only their names); over HTTP they are base64 in the JSON body.
|
|
206
|
-
|
|
207
|
-
Malformed steps are answered before a browser opens — an unknown key returns `Unknown journey step "hover". Steps are: click, fill, select, press, wait, screenshot, expect.` (a `400` on the HTTP route), distinct from the `502` a render that could not run returns.
|
|
208
|
-
|
|
209
|
-
Journeys are also the file format of `tests/journeys/*.yaml`, which `lowdefy test` runs through this same route — write the journey the agent used to verify a change, and it becomes the regression test for it.
|
|
210
|
-
|
|
211
126
|
## Setting up a project — one command
|
|
212
127
|
|
|
213
128
|
```bash
|
|
@@ -290,7 +205,6 @@ Everything the MCP tools serve is also available as plain GET routes — useful
|
|
|
290
205
|
| `GET /lowdefy-docs/build-status` | Current build errors/warnings + recent browser runtime errors |
|
|
291
206
|
| `GET /lowdefy-docs/page-config/{pageId}` | Fully built page config, or its build errors |
|
|
292
207
|
| `GET /lowdefy-docs/screenshot/{pageId}` | PNG screenshot of the rendered page |
|
|
293
|
-
| `POST /lowdefy-docs/journey` | Drive a page headless through declarative steps and assert what happens; screenshots returned as base64 |
|
|
294
208
|
| `GET /lowdefy-docs/find/{id}?pageId=` | Locate where a page/block/request id is defined |
|
|
295
209
|
| `GET /lowdefy-docs/app-map` | Whole-app graph: pages, menus, connections, endpoints, agents |
|
|
296
210
|
| `GET /lowdefy-docs/inspect-state/{pageId}` | Live state/requests/eventLog of a running page (tab or headless) |
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Lowdefy provides several ways to style blocks and customize the look of your app:
|
|
4
4
|
|
|
5
5
|
- **`class`** — Apply CSS class names (including Tailwind CSS utility classes) to blocks.
|
|
6
|
-
- **`style`** — Apply inline CSS styles to blocks. Use
|
|
6
|
+
- **`style`** — Apply inline CSS styles to blocks. Use `--`-prefixed keys to target specific parts (CSS slots).
|
|
7
7
|
- **`properties.theme`** — Override antd design tokens per block. See [Theming](/theming) for details.
|
|
8
8
|
- **`public/styles.css`** — A global CSS file for custom styles.
|
|
9
9
|
|
|
@@ -11,7 +11,7 @@ Lowdefy provides several ways to style blocks and customize the look of your app
|
|
|
11
11
|
|
|
12
12
|
The `class` property applies CSS class names to a block. [Tailwind CSS](https://tailwindcss.com/) is always available in Lowdefy apps, so you can use any Tailwind utility classes directly.
|
|
13
13
|
|
|
14
|
-
`class` can be a string, an array of strings, an object keyed by the block's CSS keys
|
|
14
|
+
`class` can be a string, an array of strings, or an object keyed by the block's CSS keys:
|
|
15
15
|
|
|
16
16
|
```yaml
|
|
17
17
|
# String — applied to the block wrapper
|
|
@@ -27,60 +27,15 @@ The `class` property applies CSS class names to a block. [Tailwind CSS](https://
|
|
|
27
27
|
- shadow-lg
|
|
28
28
|
- rounded-xl
|
|
29
29
|
|
|
30
|
-
# Object — target specific parts of the block using CSS keys (
|
|
30
|
+
# Object — target specific parts of the block using CSS keys (-- prefix)
|
|
31
31
|
- id: my_card
|
|
32
32
|
type: Card
|
|
33
33
|
class:
|
|
34
34
|
.element: "shadow-lg"
|
|
35
35
|
.header: "bg-gray-100"
|
|
36
36
|
.body: "p-8"
|
|
37
|
-
|
|
38
|
-
# Operator — the block's classes are computed at runtime
|
|
39
|
-
- id: status_badge
|
|
40
|
-
type: Box
|
|
41
|
-
class:
|
|
42
|
-
_if:
|
|
43
|
-
test:
|
|
44
|
-
_eq:
|
|
45
|
-
- _state: status
|
|
46
|
-
- error
|
|
47
|
-
then: bg-red-100 text-red-700
|
|
48
|
-
else: bg-green-100 text-green-700
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
An operator's result may be a string, an array of strings, or an object of `{ class: boolean }` where each class with a truthy value is applied:
|
|
52
|
-
|
|
53
|
-
```yaml
|
|
54
|
-
- id: status_badge
|
|
55
|
-
type: Box
|
|
56
|
-
class:
|
|
57
|
-
_if:
|
|
58
|
-
test:
|
|
59
|
-
_eq:
|
|
60
|
-
- _state: status
|
|
61
|
-
- error
|
|
62
|
-
then:
|
|
63
|
-
bg-red-100: true
|
|
64
|
-
text-red-700: true
|
|
65
|
-
else: bg-green-100
|
|
66
37
|
```
|
|
67
38
|
|
|
68
|
-
An operator at the root of `class` computes the classes of the block wrapper. To compute a specific part's classes, place the operator under that CSS key:
|
|
69
|
-
|
|
70
|
-
```yaml
|
|
71
|
-
- id: my_card
|
|
72
|
-
type: Card
|
|
73
|
-
class:
|
|
74
|
-
.header:
|
|
75
|
-
_if:
|
|
76
|
-
test:
|
|
77
|
-
_state: highlighted
|
|
78
|
-
then: bg-yellow-100
|
|
79
|
-
else: bg-gray-100
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
> **Note:** An operator's result is never expanded into a map of CSS keys — a root operator always sets the block wrapper's classes.
|
|
83
|
-
|
|
84
39
|
Tailwind responsive prefixes work as expected:
|
|
85
40
|
|
|
86
41
|
```yaml
|
|
@@ -103,7 +58,7 @@ See [Theming](/theming) for the full list of bridged tokens and how to add custo
|
|
|
103
58
|
|
|
104
59
|
## The `style` property
|
|
105
60
|
|
|
106
|
-
The `style` property applies inline CSS styles to a block. When used with flat CSS properties (no
|
|
61
|
+
The `style` property applies inline CSS styles to a block. When used with flat CSS properties (no `--` prefix), it targets the block's layout wrapper:
|
|
107
62
|
|
|
108
63
|
```yaml
|
|
109
64
|
- id: my_block
|
|
@@ -148,7 +103,7 @@ Each block's documentation page lists its supported CSS keys.
|
|
|
148
103
|
|
|
149
104
|
Each block declares named style targets in its `meta.cssKeys`. For example, the [Card](/Card) block supports: `element`, `header`, `body`, `cover`, `actions`, `extra`.
|
|
150
105
|
|
|
151
|
-
Both `class` (object form) and `style` use
|
|
106
|
+
Both `class` (object form) and `style` use `--`-prefixed versions of these keys to target specific parts of a block. The `--` prefix mirrors CSS custom property convention and avoids confusion with CSS property names.
|
|
152
107
|
|
|
153
108
|
To find the CSS keys for a block, check the block's documentation page.
|
|
154
109
|
|
|
@@ -225,11 +225,9 @@ events:
|
|
|
225
225
|
searchOpen: true
|
|
226
226
|
```
|
|
227
227
|
|
|
228
|
-
## Page
|
|
228
|
+
## Page initialization events
|
|
229
229
|
|
|
230
|
-
The first blocks on a page, usually a [`container`](/container) type block, can define
|
|
231
|
-
|
|
232
|
-
### Page initialization events
|
|
230
|
+
The first blocks on a page, usually a [`container`](/container) type block, can define `onInit` and `onInitAsync` events. All blocks have `onMount` and `onMountAsync` events, that can be used to initialize the page or blocks.
|
|
233
231
|
|
|
234
232
|
The `onInit` event is triggered the first time a page is loaded. This event blocks page render, in other words, the page __will__ remain in a loading state, rendering only the progress bar, until all the actions have completed execution. It can be used to set up [`state`](/page-and-app-state). Actions that take a long time to execute, like `Request`, should be used sparingly here for a better user experience.
|
|
235
233
|
|
|
@@ -239,62 +237,6 @@ The `onMount` event is triggered every time a block is rendered on a page. This
|
|
|
239
237
|
|
|
240
238
|
The `onMountAsync` event is triggered every time a block is mounted, but does not render the block in loading.
|
|
241
239
|
|
|
242
|
-
### Browser lifecycle events
|
|
243
|
-
|
|
244
|
-
The first blocks on a page can also define events that react to the browser: `onVisible`, `onHidden`, `onOnline`, `onOffline` and `onResize`. These are useful to refresh data that went stale while the user was away, instead of polling the server on a timer.
|
|
245
|
-
|
|
246
|
-
These events are only attached while the page is mounted, and are removed again when the user navigates away, so they never trigger for a page the user has left. They never trigger on the initial page load either — only a change after the page has loaded triggers them. Their action chains run like `onMountAsync`: they do not keep the page or block in a loading state.
|
|
247
|
-
|
|
248
|
-
The `onVisible` event is triggered when the browser tab becomes visible again, or when the window regains focus. Rapid pairs of these signals — a tab switch usually produces both — are coalesced over 300ms, so the event is only triggered once. The [`_event`](/_event) object contains `visible: true` and `reason`, which is `visibility` when the browser reported the tab becoming visible, or `focus` when the window regained focus.
|
|
249
|
-
|
|
250
|
-
```yaml
|
|
251
|
-
events:
|
|
252
|
-
onVisible:
|
|
253
|
-
- id: refresh_tasks
|
|
254
|
-
type: Request
|
|
255
|
-
params: get_tasks
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
The `onHidden` event is triggered when the browser tab is hidden, or when the window loses focus, coalesced in the same way. The `_event` object contains `visible: false` and the same `reason` field.
|
|
259
|
-
|
|
260
|
-
```yaml
|
|
261
|
-
events:
|
|
262
|
-
onHidden:
|
|
263
|
-
- id: stop_refreshing
|
|
264
|
-
type: SetState
|
|
265
|
-
params:
|
|
266
|
-
live: false
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
The `onOnline` and `onOffline` events are triggered when the browser reports that the network connection was regained or lost. The `_event` object contains `online: true` or `online: false`.
|
|
270
|
-
|
|
271
|
-
```yaml
|
|
272
|
-
events:
|
|
273
|
-
onOnline:
|
|
274
|
-
- id: back_online
|
|
275
|
-
type: Message
|
|
276
|
-
params:
|
|
277
|
-
content: You are back online.
|
|
278
|
-
onOffline:
|
|
279
|
-
- id: went_offline
|
|
280
|
-
type: Message
|
|
281
|
-
params:
|
|
282
|
-
status: warning
|
|
283
|
-
content: You are offline, changes will not be saved.
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
The `onResize` event is triggered when the window is resized, debounced by 200ms so that the actions only run once the user stops resizing. The `_event` object contains the `width` and `height` of the window.
|
|
287
|
-
|
|
288
|
-
```yaml
|
|
289
|
-
events:
|
|
290
|
-
onResize:
|
|
291
|
-
- id: set_width
|
|
292
|
-
type: SetState
|
|
293
|
-
params:
|
|
294
|
-
window_width:
|
|
295
|
-
_event: width
|
|
296
|
-
```
|
|
297
|
-
|
|
298
240
|
## Action types
|
|
299
241
|
|
|
300
242
|
The following actions can be used:
|
|
@@ -327,7 +269,3 @@ See additional action type available under the Actions tab in the menu.
|
|
|
327
269
|
- The `onInitAsync` event is triggered the first time a page is mounted and does not keep the page in loading.
|
|
328
270
|
- The `onMount` events is triggered the every time a block is mounted and keeps the block in loading until all actions have finished.
|
|
329
271
|
- The `onMountAsync` event is triggered the every time a block is mounted, after `onMount` has completed, and does not keep the block in loading.
|
|
330
|
-
- The `onVisible` and `onHidden` events are triggered when the browser tab is shown or hidden, or when the window gains or loses focus, coalesced over 300ms.
|
|
331
|
-
- The `onOnline` and `onOffline` events are triggered when the browser reports that the network connection was regained or lost.
|
|
332
|
-
- The `onResize` event is triggered when the window is resized, debounced by 200ms.
|
|
333
|
-
- Browser lifecycle events are never triggered on the initial page load, and are removed when the user navigates away from the page.
|
package/content/concepts/i18n.md
CHANGED
|
@@ -214,7 +214,7 @@ config:
|
|
|
214
214
|
agent.antdx.actions.feedbackDislike: 'Gefällt mir nicht'
|
|
215
215
|
```
|
|
216
216
|
|
|
217
|
-
**Agent runtime errors.** HTTP
|
|
217
|
+
**Agent runtime errors.** HTTP 400/500 errors from the agent endpoint (`Only POST requests are supported.`, `Invalid agent path`, `Agent "X" does not exist.`, etc.) translate via `agent.runtime.*` keys against the request's `Accept-Language`. Server-side validation errors and stack traces stay in English (developer diagnostics).
|
|
218
218
|
|
|
219
219
|
**Agent config translation.** `agent.properties.instructions` passes through the operator parser at request time, so `_t:` works:
|
|
220
220
|
|
|
@@ -34,15 +34,12 @@ The `MongoDBCollection` connection sets up a connection to a MongoDB deployment.
|
|
|
34
34
|
|
|
35
35
|
>Since the connection URI contains authentication secrets, it should be stored using the [`_secret`](operators/secret.md) operator.
|
|
36
36
|
|
|
37
|
-
When
|
|
37
|
+
When using MongoDBUpdateOne and MongoDBDeleteOne requests, take note that the responses differ if the connection has a log collection.
|
|
38
38
|
|
|
39
39
|
#### Properties
|
|
40
40
|
- `databaseUri: string`: __Required__ - Connection uri string for the MongoDb deployment. Should be stored using the [_secret](operators/secret.md) operator.
|
|
41
41
|
- `databaseName: string`: Default: Database specified in connection string - The name of the database in the MongoDB deployment.
|
|
42
42
|
- `collection: string`: __Required__ - The name of the MongoDB collection.
|
|
43
|
-
- `changeLog: object`: Log all changes made by write requests to a log collection.
|
|
44
|
-
- `collection: string`: __Required__ - The name of the collection change log records are written to.
|
|
45
|
-
- `meta: object`: Additional data to include in every change log record, for example the user making the change.
|
|
46
43
|
- `read: boolean`: Default: `true` - Allow read operations like find on the collection.
|
|
47
44
|
- `write: boolean`: Default: `false` - Allow write operations like update on the collection.
|
|
48
45
|
- `options: object`: See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/interfaces/mongoclientoptions.html) for more information.
|
|
@@ -108,13 +105,10 @@ Request types:
|
|
|
108
105
|
- MongoDBDeleteOne
|
|
109
106
|
- MongoDBFind
|
|
110
107
|
- MongoDBFindOne
|
|
111
|
-
- MongoDBInsertConsecutiveId
|
|
112
108
|
- MongoDBInsertMany
|
|
113
|
-
- MongoDBInsertManyConsecutiveIds
|
|
114
109
|
- MongoDBInsertOne
|
|
115
110
|
- MongoDBUpdateMany
|
|
116
111
|
- MongoDBUpdateOne
|
|
117
|
-
- MongoDBVersionedUpdateOne
|
|
118
112
|
|
|
119
113
|
|
|
120
114
|
### MongoDBAggregation
|
|
@@ -297,7 +291,7 @@ requests:
|
|
|
297
291
|
### MongoDBDeleteOne
|
|
298
292
|
|
|
299
293
|
The `MongoDBDeleteOne` request deletes a single document in the collection specified in the connectionId. It requires a filter, which is written in the query syntax, to select a document to delete. It will delete the first document that matches the filter.
|
|
300
|
-
>
|
|
294
|
+
> MongoDBDeleteOne response differs when the connection has a log collection. When a log collection is set on the connection, a findOneAndDelete operation is performed compared to the standard deleteOne operation.
|
|
301
295
|
|
|
302
296
|
#### Properties
|
|
303
297
|
- `filter: object`: __Required__ - The filter used to select the document to update.
|
|
@@ -471,34 +465,6 @@ requests:
|
|
|
471
465
|
_payload: _id
|
|
472
466
|
```
|
|
473
467
|
|
|
474
|
-
### MongoDBInsertConsecutiveId
|
|
475
|
-
|
|
476
|
-
The `MongoDBInsertConsecutiveId` request inserts a single document into the collection specified in the connectionId, assigning a sequential, human-readable `_id` like `INV0001`. The id is built from a prefix and the next consecutive number for that prefix, zero-padded to `length` digits. The id read and the insert run inside a transaction so concurrent requests cannot claim the same id.
|
|
477
|
-
|
|
478
|
-
> Transactions require MongoDB to run as a replica set. Standalone deployments are not supported by this request.
|
|
479
|
-
|
|
480
|
-
#### Properties
|
|
481
|
-
- `doc: object`: __Required__ - The document to be inserted. The `_id` is assigned by the request.
|
|
482
|
-
- `prefix: string`: __Required__ - Prefix to add to the id, for example `INV`.
|
|
483
|
-
- `length: number`: The numeric part of the id is zero-padded to this number of digits. If omitted, the number is not padded.
|
|
484
|
-
- `options: object`: Optional settings passed to the insert. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#insertone) for more information.
|
|
485
|
-
|
|
486
|
-
#### Examples
|
|
487
|
-
|
|
488
|
-
###### Insert an invoice with a sequential id (INV0001, INV0002, ...):
|
|
489
|
-
```yaml
|
|
490
|
-
requests:
|
|
491
|
-
- id: insert_invoice
|
|
492
|
-
type: MongoDBInsertConsecutiveId
|
|
493
|
-
connectionId: my_mongodb_collection_id
|
|
494
|
-
properties:
|
|
495
|
-
prefix: INV
|
|
496
|
-
length: 4
|
|
497
|
-
doc:
|
|
498
|
-
amount:
|
|
499
|
-
_state: amount
|
|
500
|
-
```
|
|
501
|
-
|
|
502
468
|
### MongoDBInsertMany
|
|
503
469
|
|
|
504
470
|
The `MongoDBInsertMany` request inserts an array of documents into the collection specified in the connectionId. If a `_id` field is not specified on a document, a MongoDB `ObjectID` will be generated.
|
|
@@ -546,33 +512,6 @@ requests:
|
|
|
546
512
|
|
|
547
513
|
```
|
|
548
514
|
|
|
549
|
-
### MongoDBInsertManyConsecutiveIds
|
|
550
|
-
|
|
551
|
-
The `MongoDBInsertManyConsecutiveIds` request inserts an array of documents into the collection specified in the connectionId, assigning each document a sequential, human-readable `_id` like `INV0001`. Ids continue from the highest existing id for the prefix. The id read and the insert run inside a transaction so concurrent requests cannot claim the same ids.
|
|
552
|
-
|
|
553
|
-
> Transactions require MongoDB to run as a replica set. Standalone deployments are not supported by this request.
|
|
554
|
-
|
|
555
|
-
#### Properties
|
|
556
|
-
- `docs: object[]`: __Required__ - The documents to be inserted. The `_id` values are assigned by the request.
|
|
557
|
-
- `prefix: string`: __Required__ - Prefix to add to the ids, for example `INV`.
|
|
558
|
-
- `length: number`: The numeric part of each id is zero-padded to this number of digits. If omitted, the numbers are not padded.
|
|
559
|
-
- `options: object`: Optional settings passed to the insert. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#insertmany) for more information.
|
|
560
|
-
|
|
561
|
-
#### Examples
|
|
562
|
-
|
|
563
|
-
###### Insert order lines with sequential ids:
|
|
564
|
-
```yaml
|
|
565
|
-
requests:
|
|
566
|
-
- id: insert_order_lines
|
|
567
|
-
type: MongoDBInsertManyConsecutiveIds
|
|
568
|
-
connectionId: my_mongodb_collection_id
|
|
569
|
-
properties:
|
|
570
|
-
prefix: LINE
|
|
571
|
-
length: 6
|
|
572
|
-
docs:
|
|
573
|
-
_state: order_lines
|
|
574
|
-
```
|
|
575
|
-
|
|
576
515
|
### MongoDBInsertOne
|
|
577
516
|
|
|
578
517
|
The `MongoDBInsertOne` request inserts a document into the collection specified in the connectionId. If a `_id` field is not specified, a MongoDB `ObjectID` will be generated.
|
|
@@ -680,15 +619,11 @@ requests:
|
|
|
680
619
|
### MongoDBUpdateOne
|
|
681
620
|
|
|
682
621
|
The `MongoDBUpdateOne` request updates a single document in the collection specified in the connectionId. It requires a filter, which is written in the query syntax, to select a document to update. It will update the first document that matches the filter. If the `upsert` option is set to true, it will insert a new document if no document is found to update.
|
|
683
|
-
|
|
684
|
-
If no document matches the filter, the request throws `No matching record to update.` — a silent no-op update usually indicates a bug. Set `disableNoMatchError: true` on the request to restore the pre-5.5.0 behavior of returning `matchedCount: 0`. Requests with the `upsert` option never throw this error. Running `lowdefy upgrade` adds `disableNoMatchError: true` to existing requests so upgraded apps keep their behavior.
|
|
685
|
-
|
|
686
|
-
> When the connection has a log collection, a findOneAndUpdate operation is performed instead of the standard updateOne operation so before and after document snapshots can be captured in the change log. The response shape is the same in both cases.
|
|
622
|
+
> MongoDBUpdateOne response differs when the connection has a log collection. When a log collection is set on the connection, a findOneAndUpdate operation is performed compared to the standard updateOne operation.
|
|
687
623
|
|
|
688
624
|
#### Properties
|
|
689
625
|
- `filter: object`: __Required__ - The filter used to select the document to update.
|
|
690
626
|
- `update: object | object[]`: __Required__ - The update operations to be applied to the document.
|
|
691
|
-
- `disableNoMatchError: boolean`: Default: `false` - Do not throw an error when no document matches the filter.
|
|
692
627
|
- `options: object`: Optional settings. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#updateone) for more information. Supported settings are:
|
|
693
628
|
- `arrayFilters: object[]`: _Array_ - Array filters for the [`$[<identifier>]`](https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/) array update operator.
|
|
694
629
|
- `authdb: string`: Specifies the authentication information to be used.
|
|
@@ -757,47 +692,6 @@ requests:
|
|
|
757
692
|
_date: now
|
|
758
693
|
```
|
|
759
694
|
|
|
760
|
-
### MongoDBVersionedUpdateOne
|
|
761
|
-
|
|
762
|
-
The `MongoDBVersionedUpdateOne` request updates a single document while preserving the previous version. The matched document is re-inserted under a new `_id`, and the update is applied to the new copy — so the collection keeps a full version history of the document.
|
|
763
|
-
|
|
764
|
-
If no document matches the filter, the request throws `No matching record to update.`. Set `disableNoMatchError: true` on the request to suppress the error. Requests with the `upsert` update option never throw this error.
|
|
765
|
-
|
|
766
|
-
> The version insert and the update are separate operations, not a transaction. If the update fails, the inserted version copy remains in the collection.
|
|
767
|
-
|
|
768
|
-
> When the connection has a log collection, a findOneAndUpdate operation is performed instead of the standard updateOne operation so before and after document snapshots can be captured in the change log. The response shape is the same in both cases.
|
|
769
|
-
|
|
770
|
-
#### Properties
|
|
771
|
-
- `filter: object`: __Required__ - The filter used to select the document to version and update.
|
|
772
|
-
- `update: object | object[]`: __Required__ - The update operations to be applied to the new copy of the document.
|
|
773
|
-
- `disableNoMatchError: boolean`: Default: `false` - Do not throw an error when no document matches the filter.
|
|
774
|
-
- `options: object`: Optional settings for each underlying operation:
|
|
775
|
-
- `find: object`: Options for the find one operation. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#findone).
|
|
776
|
-
- `insert: object`: Options for the insert one operation that creates the version copy. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#insertone).
|
|
777
|
-
- `update: object`: Options for the update operation. See the [driver documentation](https://mongodb.github.io/node-mongodb-native/4.0/classes/collection.html#updateone).
|
|
778
|
-
|
|
779
|
-
#### Examples
|
|
780
|
-
|
|
781
|
-
###### Update a document, keeping the previous version:
|
|
782
|
-
```yaml
|
|
783
|
-
requests:
|
|
784
|
-
- id: versioned_update
|
|
785
|
-
type: MongoDBVersionedUpdateOne
|
|
786
|
-
connectionId: my_mongodb_collection_id
|
|
787
|
-
payload:
|
|
788
|
-
doc_id:
|
|
789
|
-
_state: doc_id
|
|
790
|
-
properties:
|
|
791
|
-
filter:
|
|
792
|
-
doc_id:
|
|
793
|
-
_payload: doc_id
|
|
794
|
-
current: true
|
|
795
|
-
update:
|
|
796
|
-
$set:
|
|
797
|
-
status:
|
|
798
|
-
_state: status
|
|
799
|
-
```
|
|
800
|
-
|
|
801
695
|
## Websockets
|
|
802
696
|
|
|
803
697
|
Websocket types:
|