@promptbook/remote-client 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.
- 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 +2 -2
- 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/README.md
CHANGED
|
@@ -455,28 +455,28 @@ npx ts-node ./src/cli/test/ptbk.ts coder verify
|
|
|
455
455
|
|
|
456
456
|
#### Using `ptbk coder` in an external project
|
|
457
457
|
|
|
458
|
-
If you want to use the workflow in another repository, install the package and invoke the `ptbk` binary.
|
|
458
|
+
If you want to use the workflow in another repository, install the package and invoke the `ptbk` binary directly.
|
|
459
459
|
|
|
460
460
|
```bash
|
|
461
461
|
npm install ptbk
|
|
462
462
|
|
|
463
463
|
ptbk coder init
|
|
464
464
|
|
|
465
|
-
|
|
465
|
+
ptbk coder generate-boilerplates
|
|
466
466
|
|
|
467
|
-
|
|
467
|
+
ptbk coder generate-boilerplates --template prompts/templates/common.md
|
|
468
468
|
|
|
469
|
-
|
|
469
|
+
ptbk coder run --agent github-copilot --model gpt-5.4 --thinking-level xhigh --context AGENTS.md --test npm run test
|
|
470
470
|
|
|
471
|
-
|
|
471
|
+
ptbk coder run --agent github-copilot --model gpt-5.4 --thinking-level xhigh --context AGENTS.md --auto-push
|
|
472
472
|
|
|
473
|
-
|
|
473
|
+
ptbk coder run --agent github-copilot --model gpt-5.4 --thinking-level xhigh --context AGENTS.md --test npm run test --ignore-git-changes --no-wait
|
|
474
474
|
|
|
475
|
-
|
|
475
|
+
ptbk coder find-refactor-candidates
|
|
476
476
|
|
|
477
|
-
|
|
477
|
+
ptbk coder find-refactor-candidates --level xhigh
|
|
478
478
|
|
|
479
|
-
|
|
479
|
+
ptbk coder verify
|
|
480
480
|
```
|
|
481
481
|
|
|
482
482
|
`ptbk coder init` also bootstraps a starter `AGENTS.md`, adds `package.json` scripts for the four main coder commands, adds the shared `/.promptbook` temp ignore to `.gitignore`, and configures `.vscode/settings.json` so pasted images from `prompts/*.md` land in `prompts/screenshots/`.
|
package/esm/index.es.js
CHANGED
|
@@ -20,7 +20,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
20
20
|
* @generated
|
|
21
21
|
* @see https://github.com/webgptorg/promptbook
|
|
22
22
|
*/
|
|
23
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
23
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-79';
|
|
24
24
|
/**
|
|
25
25
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
26
26
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -562,6 +562,111 @@ function checkChannelValue(channelName, value) {
|
|
|
562
562
|
}
|
|
563
563
|
}
|
|
564
564
|
|
|
565
|
+
/**
|
|
566
|
+
* Shared immutable channel storage and serialization helpers for `Color`.
|
|
567
|
+
*
|
|
568
|
+
* @private base class of Color
|
|
569
|
+
*/
|
|
570
|
+
class ColorValue {
|
|
571
|
+
constructor(red, green, blue, alpha = 255) {
|
|
572
|
+
this.red = red;
|
|
573
|
+
this.green = green;
|
|
574
|
+
this.blue = blue;
|
|
575
|
+
this.alpha = alpha;
|
|
576
|
+
checkChannelValue('Red', red);
|
|
577
|
+
checkChannelValue('Green', green);
|
|
578
|
+
checkChannelValue('Blue', blue);
|
|
579
|
+
checkChannelValue('Alpha', alpha);
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Shortcut for `red` property
|
|
583
|
+
* Number from 0 to 255
|
|
584
|
+
* @alias red
|
|
585
|
+
*/
|
|
586
|
+
get r() {
|
|
587
|
+
return this.red;
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Shortcut for `green` property
|
|
591
|
+
* Number from 0 to 255
|
|
592
|
+
* @alias green
|
|
593
|
+
*/
|
|
594
|
+
get g() {
|
|
595
|
+
return this.green;
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Shortcut for `blue` property
|
|
599
|
+
* Number from 0 to 255
|
|
600
|
+
* @alias blue
|
|
601
|
+
*/
|
|
602
|
+
get b() {
|
|
603
|
+
return this.blue;
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Shortcut for `alpha` property
|
|
607
|
+
* Number from 0 (transparent) to 255 (opaque)
|
|
608
|
+
* @alias alpha
|
|
609
|
+
*/
|
|
610
|
+
get a() {
|
|
611
|
+
return this.alpha;
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Shortcut for `alpha` property
|
|
615
|
+
* Number from 0 (transparent) to 255 (opaque)
|
|
616
|
+
* @alias alpha
|
|
617
|
+
*/
|
|
618
|
+
get opacity() {
|
|
619
|
+
return this.alpha;
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* Shortcut for 1-`alpha` property
|
|
623
|
+
*/
|
|
624
|
+
get transparency() {
|
|
625
|
+
return 255 - this.alpha;
|
|
626
|
+
}
|
|
627
|
+
clone() {
|
|
628
|
+
return take(this.createColor(this.red, this.green, this.blue, this.alpha));
|
|
629
|
+
}
|
|
630
|
+
toString() {
|
|
631
|
+
return this.toHex();
|
|
632
|
+
}
|
|
633
|
+
toHex() {
|
|
634
|
+
if (this.alpha === 255) {
|
|
635
|
+
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
636
|
+
.toString(16)
|
|
637
|
+
.padStart(2, '0')}`;
|
|
638
|
+
}
|
|
639
|
+
else {
|
|
640
|
+
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
641
|
+
.toString(16)
|
|
642
|
+
.padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
toRgb() {
|
|
646
|
+
if (this.alpha === 255) {
|
|
647
|
+
return `rgb(${this.red}, ${this.green}, ${this.blue})`;
|
|
648
|
+
}
|
|
649
|
+
else {
|
|
650
|
+
return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
toHsl() {
|
|
654
|
+
throw new Error(`Getting HSL is not implemented`);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* Checks if the given value is a valid hex color string
|
|
660
|
+
*
|
|
661
|
+
* @param value - value to check
|
|
662
|
+
* @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
|
|
663
|
+
*
|
|
664
|
+
* @private function of Color
|
|
665
|
+
*/
|
|
666
|
+
function isHexColorString(value) {
|
|
667
|
+
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));
|
|
668
|
+
}
|
|
669
|
+
|
|
565
670
|
/**
|
|
566
671
|
* Constant for short hex lengths.
|
|
567
672
|
*/
|
|
@@ -773,16 +878,53 @@ function parseAlphaValue(value) {
|
|
|
773
878
|
|
|
774
879
|
/**
|
|
775
880
|
* Pattern matching hsl regex.
|
|
881
|
+
*
|
|
882
|
+
* @private function of Color
|
|
776
883
|
*/
|
|
777
884
|
const HSL_REGEX_PATTERN = /^hsl\(\s*([0-9.]+)\s*,\s*([0-9.]+)%\s*,\s*([0-9.]+)%\s*\)$/;
|
|
778
885
|
/**
|
|
779
886
|
* Pattern matching RGB regex.
|
|
887
|
+
*
|
|
888
|
+
* @private function of Color
|
|
780
889
|
*/
|
|
781
890
|
const RGB_REGEX_PATTERN = /^rgb\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/;
|
|
782
891
|
/**
|
|
783
892
|
* Pattern matching rgba regex.
|
|
893
|
+
*
|
|
894
|
+
* @private function of Color
|
|
784
895
|
*/
|
|
785
896
|
const RGBA_REGEX_PATTERN = /^rgba\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/;
|
|
897
|
+
/**
|
|
898
|
+
* Parses a supported color string into RGBA channels.
|
|
899
|
+
*
|
|
900
|
+
* @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`,...
|
|
901
|
+
* @returns RGBA channel values.
|
|
902
|
+
*
|
|
903
|
+
* @private function of Color
|
|
904
|
+
*/
|
|
905
|
+
function parseColorString(color) {
|
|
906
|
+
const trimmed = color.trim();
|
|
907
|
+
const cssColor = CSS_COLORS[trimmed];
|
|
908
|
+
if (cssColor) {
|
|
909
|
+
return parseColorString(cssColor);
|
|
910
|
+
}
|
|
911
|
+
else if (isHexColorString(trimmed)) {
|
|
912
|
+
return parseHexColor(trimmed);
|
|
913
|
+
}
|
|
914
|
+
if (HSL_REGEX_PATTERN.test(trimmed)) {
|
|
915
|
+
return parseHslColor(trimmed);
|
|
916
|
+
}
|
|
917
|
+
else if (RGB_REGEX_PATTERN.test(trimmed)) {
|
|
918
|
+
return parseRgbColor(trimmed);
|
|
919
|
+
}
|
|
920
|
+
else if (RGBA_REGEX_PATTERN.test(trimmed)) {
|
|
921
|
+
return parseRgbaColor(trimmed);
|
|
922
|
+
}
|
|
923
|
+
else {
|
|
924
|
+
throw new Error(`Can not create a new Color instance from string "${trimmed}".`);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
|
|
786
928
|
/**
|
|
787
929
|
* Color object represents an RGB color with alpha channel
|
|
788
930
|
*
|
|
@@ -790,7 +932,7 @@ const RGBA_REGEX_PATTERN = /^rgba\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.
|
|
|
790
932
|
*
|
|
791
933
|
* @public exported from `@promptbook/color`
|
|
792
934
|
*/
|
|
793
|
-
class Color {
|
|
935
|
+
class Color extends ColorValue {
|
|
794
936
|
/**
|
|
795
937
|
* Creates a new Color instance from miscellaneous formats
|
|
796
938
|
* - It can receive Color instance and just return the same instance
|
|
@@ -863,25 +1005,7 @@ class Color {
|
|
|
863
1005
|
* @returns Color object
|
|
864
1006
|
*/
|
|
865
1007
|
static fromString(color) {
|
|
866
|
-
|
|
867
|
-
if (CSS_COLORS[trimmed]) {
|
|
868
|
-
return Color.fromString(CSS_COLORS[trimmed]);
|
|
869
|
-
}
|
|
870
|
-
else if (Color.isHexColorString(trimmed)) {
|
|
871
|
-
return Color.fromHex(trimmed);
|
|
872
|
-
}
|
|
873
|
-
if (HSL_REGEX_PATTERN.test(trimmed)) {
|
|
874
|
-
return Color.fromHsl(trimmed);
|
|
875
|
-
}
|
|
876
|
-
else if (RGB_REGEX_PATTERN.test(trimmed)) {
|
|
877
|
-
return Color.fromRgbString(trimmed);
|
|
878
|
-
}
|
|
879
|
-
else if (RGBA_REGEX_PATTERN.test(trimmed)) {
|
|
880
|
-
return Color.fromRgbaString(trimmed);
|
|
881
|
-
}
|
|
882
|
-
else {
|
|
883
|
-
throw new Error(`Can not create a new Color instance from string "${trimmed}".`);
|
|
884
|
-
}
|
|
1008
|
+
return Color.fromColorChannels(parseColorString(color));
|
|
885
1009
|
}
|
|
886
1010
|
/**
|
|
887
1011
|
* Gets common color
|
|
@@ -911,8 +1035,7 @@ class Color {
|
|
|
911
1035
|
* @returns Color object
|
|
912
1036
|
*/
|
|
913
1037
|
static fromHex(hex) {
|
|
914
|
-
|
|
915
|
-
return take(new Color(red, green, blue, alpha));
|
|
1038
|
+
return Color.fromColorChannels(parseHexColor(hex));
|
|
916
1039
|
}
|
|
917
1040
|
/**
|
|
918
1041
|
* Creates a new Color instance from color in hsl format
|
|
@@ -921,8 +1044,7 @@ class Color {
|
|
|
921
1044
|
* @returns Color object
|
|
922
1045
|
*/
|
|
923
1046
|
static fromHsl(hsl) {
|
|
924
|
-
|
|
925
|
-
return take(new Color(red, green, blue, alpha));
|
|
1047
|
+
return Color.fromColorChannels(parseHslColor(hsl));
|
|
926
1048
|
}
|
|
927
1049
|
/**
|
|
928
1050
|
* Creates a new Color instance from color in rgb format
|
|
@@ -931,8 +1053,7 @@ class Color {
|
|
|
931
1053
|
* @returns Color object
|
|
932
1054
|
*/
|
|
933
1055
|
static fromRgbString(rgb) {
|
|
934
|
-
|
|
935
|
-
return take(new Color(red, green, blue, alpha));
|
|
1056
|
+
return Color.fromColorChannels(parseRgbColor(rgb));
|
|
936
1057
|
}
|
|
937
1058
|
/**
|
|
938
1059
|
* Creates a new Color instance from color in rbga format
|
|
@@ -941,8 +1062,7 @@ class Color {
|
|
|
941
1062
|
* @returns Color object
|
|
942
1063
|
*/
|
|
943
1064
|
static fromRgbaString(rgba) {
|
|
944
|
-
|
|
945
|
-
return take(new Color(red, green, blue, alpha));
|
|
1065
|
+
return Color.fromColorChannels(parseRgbaColor(rgba));
|
|
946
1066
|
}
|
|
947
1067
|
/**
|
|
948
1068
|
* Creates a new Color for color channels values
|
|
@@ -954,7 +1074,7 @@ class Color {
|
|
|
954
1074
|
* @returns Color object
|
|
955
1075
|
*/
|
|
956
1076
|
static fromValues(red, green, blue, alpha = 255) {
|
|
957
|
-
return
|
|
1077
|
+
return Color.fromColorChannels({ red, green, blue, alpha });
|
|
958
1078
|
}
|
|
959
1079
|
/**
|
|
960
1080
|
* Checks if the given value is a valid Color object.
|
|
@@ -987,8 +1107,7 @@ class Color {
|
|
|
987
1107
|
* @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
|
|
988
1108
|
*/
|
|
989
1109
|
static isHexColorString(value) {
|
|
990
|
-
return (
|
|
991
|
-
/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value));
|
|
1110
|
+
return isHexColorString(value);
|
|
992
1111
|
}
|
|
993
1112
|
/**
|
|
994
1113
|
* Creates new Color object
|
|
@@ -1001,89 +1120,13 @@ class Color {
|
|
|
1001
1120
|
* @param alpha number from 0 (transparent) to 255 (opaque)
|
|
1002
1121
|
*/
|
|
1003
1122
|
constructor(red, green, blue, alpha = 255) {
|
|
1004
|
-
|
|
1005
|
-
this.green = green;
|
|
1006
|
-
this.blue = blue;
|
|
1007
|
-
this.alpha = alpha;
|
|
1008
|
-
checkChannelValue('Red', red);
|
|
1009
|
-
checkChannelValue('Green', green);
|
|
1010
|
-
checkChannelValue('Blue', blue);
|
|
1011
|
-
checkChannelValue('Alpha', alpha);
|
|
1012
|
-
}
|
|
1013
|
-
/**
|
|
1014
|
-
* Shortcut for `red` property
|
|
1015
|
-
* Number from 0 to 255
|
|
1016
|
-
* @alias red
|
|
1017
|
-
*/
|
|
1018
|
-
get r() {
|
|
1019
|
-
return this.red;
|
|
1020
|
-
}
|
|
1021
|
-
/**
|
|
1022
|
-
* Shortcut for `green` property
|
|
1023
|
-
* Number from 0 to 255
|
|
1024
|
-
* @alias green
|
|
1025
|
-
*/
|
|
1026
|
-
get g() {
|
|
1027
|
-
return this.green;
|
|
1028
|
-
}
|
|
1029
|
-
/**
|
|
1030
|
-
* Shortcut for `blue` property
|
|
1031
|
-
* Number from 0 to 255
|
|
1032
|
-
* @alias blue
|
|
1033
|
-
*/
|
|
1034
|
-
get b() {
|
|
1035
|
-
return this.blue;
|
|
1036
|
-
}
|
|
1037
|
-
/**
|
|
1038
|
-
* Shortcut for `alpha` property
|
|
1039
|
-
* Number from 0 (transparent) to 255 (opaque)
|
|
1040
|
-
* @alias alpha
|
|
1041
|
-
*/
|
|
1042
|
-
get a() {
|
|
1043
|
-
return this.alpha;
|
|
1123
|
+
super(red, green, blue, alpha);
|
|
1044
1124
|
}
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
* Number from 0 (transparent) to 255 (opaque)
|
|
1048
|
-
* @alias alpha
|
|
1049
|
-
*/
|
|
1050
|
-
get opacity() {
|
|
1051
|
-
return this.alpha;
|
|
1125
|
+
createColor(red, green, blue, alpha) {
|
|
1126
|
+
return new Color(red, green, blue, alpha);
|
|
1052
1127
|
}
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
*/
|
|
1056
|
-
get transparency() {
|
|
1057
|
-
return 255 - this.alpha;
|
|
1058
|
-
}
|
|
1059
|
-
clone() {
|
|
1060
|
-
return take(new Color(this.red, this.green, this.blue, this.alpha));
|
|
1061
|
-
}
|
|
1062
|
-
toString() {
|
|
1063
|
-
return this.toHex();
|
|
1064
|
-
}
|
|
1065
|
-
toHex() {
|
|
1066
|
-
if (this.alpha === 255) {
|
|
1067
|
-
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
1068
|
-
.toString(16)
|
|
1069
|
-
.padStart(2, '0')}`;
|
|
1070
|
-
}
|
|
1071
|
-
else {
|
|
1072
|
-
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
1073
|
-
.toString(16)
|
|
1074
|
-
.padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
toRgb() {
|
|
1078
|
-
if (this.alpha === 255) {
|
|
1079
|
-
return `rgb(${this.red}, ${this.green}, ${this.blue})`;
|
|
1080
|
-
}
|
|
1081
|
-
else {
|
|
1082
|
-
return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
toHsl() {
|
|
1086
|
-
throw new Error(`Getting HSL is not implemented`);
|
|
1128
|
+
static fromColorChannels({ red, green, blue, alpha }) {
|
|
1129
|
+
return take(new Color(red, green, blue, alpha));
|
|
1087
1130
|
}
|
|
1088
1131
|
}
|
|
1089
1132
|
|
|
@@ -2616,120 +2659,183 @@ function $deepFreeze(objectValue) {
|
|
|
2616
2659
|
* @public exported from `@promptbook/utils`
|
|
2617
2660
|
*/
|
|
2618
2661
|
function checkSerializableAsJson(options) {
|
|
2619
|
-
|
|
2662
|
+
checkSerializableValue(options);
|
|
2663
|
+
}
|
|
2664
|
+
// TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
2665
|
+
// TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
2666
|
+
// Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
2667
|
+
/**
|
|
2668
|
+
* Checks one value and dispatches to the appropriate specialized validator.
|
|
2669
|
+
*
|
|
2670
|
+
* @private function of `checkSerializableAsJson`
|
|
2671
|
+
*/
|
|
2672
|
+
function checkSerializableValue(options) {
|
|
2673
|
+
const { value } = options;
|
|
2674
|
+
if (isSerializablePrimitive(value)) {
|
|
2675
|
+
return;
|
|
2676
|
+
}
|
|
2620
2677
|
if (value === undefined) {
|
|
2621
|
-
throw new UnexpectedError(`${name} is undefined`);
|
|
2678
|
+
throw new UnexpectedError(`${options.name} is undefined`);
|
|
2622
2679
|
}
|
|
2623
|
-
|
|
2624
|
-
|
|
2680
|
+
if (typeof value === 'symbol') {
|
|
2681
|
+
throw new UnexpectedError(`${options.name} is symbol`);
|
|
2625
2682
|
}
|
|
2626
|
-
|
|
2627
|
-
|
|
2683
|
+
if (typeof value === 'function') {
|
|
2684
|
+
throw new UnexpectedError(`${options.name} is function`);
|
|
2628
2685
|
}
|
|
2629
|
-
|
|
2686
|
+
if (Array.isArray(value)) {
|
|
2687
|
+
checkSerializableArray(options, value);
|
|
2630
2688
|
return;
|
|
2631
2689
|
}
|
|
2632
|
-
|
|
2690
|
+
if (value !== null && typeof value === 'object') {
|
|
2691
|
+
checkSerializableObject(options, value);
|
|
2633
2692
|
return;
|
|
2634
2693
|
}
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2694
|
+
throwUnknownTypeError(options);
|
|
2695
|
+
}
|
|
2696
|
+
/**
|
|
2697
|
+
* Checks the primitive values that are directly JSON serializable.
|
|
2698
|
+
*
|
|
2699
|
+
* @private function of `checkSerializableAsJson`
|
|
2700
|
+
*/
|
|
2701
|
+
function isSerializablePrimitive(value) {
|
|
2702
|
+
return (value === null ||
|
|
2703
|
+
typeof value === 'boolean' ||
|
|
2704
|
+
(typeof value === 'number' && !isNaN(value)) ||
|
|
2705
|
+
typeof value === 'string');
|
|
2706
|
+
}
|
|
2707
|
+
/**
|
|
2708
|
+
* Recursively checks JSON array items.
|
|
2709
|
+
*
|
|
2710
|
+
* @private function of `checkSerializableAsJson`
|
|
2711
|
+
*/
|
|
2712
|
+
function checkSerializableArray(context, arrayValue) {
|
|
2713
|
+
for (let index = 0; index < arrayValue.length; index++) {
|
|
2714
|
+
checkSerializableAsJson({
|
|
2715
|
+
...context,
|
|
2716
|
+
name: `${context.name}[${index}]`,
|
|
2717
|
+
value: arrayValue[index],
|
|
2718
|
+
});
|
|
2645
2719
|
}
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2720
|
+
}
|
|
2721
|
+
/**
|
|
2722
|
+
* Checks object-like values and dispatches special unsupported built-ins.
|
|
2723
|
+
*
|
|
2724
|
+
* @private function of `checkSerializableAsJson`
|
|
2725
|
+
*/
|
|
2726
|
+
function checkSerializableObject(context, objectValue) {
|
|
2727
|
+
checkUnsupportedObjectType(context, objectValue);
|
|
2728
|
+
checkSerializableObjectEntries(context, objectValue);
|
|
2729
|
+
assertJsonStringificationSucceeds(context, objectValue);
|
|
2730
|
+
}
|
|
2731
|
+
/**
|
|
2732
|
+
* Rejects built-in objects that must be converted before JSON serialization.
|
|
2733
|
+
*
|
|
2734
|
+
* @private function of `checkSerializableAsJson`
|
|
2735
|
+
*/
|
|
2736
|
+
function checkUnsupportedObjectType(context, objectValue) {
|
|
2737
|
+
if (objectValue instanceof Date) {
|
|
2738
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
2739
|
+
\`${context.name}\` is Date
|
|
2650
2740
|
|
|
2651
|
-
|
|
2741
|
+
Use \`string_date_iso8601\` instead
|
|
2652
2742
|
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2743
|
+
Additional message for \`${context.name}\`:
|
|
2744
|
+
${block(context.message || '(nothing)')}
|
|
2745
|
+
`));
|
|
2746
|
+
}
|
|
2747
|
+
if (objectValue instanceof Map) {
|
|
2748
|
+
throw new UnexpectedError(`${context.name} is Map`);
|
|
2749
|
+
}
|
|
2750
|
+
if (objectValue instanceof Set) {
|
|
2751
|
+
throw new UnexpectedError(`${context.name} is Set`);
|
|
2752
|
+
}
|
|
2753
|
+
if (objectValue instanceof RegExp) {
|
|
2754
|
+
throw new UnexpectedError(`${context.name} is RegExp`);
|
|
2755
|
+
}
|
|
2756
|
+
if (objectValue instanceof Error) {
|
|
2757
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
2758
|
+
\`${context.name}\` is unserialized Error
|
|
2669
2759
|
|
|
2670
|
-
|
|
2760
|
+
Use function \`serializeError\`
|
|
2671
2761
|
|
|
2672
|
-
|
|
2673
|
-
|
|
2762
|
+
Additional message for \`${context.name}\`:
|
|
2763
|
+
${block(context.message || '(nothing)')}
|
|
2674
2764
|
|
|
2675
|
-
|
|
2765
|
+
`));
|
|
2766
|
+
}
|
|
2767
|
+
}
|
|
2768
|
+
/**
|
|
2769
|
+
* Recursively checks object properties while preserving omitted `undefined` keys.
|
|
2770
|
+
*
|
|
2771
|
+
* @private function of `checkSerializableAsJson`
|
|
2772
|
+
*/
|
|
2773
|
+
function checkSerializableObjectEntries(context, objectValue) {
|
|
2774
|
+
for (const [subName, subValue] of Object.entries(objectValue)) {
|
|
2775
|
+
if (subValue === undefined) {
|
|
2776
|
+
// Note: undefined in object is serializable - it is just omitted
|
|
2777
|
+
continue;
|
|
2676
2778
|
}
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2779
|
+
checkSerializableAsJson({
|
|
2780
|
+
...context,
|
|
2781
|
+
name: `${context.name}.${subName}`,
|
|
2782
|
+
value: subValue,
|
|
2783
|
+
});
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2786
|
+
/**
|
|
2787
|
+
* Uses `JSON.stringify` as the final guard for cases like circular references.
|
|
2788
|
+
*
|
|
2789
|
+
* @private function of `checkSerializableAsJson`
|
|
2790
|
+
*/
|
|
2791
|
+
function assertJsonStringificationSucceeds(context, objectValue) {
|
|
2792
|
+
try {
|
|
2793
|
+
JSON.stringify(objectValue); // <- TODO: [0]
|
|
2794
|
+
}
|
|
2795
|
+
catch (error) {
|
|
2796
|
+
assertsError(error);
|
|
2797
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
2798
|
+
\`${context.name}\` is not serializable
|
|
2692
2799
|
|
|
2693
|
-
|
|
2800
|
+
${block(error.stack || error.message)}
|
|
2694
2801
|
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2802
|
+
Additional message for \`${context.name}\`:
|
|
2803
|
+
${block(context.message || '(nothing)')}
|
|
2804
|
+
`));
|
|
2805
|
+
}
|
|
2806
|
+
/*
|
|
2807
|
+
TODO: [0] Is there some more elegant way to check circular references?
|
|
2808
|
+
const seen = new Set();
|
|
2809
|
+
const stack = [{ value }];
|
|
2810
|
+
while (stack.length > 0) {
|
|
2811
|
+
const { value } = stack.pop()!;
|
|
2812
|
+
if (typeof value === 'object' && value !== null) {
|
|
2813
|
+
if (seen.has(value)) {
|
|
2814
|
+
throw new UnexpectedError(`${name} has circular reference`);
|
|
2698
2815
|
}
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
const { value } = stack.pop()!;
|
|
2705
|
-
if (typeof value === 'object' && value !== null) {
|
|
2706
|
-
if (seen.has(value)) {
|
|
2707
|
-
throw new UnexpectedError(`${name} has circular reference`);
|
|
2708
|
-
}
|
|
2709
|
-
seen.add(value);
|
|
2710
|
-
if (Array.isArray(value)) {
|
|
2711
|
-
stack.push(...value.map((value) => ({ value })));
|
|
2712
|
-
} else {
|
|
2713
|
-
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
2714
|
-
}
|
|
2715
|
-
}
|
|
2816
|
+
seen.add(value);
|
|
2817
|
+
if (Array.isArray(value)) {
|
|
2818
|
+
stack.push(...value.map((value) => ({ value })));
|
|
2819
|
+
} else {
|
|
2820
|
+
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
2716
2821
|
}
|
|
2717
|
-
*/
|
|
2718
|
-
return;
|
|
2719
2822
|
}
|
|
2720
2823
|
}
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2824
|
+
*/
|
|
2825
|
+
}
|
|
2826
|
+
/**
|
|
2827
|
+
* Throws the fallback error for unsupported value types like `bigint` and `NaN`.
|
|
2828
|
+
*
|
|
2829
|
+
* @private function of `checkSerializableAsJson`
|
|
2830
|
+
*/
|
|
2831
|
+
function throwUnknownTypeError(context) {
|
|
2832
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
2833
|
+
\`${context.name}\` is unknown type
|
|
2724
2834
|
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
}
|
|
2835
|
+
Additional message for \`${context.name}\`:
|
|
2836
|
+
${block(context.message || '(nothing)')}
|
|
2837
|
+
`));
|
|
2729
2838
|
}
|
|
2730
|
-
// TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
2731
|
-
// TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
2732
|
-
// Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
2733
2839
|
|
|
2734
2840
|
/**
|
|
2735
2841
|
* Creates a deep clone of the given object
|