@promptbook/markitdown 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/umd/index.umd.js CHANGED
@@ -23,7 +23,7 @@
23
23
  * @generated
24
24
  * @see https://github.com/webgptorg/promptbook
25
25
  */
26
- const PROMPTBOOK_ENGINE_VERSION = '0.112.0-73';
26
+ const PROMPTBOOK_ENGINE_VERSION = '0.112.0-79';
27
27
  /**
28
28
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
29
29
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -291,6 +291,111 @@
291
291
  }
292
292
  }
293
293
 
294
+ /**
295
+ * Shared immutable channel storage and serialization helpers for `Color`.
296
+ *
297
+ * @private base class of Color
298
+ */
299
+ class ColorValue {
300
+ constructor(red, green, blue, alpha = 255) {
301
+ this.red = red;
302
+ this.green = green;
303
+ this.blue = blue;
304
+ this.alpha = alpha;
305
+ checkChannelValue('Red', red);
306
+ checkChannelValue('Green', green);
307
+ checkChannelValue('Blue', blue);
308
+ checkChannelValue('Alpha', alpha);
309
+ }
310
+ /**
311
+ * Shortcut for `red` property
312
+ * Number from 0 to 255
313
+ * @alias red
314
+ */
315
+ get r() {
316
+ return this.red;
317
+ }
318
+ /**
319
+ * Shortcut for `green` property
320
+ * Number from 0 to 255
321
+ * @alias green
322
+ */
323
+ get g() {
324
+ return this.green;
325
+ }
326
+ /**
327
+ * Shortcut for `blue` property
328
+ * Number from 0 to 255
329
+ * @alias blue
330
+ */
331
+ get b() {
332
+ return this.blue;
333
+ }
334
+ /**
335
+ * Shortcut for `alpha` property
336
+ * Number from 0 (transparent) to 255 (opaque)
337
+ * @alias alpha
338
+ */
339
+ get a() {
340
+ return this.alpha;
341
+ }
342
+ /**
343
+ * Shortcut for `alpha` property
344
+ * Number from 0 (transparent) to 255 (opaque)
345
+ * @alias alpha
346
+ */
347
+ get opacity() {
348
+ return this.alpha;
349
+ }
350
+ /**
351
+ * Shortcut for 1-`alpha` property
352
+ */
353
+ get transparency() {
354
+ return 255 - this.alpha;
355
+ }
356
+ clone() {
357
+ return take(this.createColor(this.red, this.green, this.blue, this.alpha));
358
+ }
359
+ toString() {
360
+ return this.toHex();
361
+ }
362
+ toHex() {
363
+ if (this.alpha === 255) {
364
+ return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
365
+ .toString(16)
366
+ .padStart(2, '0')}`;
367
+ }
368
+ else {
369
+ return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
370
+ .toString(16)
371
+ .padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
372
+ }
373
+ }
374
+ toRgb() {
375
+ if (this.alpha === 255) {
376
+ return `rgb(${this.red}, ${this.green}, ${this.blue})`;
377
+ }
378
+ else {
379
+ return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
380
+ }
381
+ }
382
+ toHsl() {
383
+ throw new Error(`Getting HSL is not implemented`);
384
+ }
385
+ }
386
+
387
+ /**
388
+ * Checks if the given value is a valid hex color string
389
+ *
390
+ * @param value - value to check
391
+ * @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
392
+ *
393
+ * @private function of Color
394
+ */
395
+ function isHexColorString(value) {
396
+ 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));
397
+ }
398
+
294
399
  /**
295
400
  * Constant for short hex lengths.
296
401
  */
@@ -502,16 +607,53 @@
502
607
 
503
608
  /**
504
609
  * Pattern matching hsl regex.
610
+ *
611
+ * @private function of Color
505
612
  */
506
613
  const HSL_REGEX_PATTERN = /^hsl\(\s*([0-9.]+)\s*,\s*([0-9.]+)%\s*,\s*([0-9.]+)%\s*\)$/;
507
614
  /**
508
615
  * Pattern matching RGB regex.
616
+ *
617
+ * @private function of Color
509
618
  */
510
619
  const RGB_REGEX_PATTERN = /^rgb\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/;
511
620
  /**
512
621
  * Pattern matching rgba regex.
622
+ *
623
+ * @private function of Color
513
624
  */
514
625
  const RGBA_REGEX_PATTERN = /^rgba\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/;
626
+ /**
627
+ * Parses a supported color string into RGBA channels.
628
+ *
629
+ * @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`,...
630
+ * @returns RGBA channel values.
631
+ *
632
+ * @private function of Color
633
+ */
634
+ function parseColorString(color) {
635
+ const trimmed = color.trim();
636
+ const cssColor = CSS_COLORS[trimmed];
637
+ if (cssColor) {
638
+ return parseColorString(cssColor);
639
+ }
640
+ else if (isHexColorString(trimmed)) {
641
+ return parseHexColor(trimmed);
642
+ }
643
+ if (HSL_REGEX_PATTERN.test(trimmed)) {
644
+ return parseHslColor(trimmed);
645
+ }
646
+ else if (RGB_REGEX_PATTERN.test(trimmed)) {
647
+ return parseRgbColor(trimmed);
648
+ }
649
+ else if (RGBA_REGEX_PATTERN.test(trimmed)) {
650
+ return parseRgbaColor(trimmed);
651
+ }
652
+ else {
653
+ throw new Error(`Can not create a new Color instance from string "${trimmed}".`);
654
+ }
655
+ }
656
+
515
657
  /**
516
658
  * Color object represents an RGB color with alpha channel
517
659
  *
@@ -519,7 +661,7 @@
519
661
  *
520
662
  * @public exported from `@promptbook/color`
521
663
  */
522
- class Color {
664
+ class Color extends ColorValue {
523
665
  /**
524
666
  * Creates a new Color instance from miscellaneous formats
525
667
  * - It can receive Color instance and just return the same instance
@@ -592,25 +734,7 @@
592
734
  * @returns Color object
593
735
  */
594
736
  static fromString(color) {
595
- const trimmed = color.trim();
596
- if (CSS_COLORS[trimmed]) {
597
- return Color.fromString(CSS_COLORS[trimmed]);
598
- }
599
- else if (Color.isHexColorString(trimmed)) {
600
- return Color.fromHex(trimmed);
601
- }
602
- if (HSL_REGEX_PATTERN.test(trimmed)) {
603
- return Color.fromHsl(trimmed);
604
- }
605
- else if (RGB_REGEX_PATTERN.test(trimmed)) {
606
- return Color.fromRgbString(trimmed);
607
- }
608
- else if (RGBA_REGEX_PATTERN.test(trimmed)) {
609
- return Color.fromRgbaString(trimmed);
610
- }
611
- else {
612
- throw new Error(`Can not create a new Color instance from string "${trimmed}".`);
613
- }
737
+ return Color.fromColorChannels(parseColorString(color));
614
738
  }
615
739
  /**
616
740
  * Gets common color
@@ -640,8 +764,7 @@
640
764
  * @returns Color object
641
765
  */
642
766
  static fromHex(hex) {
643
- const { red, green, blue, alpha } = parseHexColor(hex);
644
- return take(new Color(red, green, blue, alpha));
767
+ return Color.fromColorChannels(parseHexColor(hex));
645
768
  }
646
769
  /**
647
770
  * Creates a new Color instance from color in hsl format
@@ -650,8 +773,7 @@
650
773
  * @returns Color object
651
774
  */
652
775
  static fromHsl(hsl) {
653
- const { red, green, blue, alpha } = parseHslColor(hsl);
654
- return take(new Color(red, green, blue, alpha));
776
+ return Color.fromColorChannels(parseHslColor(hsl));
655
777
  }
656
778
  /**
657
779
  * Creates a new Color instance from color in rgb format
@@ -660,8 +782,7 @@
660
782
  * @returns Color object
661
783
  */
662
784
  static fromRgbString(rgb) {
663
- const { red, green, blue, alpha } = parseRgbColor(rgb);
664
- return take(new Color(red, green, blue, alpha));
785
+ return Color.fromColorChannels(parseRgbColor(rgb));
665
786
  }
666
787
  /**
667
788
  * Creates a new Color instance from color in rbga format
@@ -670,8 +791,7 @@
670
791
  * @returns Color object
671
792
  */
672
793
  static fromRgbaString(rgba) {
673
- const { red, green, blue, alpha } = parseRgbaColor(rgba);
674
- return take(new Color(red, green, blue, alpha));
794
+ return Color.fromColorChannels(parseRgbaColor(rgba));
675
795
  }
676
796
  /**
677
797
  * Creates a new Color for color channels values
@@ -683,7 +803,7 @@
683
803
  * @returns Color object
684
804
  */
685
805
  static fromValues(red, green, blue, alpha = 255) {
686
- return take(new Color(red, green, blue, alpha));
806
+ return Color.fromColorChannels({ red, green, blue, alpha });
687
807
  }
688
808
  /**
689
809
  * Checks if the given value is a valid Color object.
@@ -716,8 +836,7 @@
716
836
  * @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
717
837
  */
718
838
  static isHexColorString(value) {
719
- return (typeof value === 'string' &&
720
- /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value));
839
+ return isHexColorString(value);
721
840
  }
722
841
  /**
723
842
  * Creates new Color object
@@ -730,89 +849,13 @@
730
849
  * @param alpha number from 0 (transparent) to 255 (opaque)
731
850
  */
732
851
  constructor(red, green, blue, alpha = 255) {
733
- this.red = red;
734
- this.green = green;
735
- this.blue = blue;
736
- this.alpha = alpha;
737
- checkChannelValue('Red', red);
738
- checkChannelValue('Green', green);
739
- checkChannelValue('Blue', blue);
740
- checkChannelValue('Alpha', alpha);
852
+ super(red, green, blue, alpha);
741
853
  }
742
- /**
743
- * Shortcut for `red` property
744
- * Number from 0 to 255
745
- * @alias red
746
- */
747
- get r() {
748
- return this.red;
854
+ createColor(red, green, blue, alpha) {
855
+ return new Color(red, green, blue, alpha);
749
856
  }
750
- /**
751
- * Shortcut for `green` property
752
- * Number from 0 to 255
753
- * @alias green
754
- */
755
- get g() {
756
- return this.green;
757
- }
758
- /**
759
- * Shortcut for `blue` property
760
- * Number from 0 to 255
761
- * @alias blue
762
- */
763
- get b() {
764
- return this.blue;
765
- }
766
- /**
767
- * Shortcut for `alpha` property
768
- * Number from 0 (transparent) to 255 (opaque)
769
- * @alias alpha
770
- */
771
- get a() {
772
- return this.alpha;
773
- }
774
- /**
775
- * Shortcut for `alpha` property
776
- * Number from 0 (transparent) to 255 (opaque)
777
- * @alias alpha
778
- */
779
- get opacity() {
780
- return this.alpha;
781
- }
782
- /**
783
- * Shortcut for 1-`alpha` property
784
- */
785
- get transparency() {
786
- return 255 - this.alpha;
787
- }
788
- clone() {
789
- return take(new Color(this.red, this.green, this.blue, this.alpha));
790
- }
791
- toString() {
792
- return this.toHex();
793
- }
794
- toHex() {
795
- if (this.alpha === 255) {
796
- return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
797
- .toString(16)
798
- .padStart(2, '0')}`;
799
- }
800
- else {
801
- return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
802
- .toString(16)
803
- .padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
804
- }
805
- }
806
- toRgb() {
807
- if (this.alpha === 255) {
808
- return `rgb(${this.red}, ${this.green}, ${this.blue})`;
809
- }
810
- else {
811
- return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
812
- }
813
- }
814
- toHsl() {
815
- throw new Error(`Getting HSL is not implemented`);
857
+ static fromColorChannels({ red, green, blue, alpha }) {
858
+ return take(new Color(red, green, blue, alpha));
816
859
  }
817
860
  }
818
861
 
@@ -2221,7 +2264,7 @@
2221
2264
  */
2222
2265
  function createPostprocessingCommands(task) {
2223
2266
  var _a;
2224
- return ((_a = task.postprocessingFunctionNames) === null || _a === void 0 ? void 0 : _a.map((postprocessingFunctionName) => `POSTPROCESSING \`${postprocessingFunctionName}\``)) || [];
2267
+ return (((_a = task.postprocessingFunctionNames) === null || _a === void 0 ? void 0 : _a.map((postprocessingFunctionName) => `POSTPROCESSING \`${postprocessingFunctionName}\``)) || []);
2225
2268
  }
2226
2269
  /**
2227
2270
  * Collects expectation commands.
@@ -2386,120 +2429,183 @@
2386
2429
  * @public exported from `@promptbook/utils`
2387
2430
  */
2388
2431
  function checkSerializableAsJson(options) {
2389
- const { value, name, message } = options;
2432
+ checkSerializableValue(options);
2433
+ }
2434
+ // TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
2435
+ // TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
2436
+ // Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
2437
+ /**
2438
+ * Checks one value and dispatches to the appropriate specialized validator.
2439
+ *
2440
+ * @private function of `checkSerializableAsJson`
2441
+ */
2442
+ function checkSerializableValue(options) {
2443
+ const { value } = options;
2444
+ if (isSerializablePrimitive(value)) {
2445
+ return;
2446
+ }
2390
2447
  if (value === undefined) {
2391
- throw new UnexpectedError(`${name} is undefined`);
2448
+ throw new UnexpectedError(`${options.name} is undefined`);
2392
2449
  }
2393
- else if (value === null) {
2394
- return;
2450
+ if (typeof value === 'symbol') {
2451
+ throw new UnexpectedError(`${options.name} is symbol`);
2395
2452
  }
2396
- else if (typeof value === 'boolean') {
2397
- return;
2453
+ if (typeof value === 'function') {
2454
+ throw new UnexpectedError(`${options.name} is function`);
2398
2455
  }
2399
- else if (typeof value === 'number' && !isNaN(value)) {
2456
+ if (Array.isArray(value)) {
2457
+ checkSerializableArray(options, value);
2400
2458
  return;
2401
2459
  }
2402
- else if (typeof value === 'string') {
2460
+ if (value !== null && typeof value === 'object') {
2461
+ checkSerializableObject(options, value);
2403
2462
  return;
2404
2463
  }
2405
- else if (typeof value === 'symbol') {
2406
- throw new UnexpectedError(`${name} is symbol`);
2407
- }
2408
- else if (typeof value === 'function') {
2409
- throw new UnexpectedError(`${name} is function`);
2410
- }
2411
- else if (typeof value === 'object' && Array.isArray(value)) {
2412
- for (let i = 0; i < value.length; i++) {
2413
- checkSerializableAsJson({ name: `${name}[${i}]`, value: value[i], message });
2414
- }
2464
+ throwUnknownTypeError(options);
2465
+ }
2466
+ /**
2467
+ * Checks the primitive values that are directly JSON serializable.
2468
+ *
2469
+ * @private function of `checkSerializableAsJson`
2470
+ */
2471
+ function isSerializablePrimitive(value) {
2472
+ return (value === null ||
2473
+ typeof value === 'boolean' ||
2474
+ (typeof value === 'number' && !isNaN(value)) ||
2475
+ typeof value === 'string');
2476
+ }
2477
+ /**
2478
+ * Recursively checks JSON array items.
2479
+ *
2480
+ * @private function of `checkSerializableAsJson`
2481
+ */
2482
+ function checkSerializableArray(context, arrayValue) {
2483
+ for (let index = 0; index < arrayValue.length; index++) {
2484
+ checkSerializableAsJson({
2485
+ ...context,
2486
+ name: `${context.name}[${index}]`,
2487
+ value: arrayValue[index],
2488
+ });
2415
2489
  }
2416
- else if (typeof value === 'object') {
2417
- if (value instanceof Date) {
2418
- throw new UnexpectedError(spacetrim.spaceTrim((block) => `
2419
- \`${name}\` is Date
2490
+ }
2491
+ /**
2492
+ * Checks object-like values and dispatches special unsupported built-ins.
2493
+ *
2494
+ * @private function of `checkSerializableAsJson`
2495
+ */
2496
+ function checkSerializableObject(context, objectValue) {
2497
+ checkUnsupportedObjectType(context, objectValue);
2498
+ checkSerializableObjectEntries(context, objectValue);
2499
+ assertJsonStringificationSucceeds(context, objectValue);
2500
+ }
2501
+ /**
2502
+ * Rejects built-in objects that must be converted before JSON serialization.
2503
+ *
2504
+ * @private function of `checkSerializableAsJson`
2505
+ */
2506
+ function checkUnsupportedObjectType(context, objectValue) {
2507
+ if (objectValue instanceof Date) {
2508
+ throw new UnexpectedError(spacetrim.spaceTrim((block) => `
2509
+ \`${context.name}\` is Date
2420
2510
 
2421
- Use \`string_date_iso8601\` instead
2511
+ Use \`string_date_iso8601\` instead
2422
2512
 
2423
- Additional message for \`${name}\`:
2424
- ${block(message || '(nothing)')}
2425
- `));
2426
- }
2427
- else if (value instanceof Map) {
2428
- throw new UnexpectedError(`${name} is Map`);
2429
- }
2430
- else if (value instanceof Set) {
2431
- throw new UnexpectedError(`${name} is Set`);
2432
- }
2433
- else if (value instanceof RegExp) {
2434
- throw new UnexpectedError(`${name} is RegExp`);
2435
- }
2436
- else if (value instanceof Error) {
2437
- throw new UnexpectedError(spacetrim.spaceTrim((block) => `
2438
- \`${name}\` is unserialized Error
2513
+ Additional message for \`${context.name}\`:
2514
+ ${block(context.message || '(nothing)')}
2515
+ `));
2516
+ }
2517
+ if (objectValue instanceof Map) {
2518
+ throw new UnexpectedError(`${context.name} is Map`);
2519
+ }
2520
+ if (objectValue instanceof Set) {
2521
+ throw new UnexpectedError(`${context.name} is Set`);
2522
+ }
2523
+ if (objectValue instanceof RegExp) {
2524
+ throw new UnexpectedError(`${context.name} is RegExp`);
2525
+ }
2526
+ if (objectValue instanceof Error) {
2527
+ throw new UnexpectedError(spacetrim.spaceTrim((block) => `
2528
+ \`${context.name}\` is unserialized Error
2439
2529
 
2440
- Use function \`serializeError\`
2530
+ Use function \`serializeError\`
2441
2531
 
2442
- Additional message for \`${name}\`:
2443
- ${block(message || '(nothing)')}
2532
+ Additional message for \`${context.name}\`:
2533
+ ${block(context.message || '(nothing)')}
2444
2534
 
2445
- `));
2535
+ `));
2536
+ }
2537
+ }
2538
+ /**
2539
+ * Recursively checks object properties while preserving omitted `undefined` keys.
2540
+ *
2541
+ * @private function of `checkSerializableAsJson`
2542
+ */
2543
+ function checkSerializableObjectEntries(context, objectValue) {
2544
+ for (const [subName, subValue] of Object.entries(objectValue)) {
2545
+ if (subValue === undefined) {
2546
+ // Note: undefined in object is serializable - it is just omitted
2547
+ continue;
2446
2548
  }
2447
- else {
2448
- for (const [subName, subValue] of Object.entries(value)) {
2449
- if (subValue === undefined) {
2450
- // Note: undefined in object is serializable - it is just omitted
2451
- continue;
2452
- }
2453
- checkSerializableAsJson({ name: `${name}.${subName}`, value: subValue, message });
2454
- }
2455
- try {
2456
- JSON.stringify(value); // <- TODO: [0]
2457
- }
2458
- catch (error) {
2459
- assertsError(error);
2460
- throw new UnexpectedError(spacetrim.spaceTrim((block) => `
2461
- \`${name}\` is not serializable
2549
+ checkSerializableAsJson({
2550
+ ...context,
2551
+ name: `${context.name}.${subName}`,
2552
+ value: subValue,
2553
+ });
2554
+ }
2555
+ }
2556
+ /**
2557
+ * Uses `JSON.stringify` as the final guard for cases like circular references.
2558
+ *
2559
+ * @private function of `checkSerializableAsJson`
2560
+ */
2561
+ function assertJsonStringificationSucceeds(context, objectValue) {
2562
+ try {
2563
+ JSON.stringify(objectValue); // <- TODO: [0]
2564
+ }
2565
+ catch (error) {
2566
+ assertsError(error);
2567
+ throw new UnexpectedError(spacetrim.spaceTrim((block) => `
2568
+ \`${context.name}\` is not serializable
2462
2569
 
2463
- ${block(error.stack || error.message)}
2570
+ ${block(error.stack || error.message)}
2464
2571
 
2465
- Additional message for \`${name}\`:
2466
- ${block(message || '(nothing)')}
2467
- `));
2572
+ Additional message for \`${context.name}\`:
2573
+ ${block(context.message || '(nothing)')}
2574
+ `));
2575
+ }
2576
+ /*
2577
+ TODO: [0] Is there some more elegant way to check circular references?
2578
+ const seen = new Set();
2579
+ const stack = [{ value }];
2580
+ while (stack.length > 0) {
2581
+ const { value } = stack.pop()!;
2582
+ if (typeof value === 'object' && value !== null) {
2583
+ if (seen.has(value)) {
2584
+ throw new UnexpectedError(`${name} has circular reference`);
2468
2585
  }
2469
- /*
2470
- TODO: [0] Is there some more elegant way to check circular references?
2471
- const seen = new Set();
2472
- const stack = [{ value }];
2473
- while (stack.length > 0) {
2474
- const { value } = stack.pop()!;
2475
- if (typeof value === 'object' && value !== null) {
2476
- if (seen.has(value)) {
2477
- throw new UnexpectedError(`${name} has circular reference`);
2478
- }
2479
- seen.add(value);
2480
- if (Array.isArray(value)) {
2481
- stack.push(...value.map((value) => ({ value })));
2482
- } else {
2483
- stack.push(...Object.values(value).map((value) => ({ value })));
2484
- }
2485
- }
2586
+ seen.add(value);
2587
+ if (Array.isArray(value)) {
2588
+ stack.push(...value.map((value) => ({ value })));
2589
+ } else {
2590
+ stack.push(...Object.values(value).map((value) => ({ value })));
2486
2591
  }
2487
- */
2488
- return;
2489
2592
  }
2490
2593
  }
2491
- else {
2492
- throw new UnexpectedError(spacetrim.spaceTrim((block) => `
2493
- \`${name}\` is unknown type
2594
+ */
2595
+ }
2596
+ /**
2597
+ * Throws the fallback error for unsupported value types like `bigint` and `NaN`.
2598
+ *
2599
+ * @private function of `checkSerializableAsJson`
2600
+ */
2601
+ function throwUnknownTypeError(context) {
2602
+ throw new UnexpectedError(spacetrim.spaceTrim((block) => `
2603
+ \`${context.name}\` is unknown type
2494
2604
 
2495
- Additional message for \`${name}\`:
2496
- ${block(message || '(nothing)')}
2497
- `));
2498
- }
2605
+ Additional message for \`${context.name}\`:
2606
+ ${block(context.message || '(nothing)')}
2607
+ `));
2499
2608
  }
2500
- // TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
2501
- // TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
2502
- // Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
2503
2609
 
2504
2610
  /**
2505
2611
  * Creates a deep clone of the given object
@@ -3063,8 +3169,7 @@
3063
3169
  * @private internal utility of `validatePipeline`
3064
3170
  */
3065
3171
  function validateTaskSupportsJokers(task, pipelineIdentification) {
3066
- if (task.format ||
3067
- task.expectations /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
3172
+ if (task.format || task.expectations /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
3068
3173
  return;
3069
3174
  }
3070
3175
  throw new PipelineLogicError(spacetrim.spaceTrim((block) => `
@@ -7132,9 +7237,7 @@
7132
7237
  ${block(quoteMultilineText(((_b = failure.error) === null || _b === void 0 ? void 0 : _b.message) || ''))}
7133
7238
 
7134
7239
  Result:
7135
- ${block(failure.result === null
7136
- ? 'null'
7137
- : quoteMultilineText(spacetrim.spaceTrim(failure.result)))}
7240
+ ${block(failure.result === null ? 'null' : quoteMultilineText(spacetrim.spaceTrim(failure.result)))}
7138
7241
  `;
7139
7242
  }))
7140
7243
  .join('\n\n---\n\n');