@promptbook/pdf 0.112.0-73 → 0.112.0-79

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 (74) hide show
  1. package/README.md +9 -9
  2. package/esm/index.es.js +313 -210
  3. package/esm/index.es.js.map +1 -1
  4. package/esm/src/avatars/types/AvatarVisualDefinition.d.ts +1 -1
  5. package/esm/src/avatars/visuals/octopus3d2AvatarVisual.d.ts +7 -0
  6. package/esm/src/avatars/visuals/octopus3dAvatarVisualShared.d.ts +37 -0
  7. package/esm/src/book-components/Chat/save/_common/chatExportRendering.d.ts +47 -0
  8. package/esm/src/book-components/Chat/save/html/htmlSaveFormatDefinition.d.ts +12 -0
  9. package/esm/src/book-components/Chat/save/index.d.ts +2 -2
  10. package/esm/src/book-components/Chat/save/markdown/mdSaveFormatDefinition.d.ts +5 -3
  11. package/esm/src/book-components/Chat/save/pdf/buildChatPdf.d.ts +3 -3
  12. package/esm/src/book-components/Chat/save/pdf/pdfSaveFormatDefinition.d.ts +1 -1
  13. package/esm/src/cli/cli-commands/agent/agentProjectPaths.d.ts +8 -8
  14. package/esm/src/cli/cli-commands/agent/initializeAgentRunnerCommand.d.ts +1 -1
  15. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer.d.ts +56 -0
  16. package/esm/src/cli/cli-commands/agents-server/buildAgentsServer.test.d.ts +1 -0
  17. package/esm/src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.d.ts +7 -0
  18. package/esm/src/cli/cli-commands/agents-server/ensureAgentsServerGitignoreFile.d.ts +7 -0
  19. package/esm/src/cli/cli-commands/agents-server/init.d.ts +9 -0
  20. package/esm/src/cli/cli-commands/agents-server/init.test.d.ts +1 -0
  21. package/esm/src/cli/cli-commands/agents-server/initializeAgentsServerProjectConfiguration.d.ts +17 -0
  22. package/esm/src/cli/cli-commands/agents-server/printAgentsServerInitializationSummary.d.ts +7 -0
  23. package/esm/src/cli/cli-commands/agents-server/run.d.ts +14 -0
  24. package/esm/src/cli/cli-commands/agents-server/run.test.d.ts +1 -0
  25. package/esm/src/cli/cli-commands/agents-server/startAgentsServer.d.ts +23 -0
  26. package/esm/src/cli/cli-commands/agents-server.d.ts +8 -0
  27. package/esm/src/cli/cli-commands/common/projectInitialization.d.ts +65 -0
  28. package/esm/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +44 -0
  29. package/esm/src/cli/common/$deprecateCliCommand.d.ts +8 -0
  30. package/esm/src/cli/common/$deprecateCliCommand.test.d.ts +1 -0
  31. package/esm/src/utils/color/Color.d.ts +4 -44
  32. package/esm/src/utils/color/ColorValue.d.ts +55 -0
  33. package/esm/src/utils/color/isHexColorString.d.ts +10 -0
  34. package/esm/src/utils/color/parseColorString.d.ts +11 -0
  35. package/esm/src/version.d.ts +1 -1
  36. package/package.json +2 -2
  37. package/umd/index.umd.js +313 -210
  38. package/umd/index.umd.js.map +1 -1
  39. package/umd/src/avatars/types/AvatarVisualDefinition.d.ts +1 -1
  40. package/umd/src/avatars/visuals/octopus3d2AvatarVisual.d.ts +7 -0
  41. package/umd/src/avatars/visuals/octopus3dAvatarVisualShared.d.ts +37 -0
  42. package/umd/src/book-components/Chat/save/_common/chatExportRendering.d.ts +47 -0
  43. package/umd/src/book-components/Chat/save/html/htmlSaveFormatDefinition.d.ts +12 -0
  44. package/umd/src/book-components/Chat/save/index.d.ts +2 -2
  45. package/umd/src/book-components/Chat/save/markdown/mdSaveFormatDefinition.d.ts +5 -3
  46. package/umd/src/book-components/Chat/save/pdf/buildChatPdf.d.ts +3 -3
  47. package/umd/src/book-components/Chat/save/pdf/pdfSaveFormatDefinition.d.ts +1 -1
  48. package/umd/src/cli/cli-commands/agent/agentProjectPaths.d.ts +8 -8
  49. package/umd/src/cli/cli-commands/agent/initializeAgentRunnerCommand.d.ts +1 -1
  50. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer.d.ts +56 -0
  51. package/umd/src/cli/cli-commands/agents-server/buildAgentsServer.test.d.ts +1 -0
  52. package/umd/src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.d.ts +7 -0
  53. package/umd/src/cli/cli-commands/agents-server/ensureAgentsServerGitignoreFile.d.ts +7 -0
  54. package/umd/src/cli/cli-commands/agents-server/init.d.ts +9 -0
  55. package/umd/src/cli/cli-commands/agents-server/init.test.d.ts +1 -0
  56. package/umd/src/cli/cli-commands/agents-server/initializeAgentsServerProjectConfiguration.d.ts +17 -0
  57. package/umd/src/cli/cli-commands/agents-server/printAgentsServerInitializationSummary.d.ts +7 -0
  58. package/umd/src/cli/cli-commands/agents-server/run.d.ts +14 -0
  59. package/umd/src/cli/cli-commands/agents-server/run.test.d.ts +1 -0
  60. package/umd/src/cli/cli-commands/agents-server/startAgentsServer.d.ts +23 -0
  61. package/umd/src/cli/cli-commands/agents-server.d.ts +8 -0
  62. package/umd/src/cli/cli-commands/common/projectInitialization.d.ts +65 -0
  63. package/umd/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +44 -0
  64. package/umd/src/cli/common/$deprecateCliCommand.d.ts +8 -0
  65. package/umd/src/cli/common/$deprecateCliCommand.test.d.ts +1 -0
  66. package/umd/src/utils/color/Color.d.ts +4 -44
  67. package/umd/src/utils/color/ColorValue.d.ts +55 -0
  68. package/umd/src/utils/color/isHexColorString.d.ts +10 -0
  69. package/umd/src/utils/color/parseColorString.d.ts +11 -0
  70. package/umd/src/version.d.ts +1 -1
  71. package/esm/src/cli/cli-commands/coder/appendBlock.d.ts +0 -6
  72. package/esm/src/cli/cli-commands/coder/readTextFileIfExists.d.ts +0 -6
  73. package/umd/src/cli/cli-commands/coder/appendBlock.d.ts +0 -6
  74. package/umd/src/cli/cli-commands/coder/readTextFileIfExists.d.ts +0 -6
package/esm/index.es.js CHANGED
@@ -24,7 +24,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
24
24
  * @generated
25
25
  * @see https://github.com/webgptorg/promptbook
26
26
  */
27
- const PROMPTBOOK_ENGINE_VERSION = '0.112.0-73';
27
+ const PROMPTBOOK_ENGINE_VERSION = '0.112.0-79';
28
28
  /**
29
29
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
30
30
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -306,6 +306,111 @@ function checkChannelValue(channelName, value) {
306
306
  }
307
307
  }
308
308
 
309
+ /**
310
+ * Shared immutable channel storage and serialization helpers for `Color`.
311
+ *
312
+ * @private base class of Color
313
+ */
314
+ class ColorValue {
315
+ constructor(red, green, blue, alpha = 255) {
316
+ this.red = red;
317
+ this.green = green;
318
+ this.blue = blue;
319
+ this.alpha = alpha;
320
+ checkChannelValue('Red', red);
321
+ checkChannelValue('Green', green);
322
+ checkChannelValue('Blue', blue);
323
+ checkChannelValue('Alpha', alpha);
324
+ }
325
+ /**
326
+ * Shortcut for `red` property
327
+ * Number from 0 to 255
328
+ * @alias red
329
+ */
330
+ get r() {
331
+ return this.red;
332
+ }
333
+ /**
334
+ * Shortcut for `green` property
335
+ * Number from 0 to 255
336
+ * @alias green
337
+ */
338
+ get g() {
339
+ return this.green;
340
+ }
341
+ /**
342
+ * Shortcut for `blue` property
343
+ * Number from 0 to 255
344
+ * @alias blue
345
+ */
346
+ get b() {
347
+ return this.blue;
348
+ }
349
+ /**
350
+ * Shortcut for `alpha` property
351
+ * Number from 0 (transparent) to 255 (opaque)
352
+ * @alias alpha
353
+ */
354
+ get a() {
355
+ return this.alpha;
356
+ }
357
+ /**
358
+ * Shortcut for `alpha` property
359
+ * Number from 0 (transparent) to 255 (opaque)
360
+ * @alias alpha
361
+ */
362
+ get opacity() {
363
+ return this.alpha;
364
+ }
365
+ /**
366
+ * Shortcut for 1-`alpha` property
367
+ */
368
+ get transparency() {
369
+ return 255 - this.alpha;
370
+ }
371
+ clone() {
372
+ return take(this.createColor(this.red, this.green, this.blue, this.alpha));
373
+ }
374
+ toString() {
375
+ return this.toHex();
376
+ }
377
+ toHex() {
378
+ if (this.alpha === 255) {
379
+ return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
380
+ .toString(16)
381
+ .padStart(2, '0')}`;
382
+ }
383
+ else {
384
+ return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
385
+ .toString(16)
386
+ .padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
387
+ }
388
+ }
389
+ toRgb() {
390
+ if (this.alpha === 255) {
391
+ return `rgb(${this.red}, ${this.green}, ${this.blue})`;
392
+ }
393
+ else {
394
+ return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
395
+ }
396
+ }
397
+ toHsl() {
398
+ throw new Error(`Getting HSL is not implemented`);
399
+ }
400
+ }
401
+
402
+ /**
403
+ * Checks if the given value is a valid hex color string
404
+ *
405
+ * @param value - value to check
406
+ * @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
407
+ *
408
+ * @private function of Color
409
+ */
410
+ function isHexColorString(value) {
411
+ return (typeof value === 'string' && /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value));
412
+ }
413
+
309
414
  /**
310
415
  * Constant for short hex lengths.
311
416
  */
@@ -517,16 +622,53 @@ function parseAlphaValue(value) {
517
622
 
518
623
  /**
519
624
  * Pattern matching hsl regex.
625
+ *
626
+ * @private function of Color
520
627
  */
521
628
  const HSL_REGEX_PATTERN = /^hsl\(\s*([0-9.]+)\s*,\s*([0-9.]+)%\s*,\s*([0-9.]+)%\s*\)$/;
522
629
  /**
523
630
  * Pattern matching RGB regex.
631
+ *
632
+ * @private function of Color
524
633
  */
525
634
  const RGB_REGEX_PATTERN = /^rgb\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/;
526
635
  /**
527
636
  * Pattern matching rgba regex.
637
+ *
638
+ * @private function of Color
528
639
  */
529
640
  const RGBA_REGEX_PATTERN = /^rgba\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/;
641
+ /**
642
+ * Parses a supported color string into RGBA channels.
643
+ *
644
+ * @param color as a string for example `#009edd`, `rgb(0,158,221)`, `rgb(0%,62%,86.7%)`, `hsl(197.1,100%,43.3%)`, `red`, `darkgrey`,...
645
+ * @returns RGBA channel values.
646
+ *
647
+ * @private function of Color
648
+ */
649
+ function parseColorString(color) {
650
+ const trimmed = color.trim();
651
+ const cssColor = CSS_COLORS[trimmed];
652
+ if (cssColor) {
653
+ return parseColorString(cssColor);
654
+ }
655
+ else if (isHexColorString(trimmed)) {
656
+ return parseHexColor(trimmed);
657
+ }
658
+ if (HSL_REGEX_PATTERN.test(trimmed)) {
659
+ return parseHslColor(trimmed);
660
+ }
661
+ else if (RGB_REGEX_PATTERN.test(trimmed)) {
662
+ return parseRgbColor(trimmed);
663
+ }
664
+ else if (RGBA_REGEX_PATTERN.test(trimmed)) {
665
+ return parseRgbaColor(trimmed);
666
+ }
667
+ else {
668
+ throw new Error(`Can not create a new Color instance from string "${trimmed}".`);
669
+ }
670
+ }
671
+
530
672
  /**
531
673
  * Color object represents an RGB color with alpha channel
532
674
  *
@@ -534,7 +676,7 @@ const RGBA_REGEX_PATTERN = /^rgba\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.
534
676
  *
535
677
  * @public exported from `@promptbook/color`
536
678
  */
537
- class Color {
679
+ class Color extends ColorValue {
538
680
  /**
539
681
  * Creates a new Color instance from miscellaneous formats
540
682
  * - It can receive Color instance and just return the same instance
@@ -607,25 +749,7 @@ class Color {
607
749
  * @returns Color object
608
750
  */
609
751
  static fromString(color) {
610
- const trimmed = color.trim();
611
- if (CSS_COLORS[trimmed]) {
612
- return Color.fromString(CSS_COLORS[trimmed]);
613
- }
614
- else if (Color.isHexColorString(trimmed)) {
615
- return Color.fromHex(trimmed);
616
- }
617
- if (HSL_REGEX_PATTERN.test(trimmed)) {
618
- return Color.fromHsl(trimmed);
619
- }
620
- else if (RGB_REGEX_PATTERN.test(trimmed)) {
621
- return Color.fromRgbString(trimmed);
622
- }
623
- else if (RGBA_REGEX_PATTERN.test(trimmed)) {
624
- return Color.fromRgbaString(trimmed);
625
- }
626
- else {
627
- throw new Error(`Can not create a new Color instance from string "${trimmed}".`);
628
- }
752
+ return Color.fromColorChannels(parseColorString(color));
629
753
  }
630
754
  /**
631
755
  * Gets common color
@@ -655,8 +779,7 @@ class Color {
655
779
  * @returns Color object
656
780
  */
657
781
  static fromHex(hex) {
658
- const { red, green, blue, alpha } = parseHexColor(hex);
659
- return take(new Color(red, green, blue, alpha));
782
+ return Color.fromColorChannels(parseHexColor(hex));
660
783
  }
661
784
  /**
662
785
  * Creates a new Color instance from color in hsl format
@@ -665,8 +788,7 @@ class Color {
665
788
  * @returns Color object
666
789
  */
667
790
  static fromHsl(hsl) {
668
- const { red, green, blue, alpha } = parseHslColor(hsl);
669
- return take(new Color(red, green, blue, alpha));
791
+ return Color.fromColorChannels(parseHslColor(hsl));
670
792
  }
671
793
  /**
672
794
  * Creates a new Color instance from color in rgb format
@@ -675,8 +797,7 @@ class Color {
675
797
  * @returns Color object
676
798
  */
677
799
  static fromRgbString(rgb) {
678
- const { red, green, blue, alpha } = parseRgbColor(rgb);
679
- return take(new Color(red, green, blue, alpha));
800
+ return Color.fromColorChannels(parseRgbColor(rgb));
680
801
  }
681
802
  /**
682
803
  * Creates a new Color instance from color in rbga format
@@ -685,8 +806,7 @@ class Color {
685
806
  * @returns Color object
686
807
  */
687
808
  static fromRgbaString(rgba) {
688
- const { red, green, blue, alpha } = parseRgbaColor(rgba);
689
- return take(new Color(red, green, blue, alpha));
809
+ return Color.fromColorChannels(parseRgbaColor(rgba));
690
810
  }
691
811
  /**
692
812
  * Creates a new Color for color channels values
@@ -698,7 +818,7 @@ class Color {
698
818
  * @returns Color object
699
819
  */
700
820
  static fromValues(red, green, blue, alpha = 255) {
701
- return take(new Color(red, green, blue, alpha));
821
+ return Color.fromColorChannels({ red, green, blue, alpha });
702
822
  }
703
823
  /**
704
824
  * Checks if the given value is a valid Color object.
@@ -731,8 +851,7 @@ class Color {
731
851
  * @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
732
852
  */
733
853
  static isHexColorString(value) {
734
- return (typeof value === 'string' &&
735
- /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value));
854
+ return isHexColorString(value);
736
855
  }
737
856
  /**
738
857
  * Creates new Color object
@@ -745,89 +864,13 @@ class Color {
745
864
  * @param alpha number from 0 (transparent) to 255 (opaque)
746
865
  */
747
866
  constructor(red, green, blue, alpha = 255) {
748
- this.red = red;
749
- this.green = green;
750
- this.blue = blue;
751
- this.alpha = alpha;
752
- checkChannelValue('Red', red);
753
- checkChannelValue('Green', green);
754
- checkChannelValue('Blue', blue);
755
- checkChannelValue('Alpha', alpha);
867
+ super(red, green, blue, alpha);
756
868
  }
757
- /**
758
- * Shortcut for `red` property
759
- * Number from 0 to 255
760
- * @alias red
761
- */
762
- get r() {
763
- return this.red;
869
+ createColor(red, green, blue, alpha) {
870
+ return new Color(red, green, blue, alpha);
764
871
  }
765
- /**
766
- * Shortcut for `green` property
767
- * Number from 0 to 255
768
- * @alias green
769
- */
770
- get g() {
771
- return this.green;
772
- }
773
- /**
774
- * Shortcut for `blue` property
775
- * Number from 0 to 255
776
- * @alias blue
777
- */
778
- get b() {
779
- return this.blue;
780
- }
781
- /**
782
- * Shortcut for `alpha` property
783
- * Number from 0 (transparent) to 255 (opaque)
784
- * @alias alpha
785
- */
786
- get a() {
787
- return this.alpha;
788
- }
789
- /**
790
- * Shortcut for `alpha` property
791
- * Number from 0 (transparent) to 255 (opaque)
792
- * @alias alpha
793
- */
794
- get opacity() {
795
- return this.alpha;
796
- }
797
- /**
798
- * Shortcut for 1-`alpha` property
799
- */
800
- get transparency() {
801
- return 255 - this.alpha;
802
- }
803
- clone() {
804
- return take(new Color(this.red, this.green, this.blue, this.alpha));
805
- }
806
- toString() {
807
- return this.toHex();
808
- }
809
- toHex() {
810
- if (this.alpha === 255) {
811
- return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
812
- .toString(16)
813
- .padStart(2, '0')}`;
814
- }
815
- else {
816
- return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
817
- .toString(16)
818
- .padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
819
- }
820
- }
821
- toRgb() {
822
- if (this.alpha === 255) {
823
- return `rgb(${this.red}, ${this.green}, ${this.blue})`;
824
- }
825
- else {
826
- return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
827
- }
828
- }
829
- toHsl() {
830
- throw new Error(`Getting HSL is not implemented`);
872
+ static fromColorChannels({ red, green, blue, alpha }) {
873
+ return take(new Color(red, green, blue, alpha));
831
874
  }
832
875
  }
833
876
 
@@ -2236,7 +2279,7 @@ function createJokerCommands(task) {
2236
2279
  */
2237
2280
  function createPostprocessingCommands(task) {
2238
2281
  var _a;
2239
- return ((_a = task.postprocessingFunctionNames) === null || _a === void 0 ? void 0 : _a.map((postprocessingFunctionName) => `POSTPROCESSING \`${postprocessingFunctionName}\``)) || [];
2282
+ return (((_a = task.postprocessingFunctionNames) === null || _a === void 0 ? void 0 : _a.map((postprocessingFunctionName) => `POSTPROCESSING \`${postprocessingFunctionName}\``)) || []);
2240
2283
  }
2241
2284
  /**
2242
2285
  * Collects expectation commands.
@@ -2401,120 +2444,183 @@ function $deepFreeze(objectValue) {
2401
2444
  * @public exported from `@promptbook/utils`
2402
2445
  */
2403
2446
  function checkSerializableAsJson(options) {
2404
- const { value, name, message } = options;
2447
+ checkSerializableValue(options);
2448
+ }
2449
+ // TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
2450
+ // TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
2451
+ // Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
2452
+ /**
2453
+ * Checks one value and dispatches to the appropriate specialized validator.
2454
+ *
2455
+ * @private function of `checkSerializableAsJson`
2456
+ */
2457
+ function checkSerializableValue(options) {
2458
+ const { value } = options;
2459
+ if (isSerializablePrimitive(value)) {
2460
+ return;
2461
+ }
2405
2462
  if (value === undefined) {
2406
- throw new UnexpectedError(`${name} is undefined`);
2463
+ throw new UnexpectedError(`${options.name} is undefined`);
2407
2464
  }
2408
- else if (value === null) {
2409
- return;
2465
+ if (typeof value === 'symbol') {
2466
+ throw new UnexpectedError(`${options.name} is symbol`);
2410
2467
  }
2411
- else if (typeof value === 'boolean') {
2412
- return;
2468
+ if (typeof value === 'function') {
2469
+ throw new UnexpectedError(`${options.name} is function`);
2413
2470
  }
2414
- else if (typeof value === 'number' && !isNaN(value)) {
2471
+ if (Array.isArray(value)) {
2472
+ checkSerializableArray(options, value);
2415
2473
  return;
2416
2474
  }
2417
- else if (typeof value === 'string') {
2475
+ if (value !== null && typeof value === 'object') {
2476
+ checkSerializableObject(options, value);
2418
2477
  return;
2419
2478
  }
2420
- else if (typeof value === 'symbol') {
2421
- throw new UnexpectedError(`${name} is symbol`);
2422
- }
2423
- else if (typeof value === 'function') {
2424
- throw new UnexpectedError(`${name} is function`);
2425
- }
2426
- else if (typeof value === 'object' && Array.isArray(value)) {
2427
- for (let i = 0; i < value.length; i++) {
2428
- checkSerializableAsJson({ name: `${name}[${i}]`, value: value[i], message });
2429
- }
2479
+ throwUnknownTypeError(options);
2480
+ }
2481
+ /**
2482
+ * Checks the primitive values that are directly JSON serializable.
2483
+ *
2484
+ * @private function of `checkSerializableAsJson`
2485
+ */
2486
+ function isSerializablePrimitive(value) {
2487
+ return (value === null ||
2488
+ typeof value === 'boolean' ||
2489
+ (typeof value === 'number' && !isNaN(value)) ||
2490
+ typeof value === 'string');
2491
+ }
2492
+ /**
2493
+ * Recursively checks JSON array items.
2494
+ *
2495
+ * @private function of `checkSerializableAsJson`
2496
+ */
2497
+ function checkSerializableArray(context, arrayValue) {
2498
+ for (let index = 0; index < arrayValue.length; index++) {
2499
+ checkSerializableAsJson({
2500
+ ...context,
2501
+ name: `${context.name}[${index}]`,
2502
+ value: arrayValue[index],
2503
+ });
2430
2504
  }
2431
- else if (typeof value === 'object') {
2432
- if (value instanceof Date) {
2433
- throw new UnexpectedError(spaceTrim$1((block) => `
2434
- \`${name}\` is Date
2505
+ }
2506
+ /**
2507
+ * Checks object-like values and dispatches special unsupported built-ins.
2508
+ *
2509
+ * @private function of `checkSerializableAsJson`
2510
+ */
2511
+ function checkSerializableObject(context, objectValue) {
2512
+ checkUnsupportedObjectType(context, objectValue);
2513
+ checkSerializableObjectEntries(context, objectValue);
2514
+ assertJsonStringificationSucceeds(context, objectValue);
2515
+ }
2516
+ /**
2517
+ * Rejects built-in objects that must be converted before JSON serialization.
2518
+ *
2519
+ * @private function of `checkSerializableAsJson`
2520
+ */
2521
+ function checkUnsupportedObjectType(context, objectValue) {
2522
+ if (objectValue instanceof Date) {
2523
+ throw new UnexpectedError(spaceTrim$1((block) => `
2524
+ \`${context.name}\` is Date
2435
2525
 
2436
- Use \`string_date_iso8601\` instead
2526
+ Use \`string_date_iso8601\` instead
2437
2527
 
2438
- Additional message for \`${name}\`:
2439
- ${block(message || '(nothing)')}
2440
- `));
2441
- }
2442
- else if (value instanceof Map) {
2443
- throw new UnexpectedError(`${name} is Map`);
2444
- }
2445
- else if (value instanceof Set) {
2446
- throw new UnexpectedError(`${name} is Set`);
2447
- }
2448
- else if (value instanceof RegExp) {
2449
- throw new UnexpectedError(`${name} is RegExp`);
2450
- }
2451
- else if (value instanceof Error) {
2452
- throw new UnexpectedError(spaceTrim$1((block) => `
2453
- \`${name}\` is unserialized Error
2528
+ Additional message for \`${context.name}\`:
2529
+ ${block(context.message || '(nothing)')}
2530
+ `));
2531
+ }
2532
+ if (objectValue instanceof Map) {
2533
+ throw new UnexpectedError(`${context.name} is Map`);
2534
+ }
2535
+ if (objectValue instanceof Set) {
2536
+ throw new UnexpectedError(`${context.name} is Set`);
2537
+ }
2538
+ if (objectValue instanceof RegExp) {
2539
+ throw new UnexpectedError(`${context.name} is RegExp`);
2540
+ }
2541
+ if (objectValue instanceof Error) {
2542
+ throw new UnexpectedError(spaceTrim$1((block) => `
2543
+ \`${context.name}\` is unserialized Error
2454
2544
 
2455
- Use function \`serializeError\`
2545
+ Use function \`serializeError\`
2456
2546
 
2457
- Additional message for \`${name}\`:
2458
- ${block(message || '(nothing)')}
2547
+ Additional message for \`${context.name}\`:
2548
+ ${block(context.message || '(nothing)')}
2459
2549
 
2460
- `));
2550
+ `));
2551
+ }
2552
+ }
2553
+ /**
2554
+ * Recursively checks object properties while preserving omitted `undefined` keys.
2555
+ *
2556
+ * @private function of `checkSerializableAsJson`
2557
+ */
2558
+ function checkSerializableObjectEntries(context, objectValue) {
2559
+ for (const [subName, subValue] of Object.entries(objectValue)) {
2560
+ if (subValue === undefined) {
2561
+ // Note: undefined in object is serializable - it is just omitted
2562
+ continue;
2461
2563
  }
2462
- else {
2463
- for (const [subName, subValue] of Object.entries(value)) {
2464
- if (subValue === undefined) {
2465
- // Note: undefined in object is serializable - it is just omitted
2466
- continue;
2467
- }
2468
- checkSerializableAsJson({ name: `${name}.${subName}`, value: subValue, message });
2469
- }
2470
- try {
2471
- JSON.stringify(value); // <- TODO: [0]
2472
- }
2473
- catch (error) {
2474
- assertsError(error);
2475
- throw new UnexpectedError(spaceTrim$1((block) => `
2476
- \`${name}\` is not serializable
2564
+ checkSerializableAsJson({
2565
+ ...context,
2566
+ name: `${context.name}.${subName}`,
2567
+ value: subValue,
2568
+ });
2569
+ }
2570
+ }
2571
+ /**
2572
+ * Uses `JSON.stringify` as the final guard for cases like circular references.
2573
+ *
2574
+ * @private function of `checkSerializableAsJson`
2575
+ */
2576
+ function assertJsonStringificationSucceeds(context, objectValue) {
2577
+ try {
2578
+ JSON.stringify(objectValue); // <- TODO: [0]
2579
+ }
2580
+ catch (error) {
2581
+ assertsError(error);
2582
+ throw new UnexpectedError(spaceTrim$1((block) => `
2583
+ \`${context.name}\` is not serializable
2477
2584
 
2478
- ${block(error.stack || error.message)}
2585
+ ${block(error.stack || error.message)}
2479
2586
 
2480
- Additional message for \`${name}\`:
2481
- ${block(message || '(nothing)')}
2482
- `));
2587
+ Additional message for \`${context.name}\`:
2588
+ ${block(context.message || '(nothing)')}
2589
+ `));
2590
+ }
2591
+ /*
2592
+ TODO: [0] Is there some more elegant way to check circular references?
2593
+ const seen = new Set();
2594
+ const stack = [{ value }];
2595
+ while (stack.length > 0) {
2596
+ const { value } = stack.pop()!;
2597
+ if (typeof value === 'object' && value !== null) {
2598
+ if (seen.has(value)) {
2599
+ throw new UnexpectedError(`${name} has circular reference`);
2483
2600
  }
2484
- /*
2485
- TODO: [0] Is there some more elegant way to check circular references?
2486
- const seen = new Set();
2487
- const stack = [{ value }];
2488
- while (stack.length > 0) {
2489
- const { value } = stack.pop()!;
2490
- if (typeof value === 'object' && value !== null) {
2491
- if (seen.has(value)) {
2492
- throw new UnexpectedError(`${name} has circular reference`);
2493
- }
2494
- seen.add(value);
2495
- if (Array.isArray(value)) {
2496
- stack.push(...value.map((value) => ({ value })));
2497
- } else {
2498
- stack.push(...Object.values(value).map((value) => ({ value })));
2499
- }
2500
- }
2601
+ seen.add(value);
2602
+ if (Array.isArray(value)) {
2603
+ stack.push(...value.map((value) => ({ value })));
2604
+ } else {
2605
+ stack.push(...Object.values(value).map((value) => ({ value })));
2501
2606
  }
2502
- */
2503
- return;
2504
2607
  }
2505
2608
  }
2506
- else {
2507
- throw new UnexpectedError(spaceTrim$1((block) => `
2508
- \`${name}\` is unknown type
2609
+ */
2610
+ }
2611
+ /**
2612
+ * Throws the fallback error for unsupported value types like `bigint` and `NaN`.
2613
+ *
2614
+ * @private function of `checkSerializableAsJson`
2615
+ */
2616
+ function throwUnknownTypeError(context) {
2617
+ throw new UnexpectedError(spaceTrim$1((block) => `
2618
+ \`${context.name}\` is unknown type
2509
2619
 
2510
- Additional message for \`${name}\`:
2511
- ${block(message || '(nothing)')}
2512
- `));
2513
- }
2620
+ Additional message for \`${context.name}\`:
2621
+ ${block(context.message || '(nothing)')}
2622
+ `));
2514
2623
  }
2515
- // TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
2516
- // TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
2517
- // Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
2518
2624
 
2519
2625
  /**
2520
2626
  * Creates a deep clone of the given object
@@ -3078,8 +3184,7 @@ function hasTaskJokers(task) {
3078
3184
  * @private internal utility of `validatePipeline`
3079
3185
  */
3080
3186
  function validateTaskSupportsJokers(task, pipelineIdentification) {
3081
- if (task.format ||
3082
- task.expectations /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
3187
+ if (task.format || task.expectations /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
3083
3188
  return;
3084
3189
  }
3085
3190
  throw new PipelineLogicError(spaceTrim$1((block) => `
@@ -7147,9 +7252,7 @@ function createFailuresSummary($failedResults) {
7147
7252
  ${block(quoteMultilineText(((_b = failure.error) === null || _b === void 0 ? void 0 : _b.message) || ''))}
7148
7253
 
7149
7254
  Result:
7150
- ${block(failure.result === null
7151
- ? 'null'
7152
- : quoteMultilineText(spaceTrim$1(failure.result)))}
7255
+ ${block(failure.result === null ? 'null' : quoteMultilineText(spaceTrim$1(failure.result)))}
7153
7256
  `;
7154
7257
  }))
7155
7258
  .join('\n\n---\n\n');