@promptbook/browser 0.89.0-9 → 0.92.0-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.
Files changed (41) hide show
  1. package/README.md +9 -7
  2. package/esm/index.es.js +51 -5
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/typings/servers.d.ts +40 -0
  5. package/esm/typings/src/_packages/core.index.d.ts +10 -4
  6. package/esm/typings/src/_packages/types.index.d.ts +18 -0
  7. package/esm/typings/src/_packages/utils.index.d.ts +4 -0
  8. package/esm/typings/src/cli/cli-commands/login.d.ts +0 -1
  9. package/esm/typings/src/cli/common/$provideLlmToolsForCli.d.ts +16 -3
  10. package/esm/typings/src/cli/test/ptbk.d.ts +1 -1
  11. package/esm/typings/src/commands/EXPECT/expectCommandParser.d.ts +2 -0
  12. package/esm/typings/src/config.d.ts +10 -19
  13. package/esm/typings/src/errors/0-index.d.ts +7 -4
  14. package/esm/typings/src/errors/PipelineExecutionError.d.ts +1 -1
  15. package/esm/typings/src/errors/WrappedError.d.ts +10 -0
  16. package/esm/typings/src/errors/assertsError.d.ts +11 -0
  17. package/esm/typings/src/execution/PromptbookFetch.d.ts +1 -1
  18. package/esm/typings/src/formats/csv/utils/isValidCsvString.d.ts +9 -0
  19. package/esm/typings/src/formats/csv/utils/isValidCsvString.test.d.ts +1 -0
  20. package/esm/typings/src/formats/json/utils/isValidJsonString.d.ts +3 -0
  21. package/esm/typings/src/formats/xml/utils/isValidXmlString.d.ts +9 -0
  22. package/esm/typings/src/formats/xml/utils/isValidXmlString.test.d.ts +1 -0
  23. package/esm/typings/src/llm-providers/_common/filterModels.d.ts +15 -0
  24. package/esm/typings/src/llm-providers/_common/register/{$provideEnvFilepath.d.ts → $provideEnvFilename.d.ts} +2 -2
  25. package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsConfigurationFromEnv.d.ts +1 -1
  26. package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsForTestingAndScriptsAndPlayground.d.ts +1 -1
  27. package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsForWizzardOrCli.d.ts +11 -2
  28. package/esm/typings/src/llm-providers/_common/register/$provideLlmToolsFromEnv.d.ts +1 -1
  29. package/esm/typings/src/remote-server/openapi-types.d.ts +284 -0
  30. package/esm/typings/src/remote-server/openapi.d.ts +187 -0
  31. package/esm/typings/src/remote-server/socket-types/_subtypes/Identification.d.ts +7 -1
  32. package/esm/typings/src/remote-server/socket-types/_subtypes/identificationToPromptbookToken.d.ts +11 -0
  33. package/esm/typings/src/remote-server/socket-types/_subtypes/promptbookTokenToIdentification.d.ts +10 -0
  34. package/esm/typings/src/remote-server/startRemoteServer.d.ts +1 -2
  35. package/esm/typings/src/remote-server/types/RemoteServerOptions.d.ts +15 -9
  36. package/esm/typings/src/storage/env-storage/$EnvStorage.d.ts +40 -0
  37. package/esm/typings/src/types/typeAliases.d.ts +26 -0
  38. package/package.json +7 -3
  39. package/umd/index.umd.js +51 -5
  40. package/umd/index.umd.js.map +1 -1
  41. package/esm/typings/src/cli/test/ptbk2.d.ts +0 -5
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Function to check if a string is valid CSV
3
+ *
4
+ * @param value The string to check
5
+ * @returns True if the string is a valid CSV string, false otherwise
6
+ *
7
+ * @public exported from `@promptbook/utils`
8
+ */
9
+ export declare function isValidCsvString(value: string): boolean;
@@ -1,6 +1,9 @@
1
1
  /**
2
2
  * Function isValidJsonString will tell you if the string is valid JSON or not
3
3
  *
4
+ * @param value The string to check
5
+ * @returns True if the string is a valid JSON string, false otherwise
6
+ *
4
7
  * @public exported from `@promptbook/utils`
5
8
  */
6
9
  export declare function isValidJsonString(value: string): boolean;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Function to check if a string is valid XML
3
+ *
4
+ * @param value
5
+ * @returns True if the string is a valid XML string, false otherwise
6
+ *
7
+ * @public exported from `@promptbook/utils`
8
+ */
9
+ export declare function isValidXmlString(value: string): boolean;
@@ -0,0 +1,15 @@
1
+ import type { AvailableModel } from '../../execution/AvailableModel';
2
+ import type { LlmExecutionTools } from '../../execution/LlmExecutionTools';
3
+ /**
4
+ * Creates a wrapper around LlmExecutionTools that only exposes models matching the filter function
5
+ *
6
+ * @param llmTools The original LLM execution tools to wrap
7
+ * @param modelFilter Function that determines whether a model should be included
8
+ * @returns A new LlmExecutionTools instance with filtered models
9
+ *
10
+ * @public exported from `@promptbook/core`
11
+ */
12
+ export declare function filterModels<TLlmTools extends LlmExecutionTools>(llmTools: TLlmTools, modelFilter: (model: AvailableModel) => boolean): TLlmTools;
13
+ /**
14
+ * TODO: !!! [models] Test that this is working
15
+ */
@@ -2,11 +2,11 @@ import type { string_filename } from '../../../types/typeAliases';
2
2
  /**
3
3
  * Provides the path to the `.env` file
4
4
  *
5
- * Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access .env file
5
+ * Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access `.env` file
6
6
  *
7
7
  * @private within the repository - for CLI utils
8
8
  */
9
- export declare function $provideEnvFilepath(): Promise<string_filename | null>;
9
+ export declare function $provideEnvFilename(): Promise<string_filename | null>;
10
10
  /**
11
11
  * Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
12
12
  */
@@ -3,7 +3,7 @@ import type { LlmToolsConfiguration } from './LlmToolsConfiguration';
3
3
  * @@@
4
4
  *
5
5
  * @@@ .env
6
- * Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access .env file
6
+ * Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access `.env` file
7
7
  *
8
8
  * It looks for environment variables:
9
9
  * - `process.env.OPENAI_API_KEY`
@@ -12,7 +12,7 @@ type GetLlmToolsForTestingAndScriptsAndPlaygroundOptions = CreateLlmToolsFromCon
12
12
  /**
13
13
  * Returns LLM tools for testing purposes
14
14
  *
15
- * Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access .env file
15
+ * Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access `.env` file
16
16
  *
17
17
  * @private within the repository - JUST FOR TESTS, SCRIPTS AND PLAYGROUND
18
18
  */
@@ -5,7 +5,14 @@ import type { string_url } from '../../../types/typeAliases';
5
5
  import type { really_any } from '../../../utils/organization/really_any';
6
6
  import type { CacheLlmToolsOptions } from '../utils/cache/CacheLlmToolsOptions';
7
7
  import type { LlmExecutionToolsWithTotalUsage } from '../utils/count-total-usage/LlmExecutionToolsWithTotalUsage';
8
- type ProvideLlmToolsForWizzardOrCliOptions = Pick<CacheLlmToolsOptions, 'isCacheReloaded'> & ({
8
+ type ProvideLlmToolsForWizzardOrCliOptions = {
9
+ /**
10
+ * If true, user will be always prompted for login
11
+ *
12
+ * Note: This is used in `ptbk login` command
13
+ */
14
+ isLoginloaded?: true;
15
+ } & Pick<CacheLlmToolsOptions, 'isCacheReloaded'> & ({
9
16
  /**
10
17
  * Use local keys and execute LLMs directly
11
18
  */
@@ -29,13 +36,15 @@ type ProvideLlmToolsForWizzardOrCliOptions = Pick<CacheLlmToolsOptions, 'isCache
29
36
  readonly appId: string_app_id;
30
37
  /**
31
38
  *
39
+ *
40
+ * Note: When login prompt fails, `process.exit(1)` is called
32
41
  */
33
42
  loginPrompt(): Promisable<Identification<really_any>>;
34
43
  });
35
44
  /**
36
45
  * Returns LLM tools for CLI
37
46
  *
38
- * Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access .env file and also writes this .env file
47
+ * Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access `.env` file and also writes this .env file
39
48
  *
40
49
  * @private within the repository - for CLI utils
41
50
  */
@@ -6,7 +6,7 @@ import type { CreateLlmToolsFromConfigurationOptions } from './createLlmToolsFro
6
6
  * Note: This function is not cached, every call creates new instance of `MultipleLlmExecutionTools`
7
7
  *
8
8
  * @@@ .env
9
- * Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access .env file
9
+ * Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access `.env` file
10
10
  *
11
11
  * It looks for environment variables:
12
12
  * - `process.env.OPENAI_API_KEY`
@@ -0,0 +1,284 @@
1
+ /**
2
+ * This file was auto-generated by openapi-typescript.
3
+ * Do not make direct changes to the file.
4
+ */
5
+ export type paths = {
6
+ readonly "/": {
7
+ readonly parameters: {
8
+ readonly query?: never;
9
+ readonly header?: never;
10
+ readonly path?: never;
11
+ readonly cookie?: never;
12
+ };
13
+ /**
14
+ * Get server details
15
+ * @description Returns details about the Promptbook server.
16
+ */
17
+ readonly get: {
18
+ readonly parameters: {
19
+ readonly query?: never;
20
+ readonly header?: never;
21
+ readonly path?: never;
22
+ readonly cookie?: never;
23
+ };
24
+ readonly requestBody?: never;
25
+ readonly responses: {
26
+ /** @description Server details in markdown format. */
27
+ readonly 200: {
28
+ headers: {
29
+ readonly [name: string]: unknown;
30
+ };
31
+ content?: never;
32
+ };
33
+ };
34
+ };
35
+ readonly put?: never;
36
+ readonly post?: never;
37
+ readonly delete?: never;
38
+ readonly options?: never;
39
+ readonly head?: never;
40
+ readonly patch?: never;
41
+ readonly trace?: never;
42
+ };
43
+ readonly "/login": {
44
+ readonly parameters: {
45
+ readonly query?: never;
46
+ readonly header?: never;
47
+ readonly path?: never;
48
+ readonly cookie?: never;
49
+ };
50
+ readonly get?: never;
51
+ readonly put?: never;
52
+ /**
53
+ * Login to the server
54
+ * @description Login to the server and get identification.
55
+ */
56
+ readonly post: {
57
+ readonly parameters: {
58
+ readonly query?: never;
59
+ readonly header?: never;
60
+ readonly path?: never;
61
+ readonly cookie?: never;
62
+ };
63
+ readonly requestBody: {
64
+ readonly content: {
65
+ readonly "application/json": {
66
+ readonly username?: string;
67
+ readonly password?: string;
68
+ readonly appId?: string;
69
+ };
70
+ };
71
+ };
72
+ readonly responses: {
73
+ /** @description Successful login */
74
+ readonly 200: {
75
+ headers: {
76
+ readonly [name: string]: unknown;
77
+ };
78
+ content: {
79
+ readonly "application/json": {
80
+ readonly identification?: Record<string, never>;
81
+ };
82
+ };
83
+ };
84
+ };
85
+ };
86
+ readonly delete?: never;
87
+ readonly options?: never;
88
+ readonly head?: never;
89
+ readonly patch?: never;
90
+ readonly trace?: never;
91
+ };
92
+ readonly "/books": {
93
+ readonly parameters: {
94
+ readonly query?: never;
95
+ readonly header?: never;
96
+ readonly path?: never;
97
+ readonly cookie?: never;
98
+ };
99
+ /**
100
+ * List all books
101
+ * @description Returns a list of all available books in the collection.
102
+ */
103
+ readonly get: {
104
+ readonly parameters: {
105
+ readonly query?: never;
106
+ readonly header?: never;
107
+ readonly path?: never;
108
+ readonly cookie?: never;
109
+ };
110
+ readonly requestBody?: never;
111
+ readonly responses: {
112
+ /** @description A list of books. */
113
+ readonly 200: {
114
+ headers: {
115
+ readonly [name: string]: unknown;
116
+ };
117
+ content: {
118
+ readonly "application/json": readonly string[];
119
+ };
120
+ };
121
+ };
122
+ };
123
+ readonly put?: never;
124
+ readonly post?: never;
125
+ readonly delete?: never;
126
+ readonly options?: never;
127
+ readonly head?: never;
128
+ readonly patch?: never;
129
+ readonly trace?: never;
130
+ };
131
+ readonly [path: `/books/${string}`]: {
132
+ readonly parameters: {
133
+ readonly query?: never;
134
+ readonly header?: never;
135
+ readonly path?: never;
136
+ readonly cookie?: never;
137
+ };
138
+ /**
139
+ * Get book content
140
+ * @description Returns the content of a specific book.
141
+ */
142
+ readonly get: {
143
+ readonly parameters: {
144
+ readonly query?: never;
145
+ readonly header?: never;
146
+ readonly path: {
147
+ /** @description The ID of the book to retrieve. */
148
+ readonly bookId: string;
149
+ };
150
+ readonly cookie?: never;
151
+ };
152
+ readonly requestBody?: never;
153
+ readonly responses: {
154
+ /** @description The content of the book. */
155
+ readonly 200: {
156
+ headers: {
157
+ readonly [name: string]: unknown;
158
+ };
159
+ content: {
160
+ readonly "text/markdown": string;
161
+ };
162
+ };
163
+ /** @description Book not found. */
164
+ readonly 404: {
165
+ headers: {
166
+ readonly [name: string]: unknown;
167
+ };
168
+ content?: never;
169
+ };
170
+ };
171
+ };
172
+ readonly put?: never;
173
+ readonly post?: never;
174
+ readonly delete?: never;
175
+ readonly options?: never;
176
+ readonly head?: never;
177
+ readonly patch?: never;
178
+ readonly trace?: never;
179
+ };
180
+ readonly "/executions": {
181
+ readonly parameters: {
182
+ readonly query?: never;
183
+ readonly header?: never;
184
+ readonly path?: never;
185
+ readonly cookie?: never;
186
+ };
187
+ /**
188
+ * List all executions
189
+ * @description Returns a list of all running execution tasks.
190
+ */
191
+ readonly get: {
192
+ readonly parameters: {
193
+ readonly query?: never;
194
+ readonly header?: never;
195
+ readonly path?: never;
196
+ readonly cookie?: never;
197
+ };
198
+ readonly requestBody?: never;
199
+ readonly responses: {
200
+ /** @description A list of execution tasks. */
201
+ readonly 200: {
202
+ headers: {
203
+ readonly [name: string]: unknown;
204
+ };
205
+ content: {
206
+ readonly "application/json": readonly Record<string, never>[];
207
+ };
208
+ };
209
+ };
210
+ };
211
+ readonly put?: never;
212
+ readonly post?: never;
213
+ readonly delete?: never;
214
+ readonly options?: never;
215
+ readonly head?: never;
216
+ readonly patch?: never;
217
+ readonly trace?: never;
218
+ };
219
+ readonly "/executions/new": {
220
+ readonly parameters: {
221
+ readonly query?: never;
222
+ readonly header?: never;
223
+ readonly path?: never;
224
+ readonly cookie?: never;
225
+ };
226
+ readonly get?: never;
227
+ readonly put?: never;
228
+ /**
229
+ * Start a new execution
230
+ * @description Starts a new execution task for a given pipeline.
231
+ */
232
+ readonly post: {
233
+ readonly parameters: {
234
+ readonly query?: never;
235
+ readonly header?: never;
236
+ readonly path?: never;
237
+ readonly cookie?: never;
238
+ };
239
+ readonly requestBody: {
240
+ readonly content: {
241
+ readonly "application/json": {
242
+ readonly pipelineUrl?: string;
243
+ readonly inputParameters?: Record<string, never>;
244
+ readonly identification?: Record<string, never>;
245
+ };
246
+ };
247
+ };
248
+ readonly responses: {
249
+ /** @description The newly created execution task. */
250
+ readonly 200: {
251
+ headers: {
252
+ readonly [name: string]: unknown;
253
+ };
254
+ content: {
255
+ readonly "application/json": Record<string, never>;
256
+ };
257
+ };
258
+ /** @description Invalid input. */
259
+ readonly 400: {
260
+ headers: {
261
+ readonly [name: string]: unknown;
262
+ };
263
+ content?: never;
264
+ };
265
+ };
266
+ };
267
+ readonly delete?: never;
268
+ readonly options?: never;
269
+ readonly head?: never;
270
+ readonly patch?: never;
271
+ readonly trace?: never;
272
+ };
273
+ };
274
+ export type webhooks = Record<string, never>;
275
+ export type components = {
276
+ schemas: never;
277
+ responses: never;
278
+ parameters: never;
279
+ requestBodies: never;
280
+ headers: never;
281
+ pathItems: never;
282
+ };
283
+ export type $defs = Record<string, never>;
284
+ export type operations = Record<string, never>;
@@ -0,0 +1,187 @@
1
+ /**
2
+ * @private !!!! Decide how to expose this
3
+ */
4
+ export declare const openapiJson: {
5
+ openapi: string;
6
+ info: {
7
+ title: string;
8
+ version: string;
9
+ description: string;
10
+ };
11
+ paths: {
12
+ '/': {
13
+ get: {
14
+ summary: string;
15
+ description: string;
16
+ responses: {
17
+ '200': {
18
+ description: string;
19
+ };
20
+ };
21
+ };
22
+ };
23
+ '/login': {
24
+ post: {
25
+ summary: string;
26
+ description: string;
27
+ requestBody: {
28
+ required: boolean;
29
+ content: {
30
+ 'application/json': {
31
+ schema: {
32
+ type: string;
33
+ properties: {
34
+ username: {
35
+ type: string;
36
+ };
37
+ password: {
38
+ type: string;
39
+ };
40
+ appId: {
41
+ type: string;
42
+ };
43
+ };
44
+ };
45
+ };
46
+ };
47
+ };
48
+ responses: {
49
+ '200': {
50
+ description: string;
51
+ content: {
52
+ 'application/json': {
53
+ schema: {
54
+ type: string;
55
+ properties: {
56
+ identification: {
57
+ type: string;
58
+ };
59
+ };
60
+ };
61
+ };
62
+ };
63
+ };
64
+ };
65
+ };
66
+ };
67
+ '/books': {
68
+ get: {
69
+ summary: string;
70
+ description: string;
71
+ responses: {
72
+ '200': {
73
+ description: string;
74
+ content: {
75
+ 'application/json': {
76
+ schema: {
77
+ type: string;
78
+ items: {
79
+ type: string;
80
+ };
81
+ };
82
+ };
83
+ };
84
+ };
85
+ };
86
+ };
87
+ };
88
+ '/books/{bookId}': {
89
+ get: {
90
+ summary: string;
91
+ description: string;
92
+ parameters: {
93
+ in: string;
94
+ name: string;
95
+ required: boolean;
96
+ schema: {
97
+ type: string;
98
+ };
99
+ description: string;
100
+ }[];
101
+ responses: {
102
+ '200': {
103
+ description: string;
104
+ content: {
105
+ 'text/markdown': {
106
+ schema: {
107
+ type: string;
108
+ };
109
+ };
110
+ };
111
+ };
112
+ '404': {
113
+ description: string;
114
+ };
115
+ };
116
+ };
117
+ };
118
+ '/executions': {
119
+ get: {
120
+ summary: string;
121
+ description: string;
122
+ responses: {
123
+ '200': {
124
+ description: string;
125
+ content: {
126
+ 'application/json': {
127
+ schema: {
128
+ type: string;
129
+ items: {
130
+ type: string;
131
+ };
132
+ };
133
+ };
134
+ };
135
+ };
136
+ };
137
+ };
138
+ };
139
+ '/executions/new': {
140
+ post: {
141
+ summary: string;
142
+ description: string;
143
+ requestBody: {
144
+ required: boolean;
145
+ content: {
146
+ 'application/json': {
147
+ schema: {
148
+ type: string;
149
+ properties: {
150
+ pipelineUrl: {
151
+ type: string;
152
+ };
153
+ inputParameters: {
154
+ type: string;
155
+ };
156
+ identification: {
157
+ type: string;
158
+ };
159
+ };
160
+ };
161
+ };
162
+ };
163
+ };
164
+ responses: {
165
+ '200': {
166
+ description: string;
167
+ content: {
168
+ 'application/json': {
169
+ schema: {
170
+ type: string;
171
+ };
172
+ };
173
+ };
174
+ };
175
+ '400': {
176
+ description: string;
177
+ };
178
+ };
179
+ };
180
+ };
181
+ };
182
+ components: {};
183
+ tags: never[];
184
+ };
185
+ /**
186
+ * Note: [💞] Ignore a discrepancy between file name and entity name
187
+ */
@@ -1,4 +1,5 @@
1
1
  import type { LlmToolsConfiguration } from '../../../llm-providers/_common/register/LlmToolsConfiguration';
2
+ import type { string_ip_address } from '../../../types/typeAliases';
2
3
  import type { string_user_id } from '../../../types/typeAliases';
3
4
  import type { ApplicationRemoteServerClientOptions } from '../../types/RemoteServerOptions';
4
5
  /**
@@ -7,7 +8,12 @@ import type { ApplicationRemoteServerClientOptions } from '../../types/RemoteSer
7
8
  * @public exported from `@promptbook/remote-server`
8
9
  * @public exported from `@promptbook/remote-client`
9
10
  */
10
- export type Identification<TCustomOptions> = ApplicationModeIdentification<TCustomOptions> | AnonymousModeIdentification;
11
+ export type Identification<TCustomOptions> = (ApplicationModeIdentification<TCustomOptions> | AnonymousModeIdentification) & {
12
+ /**
13
+ * Identifier of the IP address of the client
14
+ */
15
+ readonly ipAddress?: string_ip_address;
16
+ };
11
17
  /**
12
18
  * Application mode is situation when you run known and well-defined books with your own api keys
13
19
  *
@@ -0,0 +1,11 @@
1
+ import type { string_promptbook_token } from '../../../types/typeAliases';
2
+ import type { really_unknown } from '../../../utils/organization/really_unknown';
3
+ import type { ApplicationModeIdentification } from './Identification';
4
+ /**
5
+ * Convert identification to Promptbook token
6
+ *
7
+ * @param identification
8
+ *
9
+ * @public exported from `@promptbook/core`
10
+ */
11
+ export declare function identificationToPromptbookToken(identification: ApplicationModeIdentification<really_unknown>): string_promptbook_token;
@@ -0,0 +1,10 @@
1
+ import type { string_promptbook_token } from '../../../types/typeAliases';
2
+ import type { ApplicationModeIdentification } from './Identification';
3
+ /**
4
+ * Convert Promptbook token to identification
5
+ *
6
+ * @param promptbookToken
7
+ *
8
+ * @public exported from `@promptbook/core`
9
+ */
10
+ export declare function promptbookTokenToIdentification(promptbookToken: string_promptbook_token): ApplicationModeIdentification<undefined>;
@@ -11,8 +11,7 @@ import type { RemoteServerOptions } from './types/RemoteServerOptions';
11
11
  */
12
12
  export declare function startRemoteServer<TCustomOptions = undefined>(options: RemoteServerOptions<TCustomOptions>): RemoteServer;
13
13
  /**
14
- * TODO: !! Add CORS and security - probbably via `helmet`
15
- * TODO: [👩🏾‍🤝‍🧑🏾] Allow to pass custom fetch function here - PromptbookFetch
14
+ * TODO: [🌡] Add CORS and security - probbably via `helmet`
16
15
  * TODO: Split this file into multiple functions - handler for each request
17
16
  * TODO: Maybe use `$exportJson`
18
17
  * TODO: [🧠][🛍] Maybe not `isAnonymous: boolean` BUT `mode: 'ANONYMOUS'|'COLLECTION'`