@promptbook/utils 0.112.0-73 → 0.112.0-80
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.
- package/README.md +9 -9
- package/esm/index.es.js +310 -204
- package/esm/index.es.js.map +1 -1
- package/esm/src/avatars/types/AvatarVisualDefinition.d.ts +1 -1
- package/esm/src/avatars/visuals/octopus3d2AvatarVisual.d.ts +7 -0
- package/esm/src/avatars/visuals/octopus3dAvatarVisualShared.d.ts +37 -0
- package/esm/src/book-components/Chat/save/_common/chatExportRendering.d.ts +47 -0
- package/esm/src/book-components/Chat/save/html/htmlSaveFormatDefinition.d.ts +12 -0
- package/esm/src/book-components/Chat/save/index.d.ts +2 -2
- package/esm/src/book-components/Chat/save/markdown/mdSaveFormatDefinition.d.ts +5 -3
- package/esm/src/book-components/Chat/save/pdf/buildChatPdf.d.ts +3 -3
- package/esm/src/book-components/Chat/save/pdf/pdfSaveFormatDefinition.d.ts +1 -1
- package/esm/src/cli/cli-commands/agent/agentProjectPaths.d.ts +8 -8
- package/esm/src/cli/cli-commands/agent/initializeAgentRunnerCommand.d.ts +1 -1
- package/esm/src/cli/cli-commands/agents-server/buildAgentsServer.d.ts +56 -0
- package/esm/src/cli/cli-commands/agents-server/buildAgentsServer.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.d.ts +7 -0
- package/esm/src/cli/cli-commands/agents-server/ensureAgentsServerGitignoreFile.d.ts +7 -0
- package/esm/src/cli/cli-commands/agents-server/init.d.ts +9 -0
- package/esm/src/cli/cli-commands/agents-server/init.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/agents-server/initializeAgentsServerProjectConfiguration.d.ts +17 -0
- package/esm/src/cli/cli-commands/agents-server/printAgentsServerInitializationSummary.d.ts +7 -0
- package/esm/src/cli/cli-commands/agents-server/run.d.ts +14 -0
- package/esm/src/cli/cli-commands/agents-server/run.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/agents-server/startAgentsServer.d.ts +23 -0
- package/esm/src/cli/cli-commands/agents-server.d.ts +8 -0
- package/esm/src/cli/cli-commands/common/projectInitialization.d.ts +65 -0
- package/esm/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +44 -0
- package/esm/src/cli/common/$deprecateCliCommand.d.ts +8 -0
- package/esm/src/cli/common/$deprecateCliCommand.test.d.ts +1 -0
- package/esm/src/utils/color/Color.d.ts +4 -44
- package/esm/src/utils/color/ColorValue.d.ts +55 -0
- package/esm/src/utils/color/isHexColorString.d.ts +10 -0
- package/esm/src/utils/color/parseColorString.d.ts +11 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +310 -204
- package/umd/index.umd.js.map +1 -1
- package/umd/src/avatars/types/AvatarVisualDefinition.d.ts +1 -1
- package/umd/src/avatars/visuals/octopus3d2AvatarVisual.d.ts +7 -0
- package/umd/src/avatars/visuals/octopus3dAvatarVisualShared.d.ts +37 -0
- package/umd/src/book-components/Chat/save/_common/chatExportRendering.d.ts +47 -0
- package/umd/src/book-components/Chat/save/html/htmlSaveFormatDefinition.d.ts +12 -0
- package/umd/src/book-components/Chat/save/index.d.ts +2 -2
- package/umd/src/book-components/Chat/save/markdown/mdSaveFormatDefinition.d.ts +5 -3
- package/umd/src/book-components/Chat/save/pdf/buildChatPdf.d.ts +3 -3
- package/umd/src/book-components/Chat/save/pdf/pdfSaveFormatDefinition.d.ts +1 -1
- package/umd/src/cli/cli-commands/agent/agentProjectPaths.d.ts +8 -8
- package/umd/src/cli/cli-commands/agent/initializeAgentRunnerCommand.d.ts +1 -1
- package/umd/src/cli/cli-commands/agents-server/buildAgentsServer.d.ts +56 -0
- package/umd/src/cli/cli-commands/agents-server/buildAgentsServer.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.d.ts +7 -0
- package/umd/src/cli/cli-commands/agents-server/ensureAgentsServerGitignoreFile.d.ts +7 -0
- package/umd/src/cli/cli-commands/agents-server/init.d.ts +9 -0
- package/umd/src/cli/cli-commands/agents-server/init.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/agents-server/initializeAgentsServerProjectConfiguration.d.ts +17 -0
- package/umd/src/cli/cli-commands/agents-server/printAgentsServerInitializationSummary.d.ts +7 -0
- package/umd/src/cli/cli-commands/agents-server/run.d.ts +14 -0
- package/umd/src/cli/cli-commands/agents-server/run.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/agents-server/startAgentsServer.d.ts +23 -0
- package/umd/src/cli/cli-commands/agents-server.d.ts +8 -0
- package/umd/src/cli/cli-commands/common/projectInitialization.d.ts +65 -0
- package/umd/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +44 -0
- package/umd/src/cli/common/$deprecateCliCommand.d.ts +8 -0
- package/umd/src/cli/common/$deprecateCliCommand.test.d.ts +1 -0
- package/umd/src/utils/color/Color.d.ts +4 -44
- package/umd/src/utils/color/ColorValue.d.ts +55 -0
- package/umd/src/utils/color/isHexColorString.d.ts +10 -0
- package/umd/src/utils/color/parseColorString.d.ts +11 -0
- package/umd/src/version.d.ts +1 -1
- package/esm/src/cli/cli-commands/coder/appendBlock.d.ts +0 -6
- package/esm/src/cli/cli-commands/coder/readTextFileIfExists.d.ts +0 -6
- package/umd/src/cli/cli-commands/coder/appendBlock.d.ts +0 -6
- package/umd/src/cli/cli-commands/coder/readTextFileIfExists.d.ts +0 -6
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.112.0-
|
|
25
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-80';
|
|
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
|
|
@@ -272,6 +272,111 @@
|
|
|
272
272
|
}
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
+
/**
|
|
276
|
+
* Shared immutable channel storage and serialization helpers for `Color`.
|
|
277
|
+
*
|
|
278
|
+
* @private base class of Color
|
|
279
|
+
*/
|
|
280
|
+
class ColorValue {
|
|
281
|
+
constructor(red, green, blue, alpha = 255) {
|
|
282
|
+
this.red = red;
|
|
283
|
+
this.green = green;
|
|
284
|
+
this.blue = blue;
|
|
285
|
+
this.alpha = alpha;
|
|
286
|
+
checkChannelValue('Red', red);
|
|
287
|
+
checkChannelValue('Green', green);
|
|
288
|
+
checkChannelValue('Blue', blue);
|
|
289
|
+
checkChannelValue('Alpha', alpha);
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Shortcut for `red` property
|
|
293
|
+
* Number from 0 to 255
|
|
294
|
+
* @alias red
|
|
295
|
+
*/
|
|
296
|
+
get r() {
|
|
297
|
+
return this.red;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Shortcut for `green` property
|
|
301
|
+
* Number from 0 to 255
|
|
302
|
+
* @alias green
|
|
303
|
+
*/
|
|
304
|
+
get g() {
|
|
305
|
+
return this.green;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Shortcut for `blue` property
|
|
309
|
+
* Number from 0 to 255
|
|
310
|
+
* @alias blue
|
|
311
|
+
*/
|
|
312
|
+
get b() {
|
|
313
|
+
return this.blue;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Shortcut for `alpha` property
|
|
317
|
+
* Number from 0 (transparent) to 255 (opaque)
|
|
318
|
+
* @alias alpha
|
|
319
|
+
*/
|
|
320
|
+
get a() {
|
|
321
|
+
return this.alpha;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Shortcut for `alpha` property
|
|
325
|
+
* Number from 0 (transparent) to 255 (opaque)
|
|
326
|
+
* @alias alpha
|
|
327
|
+
*/
|
|
328
|
+
get opacity() {
|
|
329
|
+
return this.alpha;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Shortcut for 1-`alpha` property
|
|
333
|
+
*/
|
|
334
|
+
get transparency() {
|
|
335
|
+
return 255 - this.alpha;
|
|
336
|
+
}
|
|
337
|
+
clone() {
|
|
338
|
+
return take(this.createColor(this.red, this.green, this.blue, this.alpha));
|
|
339
|
+
}
|
|
340
|
+
toString() {
|
|
341
|
+
return this.toHex();
|
|
342
|
+
}
|
|
343
|
+
toHex() {
|
|
344
|
+
if (this.alpha === 255) {
|
|
345
|
+
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
346
|
+
.toString(16)
|
|
347
|
+
.padStart(2, '0')}`;
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
351
|
+
.toString(16)
|
|
352
|
+
.padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
toRgb() {
|
|
356
|
+
if (this.alpha === 255) {
|
|
357
|
+
return `rgb(${this.red}, ${this.green}, ${this.blue})`;
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
toHsl() {
|
|
364
|
+
throw new Error(`Getting HSL is not implemented`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Checks if the given value is a valid hex color string
|
|
370
|
+
*
|
|
371
|
+
* @param value - value to check
|
|
372
|
+
* @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
|
|
373
|
+
*
|
|
374
|
+
* @private function of Color
|
|
375
|
+
*/
|
|
376
|
+
function isHexColorString(value) {
|
|
377
|
+
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));
|
|
378
|
+
}
|
|
379
|
+
|
|
275
380
|
/**
|
|
276
381
|
* Constant for short hex lengths.
|
|
277
382
|
*/
|
|
@@ -483,16 +588,53 @@
|
|
|
483
588
|
|
|
484
589
|
/**
|
|
485
590
|
* Pattern matching hsl regex.
|
|
591
|
+
*
|
|
592
|
+
* @private function of Color
|
|
486
593
|
*/
|
|
487
594
|
const HSL_REGEX_PATTERN = /^hsl\(\s*([0-9.]+)\s*,\s*([0-9.]+)%\s*,\s*([0-9.]+)%\s*\)$/;
|
|
488
595
|
/**
|
|
489
596
|
* Pattern matching RGB regex.
|
|
597
|
+
*
|
|
598
|
+
* @private function of Color
|
|
490
599
|
*/
|
|
491
600
|
const RGB_REGEX_PATTERN = /^rgb\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/;
|
|
492
601
|
/**
|
|
493
602
|
* Pattern matching rgba regex.
|
|
603
|
+
*
|
|
604
|
+
* @private function of Color
|
|
494
605
|
*/
|
|
495
606
|
const RGBA_REGEX_PATTERN = /^rgba\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/;
|
|
607
|
+
/**
|
|
608
|
+
* Parses a supported color string into RGBA channels.
|
|
609
|
+
*
|
|
610
|
+
* @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`,...
|
|
611
|
+
* @returns RGBA channel values.
|
|
612
|
+
*
|
|
613
|
+
* @private function of Color
|
|
614
|
+
*/
|
|
615
|
+
function parseColorString(color) {
|
|
616
|
+
const trimmed = color.trim();
|
|
617
|
+
const cssColor = CSS_COLORS[trimmed];
|
|
618
|
+
if (cssColor) {
|
|
619
|
+
return parseColorString(cssColor);
|
|
620
|
+
}
|
|
621
|
+
else if (isHexColorString(trimmed)) {
|
|
622
|
+
return parseHexColor(trimmed);
|
|
623
|
+
}
|
|
624
|
+
if (HSL_REGEX_PATTERN.test(trimmed)) {
|
|
625
|
+
return parseHslColor(trimmed);
|
|
626
|
+
}
|
|
627
|
+
else if (RGB_REGEX_PATTERN.test(trimmed)) {
|
|
628
|
+
return parseRgbColor(trimmed);
|
|
629
|
+
}
|
|
630
|
+
else if (RGBA_REGEX_PATTERN.test(trimmed)) {
|
|
631
|
+
return parseRgbaColor(trimmed);
|
|
632
|
+
}
|
|
633
|
+
else {
|
|
634
|
+
throw new Error(`Can not create a new Color instance from string "${trimmed}".`);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
496
638
|
/**
|
|
497
639
|
* Color object represents an RGB color with alpha channel
|
|
498
640
|
*
|
|
@@ -500,7 +642,7 @@
|
|
|
500
642
|
*
|
|
501
643
|
* @public exported from `@promptbook/color`
|
|
502
644
|
*/
|
|
503
|
-
class Color {
|
|
645
|
+
class Color extends ColorValue {
|
|
504
646
|
/**
|
|
505
647
|
* Creates a new Color instance from miscellaneous formats
|
|
506
648
|
* - It can receive Color instance and just return the same instance
|
|
@@ -573,25 +715,7 @@
|
|
|
573
715
|
* @returns Color object
|
|
574
716
|
*/
|
|
575
717
|
static fromString(color) {
|
|
576
|
-
|
|
577
|
-
if (CSS_COLORS[trimmed]) {
|
|
578
|
-
return Color.fromString(CSS_COLORS[trimmed]);
|
|
579
|
-
}
|
|
580
|
-
else if (Color.isHexColorString(trimmed)) {
|
|
581
|
-
return Color.fromHex(trimmed);
|
|
582
|
-
}
|
|
583
|
-
if (HSL_REGEX_PATTERN.test(trimmed)) {
|
|
584
|
-
return Color.fromHsl(trimmed);
|
|
585
|
-
}
|
|
586
|
-
else if (RGB_REGEX_PATTERN.test(trimmed)) {
|
|
587
|
-
return Color.fromRgbString(trimmed);
|
|
588
|
-
}
|
|
589
|
-
else if (RGBA_REGEX_PATTERN.test(trimmed)) {
|
|
590
|
-
return Color.fromRgbaString(trimmed);
|
|
591
|
-
}
|
|
592
|
-
else {
|
|
593
|
-
throw new Error(`Can not create a new Color instance from string "${trimmed}".`);
|
|
594
|
-
}
|
|
718
|
+
return Color.fromColorChannels(parseColorString(color));
|
|
595
719
|
}
|
|
596
720
|
/**
|
|
597
721
|
* Gets common color
|
|
@@ -621,8 +745,7 @@
|
|
|
621
745
|
* @returns Color object
|
|
622
746
|
*/
|
|
623
747
|
static fromHex(hex) {
|
|
624
|
-
|
|
625
|
-
return take(new Color(red, green, blue, alpha));
|
|
748
|
+
return Color.fromColorChannels(parseHexColor(hex));
|
|
626
749
|
}
|
|
627
750
|
/**
|
|
628
751
|
* Creates a new Color instance from color in hsl format
|
|
@@ -631,8 +754,7 @@
|
|
|
631
754
|
* @returns Color object
|
|
632
755
|
*/
|
|
633
756
|
static fromHsl(hsl) {
|
|
634
|
-
|
|
635
|
-
return take(new Color(red, green, blue, alpha));
|
|
757
|
+
return Color.fromColorChannels(parseHslColor(hsl));
|
|
636
758
|
}
|
|
637
759
|
/**
|
|
638
760
|
* Creates a new Color instance from color in rgb format
|
|
@@ -641,8 +763,7 @@
|
|
|
641
763
|
* @returns Color object
|
|
642
764
|
*/
|
|
643
765
|
static fromRgbString(rgb) {
|
|
644
|
-
|
|
645
|
-
return take(new Color(red, green, blue, alpha));
|
|
766
|
+
return Color.fromColorChannels(parseRgbColor(rgb));
|
|
646
767
|
}
|
|
647
768
|
/**
|
|
648
769
|
* Creates a new Color instance from color in rbga format
|
|
@@ -651,8 +772,7 @@
|
|
|
651
772
|
* @returns Color object
|
|
652
773
|
*/
|
|
653
774
|
static fromRgbaString(rgba) {
|
|
654
|
-
|
|
655
|
-
return take(new Color(red, green, blue, alpha));
|
|
775
|
+
return Color.fromColorChannels(parseRgbaColor(rgba));
|
|
656
776
|
}
|
|
657
777
|
/**
|
|
658
778
|
* Creates a new Color for color channels values
|
|
@@ -664,7 +784,7 @@
|
|
|
664
784
|
* @returns Color object
|
|
665
785
|
*/
|
|
666
786
|
static fromValues(red, green, blue, alpha = 255) {
|
|
667
|
-
return
|
|
787
|
+
return Color.fromColorChannels({ red, green, blue, alpha });
|
|
668
788
|
}
|
|
669
789
|
/**
|
|
670
790
|
* Checks if the given value is a valid Color object.
|
|
@@ -697,8 +817,7 @@
|
|
|
697
817
|
* @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
|
|
698
818
|
*/
|
|
699
819
|
static isHexColorString(value) {
|
|
700
|
-
return (
|
|
701
|
-
/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value));
|
|
820
|
+
return isHexColorString(value);
|
|
702
821
|
}
|
|
703
822
|
/**
|
|
704
823
|
* Creates new Color object
|
|
@@ -711,89 +830,13 @@
|
|
|
711
830
|
* @param alpha number from 0 (transparent) to 255 (opaque)
|
|
712
831
|
*/
|
|
713
832
|
constructor(red, green, blue, alpha = 255) {
|
|
714
|
-
|
|
715
|
-
this.green = green;
|
|
716
|
-
this.blue = blue;
|
|
717
|
-
this.alpha = alpha;
|
|
718
|
-
checkChannelValue('Red', red);
|
|
719
|
-
checkChannelValue('Green', green);
|
|
720
|
-
checkChannelValue('Blue', blue);
|
|
721
|
-
checkChannelValue('Alpha', alpha);
|
|
722
|
-
}
|
|
723
|
-
/**
|
|
724
|
-
* Shortcut for `red` property
|
|
725
|
-
* Number from 0 to 255
|
|
726
|
-
* @alias red
|
|
727
|
-
*/
|
|
728
|
-
get r() {
|
|
729
|
-
return this.red;
|
|
730
|
-
}
|
|
731
|
-
/**
|
|
732
|
-
* Shortcut for `green` property
|
|
733
|
-
* Number from 0 to 255
|
|
734
|
-
* @alias green
|
|
735
|
-
*/
|
|
736
|
-
get g() {
|
|
737
|
-
return this.green;
|
|
738
|
-
}
|
|
739
|
-
/**
|
|
740
|
-
* Shortcut for `blue` property
|
|
741
|
-
* Number from 0 to 255
|
|
742
|
-
* @alias blue
|
|
743
|
-
*/
|
|
744
|
-
get b() {
|
|
745
|
-
return this.blue;
|
|
746
|
-
}
|
|
747
|
-
/**
|
|
748
|
-
* Shortcut for `alpha` property
|
|
749
|
-
* Number from 0 (transparent) to 255 (opaque)
|
|
750
|
-
* @alias alpha
|
|
751
|
-
*/
|
|
752
|
-
get a() {
|
|
753
|
-
return this.alpha;
|
|
833
|
+
super(red, green, blue, alpha);
|
|
754
834
|
}
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
* Number from 0 (transparent) to 255 (opaque)
|
|
758
|
-
* @alias alpha
|
|
759
|
-
*/
|
|
760
|
-
get opacity() {
|
|
761
|
-
return this.alpha;
|
|
835
|
+
createColor(red, green, blue, alpha) {
|
|
836
|
+
return new Color(red, green, blue, alpha);
|
|
762
837
|
}
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
*/
|
|
766
|
-
get transparency() {
|
|
767
|
-
return 255 - this.alpha;
|
|
768
|
-
}
|
|
769
|
-
clone() {
|
|
770
|
-
return take(new Color(this.red, this.green, this.blue, this.alpha));
|
|
771
|
-
}
|
|
772
|
-
toString() {
|
|
773
|
-
return this.toHex();
|
|
774
|
-
}
|
|
775
|
-
toHex() {
|
|
776
|
-
if (this.alpha === 255) {
|
|
777
|
-
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
778
|
-
.toString(16)
|
|
779
|
-
.padStart(2, '0')}`;
|
|
780
|
-
}
|
|
781
|
-
else {
|
|
782
|
-
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
783
|
-
.toString(16)
|
|
784
|
-
.padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
toRgb() {
|
|
788
|
-
if (this.alpha === 255) {
|
|
789
|
-
return `rgb(${this.red}, ${this.green}, ${this.blue})`;
|
|
790
|
-
}
|
|
791
|
-
else {
|
|
792
|
-
return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
toHsl() {
|
|
796
|
-
throw new Error(`Getting HSL is not implemented`);
|
|
838
|
+
static fromColorChannels({ red, green, blue, alpha }) {
|
|
839
|
+
return take(new Color(red, green, blue, alpha));
|
|
797
840
|
}
|
|
798
841
|
}
|
|
799
842
|
|
|
@@ -1293,120 +1336,183 @@
|
|
|
1293
1336
|
* @public exported from `@promptbook/utils`
|
|
1294
1337
|
*/
|
|
1295
1338
|
function checkSerializableAsJson(options) {
|
|
1296
|
-
|
|
1339
|
+
checkSerializableValue(options);
|
|
1340
|
+
}
|
|
1341
|
+
// TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
1342
|
+
// TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
1343
|
+
// Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
1344
|
+
/**
|
|
1345
|
+
* Checks one value and dispatches to the appropriate specialized validator.
|
|
1346
|
+
*
|
|
1347
|
+
* @private function of `checkSerializableAsJson`
|
|
1348
|
+
*/
|
|
1349
|
+
function checkSerializableValue(options) {
|
|
1350
|
+
const { value } = options;
|
|
1351
|
+
if (isSerializablePrimitive(value)) {
|
|
1352
|
+
return;
|
|
1353
|
+
}
|
|
1297
1354
|
if (value === undefined) {
|
|
1298
|
-
throw new UnexpectedError(`${name} is undefined`);
|
|
1355
|
+
throw new UnexpectedError(`${options.name} is undefined`);
|
|
1299
1356
|
}
|
|
1300
|
-
|
|
1301
|
-
|
|
1357
|
+
if (typeof value === 'symbol') {
|
|
1358
|
+
throw new UnexpectedError(`${options.name} is symbol`);
|
|
1302
1359
|
}
|
|
1303
|
-
|
|
1304
|
-
|
|
1360
|
+
if (typeof value === 'function') {
|
|
1361
|
+
throw new UnexpectedError(`${options.name} is function`);
|
|
1305
1362
|
}
|
|
1306
|
-
|
|
1363
|
+
if (Array.isArray(value)) {
|
|
1364
|
+
checkSerializableArray(options, value);
|
|
1307
1365
|
return;
|
|
1308
1366
|
}
|
|
1309
|
-
|
|
1367
|
+
if (value !== null && typeof value === 'object') {
|
|
1368
|
+
checkSerializableObject(options, value);
|
|
1310
1369
|
return;
|
|
1311
1370
|
}
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1371
|
+
throwUnknownTypeError(options);
|
|
1372
|
+
}
|
|
1373
|
+
/**
|
|
1374
|
+
* Checks the primitive values that are directly JSON serializable.
|
|
1375
|
+
*
|
|
1376
|
+
* @private function of `checkSerializableAsJson`
|
|
1377
|
+
*/
|
|
1378
|
+
function isSerializablePrimitive(value) {
|
|
1379
|
+
return (value === null ||
|
|
1380
|
+
typeof value === 'boolean' ||
|
|
1381
|
+
(typeof value === 'number' && !isNaN(value)) ||
|
|
1382
|
+
typeof value === 'string');
|
|
1383
|
+
}
|
|
1384
|
+
/**
|
|
1385
|
+
* Recursively checks JSON array items.
|
|
1386
|
+
*
|
|
1387
|
+
* @private function of `checkSerializableAsJson`
|
|
1388
|
+
*/
|
|
1389
|
+
function checkSerializableArray(context, arrayValue) {
|
|
1390
|
+
for (let index = 0; index < arrayValue.length; index++) {
|
|
1391
|
+
checkSerializableAsJson({
|
|
1392
|
+
...context,
|
|
1393
|
+
name: `${context.name}[${index}]`,
|
|
1394
|
+
value: arrayValue[index],
|
|
1395
|
+
});
|
|
1322
1396
|
}
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1397
|
+
}
|
|
1398
|
+
/**
|
|
1399
|
+
* Checks object-like values and dispatches special unsupported built-ins.
|
|
1400
|
+
*
|
|
1401
|
+
* @private function of `checkSerializableAsJson`
|
|
1402
|
+
*/
|
|
1403
|
+
function checkSerializableObject(context, objectValue) {
|
|
1404
|
+
checkUnsupportedObjectType(context, objectValue);
|
|
1405
|
+
checkSerializableObjectEntries(context, objectValue);
|
|
1406
|
+
assertJsonStringificationSucceeds(context, objectValue);
|
|
1407
|
+
}
|
|
1408
|
+
/**
|
|
1409
|
+
* Rejects built-in objects that must be converted before JSON serialization.
|
|
1410
|
+
*
|
|
1411
|
+
* @private function of `checkSerializableAsJson`
|
|
1412
|
+
*/
|
|
1413
|
+
function checkUnsupportedObjectType(context, objectValue) {
|
|
1414
|
+
if (objectValue instanceof Date) {
|
|
1415
|
+
throw new UnexpectedError(spacetrim.spaceTrim((block) => `
|
|
1416
|
+
\`${context.name}\` is Date
|
|
1327
1417
|
|
|
1328
|
-
|
|
1418
|
+
Use \`string_date_iso8601\` instead
|
|
1329
1419
|
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1420
|
+
Additional message for \`${context.name}\`:
|
|
1421
|
+
${block(context.message || '(nothing)')}
|
|
1422
|
+
`));
|
|
1423
|
+
}
|
|
1424
|
+
if (objectValue instanceof Map) {
|
|
1425
|
+
throw new UnexpectedError(`${context.name} is Map`);
|
|
1426
|
+
}
|
|
1427
|
+
if (objectValue instanceof Set) {
|
|
1428
|
+
throw new UnexpectedError(`${context.name} is Set`);
|
|
1429
|
+
}
|
|
1430
|
+
if (objectValue instanceof RegExp) {
|
|
1431
|
+
throw new UnexpectedError(`${context.name} is RegExp`);
|
|
1432
|
+
}
|
|
1433
|
+
if (objectValue instanceof Error) {
|
|
1434
|
+
throw new UnexpectedError(spacetrim.spaceTrim((block) => `
|
|
1435
|
+
\`${context.name}\` is unserialized Error
|
|
1346
1436
|
|
|
1347
|
-
|
|
1437
|
+
Use function \`serializeError\`
|
|
1348
1438
|
|
|
1349
|
-
|
|
1350
|
-
|
|
1439
|
+
Additional message for \`${context.name}\`:
|
|
1440
|
+
${block(context.message || '(nothing)')}
|
|
1351
1441
|
|
|
1352
|
-
|
|
1442
|
+
`));
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
/**
|
|
1446
|
+
* Recursively checks object properties while preserving omitted `undefined` keys.
|
|
1447
|
+
*
|
|
1448
|
+
* @private function of `checkSerializableAsJson`
|
|
1449
|
+
*/
|
|
1450
|
+
function checkSerializableObjectEntries(context, objectValue) {
|
|
1451
|
+
for (const [subName, subValue] of Object.entries(objectValue)) {
|
|
1452
|
+
if (subValue === undefined) {
|
|
1453
|
+
// Note: undefined in object is serializable - it is just omitted
|
|
1454
|
+
continue;
|
|
1353
1455
|
}
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1456
|
+
checkSerializableAsJson({
|
|
1457
|
+
...context,
|
|
1458
|
+
name: `${context.name}.${subName}`,
|
|
1459
|
+
value: subValue,
|
|
1460
|
+
});
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
/**
|
|
1464
|
+
* Uses `JSON.stringify` as the final guard for cases like circular references.
|
|
1465
|
+
*
|
|
1466
|
+
* @private function of `checkSerializableAsJson`
|
|
1467
|
+
*/
|
|
1468
|
+
function assertJsonStringificationSucceeds(context, objectValue) {
|
|
1469
|
+
try {
|
|
1470
|
+
JSON.stringify(objectValue); // <- TODO: [0]
|
|
1471
|
+
}
|
|
1472
|
+
catch (error) {
|
|
1473
|
+
assertsError(error);
|
|
1474
|
+
throw new UnexpectedError(spacetrim.spaceTrim((block) => `
|
|
1475
|
+
\`${context.name}\` is not serializable
|
|
1369
1476
|
|
|
1370
|
-
|
|
1477
|
+
${block(error.stack || error.message)}
|
|
1371
1478
|
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1479
|
+
Additional message for \`${context.name}\`:
|
|
1480
|
+
${block(context.message || '(nothing)')}
|
|
1481
|
+
`));
|
|
1482
|
+
}
|
|
1483
|
+
/*
|
|
1484
|
+
TODO: [0] Is there some more elegant way to check circular references?
|
|
1485
|
+
const seen = new Set();
|
|
1486
|
+
const stack = [{ value }];
|
|
1487
|
+
while (stack.length > 0) {
|
|
1488
|
+
const { value } = stack.pop()!;
|
|
1489
|
+
if (typeof value === 'object' && value !== null) {
|
|
1490
|
+
if (seen.has(value)) {
|
|
1491
|
+
throw new UnexpectedError(`${name} has circular reference`);
|
|
1375
1492
|
}
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
const { value } = stack.pop()!;
|
|
1382
|
-
if (typeof value === 'object' && value !== null) {
|
|
1383
|
-
if (seen.has(value)) {
|
|
1384
|
-
throw new UnexpectedError(`${name} has circular reference`);
|
|
1385
|
-
}
|
|
1386
|
-
seen.add(value);
|
|
1387
|
-
if (Array.isArray(value)) {
|
|
1388
|
-
stack.push(...value.map((value) => ({ value })));
|
|
1389
|
-
} else {
|
|
1390
|
-
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1493
|
+
seen.add(value);
|
|
1494
|
+
if (Array.isArray(value)) {
|
|
1495
|
+
stack.push(...value.map((value) => ({ value })));
|
|
1496
|
+
} else {
|
|
1497
|
+
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
1393
1498
|
}
|
|
1394
|
-
*/
|
|
1395
|
-
return;
|
|
1396
1499
|
}
|
|
1397
1500
|
}
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1501
|
+
*/
|
|
1502
|
+
}
|
|
1503
|
+
/**
|
|
1504
|
+
* Throws the fallback error for unsupported value types like `bigint` and `NaN`.
|
|
1505
|
+
*
|
|
1506
|
+
* @private function of `checkSerializableAsJson`
|
|
1507
|
+
*/
|
|
1508
|
+
function throwUnknownTypeError(context) {
|
|
1509
|
+
throw new UnexpectedError(spacetrim.spaceTrim((block) => `
|
|
1510
|
+
\`${context.name}\` is unknown type
|
|
1401
1511
|
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
}
|
|
1512
|
+
Additional message for \`${context.name}\`:
|
|
1513
|
+
${block(context.message || '(nothing)')}
|
|
1514
|
+
`));
|
|
1406
1515
|
}
|
|
1407
|
-
// TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
1408
|
-
// TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
1409
|
-
// Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
1410
1516
|
|
|
1411
1517
|
/**
|
|
1412
1518
|
* Creates a deep clone of the given object
|