@promptbook/vercel 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
|
@@ -515,28 +515,28 @@ npx ts-node ./src/cli/test/ptbk.ts coder verify
|
|
|
515
515
|
|
|
516
516
|
#### Using `ptbk coder` in an external project
|
|
517
517
|
|
|
518
|
-
If you want to use the workflow in another repository, install the package and invoke the `ptbk` binary.
|
|
518
|
+
If you want to use the workflow in another repository, install the package and invoke the `ptbk` binary directly.
|
|
519
519
|
|
|
520
520
|
```bash
|
|
521
521
|
npm install ptbk
|
|
522
522
|
|
|
523
523
|
ptbk coder init
|
|
524
524
|
|
|
525
|
-
|
|
525
|
+
ptbk coder generate-boilerplates
|
|
526
526
|
|
|
527
|
-
|
|
527
|
+
ptbk coder generate-boilerplates --template prompts/templates/common.md
|
|
528
528
|
|
|
529
|
-
|
|
529
|
+
ptbk coder run --agent github-copilot --model gpt-5.4 --thinking-level xhigh --context AGENTS.md --test npm run test
|
|
530
530
|
|
|
531
|
-
|
|
531
|
+
ptbk coder run --agent github-copilot --model gpt-5.4 --thinking-level xhigh --context AGENTS.md --auto-push
|
|
532
532
|
|
|
533
|
-
|
|
533
|
+
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
|
|
534
534
|
|
|
535
|
-
|
|
535
|
+
ptbk coder find-refactor-candidates
|
|
536
536
|
|
|
537
|
-
|
|
537
|
+
ptbk coder find-refactor-candidates --level xhigh
|
|
538
538
|
|
|
539
|
-
|
|
539
|
+
ptbk coder verify
|
|
540
540
|
```
|
|
541
541
|
|
|
542
542
|
`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
|
@@ -16,7 +16,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
16
16
|
* @generated
|
|
17
17
|
* @see https://github.com/webgptorg/promptbook
|
|
18
18
|
*/
|
|
19
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
19
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-79';
|
|
20
20
|
/**
|
|
21
21
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
22
22
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -818,6 +818,111 @@ function checkChannelValue(channelName, value) {
|
|
|
818
818
|
}
|
|
819
819
|
}
|
|
820
820
|
|
|
821
|
+
/**
|
|
822
|
+
* Shared immutable channel storage and serialization helpers for `Color`.
|
|
823
|
+
*
|
|
824
|
+
* @private base class of Color
|
|
825
|
+
*/
|
|
826
|
+
class ColorValue {
|
|
827
|
+
constructor(red, green, blue, alpha = 255) {
|
|
828
|
+
this.red = red;
|
|
829
|
+
this.green = green;
|
|
830
|
+
this.blue = blue;
|
|
831
|
+
this.alpha = alpha;
|
|
832
|
+
checkChannelValue('Red', red);
|
|
833
|
+
checkChannelValue('Green', green);
|
|
834
|
+
checkChannelValue('Blue', blue);
|
|
835
|
+
checkChannelValue('Alpha', alpha);
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* Shortcut for `red` property
|
|
839
|
+
* Number from 0 to 255
|
|
840
|
+
* @alias red
|
|
841
|
+
*/
|
|
842
|
+
get r() {
|
|
843
|
+
return this.red;
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* Shortcut for `green` property
|
|
847
|
+
* Number from 0 to 255
|
|
848
|
+
* @alias green
|
|
849
|
+
*/
|
|
850
|
+
get g() {
|
|
851
|
+
return this.green;
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* Shortcut for `blue` property
|
|
855
|
+
* Number from 0 to 255
|
|
856
|
+
* @alias blue
|
|
857
|
+
*/
|
|
858
|
+
get b() {
|
|
859
|
+
return this.blue;
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Shortcut for `alpha` property
|
|
863
|
+
* Number from 0 (transparent) to 255 (opaque)
|
|
864
|
+
* @alias alpha
|
|
865
|
+
*/
|
|
866
|
+
get a() {
|
|
867
|
+
return this.alpha;
|
|
868
|
+
}
|
|
869
|
+
/**
|
|
870
|
+
* Shortcut for `alpha` property
|
|
871
|
+
* Number from 0 (transparent) to 255 (opaque)
|
|
872
|
+
* @alias alpha
|
|
873
|
+
*/
|
|
874
|
+
get opacity() {
|
|
875
|
+
return this.alpha;
|
|
876
|
+
}
|
|
877
|
+
/**
|
|
878
|
+
* Shortcut for 1-`alpha` property
|
|
879
|
+
*/
|
|
880
|
+
get transparency() {
|
|
881
|
+
return 255 - this.alpha;
|
|
882
|
+
}
|
|
883
|
+
clone() {
|
|
884
|
+
return take(this.createColor(this.red, this.green, this.blue, this.alpha));
|
|
885
|
+
}
|
|
886
|
+
toString() {
|
|
887
|
+
return this.toHex();
|
|
888
|
+
}
|
|
889
|
+
toHex() {
|
|
890
|
+
if (this.alpha === 255) {
|
|
891
|
+
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
892
|
+
.toString(16)
|
|
893
|
+
.padStart(2, '0')}`;
|
|
894
|
+
}
|
|
895
|
+
else {
|
|
896
|
+
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
897
|
+
.toString(16)
|
|
898
|
+
.padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
toRgb() {
|
|
902
|
+
if (this.alpha === 255) {
|
|
903
|
+
return `rgb(${this.red}, ${this.green}, ${this.blue})`;
|
|
904
|
+
}
|
|
905
|
+
else {
|
|
906
|
+
return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
toHsl() {
|
|
910
|
+
throw new Error(`Getting HSL is not implemented`);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
/**
|
|
915
|
+
* Checks if the given value is a valid hex color string
|
|
916
|
+
*
|
|
917
|
+
* @param value - value to check
|
|
918
|
+
* @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
|
|
919
|
+
*
|
|
920
|
+
* @private function of Color
|
|
921
|
+
*/
|
|
922
|
+
function isHexColorString(value) {
|
|
923
|
+
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));
|
|
924
|
+
}
|
|
925
|
+
|
|
821
926
|
/**
|
|
822
927
|
* Constant for short hex lengths.
|
|
823
928
|
*/
|
|
@@ -1029,16 +1134,53 @@ function parseAlphaValue(value) {
|
|
|
1029
1134
|
|
|
1030
1135
|
/**
|
|
1031
1136
|
* Pattern matching hsl regex.
|
|
1137
|
+
*
|
|
1138
|
+
* @private function of Color
|
|
1032
1139
|
*/
|
|
1033
1140
|
const HSL_REGEX_PATTERN = /^hsl\(\s*([0-9.]+)\s*,\s*([0-9.]+)%\s*,\s*([0-9.]+)%\s*\)$/;
|
|
1034
1141
|
/**
|
|
1035
1142
|
* Pattern matching RGB regex.
|
|
1143
|
+
*
|
|
1144
|
+
* @private function of Color
|
|
1036
1145
|
*/
|
|
1037
1146
|
const RGB_REGEX_PATTERN = /^rgb\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/;
|
|
1038
1147
|
/**
|
|
1039
1148
|
* Pattern matching rgba regex.
|
|
1149
|
+
*
|
|
1150
|
+
* @private function of Color
|
|
1040
1151
|
*/
|
|
1041
1152
|
const RGBA_REGEX_PATTERN = /^rgba\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/;
|
|
1153
|
+
/**
|
|
1154
|
+
* Parses a supported color string into RGBA channels.
|
|
1155
|
+
*
|
|
1156
|
+
* @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`,...
|
|
1157
|
+
* @returns RGBA channel values.
|
|
1158
|
+
*
|
|
1159
|
+
* @private function of Color
|
|
1160
|
+
*/
|
|
1161
|
+
function parseColorString(color) {
|
|
1162
|
+
const trimmed = color.trim();
|
|
1163
|
+
const cssColor = CSS_COLORS[trimmed];
|
|
1164
|
+
if (cssColor) {
|
|
1165
|
+
return parseColorString(cssColor);
|
|
1166
|
+
}
|
|
1167
|
+
else if (isHexColorString(trimmed)) {
|
|
1168
|
+
return parseHexColor(trimmed);
|
|
1169
|
+
}
|
|
1170
|
+
if (HSL_REGEX_PATTERN.test(trimmed)) {
|
|
1171
|
+
return parseHslColor(trimmed);
|
|
1172
|
+
}
|
|
1173
|
+
else if (RGB_REGEX_PATTERN.test(trimmed)) {
|
|
1174
|
+
return parseRgbColor(trimmed);
|
|
1175
|
+
}
|
|
1176
|
+
else if (RGBA_REGEX_PATTERN.test(trimmed)) {
|
|
1177
|
+
return parseRgbaColor(trimmed);
|
|
1178
|
+
}
|
|
1179
|
+
else {
|
|
1180
|
+
throw new Error(`Can not create a new Color instance from string "${trimmed}".`);
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1042
1184
|
/**
|
|
1043
1185
|
* Color object represents an RGB color with alpha channel
|
|
1044
1186
|
*
|
|
@@ -1046,7 +1188,7 @@ const RGBA_REGEX_PATTERN = /^rgba\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.
|
|
|
1046
1188
|
*
|
|
1047
1189
|
* @public exported from `@promptbook/color`
|
|
1048
1190
|
*/
|
|
1049
|
-
class Color {
|
|
1191
|
+
class Color extends ColorValue {
|
|
1050
1192
|
/**
|
|
1051
1193
|
* Creates a new Color instance from miscellaneous formats
|
|
1052
1194
|
* - It can receive Color instance and just return the same instance
|
|
@@ -1119,25 +1261,7 @@ class Color {
|
|
|
1119
1261
|
* @returns Color object
|
|
1120
1262
|
*/
|
|
1121
1263
|
static fromString(color) {
|
|
1122
|
-
|
|
1123
|
-
if (CSS_COLORS[trimmed]) {
|
|
1124
|
-
return Color.fromString(CSS_COLORS[trimmed]);
|
|
1125
|
-
}
|
|
1126
|
-
else if (Color.isHexColorString(trimmed)) {
|
|
1127
|
-
return Color.fromHex(trimmed);
|
|
1128
|
-
}
|
|
1129
|
-
if (HSL_REGEX_PATTERN.test(trimmed)) {
|
|
1130
|
-
return Color.fromHsl(trimmed);
|
|
1131
|
-
}
|
|
1132
|
-
else if (RGB_REGEX_PATTERN.test(trimmed)) {
|
|
1133
|
-
return Color.fromRgbString(trimmed);
|
|
1134
|
-
}
|
|
1135
|
-
else if (RGBA_REGEX_PATTERN.test(trimmed)) {
|
|
1136
|
-
return Color.fromRgbaString(trimmed);
|
|
1137
|
-
}
|
|
1138
|
-
else {
|
|
1139
|
-
throw new Error(`Can not create a new Color instance from string "${trimmed}".`);
|
|
1140
|
-
}
|
|
1264
|
+
return Color.fromColorChannels(parseColorString(color));
|
|
1141
1265
|
}
|
|
1142
1266
|
/**
|
|
1143
1267
|
* Gets common color
|
|
@@ -1167,8 +1291,7 @@ class Color {
|
|
|
1167
1291
|
* @returns Color object
|
|
1168
1292
|
*/
|
|
1169
1293
|
static fromHex(hex) {
|
|
1170
|
-
|
|
1171
|
-
return take(new Color(red, green, blue, alpha));
|
|
1294
|
+
return Color.fromColorChannels(parseHexColor(hex));
|
|
1172
1295
|
}
|
|
1173
1296
|
/**
|
|
1174
1297
|
* Creates a new Color instance from color in hsl format
|
|
@@ -1177,8 +1300,7 @@ class Color {
|
|
|
1177
1300
|
* @returns Color object
|
|
1178
1301
|
*/
|
|
1179
1302
|
static fromHsl(hsl) {
|
|
1180
|
-
|
|
1181
|
-
return take(new Color(red, green, blue, alpha));
|
|
1303
|
+
return Color.fromColorChannels(parseHslColor(hsl));
|
|
1182
1304
|
}
|
|
1183
1305
|
/**
|
|
1184
1306
|
* Creates a new Color instance from color in rgb format
|
|
@@ -1187,8 +1309,7 @@ class Color {
|
|
|
1187
1309
|
* @returns Color object
|
|
1188
1310
|
*/
|
|
1189
1311
|
static fromRgbString(rgb) {
|
|
1190
|
-
|
|
1191
|
-
return take(new Color(red, green, blue, alpha));
|
|
1312
|
+
return Color.fromColorChannels(parseRgbColor(rgb));
|
|
1192
1313
|
}
|
|
1193
1314
|
/**
|
|
1194
1315
|
* Creates a new Color instance from color in rbga format
|
|
@@ -1197,8 +1318,7 @@ class Color {
|
|
|
1197
1318
|
* @returns Color object
|
|
1198
1319
|
*/
|
|
1199
1320
|
static fromRgbaString(rgba) {
|
|
1200
|
-
|
|
1201
|
-
return take(new Color(red, green, blue, alpha));
|
|
1321
|
+
return Color.fromColorChannels(parseRgbaColor(rgba));
|
|
1202
1322
|
}
|
|
1203
1323
|
/**
|
|
1204
1324
|
* Creates a new Color for color channels values
|
|
@@ -1210,7 +1330,7 @@ class Color {
|
|
|
1210
1330
|
* @returns Color object
|
|
1211
1331
|
*/
|
|
1212
1332
|
static fromValues(red, green, blue, alpha = 255) {
|
|
1213
|
-
return
|
|
1333
|
+
return Color.fromColorChannels({ red, green, blue, alpha });
|
|
1214
1334
|
}
|
|
1215
1335
|
/**
|
|
1216
1336
|
* Checks if the given value is a valid Color object.
|
|
@@ -1243,8 +1363,7 @@ class Color {
|
|
|
1243
1363
|
* @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
|
|
1244
1364
|
*/
|
|
1245
1365
|
static isHexColorString(value) {
|
|
1246
|
-
return (
|
|
1247
|
-
/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value));
|
|
1366
|
+
return isHexColorString(value);
|
|
1248
1367
|
}
|
|
1249
1368
|
/**
|
|
1250
1369
|
* Creates new Color object
|
|
@@ -1257,89 +1376,13 @@ class Color {
|
|
|
1257
1376
|
* @param alpha number from 0 (transparent) to 255 (opaque)
|
|
1258
1377
|
*/
|
|
1259
1378
|
constructor(red, green, blue, alpha = 255) {
|
|
1260
|
-
|
|
1261
|
-
this.green = green;
|
|
1262
|
-
this.blue = blue;
|
|
1263
|
-
this.alpha = alpha;
|
|
1264
|
-
checkChannelValue('Red', red);
|
|
1265
|
-
checkChannelValue('Green', green);
|
|
1266
|
-
checkChannelValue('Blue', blue);
|
|
1267
|
-
checkChannelValue('Alpha', alpha);
|
|
1379
|
+
super(red, green, blue, alpha);
|
|
1268
1380
|
}
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
* Number from 0 to 255
|
|
1272
|
-
* @alias red
|
|
1273
|
-
*/
|
|
1274
|
-
get r() {
|
|
1275
|
-
return this.red;
|
|
1381
|
+
createColor(red, green, blue, alpha) {
|
|
1382
|
+
return new Color(red, green, blue, alpha);
|
|
1276
1383
|
}
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
* Number from 0 to 255
|
|
1280
|
-
* @alias green
|
|
1281
|
-
*/
|
|
1282
|
-
get g() {
|
|
1283
|
-
return this.green;
|
|
1284
|
-
}
|
|
1285
|
-
/**
|
|
1286
|
-
* Shortcut for `blue` property
|
|
1287
|
-
* Number from 0 to 255
|
|
1288
|
-
* @alias blue
|
|
1289
|
-
*/
|
|
1290
|
-
get b() {
|
|
1291
|
-
return this.blue;
|
|
1292
|
-
}
|
|
1293
|
-
/**
|
|
1294
|
-
* Shortcut for `alpha` property
|
|
1295
|
-
* Number from 0 (transparent) to 255 (opaque)
|
|
1296
|
-
* @alias alpha
|
|
1297
|
-
*/
|
|
1298
|
-
get a() {
|
|
1299
|
-
return this.alpha;
|
|
1300
|
-
}
|
|
1301
|
-
/**
|
|
1302
|
-
* Shortcut for `alpha` property
|
|
1303
|
-
* Number from 0 (transparent) to 255 (opaque)
|
|
1304
|
-
* @alias alpha
|
|
1305
|
-
*/
|
|
1306
|
-
get opacity() {
|
|
1307
|
-
return this.alpha;
|
|
1308
|
-
}
|
|
1309
|
-
/**
|
|
1310
|
-
* Shortcut for 1-`alpha` property
|
|
1311
|
-
*/
|
|
1312
|
-
get transparency() {
|
|
1313
|
-
return 255 - this.alpha;
|
|
1314
|
-
}
|
|
1315
|
-
clone() {
|
|
1316
|
-
return take(new Color(this.red, this.green, this.blue, this.alpha));
|
|
1317
|
-
}
|
|
1318
|
-
toString() {
|
|
1319
|
-
return this.toHex();
|
|
1320
|
-
}
|
|
1321
|
-
toHex() {
|
|
1322
|
-
if (this.alpha === 255) {
|
|
1323
|
-
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
1324
|
-
.toString(16)
|
|
1325
|
-
.padStart(2, '0')}`;
|
|
1326
|
-
}
|
|
1327
|
-
else {
|
|
1328
|
-
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
1329
|
-
.toString(16)
|
|
1330
|
-
.padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
|
|
1331
|
-
}
|
|
1332
|
-
}
|
|
1333
|
-
toRgb() {
|
|
1334
|
-
if (this.alpha === 255) {
|
|
1335
|
-
return `rgb(${this.red}, ${this.green}, ${this.blue})`;
|
|
1336
|
-
}
|
|
1337
|
-
else {
|
|
1338
|
-
return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
|
|
1339
|
-
}
|
|
1340
|
-
}
|
|
1341
|
-
toHsl() {
|
|
1342
|
-
throw new Error(`Getting HSL is not implemented`);
|
|
1384
|
+
static fromColorChannels({ red, green, blue, alpha }) {
|
|
1385
|
+
return take(new Color(red, green, blue, alpha));
|
|
1343
1386
|
}
|
|
1344
1387
|
}
|
|
1345
1388
|
|
|
@@ -1813,120 +1856,183 @@ function assertsError(whatWasThrown) {
|
|
|
1813
1856
|
* @public exported from `@promptbook/utils`
|
|
1814
1857
|
*/
|
|
1815
1858
|
function checkSerializableAsJson(options) {
|
|
1816
|
-
|
|
1859
|
+
checkSerializableValue(options);
|
|
1860
|
+
}
|
|
1861
|
+
// TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
1862
|
+
// TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
1863
|
+
// Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
1864
|
+
/**
|
|
1865
|
+
* Checks one value and dispatches to the appropriate specialized validator.
|
|
1866
|
+
*
|
|
1867
|
+
* @private function of `checkSerializableAsJson`
|
|
1868
|
+
*/
|
|
1869
|
+
function checkSerializableValue(options) {
|
|
1870
|
+
const { value } = options;
|
|
1871
|
+
if (isSerializablePrimitive(value)) {
|
|
1872
|
+
return;
|
|
1873
|
+
}
|
|
1817
1874
|
if (value === undefined) {
|
|
1818
|
-
throw new UnexpectedError(`${name} is undefined`);
|
|
1875
|
+
throw new UnexpectedError(`${options.name} is undefined`);
|
|
1819
1876
|
}
|
|
1820
|
-
|
|
1821
|
-
|
|
1877
|
+
if (typeof value === 'symbol') {
|
|
1878
|
+
throw new UnexpectedError(`${options.name} is symbol`);
|
|
1822
1879
|
}
|
|
1823
|
-
|
|
1824
|
-
|
|
1880
|
+
if (typeof value === 'function') {
|
|
1881
|
+
throw new UnexpectedError(`${options.name} is function`);
|
|
1825
1882
|
}
|
|
1826
|
-
|
|
1883
|
+
if (Array.isArray(value)) {
|
|
1884
|
+
checkSerializableArray(options, value);
|
|
1827
1885
|
return;
|
|
1828
1886
|
}
|
|
1829
|
-
|
|
1887
|
+
if (value !== null && typeof value === 'object') {
|
|
1888
|
+
checkSerializableObject(options, value);
|
|
1830
1889
|
return;
|
|
1831
1890
|
}
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1891
|
+
throwUnknownTypeError(options);
|
|
1892
|
+
}
|
|
1893
|
+
/**
|
|
1894
|
+
* Checks the primitive values that are directly JSON serializable.
|
|
1895
|
+
*
|
|
1896
|
+
* @private function of `checkSerializableAsJson`
|
|
1897
|
+
*/
|
|
1898
|
+
function isSerializablePrimitive(value) {
|
|
1899
|
+
return (value === null ||
|
|
1900
|
+
typeof value === 'boolean' ||
|
|
1901
|
+
(typeof value === 'number' && !isNaN(value)) ||
|
|
1902
|
+
typeof value === 'string');
|
|
1903
|
+
}
|
|
1904
|
+
/**
|
|
1905
|
+
* Recursively checks JSON array items.
|
|
1906
|
+
*
|
|
1907
|
+
* @private function of `checkSerializableAsJson`
|
|
1908
|
+
*/
|
|
1909
|
+
function checkSerializableArray(context, arrayValue) {
|
|
1910
|
+
for (let index = 0; index < arrayValue.length; index++) {
|
|
1911
|
+
checkSerializableAsJson({
|
|
1912
|
+
...context,
|
|
1913
|
+
name: `${context.name}[${index}]`,
|
|
1914
|
+
value: arrayValue[index],
|
|
1915
|
+
});
|
|
1842
1916
|
}
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1917
|
+
}
|
|
1918
|
+
/**
|
|
1919
|
+
* Checks object-like values and dispatches special unsupported built-ins.
|
|
1920
|
+
*
|
|
1921
|
+
* @private function of `checkSerializableAsJson`
|
|
1922
|
+
*/
|
|
1923
|
+
function checkSerializableObject(context, objectValue) {
|
|
1924
|
+
checkUnsupportedObjectType(context, objectValue);
|
|
1925
|
+
checkSerializableObjectEntries(context, objectValue);
|
|
1926
|
+
assertJsonStringificationSucceeds(context, objectValue);
|
|
1927
|
+
}
|
|
1928
|
+
/**
|
|
1929
|
+
* Rejects built-in objects that must be converted before JSON serialization.
|
|
1930
|
+
*
|
|
1931
|
+
* @private function of `checkSerializableAsJson`
|
|
1932
|
+
*/
|
|
1933
|
+
function checkUnsupportedObjectType(context, objectValue) {
|
|
1934
|
+
if (objectValue instanceof Date) {
|
|
1935
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1936
|
+
\`${context.name}\` is Date
|
|
1847
1937
|
|
|
1848
|
-
|
|
1938
|
+
Use \`string_date_iso8601\` instead
|
|
1849
1939
|
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1940
|
+
Additional message for \`${context.name}\`:
|
|
1941
|
+
${block(context.message || '(nothing)')}
|
|
1942
|
+
`));
|
|
1943
|
+
}
|
|
1944
|
+
if (objectValue instanceof Map) {
|
|
1945
|
+
throw new UnexpectedError(`${context.name} is Map`);
|
|
1946
|
+
}
|
|
1947
|
+
if (objectValue instanceof Set) {
|
|
1948
|
+
throw new UnexpectedError(`${context.name} is Set`);
|
|
1949
|
+
}
|
|
1950
|
+
if (objectValue instanceof RegExp) {
|
|
1951
|
+
throw new UnexpectedError(`${context.name} is RegExp`);
|
|
1952
|
+
}
|
|
1953
|
+
if (objectValue instanceof Error) {
|
|
1954
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1955
|
+
\`${context.name}\` is unserialized Error
|
|
1866
1956
|
|
|
1867
|
-
|
|
1957
|
+
Use function \`serializeError\`
|
|
1868
1958
|
|
|
1869
|
-
|
|
1870
|
-
|
|
1959
|
+
Additional message for \`${context.name}\`:
|
|
1960
|
+
${block(context.message || '(nothing)')}
|
|
1871
1961
|
|
|
1872
|
-
|
|
1962
|
+
`));
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
/**
|
|
1966
|
+
* Recursively checks object properties while preserving omitted `undefined` keys.
|
|
1967
|
+
*
|
|
1968
|
+
* @private function of `checkSerializableAsJson`
|
|
1969
|
+
*/
|
|
1970
|
+
function checkSerializableObjectEntries(context, objectValue) {
|
|
1971
|
+
for (const [subName, subValue] of Object.entries(objectValue)) {
|
|
1972
|
+
if (subValue === undefined) {
|
|
1973
|
+
// Note: undefined in object is serializable - it is just omitted
|
|
1974
|
+
continue;
|
|
1873
1975
|
}
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1976
|
+
checkSerializableAsJson({
|
|
1977
|
+
...context,
|
|
1978
|
+
name: `${context.name}.${subName}`,
|
|
1979
|
+
value: subValue,
|
|
1980
|
+
});
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
/**
|
|
1984
|
+
* Uses `JSON.stringify` as the final guard for cases like circular references.
|
|
1985
|
+
*
|
|
1986
|
+
* @private function of `checkSerializableAsJson`
|
|
1987
|
+
*/
|
|
1988
|
+
function assertJsonStringificationSucceeds(context, objectValue) {
|
|
1989
|
+
try {
|
|
1990
|
+
JSON.stringify(objectValue); // <- TODO: [0]
|
|
1991
|
+
}
|
|
1992
|
+
catch (error) {
|
|
1993
|
+
assertsError(error);
|
|
1994
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1995
|
+
\`${context.name}\` is not serializable
|
|
1889
1996
|
|
|
1890
|
-
|
|
1997
|
+
${block(error.stack || error.message)}
|
|
1891
1998
|
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1999
|
+
Additional message for \`${context.name}\`:
|
|
2000
|
+
${block(context.message || '(nothing)')}
|
|
2001
|
+
`));
|
|
2002
|
+
}
|
|
2003
|
+
/*
|
|
2004
|
+
TODO: [0] Is there some more elegant way to check circular references?
|
|
2005
|
+
const seen = new Set();
|
|
2006
|
+
const stack = [{ value }];
|
|
2007
|
+
while (stack.length > 0) {
|
|
2008
|
+
const { value } = stack.pop()!;
|
|
2009
|
+
if (typeof value === 'object' && value !== null) {
|
|
2010
|
+
if (seen.has(value)) {
|
|
2011
|
+
throw new UnexpectedError(`${name} has circular reference`);
|
|
1895
2012
|
}
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
const { value } = stack.pop()!;
|
|
1902
|
-
if (typeof value === 'object' && value !== null) {
|
|
1903
|
-
if (seen.has(value)) {
|
|
1904
|
-
throw new UnexpectedError(`${name} has circular reference`);
|
|
1905
|
-
}
|
|
1906
|
-
seen.add(value);
|
|
1907
|
-
if (Array.isArray(value)) {
|
|
1908
|
-
stack.push(...value.map((value) => ({ value })));
|
|
1909
|
-
} else {
|
|
1910
|
-
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
1911
|
-
}
|
|
1912
|
-
}
|
|
2013
|
+
seen.add(value);
|
|
2014
|
+
if (Array.isArray(value)) {
|
|
2015
|
+
stack.push(...value.map((value) => ({ value })));
|
|
2016
|
+
} else {
|
|
2017
|
+
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
1913
2018
|
}
|
|
1914
|
-
*/
|
|
1915
|
-
return;
|
|
1916
2019
|
}
|
|
1917
2020
|
}
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
2021
|
+
*/
|
|
2022
|
+
}
|
|
2023
|
+
/**
|
|
2024
|
+
* Throws the fallback error for unsupported value types like `bigint` and `NaN`.
|
|
2025
|
+
*
|
|
2026
|
+
* @private function of `checkSerializableAsJson`
|
|
2027
|
+
*/
|
|
2028
|
+
function throwUnknownTypeError(context) {
|
|
2029
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
2030
|
+
\`${context.name}\` is unknown type
|
|
1921
2031
|
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
}
|
|
2032
|
+
Additional message for \`${context.name}\`:
|
|
2033
|
+
${block(context.message || '(nothing)')}
|
|
2034
|
+
`));
|
|
1926
2035
|
}
|
|
1927
|
-
// TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
1928
|
-
// TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
1929
|
-
// Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
1930
2036
|
|
|
1931
2037
|
/**
|
|
1932
2038
|
* Creates a deep clone of the given object
|