@picked/client 0.0.70 → 0.0.71-next.2

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.
Files changed (249) hide show
  1. package/dist/.tsbuildinfo +1 -0
  2. package/dist/api-B0ydpQBE.js +38 -0
  3. package/dist/api-CObostrU.cjs +1 -0
  4. package/dist/cjs/form/index.js +1 -1
  5. package/dist/cjs/index.js +2 -2
  6. package/dist/cjs/plugins/dom-observer/index.js +1 -1
  7. package/dist/cjs/plugins/dynamic-experiences/index.js +1 -1
  8. package/dist/cjs/server/index.js +1 -1
  9. package/dist/docs/explanation/conditions-and-the-logic-engine.md +94 -0
  10. package/dist/docs/explanation/feature-flag-allocation.md +176 -0
  11. package/dist/docs/explanation/how-picked-works.md +102 -0
  12. package/dist/docs/explanation/how-pickedql-works.md +76 -0
  13. package/dist/docs/explanation/pages-and-flows.md +64 -0
  14. package/dist/docs/explanation/the-content-model.md +77 -0
  15. package/dist/docs/explanation/the-two-apis.md +68 -0
  16. package/dist/docs/explanation/why-server-side-rendering.md +76 -0
  17. package/dist/docs/explanation/workspaces-and-versions.md +71 -0
  18. package/dist/docs/how-to/add-a-step-field-or-action.md +43 -0
  19. package/dist/docs/{pickedql/examples.md → how-to/analytics/index.md} +19 -6
  20. package/dist/docs/how-to/archive-or-delete-a-workspace.md +46 -0
  21. package/dist/docs/how-to/authenticate-with-a-magic-link.md +40 -0
  22. package/dist/docs/how-to/authenticate-with-a-password.md +51 -0
  23. package/dist/docs/how-to/authenticate-with-an-api-key.md +51 -0
  24. package/dist/docs/how-to/authenticate-with-oauth.md +40 -0
  25. package/dist/docs/{flow-builder/building-flows.md → how-to/build-a-flow.md} +13 -9
  26. package/dist/docs/how-to/connect-the-mcp-server.md +38 -0
  27. package/dist/docs/how-to/create-a-project.md +29 -0
  28. package/dist/docs/how-to/create-an-experience.md +42 -0
  29. package/dist/docs/how-to/create-and-revoke-an-api-key.md +37 -0
  30. package/dist/docs/how-to/debug-with-the-chrome-extension.md +57 -0
  31. package/dist/docs/how-to/define-a-page-layout.md +39 -0
  32. package/dist/docs/how-to/fill-and-publish-a-page.md +50 -0
  33. package/dist/docs/{gtm-template.md → how-to/install-the-gtm-template.md} +9 -3
  34. package/dist/docs/how-to/install-the-sdk.md +68 -0
  35. package/dist/docs/how-to/install-the-vite-plugin.md +56 -0
  36. package/dist/docs/how-to/invite-and-remove-members.md +34 -0
  37. package/dist/docs/how-to/preview-a-workspace.md +28 -0
  38. package/dist/docs/how-to/publish-a-workspace.md +30 -0
  39. package/dist/docs/how-to/read-a-feature-flag.md +101 -0
  40. package/dist/docs/how-to/register-a-component.md +55 -0
  41. package/dist/docs/how-to/register-an-action-handler.md +67 -0
  42. package/dist/docs/how-to/render-a-step-form.md +132 -0
  43. package/dist/docs/how-to/render-an-unpublished-preview.md +41 -0
  44. package/dist/docs/how-to/reuse-a-section.md +37 -0
  45. package/dist/docs/how-to/reuse-a-step-field-or-action.md +28 -0
  46. package/dist/docs/how-to/roll-back-a-published-version.md +26 -0
  47. package/dist/docs/how-to/run-an-ab-test.md +49 -0
  48. package/dist/docs/how-to/run-code-on-a-form-submission.md +125 -0
  49. package/dist/docs/how-to/server-render-a-page.md +81 -0
  50. package/dist/docs/how-to/set-a-content-security-policy.md +32 -0
  51. package/dist/docs/how-to/set-up-mfa.md +69 -0
  52. package/dist/docs/how-to/upload-and-use-an-asset.mdx +73 -0
  53. package/dist/docs/how-to/validate-a-field.md +52 -0
  54. package/dist/docs/how-to/write-a-condition.md +45 -0
  55. package/dist/docs/how-to/write-a-predicate.md +60 -0
  56. package/dist/docs/index.md +41 -70
  57. package/dist/docs/reference/dashboard/actions.mdx +53 -0
  58. package/dist/docs/{api-keys.mdx → reference/dashboard/api-keys.mdx} +7 -15
  59. package/dist/docs/reference/dashboard/conditions.mdx +42 -0
  60. package/dist/docs/reference/dashboard/content/asset-library.mdx +63 -0
  61. package/dist/docs/{content → reference/dashboard/content}/content-entries.mdx +11 -3
  62. package/dist/docs/{content → reference/dashboard/content}/layouts.mdx +11 -35
  63. package/dist/docs/reference/dashboard/content/pages.mdx +35 -0
  64. package/dist/docs/reference/dashboard/content/sections.mdx +28 -0
  65. package/dist/docs/{experiences.mdx → reference/dashboard/experiences.mdx} +9 -16
  66. package/dist/docs/{features.mdx → reference/dashboard/features.mdx} +26 -41
  67. package/dist/docs/{fields.mdx → reference/dashboard/fields.mdx} +26 -20
  68. package/dist/docs/{flow-builder/overview.mdx → reference/dashboard/flow-builder/canvas.mdx} +8 -13
  69. package/dist/docs/{flow-builder → reference/dashboard/flow-builder}/condition-builder.md +5 -13
  70. package/dist/docs/{flow-builder → reference/dashboard/flow-builder}/keyboard-shortcuts.md +7 -1
  71. package/dist/docs/{flow-builder → reference/dashboard/flow-builder}/nodes.md +10 -3
  72. package/dist/docs/reference/dashboard/projects.mdx +44 -0
  73. package/dist/docs/reference/dashboard/reports.mdx +43 -0
  74. package/dist/docs/reference/dashboard/steps.mdx +37 -0
  75. package/dist/docs/{team-management.md → reference/dashboard/team-management.md} +5 -22
  76. package/dist/docs/{workspace-versioning.mdx → reference/dashboard/workspace-versioning.mdx} +6 -10
  77. package/dist/docs/reference/dashboard/workspaces.mdx +76 -0
  78. package/dist/docs/{delivery-api → reference/delivery-api}/experience-content.md +11 -4
  79. package/dist/docs/reference/delivery-api/index.md +45 -0
  80. package/dist/docs/{delivery-api → reference/delivery-api}/preview-caching-crawling.md +12 -5
  81. package/dist/docs/{delivery-api → reference/delivery-api}/project-config.md +11 -4
  82. package/dist/docs/reference/glossary.md +173 -0
  83. package/dist/docs/reference/management-api/authentication.md +74 -0
  84. package/dist/docs/{api → reference/management-api}/authorization-and-scopes.md +10 -3
  85. package/dist/docs/{api → reference/management-api}/error-handling.md +9 -3
  86. package/dist/docs/{api → reference/management-api}/pagination.md +6 -0
  87. package/dist/docs/{pickedql → reference/pickedql}/data-sources.md +16 -9
  88. package/dist/docs/{pickedql → reference/pickedql}/dimensions.md +7 -0
  89. package/dist/docs/{pickedql → reference/pickedql}/filtering.md +7 -0
  90. package/dist/docs/reference/pickedql/index.md +18 -0
  91. package/dist/docs/{pickedql → reference/pickedql}/schema.md +13 -6
  92. package/dist/docs/{pickedql → reference/pickedql}/virtual-functions.md +7 -0
  93. package/dist/docs/reference/sdk/actions.md +30 -0
  94. package/dist/docs/{sdk → reference/sdk}/conditions.md +8 -1
  95. package/dist/docs/reference/sdk/content-security-policy.md +21 -0
  96. package/dist/docs/reference/sdk/experiences.md +51 -0
  97. package/dist/docs/{sdk → reference/sdk}/features.md +30 -117
  98. package/dist/docs/{sdk → reference/sdk}/fields.md +10 -88
  99. package/dist/docs/reference/sdk/index.md +68 -0
  100. package/dist/docs/{sdk → reference/sdk}/plugins/create-experience.md +10 -22
  101. package/dist/docs/reference/sdk/plugins/dynamic-experiences.md +26 -0
  102. package/dist/docs/reference/sdk/plugins/index.md +29 -0
  103. package/dist/docs/{sdk → reference/sdk}/plugins/window-object.md +6 -0
  104. package/dist/docs/reference/sdk/predicates.md +43 -0
  105. package/dist/docs/reference/sdk/ssr/index.md +33 -0
  106. package/dist/docs/{sdk → reference/sdk}/ssr/rendering-and-hydration.md +4 -63
  107. package/dist/docs/{sdk → reference/sdk}/ssr/serialize.md +6 -33
  108. package/dist/docs/{sdk → reference/sdk}/ssr/slots-and-placements.md +7 -1
  109. package/dist/docs/reference/sdk/steps.md +87 -0
  110. package/dist/docs/reference/tools/chrome-extension.md +16 -0
  111. package/dist/docs/{image-optimisation-service.md → reference/tools/image-optimisation-service.md} +8 -0
  112. package/dist/docs/{mcp.md → reference/tools/mcp.md} +5 -45
  113. package/dist/docs/{vite-plugin.md → reference/tools/vite-plugin.md} +8 -38
  114. package/dist/docs/{api/index.md → tutorials/first-api-call.md} +27 -15
  115. package/dist/docs/tutorials/first-experience-in-the-dashboard.mdx +143 -0
  116. package/dist/docs/tutorials/first-experience.mdx +255 -0
  117. package/dist/docs/tutorials/first-server-rendered-page.mdx +186 -0
  118. package/dist/{dom-BwmTHeT7.js → dom-BqcToNL0.js} +1 -3
  119. package/dist/{dom-CDrHc_j9.cjs → dom-DlLH3FxV.cjs} +1 -1
  120. package/dist/esm/form/index.js +2 -4
  121. package/dist/esm/index.js +306 -298
  122. package/dist/esm/plugins/dom-observer/index.js +1 -1
  123. package/dist/esm/plugins/dynamic-experiences/index.js +2 -2
  124. package/dist/esm/preview/index.js +1 -1
  125. package/dist/esm/server/index.js +12 -10
  126. package/dist/{experience-instance-DOJShRk5.js → experience-instance-DGk11d8a.js} +3 -3
  127. package/dist/experience-instance-Dej3P1sE.cjs +1 -0
  128. package/dist/plugin-CNna0UjB.cjs +1 -0
  129. package/dist/{plugin-ChPkTj__.js → plugin-DUOJpHaq.js} +2 -2
  130. package/dist/{preview-channel-DW9J8t4B.js → preview-channel-CSr96XAo.js} +1 -1
  131. package/dist/{protocol-DSqOlW2r.js → protocol-C5KkkiZc.js} +1 -1
  132. package/dist/types/client.d.ts +7 -6
  133. package/dist/types/entities/action/action.d.ts +5 -4
  134. package/dist/types/entities/action/action.d.ts.map +1 -1
  135. package/dist/types/entities/component/component.d.ts +6 -5
  136. package/dist/types/entities/component/component.d.ts.map +1 -1
  137. package/dist/types/entities/condition/condition.d.ts +5 -5
  138. package/dist/types/entities/content/content.d.ts +4 -3
  139. package/dist/types/entities/experience/experience.d.ts +11 -10
  140. package/dist/types/entities/experience/experience.d.ts.map +1 -1
  141. package/dist/types/entities/experience-instance/experience-instance.d.ts +10 -9
  142. package/dist/types/entities/feature/feature.d.ts +19 -2
  143. package/dist/types/entities/feature/feature.d.ts.map +1 -1
  144. package/dist/types/entities/field/field.d.ts +7 -6
  145. package/dist/types/entities/framework/framework.d.ts +7 -6
  146. package/dist/types/entities/framework/framework.d.ts.map +1 -1
  147. package/dist/types/entities/history/history.d.ts +6 -6
  148. package/dist/types/entities/plugin/plugin.d.ts +3 -2
  149. package/dist/types/entities/plugin/plugin.d.ts.map +1 -1
  150. package/dist/types/entities/predicate/predicate.d.ts +4 -3
  151. package/dist/types/entities/predicate/predicate.d.ts.map +1 -1
  152. package/dist/types/entities/response/response-validation.d.ts +3 -2
  153. package/dist/types/entities/response/response.d.ts +12 -11
  154. package/dist/types/entities/session/session.d.ts +2 -1
  155. package/dist/types/entities/step/step.d.ts +6 -5
  156. package/dist/types/exports.d.ts +2 -1
  157. package/dist/types/exports.d.ts.map +1 -1
  158. package/dist/types/form/build-responses.d.ts +2 -1
  159. package/dist/types/form/create-field-evaluator.d.ts +4 -3
  160. package/dist/types/form/create-field-validation.d.ts +5 -4
  161. package/dist/types/form/create-form.d.ts +7 -6
  162. package/dist/types/form/create-submit-pipeline.d.ts +7 -6
  163. package/dist/types/form/get-step-fields.d.ts +3 -2
  164. package/dist/types/lifecycle/condition-selection.d.ts +14 -4
  165. package/dist/types/lifecycle/lifecycle.d.ts +4 -3
  166. package/dist/types/lifecycle/rules-logic.d.ts +4 -3
  167. package/dist/types/lifecycle/state-snapshot.d.ts +4 -3
  168. package/dist/types/picked.d.ts +64 -62
  169. package/dist/types/picked.d.ts.map +1 -1
  170. package/dist/types/ping.d.ts +1 -1
  171. package/dist/types/ping.d.ts.map +1 -1
  172. package/dist/types/plugins/create-experience/create-experience.d.ts +9 -8
  173. package/dist/types/plugins/create-experience/create-experience.d.ts.map +1 -1
  174. package/dist/types/plugins/create-experience/plugin.d.ts +3 -2
  175. package/dist/types/plugins/create-experience/plugin.d.ts.map +1 -1
  176. package/dist/types/plugins/create-experience/serialization.d.ts.map +1 -1
  177. package/dist/types/plugins/dom-observer/plugin.d.ts +1 -1
  178. package/dist/types/plugins/dynamic-experiences/plugin.d.ts +3 -3
  179. package/dist/types/plugins/dynamic-experiences/types.d.ts +8 -5
  180. package/dist/types/plugins/experience-browser-storage/plugin.d.ts +1 -1
  181. package/dist/types/plugins/experience-browser-storage/plugin.d.ts.map +1 -1
  182. package/dist/types/plugins/history-browser-storage/plugin.d.ts +1 -1
  183. package/dist/types/plugins/history-browser-storage/plugin.d.ts.map +1 -1
  184. package/dist/types/plugins/responses-browser-storage/plugin.d.ts +1 -1
  185. package/dist/types/plugins/responses-browser-storage/plugin.d.ts.map +1 -1
  186. package/dist/types/plugins/responses-indexeddb/plugin.d.ts +1 -1
  187. package/dist/types/plugins/single-page-app/plugin.d.ts +1 -1
  188. package/dist/types/plugins/single-page-app/plugin.d.ts.map +1 -1
  189. package/dist/types/plugins/web-components/plugin.d.ts +2 -1
  190. package/dist/types/plugins/window-object/plugin.d.ts +2 -2
  191. package/dist/types/preview-channel.d.ts +5 -1
  192. package/dist/types/preview-receiver/index.d.ts +18 -1
  193. package/dist/types/preview-receiver/protocol.d.ts +10 -1
  194. package/dist/types/server/index.d.ts +3 -3
  195. package/dist/types/server/serialize.d.ts +2 -2
  196. package/dist/types/utils/dom.d.ts +2 -1
  197. package/dist/types/utils/events.d.ts +6 -6
  198. package/dist/types/utils/events.d.ts.map +1 -1
  199. package/dist/types/utils/global-obj.d.ts +1 -1
  200. package/dist/types/utils/global-obj.d.ts.map +1 -1
  201. package/dist/types/utils/id.d.ts.map +1 -1
  202. package/dist/types/utils/logger.d.ts +2 -1
  203. package/dist/types/utils/logger.d.ts.map +1 -1
  204. package/dist/types/utils/node-tree/get-next-node-from-action.d.ts +2 -1
  205. package/dist/types/utils/node-tree/get-next-node-from-condition.d.ts +2 -1
  206. package/dist/types/utils/node-tree/get-next-node.d.ts +1 -1
  207. package/dist/types/utils/node-tree/get-next-node.d.ts.map +1 -1
  208. package/dist/types/utils/node-tree/get-origin-node.d.ts +1 -1
  209. package/dist/types/utils/node-tree/get-origin-node.d.ts.map +1 -1
  210. package/dist/types/utils/node-tree/min-max-steps-to-leaf.d.ts +1 -1
  211. package/dist/types/utils/node-tree/min-max-steps-to-leaf.d.ts.map +1 -1
  212. package/dist/types/utils/node-tree/min-max-steps-to-origin.d.ts +1 -1
  213. package/dist/types/utils/node-tree/min-max-steps-to-origin.d.ts.map +1 -1
  214. package/dist/types/utils/node-tree/next-reachable-step-nodes.d.ts +1 -1
  215. package/dist/types/utils/node-tree/next-reachable-step-nodes.d.ts.map +1 -1
  216. package/dist/types/utils/nodes.d.ts +1 -1
  217. package/dist/types/utils/picked-config.d.ts +2 -1
  218. package/dist/types/utils/rules-logic.d.ts +6 -2
  219. package/dist/types/utils/storage.d.ts +1 -1
  220. package/dist/types/utils/storage.d.ts.map +1 -1
  221. package/package.json +22 -23
  222. package/dist/api-CPy9G49C.js +0 -40
  223. package/dist/api-Ce6xYI--.cjs +0 -1
  224. package/dist/docs/actions.mdx +0 -98
  225. package/dist/docs/api/authentication.md +0 -403
  226. package/dist/docs/chrome-extension.md +0 -68
  227. package/dist/docs/conditions.mdx +0 -72
  228. package/dist/docs/content/asset-library.mdx +0 -124
  229. package/dist/docs/content/pages.mdx +0 -82
  230. package/dist/docs/content/sections.mdx +0 -44
  231. package/dist/docs/delivery-api/index.md +0 -53
  232. package/dist/docs/guides/build-a-personalized-page.mdx +0 -161
  233. package/dist/docs/pickedql/index.md +0 -54
  234. package/dist/docs/projects.mdx +0 -44
  235. package/dist/docs/reports.mdx +0 -20
  236. package/dist/docs/sdk/actions.md +0 -82
  237. package/dist/docs/sdk/content-security-policy.md +0 -33
  238. package/dist/docs/sdk/experiences.md +0 -64
  239. package/dist/docs/sdk/feature-allocation.md +0 -161
  240. package/dist/docs/sdk/index.md +0 -98
  241. package/dist/docs/sdk/plugins/dynamic-experiences.md +0 -84
  242. package/dist/docs/sdk/plugins/index.md +0 -9
  243. package/dist/docs/sdk/predicates.md +0 -128
  244. package/dist/docs/sdk/ssr/index.md +0 -79
  245. package/dist/docs/sdk/steps.md +0 -479
  246. package/dist/docs/steps.mdx +0 -53
  247. package/dist/docs/workspaces.mdx +0 -133
  248. package/dist/experience-instance-DurC3pE-.cjs +0 -1
  249. package/dist/plugin-DHn11gn6.cjs +0 -1
@@ -1,98 +0,0 @@
1
- ---
2
- layout: docs
3
- ---
4
-
5
- import { Screenshot } from '../../components/Screenshot'
6
-
7
- # Actions
8
-
9
- An action is a side effect that starts when the flow reaches it. Use an action to
10
- track an event, to send data to an external service, or to call a webhook.
11
-
12
- <Screenshot
13
- route="/{orgSlug}/{projectId}/workspaces/{workspaceId}/actions"
14
- alt="The actions list for a workspace on the Picked dashboard"
15
- />
16
-
17
- ## Create an action
18
-
19
- 1. Open your project.
20
- 2. Click **Actions** in the sidebar.
21
- 3. Click **New Action**.
22
- 4. Enter a name and a key.
23
- 5. Click **Create**.
24
-
25
- The key is a unique identifier for your application. You set it once, and you cannot
26
- change it later.
27
-
28
- ## Set up an action
29
-
30
- **Name**: The name that the dashboard shows. Your visitors do not see it.
31
-
32
- **Key**: The identifier that your application uses for this action. Your visitors do
33
- not see it.
34
-
35
- ## Register in your application
36
-
37
- Register your actions when you create the Picked client. Pass an `actions` object.
38
- Each key in it must match an action key from the dashboard:
39
-
40
- ```typescript
41
- import { createClient } from '@picked/client'
42
-
43
- const picked = createClient({
44
- projectId: 'your-project-id',
45
- actions: {
46
- 'track-signup': () => {
47
- analytics.track('signup_completed')
48
- },
49
- 'notify': (params) => {
50
- sendNotification(params)
51
- },
52
- 'check-eligibility': async () => {
53
- const response = await fetch('/api/eligibility')
54
- // Throw only when the request itself fails. That takes the failure branch.
55
- if (!response.ok) throw new Error('Eligibility request failed')
56
- },
57
- },
58
- })
59
- ```
60
-
61
- Each action is a function. It takes optional parameters and it usually runs a side
62
- effect. When the flow reaches an action node, the SDK calls the function that
63
- matches. The SDK then takes a branch, which depends on whether the function succeeds
64
- or throws. See [Success and failure branches](#success-and-failure-branches).
65
-
66
- See [SDK Actions](/sdk/actions) for more detail.
67
-
68
- ## Use actions in flows
69
-
70
- In the flow builder, drag an action from the entity browser onto the canvas. Connect
71
- it to the point in the flow where you want it to start.
72
-
73
- An action runs when the flow reaches its node. It does not interrupt your visitor. By
74
- default the flow continues to the next connected node.
75
-
76
- ### Success and failure branches
77
-
78
- An action node can have two outgoing branches: **success** and **failure**. The SDK
79
- chooses the branch from the outcome of the action:
80
-
81
- - **Failure** — the action throws, or its promise rejects. The flow takes the failure
82
- branch.
83
- - **Success** — the action resolves to any value: nothing, `true`, `false`, or a
84
- string. A returned `false` is a valid response and not a failure. The flow takes
85
- the success branch.
86
-
87
- Keep the failure branch for a true error. Throw on the failure case, for example
88
- `if (!response.ok) throw new Error(...)`. A valid negative result is _not_ a failure.
89
- An API that returns `200` with `{ serviced: false }` must record that value as a
90
- response. Branch on it with a condition instead of a throw.
91
-
92
- An action node can also have one plain connection, with no success or failure branch.
93
- The flow then continues through it on either outcome.
94
-
95
- ## Reuse actions
96
-
97
- An action is a project-level entity. Use the same action in more than one experience
98
- flow. A change to the options of an action applies at every place that uses it.
@@ -1,403 +0,0 @@
1
- ---
2
- layout: docs
3
- ---
4
-
5
- # Authentication
6
-
7
- The Picked API supports four ways to authenticate. They are a session from an email
8
- address and a password, an OAuth provider, a magic link, and an API key. This guide
9
- covers each one. It also covers how to control a session and how to use multi-factor
10
- authentication (MFA).
11
-
12
- ## Sign in with an email address and a password
13
-
14
- The `sessionCreate` mutation authenticates a user from an email address and a
15
- password. It returns a session.
16
-
17
- ```graphql
18
- mutation {
19
- sessionCreate(input: {
20
- email: "user@example.com"
21
- password: "secure-password"
22
- }) {
23
- session {
24
- accessToken
25
- refreshToken
26
- expiresAt
27
- user {
28
- id
29
- email
30
- }
31
- aal
32
- }
33
- requiresMfa
34
- mfaFactors {
35
- id
36
- factorType
37
- status
38
- }
39
- }
40
- }
41
- ```
42
-
43
- When the user has MFA on, the response sets `requiresMfa` to `true` and returns the
44
- `mfaFactors` of that user. The caller must then complete an MFA challenge before it
45
- receives a full session. See [MFA](#multi-factor-authentication-mfa) below.
46
-
47
- When MFA is off, the response holds a `session` with an `accessToken`, a
48
- `refreshToken`, and an `expiresAt` timestamp.
49
-
50
- ## Create an account
51
-
52
- The `accountCreate` mutation creates a new account:
53
-
54
- ```graphql
55
- mutation {
56
- accountCreate(input: {
57
- email: "newuser@example.com"
58
- password: "secure-password"
59
- metadata: { firstName: "Jane", lastName: "Doe" }
60
- }) {
61
- user {
62
- id
63
- email
64
- }
65
- session {
66
- accessToken
67
- refreshToken
68
- }
69
- }
70
- }
71
- ```
72
-
73
- The `metadata` field is optional. It takes any JSON, and you can hold profile
74
- information in it. When the account needs email verification, the session in the
75
- response is `null` until the user verifies the email address.
76
-
77
- ## Verify an email address
78
-
79
- After you create the account, the user receives a verification email with a token.
80
- The `accountVerifyEmail` mutation completes the verification:
81
-
82
- ```graphql
83
- mutation {
84
- accountVerifyEmail(input: {
85
- email: "newuser@example.com"
86
- token: "verification-token-from-email"
87
- }) {
88
- session {
89
- accessToken
90
- refreshToken
91
- }
92
- }
93
- }
94
- ```
95
-
96
- To send the verification email again:
97
-
98
- ```graphql
99
- mutation {
100
- accountResendVerification(input: {
101
- email: "newuser@example.com"
102
- }) {
103
- success
104
- }
105
- }
106
- ```
107
-
108
- ## The OAuth flow with Google
109
-
110
- The API supports Google as an OAuth provider. The flow has two steps.
111
-
112
- ### Step 1: get the authorization URL
113
-
114
- ```graphql
115
- mutation {
116
- oauthAuthorize(input: {
117
- provider: GOOGLE
118
- redirectUrl: "https://app.example.com/auth/callback"
119
- scopes: ["openid", "email", "profile"]
120
- }) {
121
- url
122
- }
123
- }
124
- ```
125
-
126
- The caller sends the user to the `url` in the response. The user authenticates with
127
- Google. Google then sends the user back to a URL on the same dashboard deployment,
128
- with a `code` parameter. The caller exchanges that code for a session.
129
-
130
- ### Step 2: exchange the code for a session
131
-
132
- ```graphql
133
- mutation {
134
- oauthCallback(input: {
135
- provider: GOOGLE
136
- code: "auth-code-from-google"
137
- }) {
138
- session {
139
- accessToken
140
- refreshToken
141
- expiresAt
142
- }
143
- }
144
- }
145
- ```
146
-
147
- ## Magic links
148
-
149
- A magic link authenticates a user through an email address, with no password.
150
-
151
- ### Send a magic link
152
-
153
- ```graphql
154
- mutation {
155
- magicLinkSend(input: {
156
- email: "user@example.com"
157
- redirectUrl: "https://app.example.com/auth/verify"
158
- }) {
159
- success
160
- }
161
- }
162
- ```
163
-
164
- The user receives an email with a link, and the link holds a token.
165
-
166
- ### Verify the magic link
167
-
168
- ```graphql
169
- mutation {
170
- magicLinkVerify(input: {
171
- email: "user@example.com"
172
- token: "token-from-magic-link"
173
- }) {
174
- session {
175
- accessToken
176
- refreshToken
177
- }
178
- }
179
- }
180
- ```
181
-
182
- ## Passwords
183
-
184
- ### Reset a password
185
-
186
- Send an email to reset the password:
187
-
188
- ```graphql
189
- mutation {
190
- passwordResetSend(input: {
191
- email: "user@example.com"
192
- redirectUrl: "https://app.example.com/reset-password"
193
- }) {
194
- success
195
- }
196
- }
197
- ```
198
-
199
- Complete the reset with the token from that email:
200
-
201
- ```graphql
202
- mutation {
203
- passwordReset(input: {
204
- email: "user@example.com"
205
- token: "reset-token-from-email"
206
- newPassword: "new-secure-password"
207
- }) {
208
- session {
209
- accessToken
210
- refreshToken
211
- }
212
- }
213
- }
214
- ```
215
-
216
- ### Change a password
217
-
218
- This mutation needs authentication:
219
-
220
- ```graphql
221
- mutation {
222
- passwordUpdate(input: {
223
- currentPassword: "old-password"
224
- newPassword: "new-secure-password"
225
- }) {
226
- success
227
- }
228
- }
229
- ```
230
-
231
- ## Multi-factor authentication (MFA)
232
-
233
- MFA adds a second layer of security, and it uses a telephone to verify the user. The
234
- API can add an MFA factor, send a challenge, verify a challenge, and remove a factor.
235
- Every MFA mutation needs authentication.
236
-
237
- ### Add a factor
238
-
239
- ```graphql
240
- mutation {
241
- mfaFactorEnroll(input: {
242
- factorType: PHONE
243
- phone: "+15551234567"
244
- friendlyName: "My Phone"
245
- }) {
246
- factor {
247
- id
248
- factorType
249
- status
250
- }
251
- }
252
- }
253
- ```
254
-
255
- A new factor has the status `UNVERIFIED` until a challenge confirms it.
256
-
257
- ### Send a challenge
258
-
259
- ```graphql
260
- mutation {
261
- mfaChallengeSend(input: {
262
- factorId: "factor-id"
263
- }) {
264
- challengeId
265
- }
266
- }
267
- ```
268
-
269
- This sends a verification code to the telephone number of the factor.
270
-
271
- ### Verify the challenge
272
-
273
- ```graphql
274
- mutation {
275
- mfaChallengeVerify(input: {
276
- factorId: "factor-id"
277
- challengeId: "challenge-id"
278
- code: "123456"
279
- }) {
280
- session {
281
- accessToken
282
- refreshToken
283
- aal
284
- }
285
- }
286
- }
287
- ```
288
-
289
- On success, the session moves to Authenticator Assurance Level `AAL2`. The status of
290
- the factor changes to `VERIFIED`.
291
-
292
- ### Remove a factor
293
-
294
- ```graphql
295
- mutation {
296
- mfaFactorUnenroll(input: {
297
- factorId: "factor-id"
298
- }) {
299
- success
300
- }
301
- }
302
- ```
303
-
304
- ## Use a session
305
-
306
- After the caller has a session, it puts the access token in the `Authorization`
307
- header of every request that needs authentication:
308
-
309
- ```
310
- Authorization: Bearer <accessToken>
311
- ```
312
-
313
- The `expiresAt` field of the session gives the time at which the access token
314
- expires. The caller must refresh the session before that time.
315
-
316
- ### Authenticator assurance levels
317
-
318
- The session holds an `aal` field, and it gives the strength of the authentication:
319
-
320
- | Level | Meaning |
321
- |-------|---------|
322
- | `AAL1` | One factor: an email address and a password, OAuth, or a magic link |
323
- | `AAL2` | More than one factor: the user completed an MFA challenge |
324
-
325
- Some operations need `AAL2`. When a caller at `AAL1` tries one of them, the API
326
- returns an authorization error.
327
-
328
- ## Refresh a session
329
-
330
- An access token has a short life. The `sessionRefresh` mutation exchanges a refresh
331
- token for a new session:
332
-
333
- ```graphql
334
- mutation {
335
- sessionRefresh(input: {
336
- refreshToken: "v1.refresh-token..."
337
- }) {
338
- session {
339
- accessToken
340
- refreshToken
341
- expiresAt
342
- }
343
- }
344
- }
345
- ```
346
-
347
- The response holds a new `accessToken` and a new `refreshToken`. The API invalidates
348
- the earlier refresh token. This mutation needs no `Authorization` header.
349
-
350
- ## API key authentication
351
-
352
- An API key gives access to the API for a long time, inside a set of scopes. Most
353
- callers use an API key for a server-to-server integration or for an automated
354
- workflow.
355
-
356
- To authenticate with an API key, include it in the `x-api-key` header:
357
-
358
- ```
359
- x-api-key: pk_live_abc123...
360
- ```
361
-
362
- An API key belongs to an organization, and it can also belong to one project. It
363
- carries a set of [authorization scopes](./authorization-and-scopes.md), and those
364
- scopes decide which operations the key can do.
365
-
366
- See [API Keys](/api-keys) for how to control a key from the dashboard.
367
-
368
- ### Create an API key
369
-
370
- The `apiKeyCreate` mutation creates a new API key. Only a user with a session can
371
- call it. Another API key cannot:
372
-
373
- ```graphql
374
- mutation {
375
- apiKeyCreate(input: {
376
- organizationId: "org-id"
377
- name: "CI/CD Pipeline Key"
378
- projectId: "project-id"
379
- scopes: [ORGANIZATION_READ, ORGANIZATION_PROJECTS_READ]
380
- }) {
381
- apiKey
382
- }
383
- }
384
- ```
385
-
386
- The response holds the full API key string one time only. Keep it in a secure place, because
387
- you cannot read it again.
388
-
389
- The scopes that you ask for must all be scopes of the user who creates the key. See
390
- [Authorization and Scopes](./authorization-and-scopes.md) for more detail.
391
-
392
- ### Revoke an API key
393
-
394
- ```graphql
395
- mutation {
396
- apiKeyRevoke(input: {
397
- keyId: "key-id"
398
- organizationId: "org-id"
399
- })
400
- }
401
- ```
402
-
403
- The API invalidates a revoked key immediately. No later request can use it.
@@ -1,68 +0,0 @@
1
- ---
2
- layout: docs
3
- ---
4
-
5
- # Chrome Extension
6
-
7
- The extension for the Picked Developer Tools adds a Picked panel to Chrome DevTools.
8
- Use the panel to check and debug your Picked integration on any page that runs the
9
- SDK.
10
-
11
- ![Picked Developer Tools](/chrome-extension-screenshot.jpg)
12
-
13
- ## Installation
14
-
15
- Install the extension from the
16
- [Chrome Web Store](https://chromewebstore.google.com/detail/picked-developer-tools/nimmdamgnhlhdpngnalkpmnleebngidh).
17
-
18
- ## Setup
19
-
20
- Add the `svelteDevtoolsPlugin` to your Picked client. The extension then connects to
21
- the SDK.
22
-
23
- ```typescript
24
- import { createPicked } from '@picked/client'
25
- import { svelteDevtoolsPlugin } from '@picked/svelte/plugins/devtools'
26
-
27
- const picked = createPicked({
28
- projectId: 'your-project-id',
29
- plugins: [
30
- svelteDevtoolsPlugin(),
31
- ],
32
- })
33
- ```
34
-
35
- ## Custom Tools
36
-
37
- You can extend the Developer Tools with your own tools for one project. They appear
38
- under a **Custom Tools** tab.
39
-
40
- Each tool is a framework-adapted component. Write it with the same
41
- `adaptReactComponent` or `adaptSvelteComponent` helper that you already use. You can
42
- therefore build the tool in the framework of your application.
43
-
44
- The tool receives the live Picked client, exactly as an experience component does. In
45
- React, use `usePicked()`. In Svelte, use `getPicked()`. A tool can read client state
46
- and call client methods.
47
-
48
- ```typescript
49
- import { createPicked } from '@picked/client'
50
- import { adaptReactComponent } from '@picked/react'
51
- import { svelteDevtoolsPlugin } from '@picked/svelte/plugins/devtools'
52
- import MyTool from './MyTool'
53
-
54
- const picked = createPicked({
55
- projectId: 'your-project-id',
56
- plugins: [
57
- svelteDevtoolsPlugin({
58
- customTools: [{ id: 'my-tool', label: 'My Tool', component: adaptReactComponent(MyTool) }],
59
- }),
60
- ],
61
- })
62
- ```
63
-
64
- Svelte renders the Developer Tools shell, so you must also register the framework of
65
- your tool on the client. A React application needs `reactFrameworkPlugin` for the
66
- tool, together with the Svelte framework and `svelteDevtoolsPlugin` for the shell.
67
- When the framework of a tool is not registered, the tab of that tool shows a warning
68
- and no content.
@@ -1,72 +0,0 @@
1
- ---
2
- layout: docs
3
- ---
4
-
5
- import { Screenshot } from '../../components/Screenshot'
6
-
7
- # Conditions
8
-
9
- A condition evaluates a rule and splits the flow into two paths. One path is for a
10
- true result, the other for a false result.
11
-
12
- <Screenshot
13
- route="/{orgSlug}/{projectId}/workspaces/{workspaceId}/conditions"
14
- alt="The conditions list for a workspace on the Picked dashboard"
15
- />
16
-
17
- ## Create a condition
18
-
19
- 1. Open your project.
20
- 2. Click **Conditions** in the sidebar.
21
- 3. Click **New Condition**.
22
- 4. Enter a name and a key.
23
- 5. Click **Create**.
24
-
25
- ## Set up a condition
26
-
27
- **Name**: The name that the dashboard shows. Your visitors do not see it.
28
-
29
- **Key**: The identifier for your application. You set it once and you cannot change
30
- it. Your visitors do not see it.
31
-
32
- ## Define the rule
33
-
34
- Choose a condition node in the flow builder to open its inspector. The **Logic**
35
- section holds a visual [condition builder](/flow-builder/condition-builder).
36
-
37
- The condition builder lets you write a rule with AND groups and OR groups. Each rule
38
- compares a data source against an operator and a value.
39
-
40
- ### Data sources
41
-
42
- **Responses** — the values that your visitors send through form fields. An example is
43
- a check of whether a visitor entered one email domain, or chose one option.
44
-
45
- **Actions** — the actions that ran during the flow.
46
-
47
- **Feature flags** — the state of each feature flag in your project. Branch on whether
48
- Picked allocates a visitor to a flag.
49
-
50
- **Location** — the parts of the current page URL of the visitor. These are the
51
- pathname, the search parameters, the hostname, and the hash. An example is content
52
- that changes with the page that the visitor is on.
53
-
54
- ### Example
55
-
56
- To take a branch on the country that a visitor chooses:
57
-
58
- 1. Add a rule: **Responses → country** equals `US`.
59
- 2. The green path, for a true result, handles a visitor in the US. The red path, for
60
- a false result, handles every other visitor.
61
-
62
- To join more than one rule, create an AND group or an OR group and add the rules
63
- inside it.
64
-
65
- ## Branches
66
-
67
- In the flow builder, a condition node has two output handles. The green handle, for a
68
- true result, leads to the path for a match. The red handle, for a false result, leads
69
- to the other path.
70
-
71
- You can chain conditions. Connect the output of one condition to the input of another
72
- to build a decision tree.