@picked/client 0.0.101-next.1 → 0.0.101-next.3
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 +34 -158
- package/dist/{api-DThEBKPu.cjs → api-9o_emCM5.cjs} +1 -1
- package/dist/{api-DcXndm41.js → api-BbQt8aW3.js} +1 -1
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/plugins/dynamic-experiences/index.js +1 -1
- package/dist/cjs/server/index.js +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/plugins/dynamic-experiences/index.js +2 -2
- package/dist/esm/server/index.js +2 -2
- package/dist/{plugin-DA34qpbe.cjs → plugin-I8_6ncy_.cjs} +1 -1
- package/dist/{plugin-BZPx7WhX.js → plugin-uZJ45vK6.js} +2 -2
- package/dist/{preview-unavailable-sDBBJFrE.cjs → preview-unavailable-BUNxTYLe.cjs} +1 -1
- package/dist/{preview-unavailable-Bg8UuQeR.js → preview-unavailable-BYFD2a58.js} +1 -1
- package/dist/{provider-BkN7A93w.cjs → provider-Bzi_Kb-n.cjs} +1 -1
- package/dist/{provider-DRNHPacW.js → provider-CQKp0iUJ.js} +1 -1
- package/package.json +5 -5
- package/dist/docs/_root.css +0 -101
- package/dist/docs/explanation/conditions-and-the-logic-engine.md +0 -94
- package/dist/docs/explanation/content-references.md +0 -99
- package/dist/docs/explanation/feature-flag-allocation.md +0 -218
- package/dist/docs/explanation/how-picked-works.md +0 -124
- package/dist/docs/explanation/how-pickedql-works.md +0 -76
- package/dist/docs/explanation/pages-and-flows.md +0 -64
- package/dist/docs/explanation/the-content-model.md +0 -87
- package/dist/docs/explanation/the-two-apis.md +0 -68
- package/dist/docs/explanation/why-server-side-rendering.md +0 -76
- package/dist/docs/explanation/workspaces-and-versions.md +0 -71
- package/dist/docs/how-to/add-a-step-field-or-action.md +0 -43
- package/dist/docs/how-to/analytics/index.md +0 -316
- package/dist/docs/how-to/archive-or-delete-a-workspace.md +0 -46
- package/dist/docs/how-to/authenticate-the-cli.md +0 -101
- package/dist/docs/how-to/authenticate-with-a-magic-link.md +0 -47
- package/dist/docs/how-to/authenticate-with-a-password.md +0 -59
- package/dist/docs/how-to/authenticate-with-an-api-key.md +0 -51
- package/dist/docs/how-to/authenticate-with-oauth.md +0 -40
- package/dist/docs/how-to/build-a-flow.md +0 -93
- package/dist/docs/how-to/call-an-external-api-from-a-workflow.md +0 -102
- package/dist/docs/how-to/connect-the-mcp-server.md +0 -46
- package/dist/docs/how-to/create-a-content-entry.md +0 -48
- package/dist/docs/how-to/create-a-project.md +0 -29
- package/dist/docs/how-to/create-an-experience.md +0 -42
- package/dist/docs/how-to/create-and-revoke-an-api-key.md +0 -42
- package/dist/docs/how-to/debug-with-the-chrome-extension.md +0 -57
- package/dist/docs/how-to/define-a-page-layout.md +0 -46
- package/dist/docs/how-to/fill-and-publish-a-page.md +0 -66
- package/dist/docs/how-to/install-the-gtm-template.md +0 -84
- package/dist/docs/how-to/install-the-sdk.md +0 -93
- package/dist/docs/how-to/install-the-vite-plugin.md +0 -69
- package/dist/docs/how-to/invite-and-remove-members.md +0 -35
- package/dist/docs/how-to/point-one-entry-at-another.md +0 -61
- package/dist/docs/how-to/preview-a-workspace.md +0 -28
- package/dist/docs/how-to/publish-a-workspace.md +0 -30
- package/dist/docs/how-to/read-a-feature-flag.md +0 -113
- package/dist/docs/how-to/read-a-referenced-entry.md +0 -109
- package/dist/docs/how-to/register-a-component.md +0 -55
- package/dist/docs/how-to/register-an-action-handler.md +0 -85
- package/dist/docs/how-to/register-an-api-that-uses-oauth2.md +0 -107
- package/dist/docs/how-to/render-a-step-form.md +0 -131
- package/dist/docs/how-to/render-an-unpublished-preview.md +0 -41
- package/dist/docs/how-to/retry-a-failed-call-with-a-loop.md +0 -81
- package/dist/docs/how-to/reuse-a-section.md +0 -53
- package/dist/docs/how-to/reuse-a-step-field-or-action.md +0 -28
- package/dist/docs/how-to/roll-back-a-published-version.md +0 -26
- package/dist/docs/how-to/run-an-ab-test.md +0 -49
- package/dist/docs/how-to/run-code-on-a-form-submission.md +0 -125
- package/dist/docs/how-to/server-render-a-page.md +0 -81
- package/dist/docs/how-to/set-a-content-security-policy.md +0 -32
- package/dist/docs/how-to/set-up-mfa.md +0 -113
- package/dist/docs/how-to/switch-workspaces.md +0 -122
- package/dist/docs/how-to/upload-and-use-an-asset.mdx +0 -73
- package/dist/docs/how-to/validate-a-field.md +0 -52
- package/dist/docs/how-to/wait-for-an-action-response.md +0 -182
- package/dist/docs/how-to/write-a-condition.md +0 -45
- package/dist/docs/how-to/write-a-predicate.md +0 -60
- package/dist/docs/index.md +0 -59
- package/dist/docs/reference/dashboard/actions.mdx +0 -56
- package/dist/docs/reference/dashboard/api-keys.mdx +0 -38
- package/dist/docs/reference/dashboard/conditions.mdx +0 -42
- package/dist/docs/reference/dashboard/content/asset-library.mdx +0 -63
- package/dist/docs/reference/dashboard/content/blocks.mdx +0 -57
- package/dist/docs/reference/dashboard/content/content-entries.mdx +0 -95
- package/dist/docs/reference/dashboard/content/models.mdx +0 -108
- package/dist/docs/reference/dashboard/content/pages.mdx +0 -61
- package/dist/docs/reference/dashboard/experiences.mdx +0 -51
- package/dist/docs/reference/dashboard/external-apis.md +0 -169
- package/dist/docs/reference/dashboard/features.mdx +0 -154
- package/dist/docs/reference/dashboard/fields.mdx +0 -106
- package/dist/docs/reference/dashboard/flow-builder/canvas.mdx +0 -58
- package/dist/docs/reference/dashboard/flow-builder/condition-builder.md +0 -57
- package/dist/docs/reference/dashboard/flow-builder/keyboard-shortcuts.md +0 -72
- package/dist/docs/reference/dashboard/flow-builder/nodes.md +0 -63
- package/dist/docs/reference/dashboard/labels.md +0 -321
- package/dist/docs/reference/dashboard/lead-search.md +0 -224
- package/dist/docs/reference/dashboard/projects.mdx +0 -44
- package/dist/docs/reference/dashboard/reports.mdx +0 -43
- package/dist/docs/reference/dashboard/steps.mdx +0 -37
- package/dist/docs/reference/dashboard/team-management.md +0 -29
- package/dist/docs/reference/dashboard/workflow-runs.md +0 -142
- package/dist/docs/reference/dashboard/workflow-templates.md +0 -182
- package/dist/docs/reference/dashboard/workflow-test-runs.md +0 -77
- package/dist/docs/reference/dashboard/workspace-versioning.mdx +0 -30
- package/dist/docs/reference/dashboard/workspaces.mdx +0 -76
- package/dist/docs/reference/delivery-api/experience-content.md +0 -152
- package/dist/docs/reference/delivery-api/index.md +0 -45
- package/dist/docs/reference/delivery-api/preview-caching-crawling.md +0 -79
- package/dist/docs/reference/delivery-api/project-config.md +0 -65
- package/dist/docs/reference/delivery-api/workspace-schema.md +0 -107
- package/dist/docs/reference/glossary.md +0 -201
- package/dist/docs/reference/management-api/authentication.md +0 -87
- package/dist/docs/reference/management-api/authorization-and-scopes.md +0 -291
- package/dist/docs/reference/management-api/error-handling.md +0 -232
- package/dist/docs/reference/management-api/pagination.md +0 -192
- package/dist/docs/reference/pickedql/data-sources.md +0 -174
- package/dist/docs/reference/pickedql/dimensions.md +0 -103
- package/dist/docs/reference/pickedql/filtering.md +0 -64
- package/dist/docs/reference/pickedql/index.md +0 -18
- package/dist/docs/reference/pickedql/schema.md +0 -172
- package/dist/docs/reference/pickedql/virtual-functions.md +0 -248
- package/dist/docs/reference/sdk/actions.md +0 -154
- package/dist/docs/reference/sdk/analytics-events.md +0 -453
- package/dist/docs/reference/sdk/conditions.md +0 -147
- package/dist/docs/reference/sdk/content-security-policy.md +0 -21
- package/dist/docs/reference/sdk/content.md +0 -253
- package/dist/docs/reference/sdk/experiences.md +0 -51
- package/dist/docs/reference/sdk/features.md +0 -256
- package/dist/docs/reference/sdk/fields.md +0 -255
- package/dist/docs/reference/sdk/index.md +0 -68
- package/dist/docs/reference/sdk/plugins/create-experience.md +0 -123
- package/dist/docs/reference/sdk/plugins/dynamic-experiences.md +0 -74
- package/dist/docs/reference/sdk/plugins/index.md +0 -29
- package/dist/docs/reference/sdk/plugins/window-object.md +0 -25
- package/dist/docs/reference/sdk/predicates.md +0 -43
- package/dist/docs/reference/sdk/ssr/index.md +0 -33
- package/dist/docs/reference/sdk/ssr/rendering-and-hydration.md +0 -103
- package/dist/docs/reference/sdk/ssr/serialize.md +0 -80
- package/dist/docs/reference/sdk/ssr/slots-and-placements.md +0 -113
- package/dist/docs/reference/sdk/steps.md +0 -86
- package/dist/docs/reference/sdk/type-generation.md +0 -265
- package/dist/docs/reference/tools/chrome-extension.md +0 -16
- package/dist/docs/reference/tools/cli.md +0 -292
- package/dist/docs/reference/tools/image-optimisation-service.md +0 -104
- package/dist/docs/reference/tools/mcp.md +0 -136
- package/dist/docs/reference/tools/vite-plugin.md +0 -163
- package/dist/docs/tutorials/first-api-call.md +0 -235
- package/dist/docs/tutorials/first-experience-in-the-dashboard.mdx +0 -143
- package/dist/docs/tutorials/first-experience.mdx +0 -254
- package/dist/docs/tutorials/first-server-rendered-page.mdx +0 -186
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: how-to
|
|
3
|
-
layout: docs
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# How to server-render a page
|
|
7
|
-
|
|
8
|
-
This guide shows you how to render a Picked Page on your server and hydrate it in the
|
|
9
|
-
browser. You need a published Page and a server that renders React or Svelte.
|
|
10
|
-
|
|
11
|
-
## 1. Make the snapshot
|
|
12
|
-
|
|
13
|
-
Create one client for each request, then call `serialize()`:
|
|
14
|
-
|
|
15
|
-
```ts
|
|
16
|
-
import { createClient } from 'picked'
|
|
17
|
-
import { serialize } from '@picked/client/server'
|
|
18
|
-
|
|
19
|
-
const client = createClient(options)
|
|
20
|
-
|
|
21
|
-
const snapshot = await serialize(client, {
|
|
22
|
-
projectConfig,
|
|
23
|
-
attributes: { location: { pathname: url.pathname } },
|
|
24
|
-
})
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
:::warning
|
|
28
|
-
Give `serialize()` one client for each request. It does not support two calls at the same
|
|
29
|
-
time on one client.
|
|
30
|
-
:::
|
|
31
|
-
|
|
32
|
-
## 2. Embed the snapshot
|
|
33
|
-
|
|
34
|
-
```ts
|
|
35
|
-
const html = `
|
|
36
|
-
<div id="root">${appHtml}</div>
|
|
37
|
-
<script>window.__PICKED__ = ${JSON.stringify(snapshot)}</script>
|
|
38
|
-
`
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## 3. Seed the client and render the slot
|
|
42
|
-
|
|
43
|
-
:::code-group
|
|
44
|
-
|
|
45
|
-
```tsx [React]
|
|
46
|
-
import { PickedProvider, ExperienceSlot } from '@picked/react'
|
|
47
|
-
|
|
48
|
-
export function Page({ snapshot }) {
|
|
49
|
-
return (
|
|
50
|
-
<PickedProvider options={options} snapshot={snapshot}>
|
|
51
|
-
<ExperienceSlot name="page" />
|
|
52
|
-
</PickedProvider>
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
```svelte [Svelte]
|
|
58
|
-
<script lang="ts">
|
|
59
|
-
import { ExperienceSlot, setPickedContext } from '@picked/svelte'
|
|
60
|
-
|
|
61
|
-
const { snapshot } = $props()
|
|
62
|
-
setPickedContext({ options, snapshot })
|
|
63
|
-
</script>
|
|
64
|
-
|
|
65
|
-
<ExperienceSlot name="page" />
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
:::
|
|
69
|
-
|
|
70
|
-
The provider seeds the client at once, so the server HTML and the first paint match.
|
|
71
|
-
|
|
72
|
-
## 4. Point the experience at the slot
|
|
73
|
-
|
|
74
|
-
Set the target selector of your Page experience to `.picked-slot-page`, then publish.
|
|
75
|
-
|
|
76
|
-
## Related
|
|
77
|
-
|
|
78
|
-
- [About server-side rendering](/explanation/why-server-side-rendering) — why the
|
|
79
|
-
snapshot carries condition results.
|
|
80
|
-
- [Server snapshot](/reference/sdk/ssr/serialize) — every parameter.
|
|
81
|
-
- [Your first server-rendered page](/tutorials/first-server-rendered-page).
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: how-to
|
|
3
|
-
layout: docs
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# How to set a Content Security Policy
|
|
7
|
-
|
|
8
|
-
This guide shows you how to let the Picked SDK load its resources under a CSP.
|
|
9
|
-
|
|
10
|
-
## Steps
|
|
11
|
-
|
|
12
|
-
Add the Picked domains to your policy.
|
|
13
|
-
|
|
14
|
-
As an HTTP header:
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
Content-Security-Policy: connect-src 'self' https://api.picked.app https://evnts.pckd.dev; img-src 'self' https://img.picked-content.com;
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
Or as a `<meta>` tag:
|
|
21
|
-
|
|
22
|
-
```html
|
|
23
|
-
<meta
|
|
24
|
-
http-equiv="Content-Security-Policy"
|
|
25
|
-
content="connect-src 'self' https://api.picked.app https://evnts.pckd.dev; img-src 'self' https://img.picked-content.com;"
|
|
26
|
-
/>
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Related
|
|
30
|
-
|
|
31
|
-
- [Content Security Policy](/reference/sdk/content-security-policy) — what each domain is
|
|
32
|
-
for.
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: how-to
|
|
3
|
-
layout: docs
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# How to set up MFA
|
|
7
|
-
|
|
8
|
-
This guide shows you how to add an authenticator app to an account, and how to sign in
|
|
9
|
-
with it. Picked supports TOTP authenticator apps only, such as Google Authenticator.
|
|
10
|
-
Every MFA mutation needs authentication.
|
|
11
|
-
|
|
12
|
-
## Who must use MFA
|
|
13
|
-
|
|
14
|
-
Picked staff, and every member of an organization that requires MFA, must sign in with an
|
|
15
|
-
authenticator app. For these users, most operations return the error code `MFA_REQUIRED`
|
|
16
|
-
until the session reaches `AAL2`. The operations that a session at `AAL1` can use are in
|
|
17
|
-
[Authenticator assurance levels](/reference/management-api/authentication#authenticator-assurance-levels).
|
|
18
|
-
The `user.mfa` field tells you where a user stands:
|
|
19
|
-
|
|
20
|
-
```graphql
|
|
21
|
-
query {
|
|
22
|
-
user {
|
|
23
|
-
mfa { required reason enrolled satisfied }
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
| Field | Meaning |
|
|
29
|
-
| --- | --- |
|
|
30
|
-
| `required` | The user must hold an `AAL2` session to use the fields that need it. |
|
|
31
|
-
| `reason` | `STAFF` or `ORGANIZATION`. Empty when `required` is false. |
|
|
32
|
-
| `enrolled` | The user holds a verified authenticator. |
|
|
33
|
-
| `satisfied` | The session that made the request meets the requirement. |
|
|
34
|
-
|
|
35
|
-
## 1. Add an authenticator
|
|
36
|
-
|
|
37
|
-
```graphql
|
|
38
|
-
mutation {
|
|
39
|
-
mfaFactorEnroll(input: { friendlyName: "Work phone" }) {
|
|
40
|
-
factor { id factorType status }
|
|
41
|
-
totp { qrCode secret uri }
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
A new factor has the status `UNVERIFIED`. Show `qrCode` (SVG markup) for the user to scan,
|
|
47
|
-
or `secret` for the user to enter into the app. The API returns it one time only.
|
|
48
|
-
|
|
49
|
-
Before it adds the factor, the mutation deletes the caller's factors that are not verified.
|
|
50
|
-
But it keeps the two newest of these factors if they are less than 60 seconds old. A
|
|
51
|
-
different setup can still use them, for example in a different browser tab. The mutation
|
|
52
|
-
also deletes a factor that is not verified and has the `friendlyName` that you give.
|
|
53
|
-
Therefore, a setup that did not finish does not stop a new setup.
|
|
54
|
-
|
|
55
|
-
## 2. Open a challenge
|
|
56
|
-
|
|
57
|
-
```graphql
|
|
58
|
-
mutation {
|
|
59
|
-
mfaChallengeCreate(input: { factorId: "factor-id" }) {
|
|
60
|
-
challengeId
|
|
61
|
-
expiresAt
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## 3. Verify the code
|
|
67
|
-
|
|
68
|
-
```graphql
|
|
69
|
-
mutation {
|
|
70
|
-
mfaChallengeVerify(input: {
|
|
71
|
-
factorId: "factor-id"
|
|
72
|
-
challengeId: "challenge-id"
|
|
73
|
-
code: "123456"
|
|
74
|
-
}) {
|
|
75
|
-
session { accessToken refreshToken aal }
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
The session moves to `AAL2`, and the factor status changes to `VERIFIED`. Use the returned
|
|
81
|
-
tokens from this point. A wrong code returns `MFA_CHALLENGE_FAILED`.
|
|
82
|
-
|
|
83
|
-
## Sign in with an authenticator
|
|
84
|
-
|
|
85
|
-
After `sessionCreate`, the session is at `AAL1`. When `session.user.mfa.enrolled` is
|
|
86
|
-
`true`, do steps 2 and 3 against one of the user's verified factors. The query
|
|
87
|
-
`user { mfaFactors { id status } }` lists them. When `required` is `true` and `enrolled`
|
|
88
|
-
is `false`, do steps 1 to 3.
|
|
89
|
-
|
|
90
|
-
## Remove an authenticator
|
|
91
|
-
|
|
92
|
-
```graphql
|
|
93
|
-
mutation {
|
|
94
|
-
mfaFactorUnenroll(input: { factorId: "factor-id" }) {
|
|
95
|
-
success
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
To remove a verified factor, the session must be at `AAL2`. An `AAL1` session receives
|
|
101
|
-
`MFA_REQUIRED`.
|
|
102
|
-
|
|
103
|
-
A user who must use MFA always keeps at least one authenticator. A request to remove
|
|
104
|
-
their last one fails with `VALIDATION_ERROR`. To replace an authenticator, add the new
|
|
105
|
-
one first, then remove the old one. A user with the `users/reset_mfa` scope clears the
|
|
106
|
-
last one with `userMfaReset`.
|
|
107
|
-
|
|
108
|
-
## Related
|
|
109
|
-
|
|
110
|
-
- [Authentication](/reference/management-api/authentication) — every mutation and the
|
|
111
|
-
assurance levels.
|
|
112
|
-
- [Authorization and scopes](/reference/management-api/authorization-and-scopes) — who
|
|
113
|
-
can reset the MFA of another user.
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: how-to
|
|
3
|
-
layout: docs
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# How to switch workspaces
|
|
7
|
-
|
|
8
|
-
This guide shows you how to point your local tooling at a different project or workspace.
|
|
9
|
-
Your application then renders that workspace's content and types on your machine. It expects
|
|
10
|
-
a `picked.config.ts` and the [CLI](/reference/tools/cli).
|
|
11
|
-
|
|
12
|
-
Your tooling reads the project and surface named in the committed `picked.config.ts`. The
|
|
13
|
-
CLI writes your choice to `.picked/settings.json` instead. That file is per-developer and
|
|
14
|
-
Git ignores it, so the committed default stays as it is and one command puts it back.
|
|
15
|
-
|
|
16
|
-
See [Workspaces](/reference/dashboard/workspaces) for what Live, Draft, and Archived mean.
|
|
17
|
-
|
|
18
|
-
## 1. Sign in
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
picked login
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
This opens your browser for a one-time OAuth sign-in and stores a session under
|
|
25
|
-
`~/.picked/`. Confirm it with `picked whoami`. See
|
|
26
|
-
[CLI authentication](/how-to/authenticate-the-cli).
|
|
27
|
-
|
|
28
|
-
## 2. Find a workspace
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
picked workspace list
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
Acme Corp. (acme-corporation)
|
|
36
|
-
Storefront [proj_a1b2]
|
|
37
|
-
Default Storefront [LIVE] (live)
|
|
38
|
-
Checkout rework [DRAFT]
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
Note the **project id** (`proj_a1b2`) and the name or the id of the workspace you want.
|
|
42
|
-
|
|
43
|
-
## 3. Switch to the draft
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
picked workspace use --project proj_a1b2 --workspace ws_draft
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
Active workspace: Checkout rework [DRAFT] in project proj_a1b2 (source: preview)
|
|
51
|
-
Generated types at /app/src/picked-env.d.ts
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
A command that names **one specific workspace** (draft, live, or archived):
|
|
55
|
-
|
|
56
|
-
- writes the selection (and its [preview token](/reference/delivery-api/preview-caching-crawling)) to
|
|
57
|
-
`.picked/settings.json`,
|
|
58
|
-
- switches the resolved `source` to `preview` for that project, and
|
|
59
|
-
- regenerates `picked-env.d.ts` from that workspace's schema (skip with `--no-generate`).
|
|
60
|
-
|
|
61
|
-
To browse instead, run `picked workspace use` with no flags. The interactive picker lists
|
|
62
|
-
every project, with **Published (live version)** and each of its workspaces.
|
|
63
|
-
|
|
64
|
-
## 4. See the draft in your app
|
|
65
|
-
|
|
66
|
-
Both readers of the selection use `.picked/settings.json` with no change to your
|
|
67
|
-
configuration:
|
|
68
|
-
|
|
69
|
-
- **Type generation** now reads the draft schema. Rerun `picked generate types` after more
|
|
70
|
-
edits.
|
|
71
|
-
- The **[Vite plugin](/reference/tools/vite-plugin)** reads the draft's configuration and
|
|
72
|
-
content in development and in a build. It sends the preview token to the
|
|
73
|
-
[Delivery API](/reference/delivery-api). Restart the dev server to apply a switch.
|
|
74
|
-
|
|
75
|
-
Your application renders the unpublished draft on your machine, with types.
|
|
76
|
-
|
|
77
|
-
## 5. Switch back to live
|
|
78
|
-
|
|
79
|
-
```bash
|
|
80
|
-
picked workspace use --project proj_a1b2
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
A command that names a project with no `--workspace`, or **Published (live version)** in the
|
|
84
|
-
picker, discards the preview token and returns `source` to `published`. To confirm what is
|
|
85
|
-
active:
|
|
86
|
-
|
|
87
|
-
```bash
|
|
88
|
-
picked status
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
```
|
|
92
|
-
Config default: project proj_a1b2 (source: published)
|
|
93
|
-
Active selection: none (using the config default).
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
## CI and headless runs
|
|
97
|
-
|
|
98
|
-
`.picked/settings.json` is a local, per-developer file. Do not commit it. To choose one
|
|
99
|
-
workspace in CI with no selection file, set the environment directly:
|
|
100
|
-
|
|
101
|
-
```bash
|
|
102
|
-
PICKED_PROJECT_ID=proj_a1b2 \
|
|
103
|
-
PICKED_PREVIEW_TOKEN="$DRAFT_TOKEN" \
|
|
104
|
-
picked generate types --check
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
`PICKED_PREVIEW_TOKEN` applies only when the resolved `source` is `preview`. See the
|
|
108
|
-
[CLI environment variables](/reference/tools/cli#environment-variables) for the full
|
|
109
|
-
precedence order.
|
|
110
|
-
|
|
111
|
-
:::note
|
|
112
|
-
A preview token is a long-lived credential for one workspace. Keep it out of the version
|
|
113
|
-
control system, as you do with each other credential. Git ignores `.picked/settings.json`
|
|
114
|
-
for this reason, because `picked workspace use` writes a token there.
|
|
115
|
-
:::
|
|
116
|
-
|
|
117
|
-
## Related
|
|
118
|
-
|
|
119
|
-
- [CLI](/reference/tools/cli) — every command and flag.
|
|
120
|
-
- [Workspaces](/reference/dashboard/workspaces) — Live, Draft, and Archived states.
|
|
121
|
-
- [Type generation](/reference/sdk/type-generation) — how the schema becomes types.
|
|
122
|
-
- [Preview, cache, and crawlers](/reference/delivery-api/preview-caching-crawling) — preview tokens on the Delivery API.
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: how-to
|
|
3
|
-
layout: docs
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
import { Screenshot } from '../../../components/Screenshot'
|
|
7
|
-
|
|
8
|
-
# How to upload and use an asset
|
|
9
|
-
|
|
10
|
-
This guide shows you how to put a file in the asset library and point at it from your
|
|
11
|
-
content.
|
|
12
|
-
|
|
13
|
-
## 1. Add the field to a layout
|
|
14
|
-
|
|
15
|
-
Two field types point at the library:
|
|
16
|
-
|
|
17
|
-
- An **Asset** field takes an image, a video, or a document.
|
|
18
|
-
- An **HTML** field takes a `.html` file.
|
|
19
|
-
|
|
20
|
-
Add one of them to a page layout or a step layout.
|
|
21
|
-
|
|
22
|
-
## 2. Choose a file
|
|
23
|
-
|
|
24
|
-
1. Open the content entry.
|
|
25
|
-
2. Click **Choose file** on the asset field. On a field that holds a value already, click
|
|
26
|
-
**Replace**.
|
|
27
|
-
3. Open the **Upload** tab to add a new file.
|
|
28
|
-
4. Open the **Library** tab to use a file that is there already.
|
|
29
|
-
5. Choose your asset.
|
|
30
|
-
|
|
31
|
-
<Screenshot
|
|
32
|
-
route="/{orgSlug}/{projectId}/design-systems/new"
|
|
33
|
-
wait='button:has-text("Upload file")'
|
|
34
|
-
click='button:has-text("Upload file")'
|
|
35
|
-
selector="[role=dialog]"
|
|
36
|
-
alt="The asset picker modal on the Picked dashboard, with the Library tab, its search box, its type filter, and its Sort menu"
|
|
37
|
-
renderWidth={1072}
|
|
38
|
-
renderHeight={790}
|
|
39
|
-
/>
|
|
40
|
-
|
|
41
|
-
<Screenshot
|
|
42
|
-
route="/{orgSlug}/{projectId}/design-systems/new"
|
|
43
|
-
wait='button:has-text("Upload file")'
|
|
44
|
-
click='button:has-text("Upload file")'
|
|
45
|
-
selector="[role=dialog]"
|
|
46
|
-
alt="The asset picker modal on the Picked dashboard, with the Library tab, its search box, its type filter, and its Sort menu"
|
|
47
|
-
renderWidth={1072}
|
|
48
|
-
renderHeight={790}
|
|
49
|
-
/>
|
|
50
|
-
|
|
51
|
-
The detail panel on the right shows the kind, the dimensions, the size, and the upload
|
|
52
|
-
date.
|
|
53
|
-
|
|
54
|
-
## 3. Find an asset in a large library
|
|
55
|
-
|
|
56
|
-
The **Library** tab has three controls, and the server applies each one across the whole
|
|
57
|
-
library:
|
|
58
|
-
|
|
59
|
-
- **Search by name** narrows the list by file name while you type.
|
|
60
|
-
- The type filter narrows the list to one media type. **All types** is the default.
|
|
61
|
-
- **Sort** orders the list by **Name**, **Date created**, or **Date updated**.
|
|
62
|
-
|
|
63
|
-
Click **Load more** at the bottom to read the next page of results.
|
|
64
|
-
|
|
65
|
-
:::tip
|
|
66
|
-
Each row has an **Open in new tab** control. Use it to check an asset again before you
|
|
67
|
-
choose it. Your choice in the picker stays as it is.
|
|
68
|
-
:::
|
|
69
|
-
|
|
70
|
-
## Related
|
|
71
|
-
|
|
72
|
-
- [Asset library](/reference/dashboard/content/asset-library) — the limits, the file
|
|
73
|
-
types, and how Picked serves an uploaded file.
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: how-to
|
|
3
|
-
layout: docs
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# How to validate a field
|
|
7
|
-
|
|
8
|
-
This guide shows you how to check what a visitor enters. Write the rule in JSON Logic. The
|
|
9
|
-
`$input` variable holds the current value of the field.
|
|
10
|
-
|
|
11
|
-
## Steps
|
|
12
|
-
|
|
13
|
-
Add a `validation` rule to `createField()`:
|
|
14
|
-
|
|
15
|
-
```ts
|
|
16
|
-
import { createField } from '@picked/client/plugins/create-experience'
|
|
17
|
-
|
|
18
|
-
const quantityField = createField({
|
|
19
|
-
id: 'quantity',
|
|
20
|
-
name: 'quantity',
|
|
21
|
-
type: 'number',
|
|
22
|
-
label: 'Quantity',
|
|
23
|
-
multiple: false,
|
|
24
|
-
required: true,
|
|
25
|
-
validation: {
|
|
26
|
-
catch: {
|
|
27
|
-
or: [
|
|
28
|
-
{
|
|
29
|
-
and: [
|
|
30
|
-
{ '>': [{ var: '$input' }, 0] },
|
|
31
|
-
{ '<=': [{ var: '$input' }, 999] },
|
|
32
|
-
],
|
|
33
|
-
},
|
|
34
|
-
{ throw: 'Please enter a value between 1 and 999' },
|
|
35
|
-
],
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
})
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
:::tip
|
|
42
|
-
The `catch` and `throw` pattern checks that the condition gives `true`. When it does not,
|
|
43
|
-
the SDK shows the `throw` message to your visitor.
|
|
44
|
-
:::
|
|
45
|
-
|
|
46
|
-
The SDK runs the rule on blur and on submit.
|
|
47
|
-
|
|
48
|
-
## Related
|
|
49
|
-
|
|
50
|
-
- [SDK fields](/reference/sdk/fields) — every field option.
|
|
51
|
-
- [About conditions and the logic engine](/explanation/conditions-and-the-logic-engine) —
|
|
52
|
-
the rule format.
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: how-to
|
|
3
|
-
layout: docs
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# How to wait for the response of an action
|
|
7
|
-
|
|
8
|
-
This guide shows you how to run an action from your application and show its response. You
|
|
9
|
-
need an action in your project first, with a key and a workflow that the action starts. See
|
|
10
|
-
[Actions](/reference/dashboard/actions).
|
|
11
|
-
|
|
12
|
-
The response is the value that the action returns. For an action that starts a workflow in
|
|
13
|
-
Picked, the response is the payload of the **Action response** node in the workflow.
|
|
14
|
-
|
|
15
|
-
## 1. Generate the types of your project
|
|
16
|
-
|
|
17
|
-
Run type generation. The generated types name the actions that start a workflow. For those
|
|
18
|
-
keys, the types of `useAction` and `getAction` include `run`. At runtime, the value includes
|
|
19
|
-
`run` for each key. See [Type generation](/reference/sdk/type-generation).
|
|
20
|
-
|
|
21
|
-
## 2. Bind the action to a component
|
|
22
|
-
|
|
23
|
-
Call `useAction` in React, or `getAction` in Svelte. Neither runs the action. The action runs
|
|
24
|
-
only when you call `run`. The action receives the arguments of `run` in `args`.
|
|
25
|
-
|
|
26
|
-
All the components that use the same key and the same experience share one run state. When
|
|
27
|
-
one of them calls `run`, all of them show that run.
|
|
28
|
-
|
|
29
|
-
:::code-group
|
|
30
|
-
|
|
31
|
-
```tsx [React]
|
|
32
|
-
import { useAction } from '@picked/react/hooks'
|
|
33
|
-
|
|
34
|
-
function CallbackButton() {
|
|
35
|
-
const callback = useAction('request-callback')
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<button onClick={() => void callback.run()} disabled={callback.status === 'running'}>
|
|
39
|
-
Get a call back
|
|
40
|
-
</button>
|
|
41
|
-
)
|
|
42
|
-
}
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
```svelte [Svelte]
|
|
46
|
-
<script lang="ts">
|
|
47
|
-
import { getAction } from '@picked/svelte/hooks'
|
|
48
|
-
|
|
49
|
-
const callback = getAction('request-callback')
|
|
50
|
-
</script>
|
|
51
|
-
|
|
52
|
-
<button onclick={() => $callback.run()} disabled={$callback.status === 'running'}>
|
|
53
|
-
Get a call back
|
|
54
|
-
</button>
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
:::
|
|
58
|
-
|
|
59
|
-
## 3. Show the response
|
|
60
|
-
|
|
61
|
-
Read `status`, `response` and `error` for the last run. Compare `response` with the values
|
|
62
|
-
that your workflow sends.
|
|
63
|
-
|
|
64
|
-
:::code-group
|
|
65
|
-
|
|
66
|
-
```tsx [React]
|
|
67
|
-
import { useAction } from '@picked/react/hooks'
|
|
68
|
-
|
|
69
|
-
// Reads the status that the workflow sends in its response.
|
|
70
|
-
function answerStatus(response: unknown): unknown {
|
|
71
|
-
return typeof response === 'object' && response !== null && 'status' in response
|
|
72
|
-
? response.status
|
|
73
|
-
: undefined
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function CallbackButton() {
|
|
77
|
-
const callback = useAction('request-callback')
|
|
78
|
-
|
|
79
|
-
if (callback.status === 'failed') return <p>We could not send your request.</p>
|
|
80
|
-
if (callback.status === 'succeeded') {
|
|
81
|
-
if (answerStatus(callback.response) === 'closed') {
|
|
82
|
-
return <p>We call back on weekdays, 8 am to 5 pm.</p>
|
|
83
|
-
}
|
|
84
|
-
return <p>Thank you. We will call you soon.</p>
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return (
|
|
88
|
-
<button onClick={() => void callback.run()} disabled={callback.status === 'running'}>
|
|
89
|
-
Get a call back
|
|
90
|
-
</button>
|
|
91
|
-
)
|
|
92
|
-
}
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
```svelte [Svelte]
|
|
96
|
-
<script lang="ts">
|
|
97
|
-
import { getAction } from '@picked/svelte/hooks'
|
|
98
|
-
|
|
99
|
-
const callback = getAction('request-callback')
|
|
100
|
-
|
|
101
|
-
// Reads the status that the workflow sends in its response.
|
|
102
|
-
function answerStatus(response: unknown): unknown {
|
|
103
|
-
return typeof response === 'object' && response !== null && 'status' in response
|
|
104
|
-
? response.status
|
|
105
|
-
: undefined
|
|
106
|
-
}
|
|
107
|
-
</script>
|
|
108
|
-
|
|
109
|
-
{#if $callback.status === 'failed'}
|
|
110
|
-
<p>We could not send your request.</p>
|
|
111
|
-
{:else if $callback.status === 'succeeded' && answerStatus($callback.response) === 'closed'}
|
|
112
|
-
<p>We call back on weekdays, 8 am to 5 pm.</p>
|
|
113
|
-
{:else if $callback.status === 'succeeded'}
|
|
114
|
-
<p>Thank you. We will call you soon.</p>
|
|
115
|
-
{:else}
|
|
116
|
-
<button onclick={() => $callback.run()} disabled={$callback.status === 'running'}>
|
|
117
|
-
Get a call back
|
|
118
|
-
</button>
|
|
119
|
-
{/if}
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
:::
|
|
123
|
-
|
|
124
|
-
`run` does not reject. It resolves to `{ status: 'succeeded', response }` or to
|
|
125
|
-
`{ status: 'failed', error }`.
|
|
126
|
-
|
|
127
|
-
## 4. Run the action outside a component
|
|
128
|
-
|
|
129
|
-
Call `client.actions.run` with the action key. It resolves to the response, and it rejects
|
|
130
|
-
when the action fails.
|
|
131
|
-
|
|
132
|
-
The client registers the actions of your project when it loads the configuration of your
|
|
133
|
-
project. For this, the client must have `dynamicExperiencesPlugin`, and you must start the
|
|
134
|
-
client. Until the client is ready, `run` rejects with `Action '<key>' is not registered`. A
|
|
135
|
-
handler that your application registers in `createClient({ actions })` is available
|
|
136
|
-
immediately.
|
|
137
|
-
|
|
138
|
-
```ts
|
|
139
|
-
import { createClient } from 'picked'
|
|
140
|
-
import { dynamicExperiencesPlugin } from '@picked/client/plugins/dynamic-experiences'
|
|
141
|
-
|
|
142
|
-
const picked = createClient({
|
|
143
|
-
projectId: 'your-project-id',
|
|
144
|
-
plugins: [dynamicExperiencesPlugin()],
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
picked.start()
|
|
148
|
-
|
|
149
|
-
// Waits until the client is ready.
|
|
150
|
-
async function whenReady(): Promise<void> {
|
|
151
|
-
if (picked.readyStore.getState()) return
|
|
152
|
-
|
|
153
|
-
await new Promise<void>((resolve) => {
|
|
154
|
-
const subscription = picked.readyStore.updates.watch((ready) => {
|
|
155
|
-
if (!ready) return
|
|
156
|
-
subscription.unsubscribe()
|
|
157
|
-
resolve()
|
|
158
|
-
})
|
|
159
|
-
})
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
async function requestCallback(): Promise<void> {
|
|
163
|
-
await whenReady()
|
|
164
|
-
|
|
165
|
-
try {
|
|
166
|
-
const response = await picked.actions.run('request-callback', { timeoutMs: 15_000 })
|
|
167
|
-
console.info('Callback response', response)
|
|
168
|
-
} catch (error) {
|
|
169
|
-
console.warn('Callback request failed', error)
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
Set `timeoutMs` to stop the wait sooner. Set `signal` to stop the wait from your own code.
|
|
175
|
-
|
|
176
|
-
## Related
|
|
177
|
-
|
|
178
|
-
- [SDK actions](/reference/sdk/actions) — every outcome, error and limit.
|
|
179
|
-
- [How to register an action handler](/how-to/register-an-action-handler) — return a
|
|
180
|
-
response from your own handler.
|
|
181
|
-
- [How to call an external API from a workflow](/how-to/call-an-external-api-from-a-workflow)
|
|
182
|
-
— a workflow that sends a response.
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: how-to
|
|
3
|
-
layout: docs
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# How to write a condition
|
|
7
|
-
|
|
8
|
-
This guide shows you how to build a rule in the visual condition builder. The builder
|
|
9
|
-
appears on a condition node, on an experience condition, on an initialize-open condition,
|
|
10
|
-
and on a field option.
|
|
11
|
-
|
|
12
|
-
## Steps
|
|
13
|
-
|
|
14
|
-
1. Choose the node or the field that takes the condition.
|
|
15
|
-
2. Find the **Logic** section in the inspector.
|
|
16
|
-
3. Choose a data source: **Responses**, **Actions**, **Feature flags**, **Conditions**,
|
|
17
|
-
or **Window Location**.
|
|
18
|
-
4. Choose an operator. The choices include equals, not equals, greater than, and
|
|
19
|
-
contains.
|
|
20
|
-
5. Enter a value.
|
|
21
|
-
|
|
22
|
-
## Join more than one rule
|
|
23
|
-
|
|
24
|
-
1. Create an AND group or an OR group.
|
|
25
|
-
2. Add your rules inside it.
|
|
26
|
-
|
|
27
|
-
With **AND** every rule must match. With **OR** one rule must match. Put a group inside
|
|
28
|
-
another group to build a larger rule.
|
|
29
|
-
|
|
30
|
-
## Example
|
|
31
|
-
|
|
32
|
-
To show a step only to a visitor who is on one page and who accepted marketing:
|
|
33
|
-
|
|
34
|
-
1. Create an AND group.
|
|
35
|
-
2. Add a rule: **Window Location → pathname** equals `/pricing`.
|
|
36
|
-
3. Add a rule: **Responses → `marketing_opt_in`** equals `true`.
|
|
37
|
-
|
|
38
|
-
The group matches only when both rules are true.
|
|
39
|
-
|
|
40
|
-
## Related
|
|
41
|
-
|
|
42
|
-
- [About conditions and the logic engine](/explanation/conditions-and-the-logic-engine) —
|
|
43
|
-
what a rule can read.
|
|
44
|
-
- [Condition builder](/reference/dashboard/flow-builder/condition-builder) — the rule
|
|
45
|
-
structure.
|