@promptbook/utils 0.79.0 → 0.80.0-0
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 +4 -0
- package/esm/index.es.js +278 -205
- package/esm/index.es.js.map +1 -1
- package/esm/typings/books/index.d.ts +6 -6
- package/esm/typings/src/_packages/core.index.d.ts +4 -2
- package/esm/typings/src/_packages/types.index.d.ts +10 -0
- package/esm/typings/src/_packages/utils.index.d.ts +4 -0
- package/esm/typings/src/cli/cli-commands/runInteractiveChatbot.d.ts +32 -0
- package/esm/typings/src/commands/_common/types/CommandParser.d.ts +3 -0
- package/esm/typings/src/config.d.ts +0 -25
- package/esm/typings/src/constants.d.ts +35 -0
- package/esm/typings/src/conversion/pipelineJsonToString.d.ts +1 -0
- package/esm/typings/src/conversion/pipelineStringToJsonSync.d.ts +1 -0
- package/esm/typings/src/high-level-abstractions/_common/HighLevelAbstraction.d.ts +20 -0
- package/esm/typings/src/high-level-abstractions/implicit-formfactor/ImplicitFormfactorHla.d.ts +10 -0
- package/esm/typings/src/high-level-abstractions/index.d.ts +44 -0
- package/esm/typings/src/high-level-abstractions/quick-chatbot/QuickChatbotHla.d.ts +10 -0
- package/esm/typings/src/llm-providers/remote/RemoteLlmExecutionTools.d.ts +1 -1
- package/esm/typings/src/llm-providers/remote/startRemoteServer.d.ts +1 -1
- package/esm/typings/src/prepare/prepareTasks.d.ts +1 -0
- package/esm/typings/src/types/typeAliases.d.ts +1 -1
- package/esm/typings/src/utils/normalization/orderJson.d.ts +21 -0
- package/esm/typings/src/utils/normalization/orderJson.test.d.ts +4 -0
- package/esm/typings/src/utils/organization/keepTypeImported.d.ts +9 -0
- package/esm/typings/src/utils/serialization/$deepFreeze.d.ts +1 -1
- package/esm/typings/src/utils/serialization/checkSerializableAsJson.d.ts +20 -2
- package/esm/typings/src/utils/serialization/deepClone.test.d.ts +1 -0
- package/esm/typings/src/utils/serialization/exportJson.d.ts +29 -0
- package/esm/typings/src/utils/serialization/isSerializableAsJson.d.ts +2 -1
- package/package.json +3 -2
- package/umd/index.umd.js +279 -204
- package/umd/index.umd.js.map +1 -1
- package/esm/typings/src/utils/serialization/$asDeeplyFrozenSerializableJson.d.ts +0 -17
package/umd/index.umd.js
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*
|
|
21
21
|
* @see https://github.com/webgptorg/promptbook
|
|
22
22
|
*/
|
|
23
|
-
var PROMPTBOOK_ENGINE_VERSION = '0.
|
|
23
|
+
var PROMPTBOOK_ENGINE_VERSION = '0.79.0';
|
|
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
|
|
@@ -172,24 +172,6 @@
|
|
|
172
172
|
* @private within the repository - too low-level in comparison with other `MAX_...`
|
|
173
173
|
*/
|
|
174
174
|
var LOOP_LIMIT = 1000;
|
|
175
|
-
/**
|
|
176
|
-
* Nonce which is used for replacing things in strings
|
|
177
|
-
*
|
|
178
|
-
* @private within the repository
|
|
179
|
-
*/
|
|
180
|
-
var REPLACING_NONCE = 'u$k42k%!V2zo34w7Fu#@QUHYPW';
|
|
181
|
-
/**
|
|
182
|
-
* @@@
|
|
183
|
-
*
|
|
184
|
-
* @private within the repository
|
|
185
|
-
*/
|
|
186
|
-
var RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;
|
|
187
|
-
/**
|
|
188
|
-
* @@@
|
|
189
|
-
*
|
|
190
|
-
* @private within the repository
|
|
191
|
-
*/
|
|
192
|
-
var RESERVED_PARAMETER_RESTRICTED = 'RESTRICTED-' + REPLACING_NONCE;
|
|
193
175
|
// <- TODO: [🧜♂️]
|
|
194
176
|
/**
|
|
195
177
|
* @@@
|
|
@@ -203,7 +185,6 @@
|
|
|
203
185
|
skipEmptyLines: true,
|
|
204
186
|
});
|
|
205
187
|
/**
|
|
206
|
-
* TODO: Extract `constants.ts` from `config.ts`
|
|
207
188
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
208
189
|
* TODO: [🧠][🧜♂️] Maybe join remoteUrl and path into single value
|
|
209
190
|
*/
|
|
@@ -1612,6 +1593,18 @@
|
|
|
1612
1593
|
return sentence.replace(/\s+/gs, ' ').trim();
|
|
1613
1594
|
}
|
|
1614
1595
|
|
|
1596
|
+
/**
|
|
1597
|
+
* Orders JSON object by keys
|
|
1598
|
+
*
|
|
1599
|
+
* @returns The same type of object as the input re-ordered
|
|
1600
|
+
* @public exported from `@promptbook/utils`
|
|
1601
|
+
*/
|
|
1602
|
+
function orderJson(options) {
|
|
1603
|
+
var value = options.value, order = options.order;
|
|
1604
|
+
var orderedValue = __assign(__assign({}, (order === undefined ? {} : Object.fromEntries(order.map(function (key) { return [key, undefined]; })))), value);
|
|
1605
|
+
return orderedValue;
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1615
1608
|
/**
|
|
1616
1609
|
* Parses keywords from any object and recursively walks through
|
|
1617
1610
|
*
|
|
@@ -1717,6 +1710,268 @@
|
|
|
1717
1710
|
return parameterNames;
|
|
1718
1711
|
}
|
|
1719
1712
|
|
|
1713
|
+
/**
|
|
1714
|
+
* Freezes the given object and all its nested objects recursively
|
|
1715
|
+
*
|
|
1716
|
+
* Note: `$` is used to indicate that this function is not a pure function - it mutates given object
|
|
1717
|
+
* Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
|
|
1718
|
+
*
|
|
1719
|
+
* @returns The same object as the input, but deeply frozen
|
|
1720
|
+
* @public exported from `@promptbook/utils`
|
|
1721
|
+
*/
|
|
1722
|
+
function $deepFreeze(objectValue) {
|
|
1723
|
+
var e_1, _a;
|
|
1724
|
+
if (Array.isArray(objectValue)) {
|
|
1725
|
+
return Object.freeze(objectValue.map(function (item) { return $deepFreeze(item); }));
|
|
1726
|
+
}
|
|
1727
|
+
var propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
1728
|
+
try {
|
|
1729
|
+
for (var propertyNames_1 = __values(propertyNames), propertyNames_1_1 = propertyNames_1.next(); !propertyNames_1_1.done; propertyNames_1_1 = propertyNames_1.next()) {
|
|
1730
|
+
var propertyName = propertyNames_1_1.value;
|
|
1731
|
+
var value = objectValue[propertyName];
|
|
1732
|
+
if (value && typeof value === 'object') {
|
|
1733
|
+
$deepFreeze(value);
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
1737
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
1738
|
+
finally {
|
|
1739
|
+
try {
|
|
1740
|
+
if (propertyNames_1_1 && !propertyNames_1_1.done && (_a = propertyNames_1.return)) _a.call(propertyNames_1);
|
|
1741
|
+
}
|
|
1742
|
+
finally { if (e_1) throw e_1.error; }
|
|
1743
|
+
}
|
|
1744
|
+
Object.freeze(objectValue);
|
|
1745
|
+
return objectValue;
|
|
1746
|
+
}
|
|
1747
|
+
/**
|
|
1748
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
1749
|
+
*/
|
|
1750
|
+
|
|
1751
|
+
/**
|
|
1752
|
+
* Checks if the value is [🚉] serializable as JSON
|
|
1753
|
+
* If not, throws an UnexpectedError with a rich error message and tracking
|
|
1754
|
+
*
|
|
1755
|
+
* - Almost all primitives are serializable BUT:
|
|
1756
|
+
* - `undefined` is not serializable
|
|
1757
|
+
* - `NaN` is not serializable
|
|
1758
|
+
* - Objects and arrays are serializable if all their properties are serializable
|
|
1759
|
+
* - Functions are not serializable
|
|
1760
|
+
* - Circular references are not serializable
|
|
1761
|
+
* - `Date` objects are not serializable
|
|
1762
|
+
* - `Map` and `Set` objects are not serializable
|
|
1763
|
+
* - `RegExp` objects are not serializable
|
|
1764
|
+
* - `Error` objects are not serializable
|
|
1765
|
+
* - `Symbol` objects are not serializable
|
|
1766
|
+
* - And much more...
|
|
1767
|
+
*
|
|
1768
|
+
* @throws UnexpectedError if the value is not serializable as JSON
|
|
1769
|
+
* @public exported from `@promptbook/utils`
|
|
1770
|
+
*/
|
|
1771
|
+
function checkSerializableAsJson(options) {
|
|
1772
|
+
var e_1, _a;
|
|
1773
|
+
var value = options.value, name = options.name, message = options.message;
|
|
1774
|
+
if (value === undefined) {
|
|
1775
|
+
throw new UnexpectedError("".concat(name, " is undefined"));
|
|
1776
|
+
}
|
|
1777
|
+
else if (value === null) {
|
|
1778
|
+
return;
|
|
1779
|
+
}
|
|
1780
|
+
else if (typeof value === 'boolean') {
|
|
1781
|
+
return;
|
|
1782
|
+
}
|
|
1783
|
+
else if (typeof value === 'number' && !isNaN(value)) {
|
|
1784
|
+
return;
|
|
1785
|
+
}
|
|
1786
|
+
else if (typeof value === 'string') {
|
|
1787
|
+
return;
|
|
1788
|
+
}
|
|
1789
|
+
else if (typeof value === 'symbol') {
|
|
1790
|
+
throw new UnexpectedError("".concat(name, " is symbol"));
|
|
1791
|
+
}
|
|
1792
|
+
else if (typeof value === 'function') {
|
|
1793
|
+
throw new UnexpectedError("".concat(name, " is function"));
|
|
1794
|
+
}
|
|
1795
|
+
else if (typeof value === 'object' && Array.isArray(value)) {
|
|
1796
|
+
for (var i = 0; i < value.length; i++) {
|
|
1797
|
+
checkSerializableAsJson({ name: "".concat(name, "[").concat(i, "]"), value: value[i], message: message });
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
else if (typeof value === 'object') {
|
|
1801
|
+
if (value instanceof Date) {
|
|
1802
|
+
throw new UnexpectedError(spaceTrim__default["default"](function (block) { return "\n `".concat(name, "` is Date\n\n Use `string_date_iso8601` instead\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n "); }));
|
|
1803
|
+
}
|
|
1804
|
+
else if (value instanceof Map) {
|
|
1805
|
+
throw new UnexpectedError("".concat(name, " is Map"));
|
|
1806
|
+
}
|
|
1807
|
+
else if (value instanceof Set) {
|
|
1808
|
+
throw new UnexpectedError("".concat(name, " is Set"));
|
|
1809
|
+
}
|
|
1810
|
+
else if (value instanceof RegExp) {
|
|
1811
|
+
throw new UnexpectedError("".concat(name, " is RegExp"));
|
|
1812
|
+
}
|
|
1813
|
+
else if (value instanceof Error) {
|
|
1814
|
+
throw new UnexpectedError(spaceTrim__default["default"](function (block) { return "\n `".concat(name, "` is unserialized Error\n\n Use function `serializeError`\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n\n "); }));
|
|
1815
|
+
}
|
|
1816
|
+
else {
|
|
1817
|
+
try {
|
|
1818
|
+
for (var _b = __values(Object.entries(value)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
1819
|
+
var _d = __read(_c.value, 2), subName = _d[0], subValue = _d[1];
|
|
1820
|
+
if (subValue === undefined) {
|
|
1821
|
+
// Note: undefined in object is serializable - it is just omited
|
|
1822
|
+
continue;
|
|
1823
|
+
}
|
|
1824
|
+
checkSerializableAsJson({ name: "".concat(name, ".").concat(subName), value: subValue, message: message });
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
1828
|
+
finally {
|
|
1829
|
+
try {
|
|
1830
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
1831
|
+
}
|
|
1832
|
+
finally { if (e_1) throw e_1.error; }
|
|
1833
|
+
}
|
|
1834
|
+
try {
|
|
1835
|
+
JSON.stringify(value); // <- TODO: [0]
|
|
1836
|
+
}
|
|
1837
|
+
catch (error) {
|
|
1838
|
+
if (!(error instanceof Error)) {
|
|
1839
|
+
throw error;
|
|
1840
|
+
}
|
|
1841
|
+
throw new UnexpectedError(spaceTrim__default["default"](function (block) { return "\n `".concat(name, "` is not serializable\n\n ").concat(block(error.toString()), "\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n "); }));
|
|
1842
|
+
}
|
|
1843
|
+
/*
|
|
1844
|
+
TODO: [0] Is there some more elegant way to check circular references?
|
|
1845
|
+
const seen = new Set();
|
|
1846
|
+
const stack = [{ value }];
|
|
1847
|
+
while (stack.length > 0) {
|
|
1848
|
+
const { value } = stack.pop()!;
|
|
1849
|
+
if (typeof value === 'object' && value !== null) {
|
|
1850
|
+
if (seen.has(value)) {
|
|
1851
|
+
throw new UnexpectedError(`${name} has circular reference`);
|
|
1852
|
+
}
|
|
1853
|
+
seen.add(value);
|
|
1854
|
+
if (Array.isArray(value)) {
|
|
1855
|
+
stack.push(...value.map((value) => ({ value })));
|
|
1856
|
+
} else {
|
|
1857
|
+
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
*/
|
|
1862
|
+
return;
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
else {
|
|
1866
|
+
throw new UnexpectedError(spaceTrim__default["default"](function (block) { return "\n `".concat(name, "` is unknown type\n\n Additional message for `").concat(name, "`:\n ").concat(block(message || '(nothing)'), "\n "); }));
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
/**
|
|
1870
|
+
* TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
1871
|
+
* TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
|
|
1872
|
+
* Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
1873
|
+
*/
|
|
1874
|
+
|
|
1875
|
+
/**
|
|
1876
|
+
* @@@
|
|
1877
|
+
*
|
|
1878
|
+
* @public exported from `@promptbook/utils`
|
|
1879
|
+
*/
|
|
1880
|
+
function deepClone(objectValue) {
|
|
1881
|
+
return JSON.parse(JSON.stringify(objectValue));
|
|
1882
|
+
/*
|
|
1883
|
+
!!!!!!!!
|
|
1884
|
+
TODO: [🧠] Is there a better implementation?
|
|
1885
|
+
> const propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
1886
|
+
> for (const propertyName of propertyNames) {
|
|
1887
|
+
> const value = (objectValue as really_any)[propertyName];
|
|
1888
|
+
> if (value && typeof value === 'object') {
|
|
1889
|
+
> deepClone(value);
|
|
1890
|
+
> }
|
|
1891
|
+
> }
|
|
1892
|
+
> return Object.assign({}, objectValue);
|
|
1893
|
+
*/
|
|
1894
|
+
}
|
|
1895
|
+
/**
|
|
1896
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
1897
|
+
*/
|
|
1898
|
+
|
|
1899
|
+
/**
|
|
1900
|
+
* Utility to export a JSON object from a function
|
|
1901
|
+
*
|
|
1902
|
+
* 1) Checks if the value is serializable as JSON
|
|
1903
|
+
* 2) Makes a deep clone of the object
|
|
1904
|
+
* 2) Orders the object properties
|
|
1905
|
+
* 2) Deeply freezes the cloned object
|
|
1906
|
+
*
|
|
1907
|
+
* Note: This function does not mutates the given object
|
|
1908
|
+
*
|
|
1909
|
+
* @returns The same type of object as the input but read-only and re-ordered
|
|
1910
|
+
* @public exported from `@promptbook/utils`
|
|
1911
|
+
*/
|
|
1912
|
+
function exportJson(options) {
|
|
1913
|
+
var name = options.name, value = options.value, order = options.order, message = options.message;
|
|
1914
|
+
checkSerializableAsJson({ name: name, value: value, message: message });
|
|
1915
|
+
var orderedValue =
|
|
1916
|
+
// TODO: Fix error "Type instantiation is excessively deep and possibly infinite."
|
|
1917
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1918
|
+
// @ts-ignore
|
|
1919
|
+
order === undefined
|
|
1920
|
+
? deepClone(value)
|
|
1921
|
+
: orderJson({
|
|
1922
|
+
value: value,
|
|
1923
|
+
// <- Note: checkSerializableAsJson asserts that the value is serializable as JSON
|
|
1924
|
+
order: order,
|
|
1925
|
+
});
|
|
1926
|
+
$deepFreeze(orderedValue);
|
|
1927
|
+
return orderedValue;
|
|
1928
|
+
}
|
|
1929
|
+
/**
|
|
1930
|
+
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
1931
|
+
*/
|
|
1932
|
+
|
|
1933
|
+
/**
|
|
1934
|
+
* Nonce which is used for replacing things in strings
|
|
1935
|
+
*
|
|
1936
|
+
* @private within the repository
|
|
1937
|
+
*/
|
|
1938
|
+
var REPLACING_NONCE = 'u$k42k%!V2zo34w7Fu#@QUHYPW';
|
|
1939
|
+
/**
|
|
1940
|
+
* @@@
|
|
1941
|
+
*
|
|
1942
|
+
* @private within the repository
|
|
1943
|
+
*/
|
|
1944
|
+
var RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;
|
|
1945
|
+
/**
|
|
1946
|
+
* @@@
|
|
1947
|
+
*
|
|
1948
|
+
* @private within the repository
|
|
1949
|
+
*/
|
|
1950
|
+
var RESERVED_PARAMETER_RESTRICTED = 'RESTRICTED-' + REPLACING_NONCE;
|
|
1951
|
+
/**
|
|
1952
|
+
* The names of the parameters that are reserved for special purposes
|
|
1953
|
+
*
|
|
1954
|
+
* @public exported from `@promptbook/core`
|
|
1955
|
+
*/
|
|
1956
|
+
exportJson({
|
|
1957
|
+
name: 'RESERVED_PARAMETER_NAMES',
|
|
1958
|
+
message: "The names of the parameters that are reserved for special purposes",
|
|
1959
|
+
value: [
|
|
1960
|
+
'content',
|
|
1961
|
+
'context',
|
|
1962
|
+
'knowledge',
|
|
1963
|
+
'examples',
|
|
1964
|
+
'modelName',
|
|
1965
|
+
'currentDate',
|
|
1966
|
+
// <- TODO: list here all command names
|
|
1967
|
+
// <- TODO: Add more like 'date', 'modelName',...
|
|
1968
|
+
// <- TODO: Add [emoji] + instructions ACRY when adding new reserved parameter
|
|
1969
|
+
],
|
|
1970
|
+
});
|
|
1971
|
+
/**
|
|
1972
|
+
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
1973
|
+
*/
|
|
1974
|
+
|
|
1720
1975
|
/**
|
|
1721
1976
|
* Replaces parameters in template with values from parameters object
|
|
1722
1977
|
*
|
|
@@ -1898,166 +2153,6 @@
|
|
|
1898
2153
|
return text;
|
|
1899
2154
|
}
|
|
1900
2155
|
|
|
1901
|
-
/**
|
|
1902
|
-
* @@@
|
|
1903
|
-
*
|
|
1904
|
-
* Note: `$` is used to indicate that this function is not a pure function - it mutates given object
|
|
1905
|
-
* Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
|
|
1906
|
-
*
|
|
1907
|
-
* @returns The same object as the input, but deeply frozen
|
|
1908
|
-
* @public exported from `@promptbook/utils`
|
|
1909
|
-
*/
|
|
1910
|
-
function $deepFreeze(objectValue) {
|
|
1911
|
-
var e_1, _a;
|
|
1912
|
-
if (Array.isArray(objectValue)) {
|
|
1913
|
-
return Object.freeze(objectValue.map(function (item) { return $deepFreeze(item); }));
|
|
1914
|
-
}
|
|
1915
|
-
var propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
1916
|
-
try {
|
|
1917
|
-
for (var propertyNames_1 = __values(propertyNames), propertyNames_1_1 = propertyNames_1.next(); !propertyNames_1_1.done; propertyNames_1_1 = propertyNames_1.next()) {
|
|
1918
|
-
var propertyName = propertyNames_1_1.value;
|
|
1919
|
-
var value = objectValue[propertyName];
|
|
1920
|
-
if (value && typeof value === 'object') {
|
|
1921
|
-
$deepFreeze(value);
|
|
1922
|
-
}
|
|
1923
|
-
}
|
|
1924
|
-
}
|
|
1925
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
1926
|
-
finally {
|
|
1927
|
-
try {
|
|
1928
|
-
if (propertyNames_1_1 && !propertyNames_1_1.done && (_a = propertyNames_1.return)) _a.call(propertyNames_1);
|
|
1929
|
-
}
|
|
1930
|
-
finally { if (e_1) throw e_1.error; }
|
|
1931
|
-
}
|
|
1932
|
-
return Object.freeze(objectValue);
|
|
1933
|
-
}
|
|
1934
|
-
/**
|
|
1935
|
-
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
1936
|
-
*/
|
|
1937
|
-
|
|
1938
|
-
/**
|
|
1939
|
-
* Checks if the value is [🚉] serializable as JSON
|
|
1940
|
-
* If not, throws an UnexpectedError with a rich error message and tracking
|
|
1941
|
-
*
|
|
1942
|
-
* - Almost all primitives are serializable BUT:
|
|
1943
|
-
* - `undefined` is not serializable
|
|
1944
|
-
* - `NaN` is not serializable
|
|
1945
|
-
* - Objects and arrays are serializable if all their properties are serializable
|
|
1946
|
-
* - Functions are not serializable
|
|
1947
|
-
* - Circular references are not serializable
|
|
1948
|
-
* - `Date` objects are not serializable
|
|
1949
|
-
* - `Map` and `Set` objects are not serializable
|
|
1950
|
-
* - `RegExp` objects are not serializable
|
|
1951
|
-
* - `Error` objects are not serializable
|
|
1952
|
-
* - `Symbol` objects are not serializable
|
|
1953
|
-
* - And much more...
|
|
1954
|
-
*
|
|
1955
|
-
* @throws UnexpectedError if the value is not serializable as JSON
|
|
1956
|
-
* @public exported from `@promptbook/utils`
|
|
1957
|
-
*/
|
|
1958
|
-
function checkSerializableAsJson(name, value) {
|
|
1959
|
-
var e_1, _a;
|
|
1960
|
-
if (value === undefined) {
|
|
1961
|
-
throw new UnexpectedError("".concat(name, " is undefined"));
|
|
1962
|
-
}
|
|
1963
|
-
else if (value === null) {
|
|
1964
|
-
return;
|
|
1965
|
-
}
|
|
1966
|
-
else if (typeof value === 'boolean') {
|
|
1967
|
-
return;
|
|
1968
|
-
}
|
|
1969
|
-
else if (typeof value === 'number' && !isNaN(value)) {
|
|
1970
|
-
return;
|
|
1971
|
-
}
|
|
1972
|
-
else if (typeof value === 'string') {
|
|
1973
|
-
return;
|
|
1974
|
-
}
|
|
1975
|
-
else if (typeof value === 'symbol') {
|
|
1976
|
-
throw new UnexpectedError("".concat(name, " is symbol"));
|
|
1977
|
-
}
|
|
1978
|
-
else if (typeof value === 'function') {
|
|
1979
|
-
throw new UnexpectedError("".concat(name, " is function"));
|
|
1980
|
-
}
|
|
1981
|
-
else if (typeof value === 'object' && Array.isArray(value)) {
|
|
1982
|
-
for (var i = 0; i < value.length; i++) {
|
|
1983
|
-
checkSerializableAsJson("".concat(name, "[").concat(i, "]"), value[i]);
|
|
1984
|
-
}
|
|
1985
|
-
}
|
|
1986
|
-
else if (typeof value === 'object') {
|
|
1987
|
-
if (value instanceof Date) {
|
|
1988
|
-
throw new UnexpectedError(spaceTrim__default["default"]("\n ".concat(name, " is Date\n\n Use `string_date_iso8601` instead\n ")));
|
|
1989
|
-
}
|
|
1990
|
-
else if (value instanceof Map) {
|
|
1991
|
-
throw new UnexpectedError("".concat(name, " is Map"));
|
|
1992
|
-
}
|
|
1993
|
-
else if (value instanceof Set) {
|
|
1994
|
-
throw new UnexpectedError("".concat(name, " is Set"));
|
|
1995
|
-
}
|
|
1996
|
-
else if (value instanceof RegExp) {
|
|
1997
|
-
throw new UnexpectedError("".concat(name, " is RegExp"));
|
|
1998
|
-
}
|
|
1999
|
-
else if (value instanceof Error) {
|
|
2000
|
-
throw new UnexpectedError(spaceTrim__default["default"]("\n ".concat(name, " is unserialized Error\n\n Use function `serializeError`\n ")));
|
|
2001
|
-
}
|
|
2002
|
-
else {
|
|
2003
|
-
try {
|
|
2004
|
-
for (var _b = __values(Object.entries(value)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
2005
|
-
var _d = __read(_c.value, 2), subName = _d[0], subValue = _d[1];
|
|
2006
|
-
if (subValue === undefined) {
|
|
2007
|
-
// Note: undefined in object is serializable - it is just omited
|
|
2008
|
-
continue;
|
|
2009
|
-
}
|
|
2010
|
-
checkSerializableAsJson("".concat(name, ".").concat(subName), subValue);
|
|
2011
|
-
}
|
|
2012
|
-
}
|
|
2013
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
2014
|
-
finally {
|
|
2015
|
-
try {
|
|
2016
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
2017
|
-
}
|
|
2018
|
-
finally { if (e_1) throw e_1.error; }
|
|
2019
|
-
}
|
|
2020
|
-
try {
|
|
2021
|
-
JSON.stringify(value); // <- TODO: [0]
|
|
2022
|
-
}
|
|
2023
|
-
catch (error) {
|
|
2024
|
-
if (!(error instanceof Error)) {
|
|
2025
|
-
throw error;
|
|
2026
|
-
}
|
|
2027
|
-
throw new UnexpectedError(spaceTrim__default["default"](function (block) { return "\n ".concat(name, " is not serializable\n\n ").concat(block(error.toString()), "\n "); }));
|
|
2028
|
-
}
|
|
2029
|
-
/*
|
|
2030
|
-
TODO: [0] Is there some more elegant way to check circular references?
|
|
2031
|
-
const seen = new Set();
|
|
2032
|
-
const stack = [{ value }];
|
|
2033
|
-
while (stack.length > 0) {
|
|
2034
|
-
const { value } = stack.pop()!;
|
|
2035
|
-
if (typeof value === 'object' && value !== null) {
|
|
2036
|
-
if (seen.has(value)) {
|
|
2037
|
-
throw new UnexpectedError(`${name} has circular reference`);
|
|
2038
|
-
}
|
|
2039
|
-
seen.add(value);
|
|
2040
|
-
if (Array.isArray(value)) {
|
|
2041
|
-
stack.push(...value.map((value) => ({ value })));
|
|
2042
|
-
} else {
|
|
2043
|
-
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
2044
|
-
}
|
|
2045
|
-
}
|
|
2046
|
-
}
|
|
2047
|
-
*/
|
|
2048
|
-
return;
|
|
2049
|
-
}
|
|
2050
|
-
}
|
|
2051
|
-
else {
|
|
2052
|
-
throw new UnexpectedError("".concat(name, " is unknown"));
|
|
2053
|
-
}
|
|
2054
|
-
}
|
|
2055
|
-
/**
|
|
2056
|
-
* TODO: [🧠][🛣] More elegant way to tracking than passing `name`
|
|
2057
|
-
* TODO: [🧠][main] !!! In-memory cache of same values to prevent multiple checks
|
|
2058
|
-
* Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
2059
|
-
*/
|
|
2060
|
-
|
|
2061
2156
|
/**
|
|
2062
2157
|
* @@@
|
|
2063
2158
|
*
|
|
@@ -2088,29 +2183,7 @@
|
|
|
2088
2183
|
* TODO: [🍙] Make some standard order of json properties
|
|
2089
2184
|
*/
|
|
2090
2185
|
|
|
2091
|
-
|
|
2092
|
-
* @@@
|
|
2093
|
-
*
|
|
2094
|
-
* @public exported from `@promptbook/utils`
|
|
2095
|
-
*/
|
|
2096
|
-
function deepClone(objectValue) {
|
|
2097
|
-
return JSON.parse(JSON.stringify(objectValue));
|
|
2098
|
-
/*
|
|
2099
|
-
TODO: [🧠] Is there a better implementation?
|
|
2100
|
-
> const propertyNames = Object.getOwnPropertyNames(objectValue);
|
|
2101
|
-
> for (const propertyName of propertyNames) {
|
|
2102
|
-
> const value = (objectValue as really_any)[propertyName];
|
|
2103
|
-
> if (value && typeof value === 'object') {
|
|
2104
|
-
> deepClone(value);
|
|
2105
|
-
> }
|
|
2106
|
-
> }
|
|
2107
|
-
> return Object.assign({}, objectValue);
|
|
2108
|
-
*/
|
|
2109
|
-
}
|
|
2110
|
-
/**
|
|
2111
|
-
* TODO: [🧠] Is there a way how to meaningfully test this utility
|
|
2112
|
-
*/
|
|
2113
|
-
|
|
2186
|
+
// <- TODO: !!!!!!! Auto convert to type `import { ... } from 'type-fest';`
|
|
2114
2187
|
/**
|
|
2115
2188
|
* Tests if the value is [🚉] serializable as JSON
|
|
2116
2189
|
*
|
|
@@ -2132,7 +2205,7 @@
|
|
|
2132
2205
|
*/
|
|
2133
2206
|
function isSerializableAsJson(value) {
|
|
2134
2207
|
try {
|
|
2135
|
-
checkSerializableAsJson(
|
|
2208
|
+
checkSerializableAsJson({ value: value });
|
|
2136
2209
|
return true;
|
|
2137
2210
|
}
|
|
2138
2211
|
catch (error) {
|
|
@@ -2554,6 +2627,7 @@
|
|
|
2554
2627
|
exports.deepClone = deepClone;
|
|
2555
2628
|
exports.deserializeError = deserializeError;
|
|
2556
2629
|
exports.difference = difference;
|
|
2630
|
+
exports.exportJson = exportJson;
|
|
2557
2631
|
exports.extractParameterNames = extractParameterNames;
|
|
2558
2632
|
exports.extractVariablesFromScript = extractVariablesFromScript;
|
|
2559
2633
|
exports.forEachAsync = forEachAsync;
|
|
@@ -2579,6 +2653,7 @@
|
|
|
2579
2653
|
exports.normalizeTo_camelCase = normalizeTo_camelCase;
|
|
2580
2654
|
exports.normalizeTo_snake_case = normalizeTo_snake_case;
|
|
2581
2655
|
exports.normalizeWhitespaces = normalizeWhitespaces;
|
|
2656
|
+
exports.orderJson = orderJson;
|
|
2582
2657
|
exports.parseKeywords = parseKeywords;
|
|
2583
2658
|
exports.parseKeywordsFromString = parseKeywordsFromString;
|
|
2584
2659
|
exports.parseNumber = parseNumber;
|