@promptbook/utils 0.102.0-12 → 0.102.0-16

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.
@@ -1,13 +1,51 @@
1
+ import type { Promisable } from 'type-fest';
1
2
  import type { string_file_extension, string_mime_type } from '../../../../types/typeAliases';
2
3
  import type { ChatMessage } from '../../types/ChatMessage';
4
+ import { ChatParticipant } from '../../types/ChatParticipant';
3
5
  /**
4
6
  * Plugin contract for chat export formatNames
7
+ *
5
8
  * @public exported from `@promptbook/components`
6
9
  */
7
10
  export type ChatSaveFormatDefinition = {
8
- formatName: string_file_extension | string_mime_type | string;
9
- label: string;
10
- getContent: (messages: ChatMessage[]) => string;
11
- mimeType: string;
12
- fileExtension: string;
11
+ /**
12
+ * A unique name for the format (e.g. 'json', 'txt', 'md', 'html', 'pdf', etc.)
13
+ */
14
+ readonly formatName: string_file_extension | string_mime_type | string;
15
+ /**
16
+ * A human-readable label for the format (e.g. 'JSON', 'Plain Text', 'Markdown', 'HTML', 'PDF', etc.) shown in UI
17
+ */
18
+ readonly label: string;
19
+ /**
20
+ * MIME type (e.g. 'application/json', 'text/plain', 'text/markdown', 'text/html', 'application/pdf', etc.)
21
+ */
22
+ readonly mimeType: string;
23
+ /**
24
+ * File extension without leading dot (e.g. 'json', 'txt', 'md', 'html', 'pdf', etc.)
25
+ */
26
+ readonly fileExtension: string;
27
+ /**
28
+ * The function that generates the content of the file to be saved
29
+ */
30
+ getContent(chatExportData: ChatExportData): Promisable<string>;
13
31
  };
32
+ /**
33
+ * Plugin contract for the data passed to `ChatSaveFormatDefinition.getContent()`
34
+ *
35
+ * @public exported from `@promptbook/components`
36
+ */
37
+ type ChatExportData = {
38
+ /**
39
+ * The title of the chat (used for file naming, etc.)
40
+ */
41
+ readonly title: string;
42
+ /**
43
+ * The chat messages to be exported
44
+ */
45
+ readonly messages: ReadonlyArray<ChatMessage>;
46
+ /**
47
+ * The participants in the chat
48
+ */
49
+ readonly participants: ReadonlyArray<ChatParticipant>;
50
+ };
51
+ export {};
@@ -5,8 +5,12 @@
5
5
  */
6
6
  export declare const htmlSaveFormatDefinition: {
7
7
  readonly formatName: "html";
8
- readonly label: "HTML";
9
- readonly getContent: (messages: import("../../types/ChatMessage").ChatMessage[]) => string;
8
+ readonly label: "Html";
9
+ readonly getContent: ({ messages }: {
10
+ readonly title: string;
11
+ readonly messages: readonly import("../../types/ChatMessage").ChatMessage[];
12
+ readonly participants: readonly import("../../types/ChatParticipant").ChatParticipant[];
13
+ }) => string;
10
14
  readonly mimeType: "text/html";
11
15
  readonly fileExtension: "html";
12
16
  };
@@ -5,32 +5,62 @@
5
5
  */
6
6
  export declare const CHAT_SAVE_FORMATS: readonly [{
7
7
  readonly formatName: "json";
8
- readonly label: "JSON (full)";
9
- readonly getContent: (messages: import("../types/ChatMessage").ChatMessage[]) => string;
8
+ readonly label: "Json";
9
+ readonly getContent: ({ messages }: {
10
+ readonly title: string;
11
+ readonly messages: readonly import("../types/ChatMessage").ChatMessage[];
12
+ readonly participants: readonly import("../types/ChatParticipant").ChatParticipant[];
13
+ }) => string;
10
14
  readonly mimeType: "application/json";
11
15
  readonly fileExtension: "json";
12
16
  }, {
13
17
  readonly formatName: "txt";
14
18
  readonly label: "Plain Text";
15
- readonly getContent: (messages: import("../types/ChatMessage").ChatMessage[]) => string;
19
+ readonly getContent: ({ messages }: {
20
+ readonly title: string;
21
+ readonly messages: readonly import("../types/ChatMessage").ChatMessage[];
22
+ readonly participants: readonly import("../types/ChatParticipant").ChatParticipant[];
23
+ }) => string;
16
24
  readonly mimeType: "text/plain";
17
25
  readonly fileExtension: "txt";
18
26
  }, {
19
27
  readonly formatName: "md";
20
28
  readonly label: "Markdown";
21
- readonly getContent: (messages: import("../types/ChatMessage").ChatMessage[]) => string;
29
+ readonly getContent: ({ messages }: {
30
+ readonly title: string;
31
+ readonly messages: readonly import("../types/ChatMessage").ChatMessage[];
32
+ readonly participants: readonly import("../types/ChatParticipant").ChatParticipant[];
33
+ }) => string;
22
34
  readonly mimeType: "text/markdown";
23
35
  readonly fileExtension: "md";
24
36
  }, {
25
37
  readonly formatName: "html";
26
- readonly label: "HTML";
27
- readonly getContent: (messages: import("../types/ChatMessage").ChatMessage[]) => string;
38
+ readonly label: "Html";
39
+ readonly getContent: ({ messages }: {
40
+ readonly title: string;
41
+ readonly messages: readonly import("../types/ChatMessage").ChatMessage[];
42
+ readonly participants: readonly import("../types/ChatParticipant").ChatParticipant[];
43
+ }) => string;
28
44
  readonly mimeType: "text/html";
29
45
  readonly fileExtension: "html";
46
+ }, {
47
+ readonly formatName: "jsx";
48
+ readonly label: "React";
49
+ readonly getContent: (chatExportData: {
50
+ readonly title: string;
51
+ readonly messages: readonly import("../types/ChatMessage").ChatMessage[];
52
+ readonly participants: readonly import("../types/ChatParticipant").ChatParticipant[];
53
+ }) => string;
54
+ readonly mimeType: "application/javascript";
55
+ readonly fileExtension: "jsx";
30
56
  }, {
31
57
  readonly formatName: "pdf";
32
- readonly label: "PDF";
33
- readonly getContent: (messages: import("../types/ChatMessage").ChatMessage[]) => string;
58
+ readonly label: "Pdf";
59
+ readonly getContent: (chatExportData: {
60
+ readonly title: string;
61
+ readonly messages: readonly import("../types/ChatMessage").ChatMessage[];
62
+ readonly participants: readonly import("../types/ChatParticipant").ChatParticipant[];
63
+ }) => Promise<string>;
34
64
  readonly mimeType: "application/pdf";
35
65
  readonly fileExtension: "pdf";
36
66
  }];
@@ -5,8 +5,12 @@
5
5
  */
6
6
  export declare const jsonSaveFormatDefinition: {
7
7
  readonly formatName: "json";
8
- readonly label: "JSON (full)";
9
- readonly getContent: (messages: import("../../types/ChatMessage").ChatMessage[]) => string;
8
+ readonly label: "Json";
9
+ readonly getContent: ({ messages }: {
10
+ readonly title: string;
11
+ readonly messages: readonly import("../../types/ChatMessage").ChatMessage[];
12
+ readonly participants: readonly import("../../types/ChatParticipant").ChatParticipant[];
13
+ }) => string;
10
14
  readonly mimeType: "application/json";
11
15
  readonly fileExtension: "json";
12
16
  };
@@ -6,7 +6,11 @@
6
6
  export declare const mdSaveFormatDefinition: {
7
7
  readonly formatName: "md";
8
8
  readonly label: "Markdown";
9
- readonly getContent: (messages: import("../../types/ChatMessage").ChatMessage[]) => string;
9
+ readonly getContent: ({ messages }: {
10
+ readonly title: string;
11
+ readonly messages: readonly import("../../types/ChatMessage").ChatMessage[];
12
+ readonly participants: readonly import("../../types/ChatParticipant").ChatParticipant[];
13
+ }) => string;
10
14
  readonly mimeType: "text/markdown";
11
15
  readonly fileExtension: "md";
12
16
  };
@@ -5,8 +5,12 @@
5
5
  */
6
6
  export declare const pdfSaveFormatDefinition: {
7
7
  readonly formatName: "pdf";
8
- readonly label: "PDF";
9
- readonly getContent: (messages: import("../../types/ChatMessage").ChatMessage[]) => string;
8
+ readonly label: "Pdf";
9
+ readonly getContent: (chatExportData: {
10
+ readonly title: string;
11
+ readonly messages: readonly import("../../types/ChatMessage").ChatMessage[];
12
+ readonly participants: readonly import("../../types/ChatParticipant").ChatParticipant[];
13
+ }) => Promise<string>;
10
14
  readonly mimeType: "application/pdf";
11
15
  readonly fileExtension: "pdf";
12
16
  };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * React <jsx/> export plugin (full metadata)
3
+ *
4
+ * @public exported from `@promptbook/components`
5
+ */
6
+ export declare const reactSaveFormatDefinition: {
7
+ readonly formatName: "jsx";
8
+ readonly label: "React";
9
+ readonly getContent: (chatExportData: {
10
+ readonly title: string;
11
+ readonly messages: readonly import("../../types/ChatMessage").ChatMessage[];
12
+ readonly participants: readonly import("../../types/ChatParticipant").ChatParticipant[];
13
+ }) => string;
14
+ readonly mimeType: "application/javascript";
15
+ readonly fileExtension: "jsx";
16
+ };
@@ -6,7 +6,11 @@
6
6
  export declare const txtSaveFormatDefinition: {
7
7
  readonly formatName: "txt";
8
8
  readonly label: "Plain Text";
9
- readonly getContent: (messages: import("../../types/ChatMessage").ChatMessage[]) => string;
9
+ readonly getContent: ({ messages }: {
10
+ readonly title: string;
11
+ readonly messages: readonly import("../../types/ChatMessage").ChatMessage[];
12
+ readonly participants: readonly import("../../types/ChatParticipant").ChatParticipant[];
13
+ }) => string;
10
14
  readonly mimeType: "text/plain";
11
15
  readonly fileExtension: "txt";
12
16
  };
@@ -111,6 +111,13 @@ export declare class Color {
111
111
  * @return {value is WithTake<Color>} Returns true if the value is a valid Color object, false otherwise.
112
112
  */
113
113
  static isColor(value: unknown): value is WithTake<Color>;
114
+ /**
115
+ * Checks if the given value is a valid hex color string
116
+ *
117
+ * @param value - value to check
118
+ * @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
119
+ */
120
+ static isHexColorString(value: unknown): value is string_color;
114
121
  /**
115
122
  * Creates new Color object
116
123
  *
@@ -0,0 +1,22 @@
1
+ import { string_javascript } from '../../types/typeAliases';
2
+ import { TODO_any } from '../organization/TODO_any';
3
+ type SerializeToPromptbookJavascriptReturn = {
4
+ /**
5
+ * Array of import statements required for the `value` to work
6
+ */
7
+ readonly imports: ReadonlyArray<string_javascript>;
8
+ /**
9
+ * The serialized value as a string of JavaScript code
10
+ */
11
+ readonly value: string_javascript;
12
+ };
13
+ /**
14
+ * Function `serializeToPromptbookJavascript` will serialize a value to a javascript representation using `@promptbook/*` entities where possible.
15
+ *
16
+ * @public exported from `@promptbook/utils`
17
+ */
18
+ export declare function serializeToPromptbookJavascript(value: TODO_any): SerializeToPromptbookJavascriptReturn;
19
+ export {};
20
+ /**
21
+ * TODO: Dynamic indentation passable through options in a second argument
22
+ */
@@ -15,7 +15,7 @@ export declare const BOOK_LANGUAGE_VERSION: string_semantic_version;
15
15
  export declare const PROMPTBOOK_ENGINE_VERSION: string_promptbook_version;
16
16
  /**
17
17
  * Represents the version string of the Promptbook engine.
18
- * It follows semantic versioning (e.g., `0.102.0-11`).
18
+ * It follows semantic versioning (e.g., `0.102.0-15`).
19
19
  *
20
20
  * @generated
21
21
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promptbook/utils",
3
- "version": "0.102.0-12",
3
+ "version": "0.102.0-16",
4
4
  "description": "Promptbook: Run AI apps in plain human language across multiple models and platforms",
5
5
  "private": false,
6
6
  "sideEffects": false,
package/umd/index.umd.js CHANGED
@@ -22,7 +22,7 @@
22
22
  * @generated
23
23
  * @see https://github.com/webgptorg/promptbook
24
24
  */
25
- const PROMPTBOOK_ENGINE_VERSION = '0.102.0-12';
25
+ const PROMPTBOOK_ENGINE_VERSION = '0.102.0-16';
26
26
  /**
27
27
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
28
28
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -305,7 +305,7 @@
305
305
  return Color.fromString(CSS_COLORS[color]);
306
306
  // -----
307
307
  }
308
- else if (/^#(?:[0-9a-fA-F]{3}){1,2}$/.test(color)) {
308
+ else if (Color.isHexColorString(color)) {
309
309
  return Color.fromHex(color);
310
310
  // -----
311
311
  }
@@ -564,6 +564,15 @@
564
564
  }
565
565
  return true;
566
566
  }
567
+ /**
568
+ * Checks if the given value is a valid hex color string
569
+ *
570
+ * @param value - value to check
571
+ * @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
572
+ */
573
+ static isHexColorString(value) {
574
+ return typeof value === 'string' && /^#(?:[0-9a-fA-F]{3}){1,2}$/.test(value);
575
+ }
567
576
  /**
568
577
  * Creates new Color object
569
578
  *
@@ -3504,6 +3513,68 @@
3504
3513
  * TODO: Type the return type correctly
3505
3514
  */
3506
3515
 
3516
+ /**
3517
+ * Function `serializeToPromptbookJavascript` will serialize a value to a javascript representation using `@promptbook/*` entities where possible.
3518
+ *
3519
+ * @public exported from `@promptbook/utils`
3520
+ */
3521
+ function serializeToPromptbookJavascript(value) {
3522
+ let serializedValue;
3523
+ let imports = [];
3524
+ if (value === null || value === undefined || typeof value === 'number' || typeof value === 'boolean') {
3525
+ serializedValue = JSON.stringify(value, null, 4);
3526
+ }
3527
+ else if (Array.isArray(value)) {
3528
+ const serializedItems = value.map((item) => serializeToPromptbookJavascript(item));
3529
+ serializedValue = `[${serializedItems.map((item) => item.value).join(', ')}]`;
3530
+ imports = serializedItems.flatMap((item) => item.imports);
3531
+ }
3532
+ else if (value instanceof Date) {
3533
+ serializedValue = `new Date('${value.toISOString()}')`;
3534
+ }
3535
+ else if (value instanceof Color) {
3536
+ serializedValue = `Color.fromHex('${value.toHex()}')`;
3537
+ imports.push(`import { Color } from '@promptbook/color';`);
3538
+ }
3539
+ else if (typeof value === 'string') {
3540
+ const trimmed = spaceTrim__default["default"](value);
3541
+ if (trimmed.includes('\n')) {
3542
+ // Multiline string -> use `spaceTrim`
3543
+ serializedValue = `spaceTrim(\`\n${value.replace(/`/g, '\\`')}\n\`)`;
3544
+ imports.push(`import { spaceTrim } from '@promptbook/utils';`);
3545
+ }
3546
+ else if (Color.isHexColorString(trimmed)) {
3547
+ return serializeToPromptbookJavascript(Color.fromHex(trimmed));
3548
+ }
3549
+ else {
3550
+ // Single line string -> use normal quotes
3551
+ serializedValue = JSON.stringify(value);
3552
+ }
3553
+ }
3554
+ else if (typeof value === 'object') {
3555
+ const entries = Object.entries(value).map(([key, val]) => {
3556
+ const serializedEntry = serializeToPromptbookJavascript(val);
3557
+ imports.push(...serializedEntry.imports);
3558
+ return [key, serializedEntry.value];
3559
+ });
3560
+ const objectString = `{\n${entries
3561
+ .map(([key, val]) => ` ${JSON.stringify(key)}: ${val === null || val === void 0 ? void 0 : val.split('\n').map((line) => ` ${line}`).join('\n')}`)
3562
+ .join(',\n')}\n}`;
3563
+ serializedValue = objectString;
3564
+ }
3565
+ else {
3566
+ throw new Error(`Cannot serialize to Promptbook Javascript value of type "${typeof value}"`);
3567
+ }
3568
+ if (serializedValue === undefined) {
3569
+ throw new UnexpectedError(`Serialization resulted in undefined value`);
3570
+ }
3571
+ const uniqueImports = Array.from(new Set(imports)).filter((imp) => !!imp && imp.trim().length > 0);
3572
+ return { imports: uniqueImports, value: serializedValue };
3573
+ }
3574
+ /**
3575
+ * TODO: Dynamic indentation passable through options in a second argument
3576
+ */
3577
+
3507
3578
  /**
3508
3579
  * Create difference set of two sets.
3509
3580
  *
@@ -3822,6 +3893,7 @@
3822
3893
  exports.renderPromptbookMermaid = renderPromptbookMermaid;
3823
3894
  exports.searchKeywords = searchKeywords;
3824
3895
  exports.serializeError = serializeError;
3896
+ exports.serializeToPromptbookJavascript = serializeToPromptbookJavascript;
3825
3897
  exports.spaceTrim = spaceTrim;
3826
3898
  exports.splitIntoSentences = splitIntoSentences;
3827
3899
  exports.suffixUrl = suffixUrl;