@promptbook/fake-llm 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
|
@@ -458,28 +458,28 @@ npx ts-node ./src/cli/test/ptbk.ts coder verify
|
|
|
458
458
|
|
|
459
459
|
#### Using `ptbk coder` in an external project
|
|
460
460
|
|
|
461
|
-
If you want to use the workflow in another repository, install the package and invoke the `ptbk` binary.
|
|
461
|
+
If you want to use the workflow in another repository, install the package and invoke the `ptbk` binary directly.
|
|
462
462
|
|
|
463
463
|
```bash
|
|
464
464
|
npm install ptbk
|
|
465
465
|
|
|
466
466
|
ptbk coder init
|
|
467
467
|
|
|
468
|
-
|
|
468
|
+
ptbk coder generate-boilerplates
|
|
469
469
|
|
|
470
|
-
|
|
470
|
+
ptbk coder generate-boilerplates --template prompts/templates/common.md
|
|
471
471
|
|
|
472
|
-
|
|
472
|
+
ptbk coder run --agent github-copilot --model gpt-5.4 --thinking-level xhigh --context AGENTS.md --test npm run test
|
|
473
473
|
|
|
474
|
-
|
|
474
|
+
ptbk coder run --agent github-copilot --model gpt-5.4 --thinking-level xhigh --context AGENTS.md --auto-push
|
|
475
475
|
|
|
476
|
-
|
|
476
|
+
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
|
|
477
477
|
|
|
478
|
-
|
|
478
|
+
ptbk coder find-refactor-candidates
|
|
479
479
|
|
|
480
|
-
|
|
480
|
+
ptbk coder find-refactor-candidates --level xhigh
|
|
481
481
|
|
|
482
|
-
|
|
482
|
+
ptbk coder verify
|
|
483
483
|
```
|
|
484
484
|
|
|
485
485
|
`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
|
|
@@ -377,6 +377,111 @@ function checkChannelValue(channelName, value) {
|
|
|
377
377
|
}
|
|
378
378
|
}
|
|
379
379
|
|
|
380
|
+
/**
|
|
381
|
+
* Shared immutable channel storage and serialization helpers for `Color`.
|
|
382
|
+
*
|
|
383
|
+
* @private base class of Color
|
|
384
|
+
*/
|
|
385
|
+
class ColorValue {
|
|
386
|
+
constructor(red, green, blue, alpha = 255) {
|
|
387
|
+
this.red = red;
|
|
388
|
+
this.green = green;
|
|
389
|
+
this.blue = blue;
|
|
390
|
+
this.alpha = alpha;
|
|
391
|
+
checkChannelValue('Red', red);
|
|
392
|
+
checkChannelValue('Green', green);
|
|
393
|
+
checkChannelValue('Blue', blue);
|
|
394
|
+
checkChannelValue('Alpha', alpha);
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Shortcut for `red` property
|
|
398
|
+
* Number from 0 to 255
|
|
399
|
+
* @alias red
|
|
400
|
+
*/
|
|
401
|
+
get r() {
|
|
402
|
+
return this.red;
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Shortcut for `green` property
|
|
406
|
+
* Number from 0 to 255
|
|
407
|
+
* @alias green
|
|
408
|
+
*/
|
|
409
|
+
get g() {
|
|
410
|
+
return this.green;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Shortcut for `blue` property
|
|
414
|
+
* Number from 0 to 255
|
|
415
|
+
* @alias blue
|
|
416
|
+
*/
|
|
417
|
+
get b() {
|
|
418
|
+
return this.blue;
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Shortcut for `alpha` property
|
|
422
|
+
* Number from 0 (transparent) to 255 (opaque)
|
|
423
|
+
* @alias alpha
|
|
424
|
+
*/
|
|
425
|
+
get a() {
|
|
426
|
+
return this.alpha;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Shortcut for `alpha` property
|
|
430
|
+
* Number from 0 (transparent) to 255 (opaque)
|
|
431
|
+
* @alias alpha
|
|
432
|
+
*/
|
|
433
|
+
get opacity() {
|
|
434
|
+
return this.alpha;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Shortcut for 1-`alpha` property
|
|
438
|
+
*/
|
|
439
|
+
get transparency() {
|
|
440
|
+
return 255 - this.alpha;
|
|
441
|
+
}
|
|
442
|
+
clone() {
|
|
443
|
+
return take(this.createColor(this.red, this.green, this.blue, this.alpha));
|
|
444
|
+
}
|
|
445
|
+
toString() {
|
|
446
|
+
return this.toHex();
|
|
447
|
+
}
|
|
448
|
+
toHex() {
|
|
449
|
+
if (this.alpha === 255) {
|
|
450
|
+
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
451
|
+
.toString(16)
|
|
452
|
+
.padStart(2, '0')}`;
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
456
|
+
.toString(16)
|
|
457
|
+
.padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
toRgb() {
|
|
461
|
+
if (this.alpha === 255) {
|
|
462
|
+
return `rgb(${this.red}, ${this.green}, ${this.blue})`;
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
toHsl() {
|
|
469
|
+
throw new Error(`Getting HSL is not implemented`);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Checks if the given value is a valid hex color string
|
|
475
|
+
*
|
|
476
|
+
* @param value - value to check
|
|
477
|
+
* @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
|
|
478
|
+
*
|
|
479
|
+
* @private function of Color
|
|
480
|
+
*/
|
|
481
|
+
function isHexColorString(value) {
|
|
482
|
+
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));
|
|
483
|
+
}
|
|
484
|
+
|
|
380
485
|
/**
|
|
381
486
|
* Constant for short hex lengths.
|
|
382
487
|
*/
|
|
@@ -588,16 +693,53 @@ function parseAlphaValue(value) {
|
|
|
588
693
|
|
|
589
694
|
/**
|
|
590
695
|
* Pattern matching hsl regex.
|
|
696
|
+
*
|
|
697
|
+
* @private function of Color
|
|
591
698
|
*/
|
|
592
699
|
const HSL_REGEX_PATTERN = /^hsl\(\s*([0-9.]+)\s*,\s*([0-9.]+)%\s*,\s*([0-9.]+)%\s*\)$/;
|
|
593
700
|
/**
|
|
594
701
|
* Pattern matching RGB regex.
|
|
702
|
+
*
|
|
703
|
+
* @private function of Color
|
|
595
704
|
*/
|
|
596
705
|
const RGB_REGEX_PATTERN = /^rgb\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/;
|
|
597
706
|
/**
|
|
598
707
|
* Pattern matching rgba regex.
|
|
708
|
+
*
|
|
709
|
+
* @private function of Color
|
|
599
710
|
*/
|
|
600
711
|
const RGBA_REGEX_PATTERN = /^rgba\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/;
|
|
712
|
+
/**
|
|
713
|
+
* Parses a supported color string into RGBA channels.
|
|
714
|
+
*
|
|
715
|
+
* @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`,...
|
|
716
|
+
* @returns RGBA channel values.
|
|
717
|
+
*
|
|
718
|
+
* @private function of Color
|
|
719
|
+
*/
|
|
720
|
+
function parseColorString(color) {
|
|
721
|
+
const trimmed = color.trim();
|
|
722
|
+
const cssColor = CSS_COLORS[trimmed];
|
|
723
|
+
if (cssColor) {
|
|
724
|
+
return parseColorString(cssColor);
|
|
725
|
+
}
|
|
726
|
+
else if (isHexColorString(trimmed)) {
|
|
727
|
+
return parseHexColor(trimmed);
|
|
728
|
+
}
|
|
729
|
+
if (HSL_REGEX_PATTERN.test(trimmed)) {
|
|
730
|
+
return parseHslColor(trimmed);
|
|
731
|
+
}
|
|
732
|
+
else if (RGB_REGEX_PATTERN.test(trimmed)) {
|
|
733
|
+
return parseRgbColor(trimmed);
|
|
734
|
+
}
|
|
735
|
+
else if (RGBA_REGEX_PATTERN.test(trimmed)) {
|
|
736
|
+
return parseRgbaColor(trimmed);
|
|
737
|
+
}
|
|
738
|
+
else {
|
|
739
|
+
throw new Error(`Can not create a new Color instance from string "${trimmed}".`);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
|
|
601
743
|
/**
|
|
602
744
|
* Color object represents an RGB color with alpha channel
|
|
603
745
|
*
|
|
@@ -605,7 +747,7 @@ const RGBA_REGEX_PATTERN = /^rgba\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.
|
|
|
605
747
|
*
|
|
606
748
|
* @public exported from `@promptbook/color`
|
|
607
749
|
*/
|
|
608
|
-
class Color {
|
|
750
|
+
class Color extends ColorValue {
|
|
609
751
|
/**
|
|
610
752
|
* Creates a new Color instance from miscellaneous formats
|
|
611
753
|
* - It can receive Color instance and just return the same instance
|
|
@@ -678,25 +820,7 @@ class Color {
|
|
|
678
820
|
* @returns Color object
|
|
679
821
|
*/
|
|
680
822
|
static fromString(color) {
|
|
681
|
-
|
|
682
|
-
if (CSS_COLORS[trimmed]) {
|
|
683
|
-
return Color.fromString(CSS_COLORS[trimmed]);
|
|
684
|
-
}
|
|
685
|
-
else if (Color.isHexColorString(trimmed)) {
|
|
686
|
-
return Color.fromHex(trimmed);
|
|
687
|
-
}
|
|
688
|
-
if (HSL_REGEX_PATTERN.test(trimmed)) {
|
|
689
|
-
return Color.fromHsl(trimmed);
|
|
690
|
-
}
|
|
691
|
-
else if (RGB_REGEX_PATTERN.test(trimmed)) {
|
|
692
|
-
return Color.fromRgbString(trimmed);
|
|
693
|
-
}
|
|
694
|
-
else if (RGBA_REGEX_PATTERN.test(trimmed)) {
|
|
695
|
-
return Color.fromRgbaString(trimmed);
|
|
696
|
-
}
|
|
697
|
-
else {
|
|
698
|
-
throw new Error(`Can not create a new Color instance from string "${trimmed}".`);
|
|
699
|
-
}
|
|
823
|
+
return Color.fromColorChannels(parseColorString(color));
|
|
700
824
|
}
|
|
701
825
|
/**
|
|
702
826
|
* Gets common color
|
|
@@ -726,8 +850,7 @@ class Color {
|
|
|
726
850
|
* @returns Color object
|
|
727
851
|
*/
|
|
728
852
|
static fromHex(hex) {
|
|
729
|
-
|
|
730
|
-
return take(new Color(red, green, blue, alpha));
|
|
853
|
+
return Color.fromColorChannels(parseHexColor(hex));
|
|
731
854
|
}
|
|
732
855
|
/**
|
|
733
856
|
* Creates a new Color instance from color in hsl format
|
|
@@ -736,8 +859,7 @@ class Color {
|
|
|
736
859
|
* @returns Color object
|
|
737
860
|
*/
|
|
738
861
|
static fromHsl(hsl) {
|
|
739
|
-
|
|
740
|
-
return take(new Color(red, green, blue, alpha));
|
|
862
|
+
return Color.fromColorChannels(parseHslColor(hsl));
|
|
741
863
|
}
|
|
742
864
|
/**
|
|
743
865
|
* Creates a new Color instance from color in rgb format
|
|
@@ -746,8 +868,7 @@ class Color {
|
|
|
746
868
|
* @returns Color object
|
|
747
869
|
*/
|
|
748
870
|
static fromRgbString(rgb) {
|
|
749
|
-
|
|
750
|
-
return take(new Color(red, green, blue, alpha));
|
|
871
|
+
return Color.fromColorChannels(parseRgbColor(rgb));
|
|
751
872
|
}
|
|
752
873
|
/**
|
|
753
874
|
* Creates a new Color instance from color in rbga format
|
|
@@ -756,8 +877,7 @@ class Color {
|
|
|
756
877
|
* @returns Color object
|
|
757
878
|
*/
|
|
758
879
|
static fromRgbaString(rgba) {
|
|
759
|
-
|
|
760
|
-
return take(new Color(red, green, blue, alpha));
|
|
880
|
+
return Color.fromColorChannels(parseRgbaColor(rgba));
|
|
761
881
|
}
|
|
762
882
|
/**
|
|
763
883
|
* Creates a new Color for color channels values
|
|
@@ -769,7 +889,7 @@ class Color {
|
|
|
769
889
|
* @returns Color object
|
|
770
890
|
*/
|
|
771
891
|
static fromValues(red, green, blue, alpha = 255) {
|
|
772
|
-
return
|
|
892
|
+
return Color.fromColorChannels({ red, green, blue, alpha });
|
|
773
893
|
}
|
|
774
894
|
/**
|
|
775
895
|
* Checks if the given value is a valid Color object.
|
|
@@ -802,8 +922,7 @@ class Color {
|
|
|
802
922
|
* @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
|
|
803
923
|
*/
|
|
804
924
|
static isHexColorString(value) {
|
|
805
|
-
return (
|
|
806
|
-
/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value));
|
|
925
|
+
return isHexColorString(value);
|
|
807
926
|
}
|
|
808
927
|
/**
|
|
809
928
|
* Creates new Color object
|
|
@@ -816,89 +935,13 @@ class Color {
|
|
|
816
935
|
* @param alpha number from 0 (transparent) to 255 (opaque)
|
|
817
936
|
*/
|
|
818
937
|
constructor(red, green, blue, alpha = 255) {
|
|
819
|
-
|
|
820
|
-
this.green = green;
|
|
821
|
-
this.blue = blue;
|
|
822
|
-
this.alpha = alpha;
|
|
823
|
-
checkChannelValue('Red', red);
|
|
824
|
-
checkChannelValue('Green', green);
|
|
825
|
-
checkChannelValue('Blue', blue);
|
|
826
|
-
checkChannelValue('Alpha', alpha);
|
|
827
|
-
}
|
|
828
|
-
/**
|
|
829
|
-
* Shortcut for `red` property
|
|
830
|
-
* Number from 0 to 255
|
|
831
|
-
* @alias red
|
|
832
|
-
*/
|
|
833
|
-
get r() {
|
|
834
|
-
return this.red;
|
|
835
|
-
}
|
|
836
|
-
/**
|
|
837
|
-
* Shortcut for `green` property
|
|
838
|
-
* Number from 0 to 255
|
|
839
|
-
* @alias green
|
|
840
|
-
*/
|
|
841
|
-
get g() {
|
|
842
|
-
return this.green;
|
|
843
|
-
}
|
|
844
|
-
/**
|
|
845
|
-
* Shortcut for `blue` property
|
|
846
|
-
* Number from 0 to 255
|
|
847
|
-
* @alias blue
|
|
848
|
-
*/
|
|
849
|
-
get b() {
|
|
850
|
-
return this.blue;
|
|
851
|
-
}
|
|
852
|
-
/**
|
|
853
|
-
* Shortcut for `alpha` property
|
|
854
|
-
* Number from 0 (transparent) to 255 (opaque)
|
|
855
|
-
* @alias alpha
|
|
856
|
-
*/
|
|
857
|
-
get a() {
|
|
858
|
-
return this.alpha;
|
|
859
|
-
}
|
|
860
|
-
/**
|
|
861
|
-
* Shortcut for `alpha` property
|
|
862
|
-
* Number from 0 (transparent) to 255 (opaque)
|
|
863
|
-
* @alias alpha
|
|
864
|
-
*/
|
|
865
|
-
get opacity() {
|
|
866
|
-
return this.alpha;
|
|
867
|
-
}
|
|
868
|
-
/**
|
|
869
|
-
* Shortcut for 1-`alpha` property
|
|
870
|
-
*/
|
|
871
|
-
get transparency() {
|
|
872
|
-
return 255 - this.alpha;
|
|
873
|
-
}
|
|
874
|
-
clone() {
|
|
875
|
-
return take(new Color(this.red, this.green, this.blue, this.alpha));
|
|
938
|
+
super(red, green, blue, alpha);
|
|
876
939
|
}
|
|
877
|
-
|
|
878
|
-
return
|
|
940
|
+
createColor(red, green, blue, alpha) {
|
|
941
|
+
return new Color(red, green, blue, alpha);
|
|
879
942
|
}
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
883
|
-
.toString(16)
|
|
884
|
-
.padStart(2, '0')}`;
|
|
885
|
-
}
|
|
886
|
-
else {
|
|
887
|
-
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
888
|
-
.toString(16)
|
|
889
|
-
.padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
toRgb() {
|
|
893
|
-
if (this.alpha === 255) {
|
|
894
|
-
return `rgb(${this.red}, ${this.green}, ${this.blue})`;
|
|
895
|
-
}
|
|
896
|
-
else {
|
|
897
|
-
return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
toHsl() {
|
|
901
|
-
throw new Error(`Getting HSL is not implemented`);
|
|
943
|
+
static fromColorChannels({ red, green, blue, alpha }) {
|
|
944
|
+
return take(new Color(red, green, blue, alpha));
|
|
902
945
|
}
|
|
903
946
|
}
|
|
904
947
|
|
|
@@ -1378,120 +1421,183 @@ function assertsError(whatWasThrown) {
|
|
|
1378
1421
|
* @public exported from `@promptbook/utils`
|
|
1379
1422
|
*/
|
|
1380
1423
|
function checkSerializableAsJson(options) {
|
|
1381
|
-
|
|
1424
|
+
checkSerializableValue(options);
|
|
1425
|
+
}
|
|
1426
|
+
// TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
1427
|
+
// TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
1428
|
+
// Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
1429
|
+
/**
|
|
1430
|
+
* Checks one value and dispatches to the appropriate specialized validator.
|
|
1431
|
+
*
|
|
1432
|
+
* @private function of `checkSerializableAsJson`
|
|
1433
|
+
*/
|
|
1434
|
+
function checkSerializableValue(options) {
|
|
1435
|
+
const { value } = options;
|
|
1436
|
+
if (isSerializablePrimitive(value)) {
|
|
1437
|
+
return;
|
|
1438
|
+
}
|
|
1382
1439
|
if (value === undefined) {
|
|
1383
|
-
throw new UnexpectedError(`${name} is undefined`);
|
|
1440
|
+
throw new UnexpectedError(`${options.name} is undefined`);
|
|
1384
1441
|
}
|
|
1385
|
-
|
|
1386
|
-
|
|
1442
|
+
if (typeof value === 'symbol') {
|
|
1443
|
+
throw new UnexpectedError(`${options.name} is symbol`);
|
|
1387
1444
|
}
|
|
1388
|
-
|
|
1389
|
-
|
|
1445
|
+
if (typeof value === 'function') {
|
|
1446
|
+
throw new UnexpectedError(`${options.name} is function`);
|
|
1390
1447
|
}
|
|
1391
|
-
|
|
1448
|
+
if (Array.isArray(value)) {
|
|
1449
|
+
checkSerializableArray(options, value);
|
|
1392
1450
|
return;
|
|
1393
1451
|
}
|
|
1394
|
-
|
|
1452
|
+
if (value !== null && typeof value === 'object') {
|
|
1453
|
+
checkSerializableObject(options, value);
|
|
1395
1454
|
return;
|
|
1396
1455
|
}
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1456
|
+
throwUnknownTypeError(options);
|
|
1457
|
+
}
|
|
1458
|
+
/**
|
|
1459
|
+
* Checks the primitive values that are directly JSON serializable.
|
|
1460
|
+
*
|
|
1461
|
+
* @private function of `checkSerializableAsJson`
|
|
1462
|
+
*/
|
|
1463
|
+
function isSerializablePrimitive(value) {
|
|
1464
|
+
return (value === null ||
|
|
1465
|
+
typeof value === 'boolean' ||
|
|
1466
|
+
(typeof value === 'number' && !isNaN(value)) ||
|
|
1467
|
+
typeof value === 'string');
|
|
1468
|
+
}
|
|
1469
|
+
/**
|
|
1470
|
+
* Recursively checks JSON array items.
|
|
1471
|
+
*
|
|
1472
|
+
* @private function of `checkSerializableAsJson`
|
|
1473
|
+
*/
|
|
1474
|
+
function checkSerializableArray(context, arrayValue) {
|
|
1475
|
+
for (let index = 0; index < arrayValue.length; index++) {
|
|
1476
|
+
checkSerializableAsJson({
|
|
1477
|
+
...context,
|
|
1478
|
+
name: `${context.name}[${index}]`,
|
|
1479
|
+
value: arrayValue[index],
|
|
1480
|
+
});
|
|
1407
1481
|
}
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1482
|
+
}
|
|
1483
|
+
/**
|
|
1484
|
+
* Checks object-like values and dispatches special unsupported built-ins.
|
|
1485
|
+
*
|
|
1486
|
+
* @private function of `checkSerializableAsJson`
|
|
1487
|
+
*/
|
|
1488
|
+
function checkSerializableObject(context, objectValue) {
|
|
1489
|
+
checkUnsupportedObjectType(context, objectValue);
|
|
1490
|
+
checkSerializableObjectEntries(context, objectValue);
|
|
1491
|
+
assertJsonStringificationSucceeds(context, objectValue);
|
|
1492
|
+
}
|
|
1493
|
+
/**
|
|
1494
|
+
* Rejects built-in objects that must be converted before JSON serialization.
|
|
1495
|
+
*
|
|
1496
|
+
* @private function of `checkSerializableAsJson`
|
|
1497
|
+
*/
|
|
1498
|
+
function checkUnsupportedObjectType(context, objectValue) {
|
|
1499
|
+
if (objectValue instanceof Date) {
|
|
1500
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1501
|
+
\`${context.name}\` is Date
|
|
1412
1502
|
|
|
1413
|
-
|
|
1503
|
+
Use \`string_date_iso8601\` instead
|
|
1414
1504
|
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1505
|
+
Additional message for \`${context.name}\`:
|
|
1506
|
+
${block(context.message || '(nothing)')}
|
|
1507
|
+
`));
|
|
1508
|
+
}
|
|
1509
|
+
if (objectValue instanceof Map) {
|
|
1510
|
+
throw new UnexpectedError(`${context.name} is Map`);
|
|
1511
|
+
}
|
|
1512
|
+
if (objectValue instanceof Set) {
|
|
1513
|
+
throw new UnexpectedError(`${context.name} is Set`);
|
|
1514
|
+
}
|
|
1515
|
+
if (objectValue instanceof RegExp) {
|
|
1516
|
+
throw new UnexpectedError(`${context.name} is RegExp`);
|
|
1517
|
+
}
|
|
1518
|
+
if (objectValue instanceof Error) {
|
|
1519
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1520
|
+
\`${context.name}\` is unserialized Error
|
|
1431
1521
|
|
|
1432
|
-
|
|
1522
|
+
Use function \`serializeError\`
|
|
1433
1523
|
|
|
1434
|
-
|
|
1435
|
-
|
|
1524
|
+
Additional message for \`${context.name}\`:
|
|
1525
|
+
${block(context.message || '(nothing)')}
|
|
1436
1526
|
|
|
1437
|
-
|
|
1527
|
+
`));
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
/**
|
|
1531
|
+
* Recursively checks object properties while preserving omitted `undefined` keys.
|
|
1532
|
+
*
|
|
1533
|
+
* @private function of `checkSerializableAsJson`
|
|
1534
|
+
*/
|
|
1535
|
+
function checkSerializableObjectEntries(context, objectValue) {
|
|
1536
|
+
for (const [subName, subValue] of Object.entries(objectValue)) {
|
|
1537
|
+
if (subValue === undefined) {
|
|
1538
|
+
// Note: undefined in object is serializable - it is just omitted
|
|
1539
|
+
continue;
|
|
1438
1540
|
}
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1541
|
+
checkSerializableAsJson({
|
|
1542
|
+
...context,
|
|
1543
|
+
name: `${context.name}.${subName}`,
|
|
1544
|
+
value: subValue,
|
|
1545
|
+
});
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
/**
|
|
1549
|
+
* Uses `JSON.stringify` as the final guard for cases like circular references.
|
|
1550
|
+
*
|
|
1551
|
+
* @private function of `checkSerializableAsJson`
|
|
1552
|
+
*/
|
|
1553
|
+
function assertJsonStringificationSucceeds(context, objectValue) {
|
|
1554
|
+
try {
|
|
1555
|
+
JSON.stringify(objectValue); // <- TODO: [0]
|
|
1556
|
+
}
|
|
1557
|
+
catch (error) {
|
|
1558
|
+
assertsError(error);
|
|
1559
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1560
|
+
\`${context.name}\` is not serializable
|
|
1454
1561
|
|
|
1455
|
-
|
|
1562
|
+
${block(error.stack || error.message)}
|
|
1456
1563
|
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1564
|
+
Additional message for \`${context.name}\`:
|
|
1565
|
+
${block(context.message || '(nothing)')}
|
|
1566
|
+
`));
|
|
1567
|
+
}
|
|
1568
|
+
/*
|
|
1569
|
+
TODO: [0] Is there some more elegant way to check circular references?
|
|
1570
|
+
const seen = new Set();
|
|
1571
|
+
const stack = [{ value }];
|
|
1572
|
+
while (stack.length > 0) {
|
|
1573
|
+
const { value } = stack.pop()!;
|
|
1574
|
+
if (typeof value === 'object' && value !== null) {
|
|
1575
|
+
if (seen.has(value)) {
|
|
1576
|
+
throw new UnexpectedError(`${name} has circular reference`);
|
|
1460
1577
|
}
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
const { value } = stack.pop()!;
|
|
1467
|
-
if (typeof value === 'object' && value !== null) {
|
|
1468
|
-
if (seen.has(value)) {
|
|
1469
|
-
throw new UnexpectedError(`${name} has circular reference`);
|
|
1470
|
-
}
|
|
1471
|
-
seen.add(value);
|
|
1472
|
-
if (Array.isArray(value)) {
|
|
1473
|
-
stack.push(...value.map((value) => ({ value })));
|
|
1474
|
-
} else {
|
|
1475
|
-
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
1476
|
-
}
|
|
1477
|
-
}
|
|
1578
|
+
seen.add(value);
|
|
1579
|
+
if (Array.isArray(value)) {
|
|
1580
|
+
stack.push(...value.map((value) => ({ value })));
|
|
1581
|
+
} else {
|
|
1582
|
+
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
1478
1583
|
}
|
|
1479
|
-
*/
|
|
1480
|
-
return;
|
|
1481
1584
|
}
|
|
1482
1585
|
}
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1586
|
+
*/
|
|
1587
|
+
}
|
|
1588
|
+
/**
|
|
1589
|
+
* Throws the fallback error for unsupported value types like `bigint` and `NaN`.
|
|
1590
|
+
*
|
|
1591
|
+
* @private function of `checkSerializableAsJson`
|
|
1592
|
+
*/
|
|
1593
|
+
function throwUnknownTypeError(context) {
|
|
1594
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1595
|
+
\`${context.name}\` is unknown type
|
|
1486
1596
|
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
}
|
|
1597
|
+
Additional message for \`${context.name}\`:
|
|
1598
|
+
${block(context.message || '(nothing)')}
|
|
1599
|
+
`));
|
|
1491
1600
|
}
|
|
1492
|
-
// TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
1493
|
-
// TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
1494
|
-
// Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
1495
1601
|
|
|
1496
1602
|
/**
|
|
1497
1603
|
* Creates a deep clone of the given object
|