@twin.org/core 0.0.2-next.3 → 0.0.2-next.4
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/dist/cjs/index.cjs +834 -823
- package/dist/esm/index.mjs +834 -823
- package/docs/changelog.md +17 -0
- package/package.json +2 -2
package/dist/esm/index.mjs
CHANGED
|
@@ -861,1055 +861,1066 @@ class GeneralError extends BaseError {
|
|
|
861
861
|
}
|
|
862
862
|
}
|
|
863
863
|
|
|
864
|
-
// Copyright 2024 IOTA Stiftung.
|
|
865
|
-
// SPDX-License-Identifier: Apache-2.0.
|
|
866
|
-
/* eslint-disable no-bitwise */
|
|
867
864
|
/**
|
|
868
|
-
* Class to
|
|
865
|
+
* Class to handle errors which are triggered by data guards.
|
|
869
866
|
*/
|
|
870
|
-
class
|
|
867
|
+
class GuardError extends BaseError {
|
|
871
868
|
/**
|
|
872
869
|
* Runtime name for the class.
|
|
873
|
-
* @internal
|
|
874
|
-
*/
|
|
875
|
-
static _CLASS_NAME = "Base32";
|
|
876
|
-
/**
|
|
877
|
-
* Alphabet table for encoding.
|
|
878
|
-
* @internal
|
|
879
|
-
*/
|
|
880
|
-
static _ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
|
881
|
-
/**
|
|
882
|
-
* Convert the base 32 string to a byte array.
|
|
883
|
-
* @param base32 The base32 string to convert.
|
|
884
|
-
* @returns The byte array.
|
|
885
|
-
* @throws If the input string contains a character not in the Base32 alphabet.
|
|
886
870
|
*/
|
|
887
|
-
static
|
|
888
|
-
let bits = 0;
|
|
889
|
-
let value = 0;
|
|
890
|
-
base32 = base32.replace(/=+$/, "");
|
|
891
|
-
let index = 0;
|
|
892
|
-
const output = new Uint8Array(Math.trunc((base32.length * 5) / 8));
|
|
893
|
-
for (let i = 0; i < base32.length; i++) {
|
|
894
|
-
const idx = Base32._ALPHABET.indexOf(base32[i]);
|
|
895
|
-
if (idx === -1) {
|
|
896
|
-
throw new GeneralError(Base32._CLASS_NAME, "invalidCharacter", {
|
|
897
|
-
invalidCharacter: base32[i]
|
|
898
|
-
});
|
|
899
|
-
}
|
|
900
|
-
value = (value << 5) | idx;
|
|
901
|
-
bits += 5;
|
|
902
|
-
if (bits >= 8) {
|
|
903
|
-
output[index++] = (value >>> (bits - 8)) & 255;
|
|
904
|
-
bits -= 8;
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
return output;
|
|
908
|
-
}
|
|
871
|
+
static CLASS_NAME = "GuardError";
|
|
909
872
|
/**
|
|
910
|
-
*
|
|
911
|
-
* @param
|
|
912
|
-
* @
|
|
873
|
+
* Create a new instance of GuardError.
|
|
874
|
+
* @param source The source of the error.
|
|
875
|
+
* @param message The message as a code.
|
|
876
|
+
* @param propertyName The property which triggered the guard error for the item.
|
|
877
|
+
* @param propertyValue The property value which triggered the guard error for the item.
|
|
878
|
+
* @param propertyOptions The property options which might be allowed.
|
|
913
879
|
*/
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
bits += 8;
|
|
921
|
-
while (bits >= 5) {
|
|
922
|
-
output += Base32._ALPHABET[(value >>> (bits - 5)) & 31];
|
|
923
|
-
bits -= 5;
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
if (bits > 0) {
|
|
927
|
-
output += Base32._ALPHABET[(value << (5 - bits)) & 31];
|
|
928
|
-
}
|
|
929
|
-
while (output.length % 8 !== 0) {
|
|
930
|
-
output += "=";
|
|
931
|
-
}
|
|
932
|
-
return output;
|
|
880
|
+
constructor(source, message, propertyName, propertyValue, propertyOptions) {
|
|
881
|
+
super(GuardError.CLASS_NAME, source, message, {
|
|
882
|
+
property: propertyName ?? "property",
|
|
883
|
+
value: Is.undefined(propertyValue) ? "undefined" : propertyValue,
|
|
884
|
+
options: propertyOptions
|
|
885
|
+
});
|
|
933
886
|
}
|
|
934
887
|
}
|
|
935
888
|
|
|
936
889
|
/**
|
|
937
|
-
* Class to help with
|
|
890
|
+
* Class to help with arrays.
|
|
938
891
|
*/
|
|
939
|
-
class
|
|
940
|
-
/**
|
|
941
|
-
* Runtime name for the class.
|
|
942
|
-
* @internal
|
|
943
|
-
*/
|
|
944
|
-
static _CLASS_NAME = "Base58";
|
|
945
|
-
/**
|
|
946
|
-
* Alphabet table for encoding.
|
|
947
|
-
* @internal
|
|
948
|
-
*/
|
|
949
|
-
static _ALPHABET =
|
|
950
|
-
// cspell:disable-next-line
|
|
951
|
-
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
952
|
-
/**
|
|
953
|
-
* Reverse map for decoding.
|
|
954
|
-
* @internal
|
|
955
|
-
*/
|
|
956
|
-
static _ALPHABET_REVERSE = [
|
|
957
|
-
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
958
|
-
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
959
|
-
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, -1, -1, -1, -1, 9, 10, 11, 12, 13, 14, 15, 16, -1,
|
|
960
|
-
17, 18, 19, 20, 21, -1, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1, -1, 33,
|
|
961
|
-
34, 35, 36, 37, 38, 39, 40, 41, 42, 43, -1, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
|
|
962
|
-
57, -1, -1, -1, -1, -1
|
|
963
|
-
];
|
|
892
|
+
class ArrayHelper {
|
|
964
893
|
/**
|
|
965
|
-
*
|
|
966
|
-
* @param
|
|
967
|
-
* @
|
|
968
|
-
* @
|
|
894
|
+
* Do the two arrays match.
|
|
895
|
+
* @param arr1 The first array.
|
|
896
|
+
* @param arr2 The second array.
|
|
897
|
+
* @returns True if both arrays are empty of have the same values.
|
|
969
898
|
*/
|
|
970
|
-
static
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
if (base58[i] !== "1") {
|
|
974
|
-
break;
|
|
975
|
-
}
|
|
976
|
-
zeroes += 1;
|
|
899
|
+
static matches(arr1, arr2) {
|
|
900
|
+
if (Is.empty(arr1) && Is.empty(arr2)) {
|
|
901
|
+
return true;
|
|
977
902
|
}
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
let length = 0;
|
|
981
|
-
for (let i = zeroes; i < base58.length; i++) {
|
|
982
|
-
const ch = base58.charCodeAt(i);
|
|
983
|
-
if (ch & 0xff80) {
|
|
984
|
-
throw new GeneralError(Base58._CLASS_NAME, "invalidCharacter", { invalidCharacter: ch });
|
|
985
|
-
}
|
|
986
|
-
const val = Base58._ALPHABET_REVERSE[ch];
|
|
987
|
-
if (val === -1) {
|
|
988
|
-
throw new GeneralError(Base58._CLASS_NAME, "invalidCharacter", { invalidCharacter: ch });
|
|
989
|
-
}
|
|
990
|
-
let carry = val;
|
|
991
|
-
let j = 0;
|
|
992
|
-
for (let k = size - 1; k >= 0; k--, j++) {
|
|
993
|
-
if (carry === 0 && j >= length) {
|
|
994
|
-
break;
|
|
995
|
-
}
|
|
996
|
-
carry += b256[k] * 58;
|
|
997
|
-
b256[k] = carry;
|
|
998
|
-
carry >>>= 8;
|
|
999
|
-
}
|
|
1000
|
-
length = j;
|
|
903
|
+
if (!((Is.array(arr1) && Is.array(arr2)) || (Is.typedArray(arr1) && Is.typedArray(arr2)))) {
|
|
904
|
+
return false;
|
|
1001
905
|
}
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
for (j = 0; j < zeroes; j++) {
|
|
1005
|
-
out[j] = 0;
|
|
906
|
+
if (arr1.length !== arr2.length) {
|
|
907
|
+
return false;
|
|
1006
908
|
}
|
|
1007
|
-
let i =
|
|
1008
|
-
|
|
1009
|
-
|
|
909
|
+
for (let i = 0; i < arr1.length; i++) {
|
|
910
|
+
if (arr1[i] !== arr2[i]) {
|
|
911
|
+
return false;
|
|
912
|
+
}
|
|
1010
913
|
}
|
|
1011
|
-
return
|
|
914
|
+
return true;
|
|
1012
915
|
}
|
|
1013
916
|
/**
|
|
1014
|
-
* Convert
|
|
1015
|
-
* @param
|
|
1016
|
-
* @returns The
|
|
917
|
+
* Convert an object or array to an array.
|
|
918
|
+
* @param value The object or array to convert.
|
|
919
|
+
* @returns The array.
|
|
1017
920
|
*/
|
|
1018
|
-
static
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
if (bytes[i] !== 0) {
|
|
1022
|
-
break;
|
|
1023
|
-
}
|
|
1024
|
-
zeroes += 1;
|
|
1025
|
-
}
|
|
1026
|
-
const size = Math.trunc(((bytes.length - zeroes) * 138) / 100) + 1;
|
|
1027
|
-
const b58 = new Uint8Array(size).fill(0);
|
|
1028
|
-
let length = 0;
|
|
1029
|
-
for (let i = zeroes; i < bytes.length; i++) {
|
|
1030
|
-
let carry = bytes[i];
|
|
1031
|
-
let j = 0;
|
|
1032
|
-
for (let k = size - 1; k >= 0; k--, j++) {
|
|
1033
|
-
if (carry === 0 && j >= length) {
|
|
1034
|
-
break;
|
|
1035
|
-
}
|
|
1036
|
-
carry += b58[k] * 256;
|
|
1037
|
-
b58[k] = carry % 58;
|
|
1038
|
-
carry = Math.trunc(carry / 58);
|
|
1039
|
-
}
|
|
1040
|
-
length = j;
|
|
1041
|
-
}
|
|
1042
|
-
let i = size - length;
|
|
1043
|
-
while (i < size && b58[i] === 0) {
|
|
1044
|
-
i += 1;
|
|
1045
|
-
}
|
|
1046
|
-
let str = "";
|
|
1047
|
-
for (let j = 0; j < zeroes; j++) {
|
|
1048
|
-
str += "1";
|
|
921
|
+
static fromObjectOrArray(value) {
|
|
922
|
+
if (Is.empty(value)) {
|
|
923
|
+
return undefined;
|
|
1049
924
|
}
|
|
1050
|
-
|
|
1051
|
-
|
|
925
|
+
if (Is.array(value)) {
|
|
926
|
+
return value;
|
|
1052
927
|
}
|
|
1053
|
-
return
|
|
928
|
+
return [value];
|
|
1054
929
|
}
|
|
1055
930
|
}
|
|
1056
931
|
|
|
1057
932
|
// Copyright 2024 IOTA Stiftung.
|
|
1058
933
|
// SPDX-License-Identifier: Apache-2.0.
|
|
1059
|
-
/* eslint-disable no-bitwise */
|
|
1060
|
-
/* eslint-disable no-mixed-operators */
|
|
1061
934
|
/**
|
|
1062
|
-
* Class to
|
|
1063
|
-
* Sourced from https://github.com/beatgammit/base64-js.
|
|
935
|
+
* Class to handle guard operations for parameters.
|
|
1064
936
|
*/
|
|
1065
|
-
class
|
|
937
|
+
class Guards {
|
|
1066
938
|
/**
|
|
1067
|
-
*
|
|
1068
|
-
* @
|
|
939
|
+
* Is the property defined.
|
|
940
|
+
* @param source The source of the error.
|
|
941
|
+
* @param property The name of the property.
|
|
942
|
+
* @param value The value to test.
|
|
943
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1069
944
|
*/
|
|
1070
|
-
static
|
|
945
|
+
static defined(source, property, value) {
|
|
946
|
+
if (Is.undefined(value)) {
|
|
947
|
+
throw new GuardError(source, "guard.undefined", property, value);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
1071
950
|
/**
|
|
1072
|
-
*
|
|
1073
|
-
* @
|
|
951
|
+
* Is the property a string.
|
|
952
|
+
* @param source The source of the error.
|
|
953
|
+
* @param property The name of the property.
|
|
954
|
+
* @param value The value to test.
|
|
955
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1074
956
|
*/
|
|
1075
|
-
static
|
|
957
|
+
static string(source, property, value) {
|
|
958
|
+
if (!Is.string(value)) {
|
|
959
|
+
throw new GuardError(source, "guard.string", property, value);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
1076
962
|
/**
|
|
1077
|
-
*
|
|
1078
|
-
* @
|
|
963
|
+
* Is the property a string with a value.
|
|
964
|
+
* @param source The source of the error.
|
|
965
|
+
* @param property The name of the property.
|
|
966
|
+
* @param value The value to test.
|
|
967
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1079
968
|
*/
|
|
1080
|
-
static
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
"52": 56,
|
|
1089
|
-
"53": 57,
|
|
1090
|
-
"54": 58,
|
|
1091
|
-
"55": 59,
|
|
1092
|
-
"56": 60,
|
|
1093
|
-
"57": 61,
|
|
1094
|
-
"65": 0,
|
|
1095
|
-
"66": 1,
|
|
1096
|
-
"67": 2,
|
|
1097
|
-
"68": 3,
|
|
1098
|
-
"69": 4,
|
|
1099
|
-
"70": 5,
|
|
1100
|
-
"71": 6,
|
|
1101
|
-
"72": 7,
|
|
1102
|
-
"73": 8,
|
|
1103
|
-
"74": 9,
|
|
1104
|
-
"75": 10,
|
|
1105
|
-
"76": 11,
|
|
1106
|
-
"77": 12,
|
|
1107
|
-
"78": 13,
|
|
1108
|
-
"79": 14,
|
|
1109
|
-
"80": 15,
|
|
1110
|
-
"81": 16,
|
|
1111
|
-
"82": 17,
|
|
1112
|
-
"83": 18,
|
|
1113
|
-
"84": 19,
|
|
1114
|
-
"85": 20,
|
|
1115
|
-
"86": 21,
|
|
1116
|
-
"87": 22,
|
|
1117
|
-
"88": 23,
|
|
1118
|
-
"89": 24,
|
|
1119
|
-
"90": 25,
|
|
1120
|
-
"95": 63,
|
|
1121
|
-
"97": 26,
|
|
1122
|
-
"98": 27,
|
|
1123
|
-
"99": 28,
|
|
1124
|
-
"100": 29,
|
|
1125
|
-
"101": 30,
|
|
1126
|
-
"102": 31,
|
|
1127
|
-
"103": 32,
|
|
1128
|
-
"104": 33,
|
|
1129
|
-
"105": 34,
|
|
1130
|
-
"106": 35,
|
|
1131
|
-
"107": 36,
|
|
1132
|
-
"108": 37,
|
|
1133
|
-
"109": 38,
|
|
1134
|
-
"110": 39,
|
|
1135
|
-
"111": 40,
|
|
1136
|
-
"112": 41,
|
|
1137
|
-
"113": 42,
|
|
1138
|
-
"114": 43,
|
|
1139
|
-
"115": 44,
|
|
1140
|
-
"116": 45,
|
|
1141
|
-
"117": 46,
|
|
1142
|
-
"118": 47,
|
|
1143
|
-
"119": 48,
|
|
1144
|
-
"120": 49,
|
|
1145
|
-
"121": 50,
|
|
1146
|
-
"122": 51
|
|
1147
|
-
};
|
|
969
|
+
static stringValue(source, property, value) {
|
|
970
|
+
if (!Is.string(value)) {
|
|
971
|
+
throw new GuardError(source, "guard.string", property, value);
|
|
972
|
+
}
|
|
973
|
+
if (value.length === 0) {
|
|
974
|
+
throw new GuardError(source, "guard.stringEmpty", property, value);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
1148
977
|
/**
|
|
1149
|
-
*
|
|
1150
|
-
* @param
|
|
1151
|
-
* @
|
|
978
|
+
* Is the property a JSON value.
|
|
979
|
+
* @param source The source of the error.
|
|
980
|
+
* @param property The name of the property.
|
|
981
|
+
* @param value The value to test.
|
|
982
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1152
983
|
*/
|
|
1153
|
-
static
|
|
1154
|
-
|
|
1155
|
-
|
|
984
|
+
static json(source, property, value) {
|
|
985
|
+
if (!Is.json(value)) {
|
|
986
|
+
throw new GuardError(source, "guard.stringJson", property, value);
|
|
987
|
+
}
|
|
1156
988
|
}
|
|
1157
989
|
/**
|
|
1158
|
-
*
|
|
1159
|
-
* @param
|
|
1160
|
-
* @
|
|
990
|
+
* Is the property a base64 string.
|
|
991
|
+
* @param source The source of the error.
|
|
992
|
+
* @param property The name of the property.
|
|
993
|
+
* @param value The value to test.
|
|
994
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1161
995
|
*/
|
|
1162
|
-
static
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
const validLen = lens[0];
|
|
1166
|
-
const placeHoldersLen = lens[1];
|
|
1167
|
-
const arr = new Uint8Array(Base64.calcByteLength(validLen, placeHoldersLen));
|
|
1168
|
-
let curByte = 0;
|
|
1169
|
-
// if there are placeholders, only get up to the last complete 4 chars
|
|
1170
|
-
const len = placeHoldersLen > 0 ? validLen - 4 : validLen;
|
|
1171
|
-
let i;
|
|
1172
|
-
for (i = 0; i < len; i += 4) {
|
|
1173
|
-
tmp =
|
|
1174
|
-
(Base64._REVERSE_LOOKUP[base64.charCodeAt(i)] << 18) |
|
|
1175
|
-
(Base64._REVERSE_LOOKUP[base64.charCodeAt(i + 1)] << 12) |
|
|
1176
|
-
(Base64._REVERSE_LOOKUP[base64.charCodeAt(i + 2)] << 6) |
|
|
1177
|
-
Base64._REVERSE_LOOKUP[base64.charCodeAt(i + 3)];
|
|
1178
|
-
arr[curByte++] = (tmp >> 16) & 0xff;
|
|
1179
|
-
arr[curByte++] = (tmp >> 8) & 0xff;
|
|
1180
|
-
arr[curByte++] = tmp & 0xff;
|
|
1181
|
-
}
|
|
1182
|
-
if (placeHoldersLen === 2) {
|
|
1183
|
-
tmp =
|
|
1184
|
-
(Base64._REVERSE_LOOKUP[base64.charCodeAt(i)] << 2) |
|
|
1185
|
-
(Base64._REVERSE_LOOKUP[base64.charCodeAt(i + 1)] >> 4);
|
|
1186
|
-
arr[curByte++] = tmp & 0xff;
|
|
996
|
+
static stringBase64(source, property, value) {
|
|
997
|
+
if (!Is.stringBase64(value)) {
|
|
998
|
+
throw new GuardError(source, "guard.base64", property, value);
|
|
1187
999
|
}
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1000
|
+
}
|
|
1001
|
+
/**
|
|
1002
|
+
* Is the property a base64 url string.
|
|
1003
|
+
* @param source The source of the error.
|
|
1004
|
+
* @param property The name of the property.
|
|
1005
|
+
* @param value The value to test.
|
|
1006
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1007
|
+
*/
|
|
1008
|
+
static stringBase64Url(source, property, value) {
|
|
1009
|
+
if (!Is.stringBase64Url(value)) {
|
|
1010
|
+
throw new GuardError(source, "guard.base64Url", property, value);
|
|
1195
1011
|
}
|
|
1196
|
-
return arr;
|
|
1197
1012
|
}
|
|
1198
1013
|
/**
|
|
1199
|
-
*
|
|
1200
|
-
* @param
|
|
1201
|
-
* @
|
|
1014
|
+
* Is the property a base58 string.
|
|
1015
|
+
* @param source The source of the error.
|
|
1016
|
+
* @param property The name of the property.
|
|
1017
|
+
* @param value The value to test.
|
|
1018
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1202
1019
|
*/
|
|
1203
|
-
static
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
const extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes
|
|
1207
|
-
const parts = [];
|
|
1208
|
-
const maxChunkLength = 16383; // must be multiple of 3
|
|
1209
|
-
// go through the array every three bytes, we'll deal with trailing stuff later
|
|
1210
|
-
for (let i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
|
|
1211
|
-
parts.push(Base64.encodeChunk(bytes, i, Math.min(i + maxChunkLength, len2)));
|
|
1020
|
+
static stringBase58(source, property, value) {
|
|
1021
|
+
if (!Is.stringBase58(value)) {
|
|
1022
|
+
throw new GuardError(source, "guard.base58", property, value);
|
|
1212
1023
|
}
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1024
|
+
}
|
|
1025
|
+
/**
|
|
1026
|
+
* Is the property a string with a hex value.
|
|
1027
|
+
* @param source The source of the error.
|
|
1028
|
+
* @param property The name of the property.
|
|
1029
|
+
* @param value The value to test.
|
|
1030
|
+
* @param allowPrefix Allow the hex to have the 0x prefix.
|
|
1031
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1032
|
+
*/
|
|
1033
|
+
static stringHex(source, property, value, allowPrefix = false) {
|
|
1034
|
+
Guards.stringValue(source, property, value);
|
|
1035
|
+
if (!HexHelper.isHex(value, allowPrefix)) {
|
|
1036
|
+
throw new GuardError(source, "guard.stringHex", property, value);
|
|
1217
1037
|
}
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1038
|
+
}
|
|
1039
|
+
/**
|
|
1040
|
+
* Is the property a string with a hex value with fixed length.
|
|
1041
|
+
* @param source The source of the error.
|
|
1042
|
+
* @param property The name of the property.
|
|
1043
|
+
* @param value The value to test.
|
|
1044
|
+
* @param length The length of the string to match.
|
|
1045
|
+
* @param allowPrefix Allow the hex to have the 0x prefix.
|
|
1046
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1047
|
+
*/
|
|
1048
|
+
static stringHexLength(source, property, value, length, allowPrefix = false) {
|
|
1049
|
+
Guards.stringHex(source, property, value, allowPrefix);
|
|
1050
|
+
if (HexHelper.stripPrefix(value).length !== length) {
|
|
1051
|
+
throw new GuardError(source, "guard.stringHexLength", property, value.length, length.toString());
|
|
1221
1052
|
}
|
|
1222
|
-
return parts.join("");
|
|
1223
1053
|
}
|
|
1224
1054
|
/**
|
|
1225
|
-
*
|
|
1226
|
-
* @param
|
|
1227
|
-
* @param
|
|
1228
|
-
* @
|
|
1229
|
-
* @
|
|
1055
|
+
* Is the property a number.
|
|
1056
|
+
* @param source The source of the error.
|
|
1057
|
+
* @param property The name of the property.
|
|
1058
|
+
* @param value The value to test.
|
|
1059
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1230
1060
|
*/
|
|
1231
|
-
static
|
|
1232
|
-
|
|
1061
|
+
static number(source, property, value) {
|
|
1062
|
+
if (!Is.number(value)) {
|
|
1063
|
+
throw new GuardError(source, "guard.number", property, value);
|
|
1064
|
+
}
|
|
1233
1065
|
}
|
|
1234
1066
|
/**
|
|
1235
|
-
*
|
|
1236
|
-
* @param
|
|
1237
|
-
* @
|
|
1238
|
-
* @
|
|
1067
|
+
* Is the property an integer.
|
|
1068
|
+
* @param source The source of the error.
|
|
1069
|
+
* @param property The name of the property.
|
|
1070
|
+
* @param value The value to test.
|
|
1071
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1239
1072
|
*/
|
|
1240
|
-
static
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
throw new GeneralError(Base64._CLASS_NAME, "length4Multiple", { value: len });
|
|
1073
|
+
static integer(source, property, value) {
|
|
1074
|
+
if (!Is.integer(value)) {
|
|
1075
|
+
throw new GuardError(source, "guard.integer", property, value);
|
|
1244
1076
|
}
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1077
|
+
}
|
|
1078
|
+
/**
|
|
1079
|
+
* Is the property a bigint.
|
|
1080
|
+
* @param source The source of the error.
|
|
1081
|
+
* @param property The name of the property.
|
|
1082
|
+
* @param value The value to test.
|
|
1083
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1084
|
+
*/
|
|
1085
|
+
static bigint(source, property, value) {
|
|
1086
|
+
if (!Is.bigint(value)) {
|
|
1087
|
+
throw new GuardError(source, "guard.bigint", property, value);
|
|
1250
1088
|
}
|
|
1251
|
-
const placeHoldersLen = validLen === len ? 0 : 4 - (validLen % 4);
|
|
1252
|
-
return [validLen, placeHoldersLen];
|
|
1253
1089
|
}
|
|
1254
1090
|
/**
|
|
1255
|
-
*
|
|
1256
|
-
* @param
|
|
1257
|
-
* @
|
|
1258
|
-
* @
|
|
1091
|
+
* Is the property a boolean.
|
|
1092
|
+
* @param source The source of the error.
|
|
1093
|
+
* @param property The name of the property.
|
|
1094
|
+
* @param value The value to test.
|
|
1095
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1259
1096
|
*/
|
|
1260
|
-
static
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
Base64._LOOKUP[num & 0x3f]);
|
|
1097
|
+
static boolean(source, property, value) {
|
|
1098
|
+
if (!Is.boolean(value)) {
|
|
1099
|
+
throw new GuardError(source, "guard.boolean", property, value);
|
|
1100
|
+
}
|
|
1265
1101
|
}
|
|
1266
1102
|
/**
|
|
1267
|
-
*
|
|
1268
|
-
* @param
|
|
1269
|
-
* @param
|
|
1270
|
-
* @param
|
|
1271
|
-
* @
|
|
1272
|
-
* @internal
|
|
1103
|
+
* Is the property a date.
|
|
1104
|
+
* @param source The source of the error.
|
|
1105
|
+
* @param property The name of the property.
|
|
1106
|
+
* @param value The value to test.
|
|
1107
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1273
1108
|
*/
|
|
1274
|
-
static
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
for (let i = start; i < end; i += 3) {
|
|
1278
|
-
tmp = ((bytes[i] << 16) & 0xff0000) + ((bytes[i + 1] << 8) & 0xff00) + (bytes[i + 2] & 0xff);
|
|
1279
|
-
output.push(Base64.tripletToBase64(tmp));
|
|
1109
|
+
static date(source, property, value) {
|
|
1110
|
+
if (!Is.date(value)) {
|
|
1111
|
+
throw new GuardError(source, "guard.date", property, value);
|
|
1280
1112
|
}
|
|
1281
|
-
return output.join("");
|
|
1282
1113
|
}
|
|
1283
|
-
}
|
|
1284
|
-
|
|
1285
|
-
// Copyright 2024 IOTA Stiftung.
|
|
1286
|
-
// SPDX-License-Identifier: Apache-2.0.
|
|
1287
|
-
/**
|
|
1288
|
-
* Class to help with base64 URL Encoding/Decoding.
|
|
1289
|
-
* https://www.rfc-editor.org/rfc/rfc4648#section-5.
|
|
1290
|
-
*/
|
|
1291
|
-
class Base64Url {
|
|
1292
1114
|
/**
|
|
1293
|
-
*
|
|
1294
|
-
* @param
|
|
1295
|
-
* @
|
|
1115
|
+
* Is the property a timestamp in milliseconds.
|
|
1116
|
+
* @param source The source of the error.
|
|
1117
|
+
* @param property The name of the property.
|
|
1118
|
+
* @param value The value to test.
|
|
1119
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1296
1120
|
*/
|
|
1297
|
-
static
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
if (base64.length > 0 && !base64.endsWith("=")) {
|
|
1301
|
-
const placeHoldersLen = 4 - (base64.length % 4);
|
|
1302
|
-
if (placeHoldersLen > 0 && placeHoldersLen < 4) {
|
|
1303
|
-
base64 = base64.padEnd(base64.length + placeHoldersLen, "=");
|
|
1304
|
-
}
|
|
1121
|
+
static timestampMilliseconds(source, property, value) {
|
|
1122
|
+
if (!Is.timestampMilliseconds(value)) {
|
|
1123
|
+
throw new GuardError(source, "guard.timestampMilliseconds", property, value);
|
|
1305
1124
|
}
|
|
1306
|
-
base64 = base64.replace(/-/g, "+").replace(/_/g, "/");
|
|
1307
|
-
return Base64.decode(base64);
|
|
1308
1125
|
}
|
|
1309
1126
|
/**
|
|
1310
|
-
*
|
|
1311
|
-
* @param
|
|
1312
|
-
* @
|
|
1127
|
+
* Is the property a timestamp in seconds.
|
|
1128
|
+
* @param source The source of the error.
|
|
1129
|
+
* @param property The name of the property.
|
|
1130
|
+
* @param value The value to test.
|
|
1131
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1313
1132
|
*/
|
|
1314
|
-
static
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1133
|
+
static timestampSeconds(source, property, value) {
|
|
1134
|
+
if (!Is.timestampSeconds(value)) {
|
|
1135
|
+
throw new GuardError(source, "guard.timestampSeconds", property, value);
|
|
1136
|
+
}
|
|
1318
1137
|
}
|
|
1319
|
-
}
|
|
1320
|
-
|
|
1321
|
-
/**
|
|
1322
|
-
* Class to handle errors which are triggered by data already existing.
|
|
1323
|
-
*/
|
|
1324
|
-
class AlreadyExistsError extends BaseError {
|
|
1325
1138
|
/**
|
|
1326
|
-
*
|
|
1139
|
+
* Is the property an object.
|
|
1140
|
+
* @param source The source of the error.
|
|
1141
|
+
* @param property The name of the property.
|
|
1142
|
+
* @param value The value to test.
|
|
1143
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1327
1144
|
*/
|
|
1328
|
-
static
|
|
1145
|
+
static object(source, property, value) {
|
|
1146
|
+
if (Is.undefined(value)) {
|
|
1147
|
+
throw new GuardError(source, "guard.objectUndefined", property, value);
|
|
1148
|
+
}
|
|
1149
|
+
if (!Is.object(value)) {
|
|
1150
|
+
throw new GuardError(source, "guard.object", property, value);
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1329
1153
|
/**
|
|
1330
|
-
*
|
|
1154
|
+
* Is the property is an object with at least one property.
|
|
1331
1155
|
* @param source The source of the error.
|
|
1332
|
-
* @param
|
|
1333
|
-
* @param
|
|
1334
|
-
* @
|
|
1156
|
+
* @param property The name of the property.
|
|
1157
|
+
* @param value The value to test.
|
|
1158
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1335
1159
|
*/
|
|
1336
|
-
|
|
1337
|
-
|
|
1160
|
+
static objectValue(source, property, value) {
|
|
1161
|
+
if (Is.undefined(value)) {
|
|
1162
|
+
throw new GuardError(source, "guard.objectUndefined", property, value);
|
|
1163
|
+
}
|
|
1164
|
+
if (!Is.object(value)) {
|
|
1165
|
+
throw new GuardError(source, "guard.object", property, value);
|
|
1166
|
+
}
|
|
1167
|
+
if (Object.keys(value || {}).length === 0) {
|
|
1168
|
+
throw new GuardError(source, "guard.objectValue", property, value);
|
|
1169
|
+
}
|
|
1338
1170
|
}
|
|
1339
|
-
}
|
|
1340
|
-
|
|
1341
|
-
/**
|
|
1342
|
-
* Class to handle errors which are triggered by conflicting data.
|
|
1343
|
-
*/
|
|
1344
|
-
class ConflictError extends BaseError {
|
|
1345
|
-
/**
|
|
1346
|
-
* Runtime name for the class.
|
|
1347
|
-
*/
|
|
1348
|
-
static CLASS_NAME = "ConflictError";
|
|
1349
1171
|
/**
|
|
1350
|
-
*
|
|
1172
|
+
* Is the property is an array.
|
|
1351
1173
|
* @param source The source of the error.
|
|
1352
|
-
* @param
|
|
1353
|
-
* @param
|
|
1354
|
-
* @
|
|
1355
|
-
* @param inner The inner error if we have wrapped another error.
|
|
1174
|
+
* @param property The name of the property.
|
|
1175
|
+
* @param value The value to test.
|
|
1176
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1356
1177
|
*/
|
|
1357
|
-
|
|
1358
|
-
|
|
1178
|
+
static array(source, property, value) {
|
|
1179
|
+
if (!Is.array(value)) {
|
|
1180
|
+
throw new GuardError(source, "guard.array", property, value);
|
|
1181
|
+
}
|
|
1359
1182
|
}
|
|
1360
|
-
}
|
|
1361
|
-
|
|
1362
|
-
/**
|
|
1363
|
-
* Class to handle errors which are triggered by data guards.
|
|
1364
|
-
*/
|
|
1365
|
-
class GuardError extends BaseError {
|
|
1366
1183
|
/**
|
|
1367
|
-
*
|
|
1368
|
-
*/
|
|
1369
|
-
static CLASS_NAME = "GuardError";
|
|
1370
|
-
/**
|
|
1371
|
-
* Create a new instance of GuardError.
|
|
1184
|
+
* Is the property is an array with at least one item.
|
|
1372
1185
|
* @param source The source of the error.
|
|
1373
|
-
* @param
|
|
1374
|
-
* @param
|
|
1375
|
-
* @
|
|
1376
|
-
* @param propertyOptions The property options which might be allowed.
|
|
1186
|
+
* @param property The name of the property.
|
|
1187
|
+
* @param value The value to test.
|
|
1188
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1377
1189
|
*/
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1190
|
+
static arrayValue(source, property, value) {
|
|
1191
|
+
if (!Is.array(value)) {
|
|
1192
|
+
throw new GuardError(source, "guard.array", property, value);
|
|
1193
|
+
}
|
|
1194
|
+
if (value.length === 0) {
|
|
1195
|
+
throw new GuardError(source, "guard.arrayValue", property, value);
|
|
1196
|
+
}
|
|
1384
1197
|
}
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1387
|
-
/**
|
|
1388
|
-
* Class to handle errors which are triggered by data not being found.
|
|
1389
|
-
*/
|
|
1390
|
-
class NotFoundError extends BaseError {
|
|
1391
1198
|
/**
|
|
1392
|
-
*
|
|
1199
|
+
* Is the property one of a list of items.
|
|
1200
|
+
* @param source The source of the error.
|
|
1201
|
+
* @param property The name of the property.
|
|
1202
|
+
* @param value The value to test.
|
|
1203
|
+
* @param options The options the value must be one of.
|
|
1204
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1393
1205
|
*/
|
|
1394
|
-
static
|
|
1206
|
+
static arrayOneOf(source, property, value, options) {
|
|
1207
|
+
if (!Is.array(options)) {
|
|
1208
|
+
throw new GuardError(source, "guard.array", property, value);
|
|
1209
|
+
}
|
|
1210
|
+
if (!options.includes(value)) {
|
|
1211
|
+
throw new GuardError(source, "guard.arrayOneOf", property, value, options.join(", "));
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1395
1214
|
/**
|
|
1396
|
-
*
|
|
1215
|
+
* Does the array start with the specified data.
|
|
1397
1216
|
* @param source The source of the error.
|
|
1398
|
-
* @param
|
|
1399
|
-
* @param
|
|
1400
|
-
* @param
|
|
1217
|
+
* @param property The name of the property.
|
|
1218
|
+
* @param value The value to test.
|
|
1219
|
+
* @param startValues The values that must start the array.
|
|
1220
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1401
1221
|
*/
|
|
1402
|
-
|
|
1403
|
-
|
|
1222
|
+
static arrayStartsWith(source, property, value, startValues) {
|
|
1223
|
+
if (!Is.arrayValue(value)) {
|
|
1224
|
+
throw new GuardError(source, "guard.array", property, value);
|
|
1225
|
+
}
|
|
1226
|
+
const startValuesArray = ArrayHelper.fromObjectOrArray(startValues);
|
|
1227
|
+
if (!Is.arrayValue(startValuesArray)) {
|
|
1228
|
+
throw new GuardError(source, "guard.array", property, startValuesArray);
|
|
1229
|
+
}
|
|
1230
|
+
for (let i = 0; i < startValuesArray.length; i++) {
|
|
1231
|
+
if (value[i] !== startValuesArray[i]) {
|
|
1232
|
+
throw new GuardError(source, "guard.arrayStartsWith", property, value, startValuesArray.join(", "));
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1404
1235
|
}
|
|
1405
|
-
}
|
|
1406
|
-
|
|
1407
|
-
/**
|
|
1408
|
-
* Class to handle errors.
|
|
1409
|
-
*/
|
|
1410
|
-
class NotImplementedError extends BaseError {
|
|
1411
1236
|
/**
|
|
1412
|
-
*
|
|
1237
|
+
* Does the array end with the specified data.
|
|
1238
|
+
* @param source The source of the error.
|
|
1239
|
+
* @param property The name of the property.
|
|
1240
|
+
* @param value The value to test.
|
|
1241
|
+
* @param endValues The values that must end the array.
|
|
1242
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1413
1243
|
*/
|
|
1414
|
-
static
|
|
1244
|
+
static arrayEndsWith(source, property, value, endValues) {
|
|
1245
|
+
if (!Is.arrayValue(value)) {
|
|
1246
|
+
throw new GuardError(source, "guard.array", property, value);
|
|
1247
|
+
}
|
|
1248
|
+
const endValuesArray = ArrayHelper.fromObjectOrArray(endValues);
|
|
1249
|
+
if (!Is.arrayValue(endValuesArray)) {
|
|
1250
|
+
throw new GuardError(source, "guard.array", property, endValuesArray);
|
|
1251
|
+
}
|
|
1252
|
+
for (let i = 0; i < endValuesArray.length; i++) {
|
|
1253
|
+
if (value[value.length - i - 1] !== endValuesArray[endValuesArray.length - i - 1]) {
|
|
1254
|
+
throw new GuardError(source, "guard.arrayEndsWith", property, value, endValuesArray.join(", "));
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1415
1258
|
/**
|
|
1416
|
-
*
|
|
1259
|
+
* Is the property a Uint8Array.
|
|
1417
1260
|
* @param source The source of the error.
|
|
1418
|
-
* @param
|
|
1261
|
+
* @param property The name of the property.
|
|
1262
|
+
* @param value The value to test.
|
|
1263
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1419
1264
|
*/
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
}
|
|
1265
|
+
static uint8Array(source, property, value) {
|
|
1266
|
+
if (!Is.uint8Array(value)) {
|
|
1267
|
+
throw new GuardError(source, "guard.uint8Array", property, value);
|
|
1268
|
+
}
|
|
1424
1269
|
}
|
|
1425
|
-
}
|
|
1426
|
-
|
|
1427
|
-
/**
|
|
1428
|
-
* Class to handle errors when a feature is unsupported.
|
|
1429
|
-
*/
|
|
1430
|
-
class NotSupportedError extends BaseError {
|
|
1431
1270
|
/**
|
|
1432
|
-
*
|
|
1271
|
+
* Is the property a function.
|
|
1272
|
+
* @param source The source of the error.
|
|
1273
|
+
* @param property The name of the property.
|
|
1274
|
+
* @param value The value to test.
|
|
1275
|
+
* @returns True if the value is a function.
|
|
1276
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1433
1277
|
*/
|
|
1434
|
-
static
|
|
1278
|
+
static function(source, property, value) {
|
|
1279
|
+
if (!Is.function(value)) {
|
|
1280
|
+
throw new GuardError(source, "guard.function", property, value);
|
|
1281
|
+
}
|
|
1282
|
+
return true;
|
|
1283
|
+
}
|
|
1435
1284
|
/**
|
|
1436
|
-
*
|
|
1285
|
+
* Is the property a string formatted as an email address.
|
|
1437
1286
|
* @param source The source of the error.
|
|
1438
|
-
* @param
|
|
1439
|
-
* @param
|
|
1287
|
+
* @param property The name of the property.
|
|
1288
|
+
* @param value The value to test.
|
|
1289
|
+
* @throws GuardError If the value does not match the assertion.
|
|
1440
1290
|
*/
|
|
1441
|
-
|
|
1442
|
-
|
|
1291
|
+
static email(source, property, value) {
|
|
1292
|
+
if (!Is.email(value)) {
|
|
1293
|
+
throw new GuardError(source, "guard.email", property, value);
|
|
1294
|
+
}
|
|
1443
1295
|
}
|
|
1444
1296
|
}
|
|
1445
1297
|
|
|
1298
|
+
// Copyright 2024 IOTA Stiftung.
|
|
1299
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
1300
|
+
/* eslint-disable no-bitwise */
|
|
1446
1301
|
/**
|
|
1447
|
-
* Class to
|
|
1302
|
+
* Class to help with base63 Encoding/Decoding.
|
|
1448
1303
|
*/
|
|
1449
|
-
class
|
|
1304
|
+
class Base32 {
|
|
1450
1305
|
/**
|
|
1451
1306
|
* Runtime name for the class.
|
|
1307
|
+
* @internal
|
|
1452
1308
|
*/
|
|
1453
|
-
static
|
|
1309
|
+
static _CLASS_NAME = "Base32";
|
|
1454
1310
|
/**
|
|
1455
|
-
*
|
|
1456
|
-
* @
|
|
1457
|
-
* @param message The message as a code.
|
|
1458
|
-
* @param inner The inner error if we have wrapped another error.
|
|
1311
|
+
* Alphabet table for encoding.
|
|
1312
|
+
* @internal
|
|
1459
1313
|
*/
|
|
1460
|
-
|
|
1461
|
-
super(UnauthorizedError.CLASS_NAME, source, message, undefined, inner);
|
|
1462
|
-
}
|
|
1463
|
-
}
|
|
1464
|
-
|
|
1465
|
-
/**
|
|
1466
|
-
* Class to handle errors when some data can not be processed.
|
|
1467
|
-
*/
|
|
1468
|
-
class UnprocessableError extends BaseError {
|
|
1314
|
+
static _ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
|
1469
1315
|
/**
|
|
1470
|
-
*
|
|
1316
|
+
* Convert the base 32 string to a byte array.
|
|
1317
|
+
* @param base32 The base32 string to convert.
|
|
1318
|
+
* @returns The byte array.
|
|
1319
|
+
* @throws If the input string contains a character not in the Base32 alphabet.
|
|
1471
1320
|
*/
|
|
1472
|
-
static
|
|
1321
|
+
static decode(base32) {
|
|
1322
|
+
Guards.string(Base32._CLASS_NAME, "base32", base32);
|
|
1323
|
+
let bits = 0;
|
|
1324
|
+
let value = 0;
|
|
1325
|
+
base32 = base32.replace(/=+$/, "");
|
|
1326
|
+
let index = 0;
|
|
1327
|
+
const output = new Uint8Array(Math.trunc((base32.length * 5) / 8));
|
|
1328
|
+
for (let i = 0; i < base32.length; i++) {
|
|
1329
|
+
const idx = Base32._ALPHABET.indexOf(base32[i]);
|
|
1330
|
+
if (idx === -1) {
|
|
1331
|
+
throw new GeneralError(Base32._CLASS_NAME, "invalidCharacter", {
|
|
1332
|
+
invalidCharacter: base32[i]
|
|
1333
|
+
});
|
|
1334
|
+
}
|
|
1335
|
+
value = (value << 5) | idx;
|
|
1336
|
+
bits += 5;
|
|
1337
|
+
if (bits >= 8) {
|
|
1338
|
+
output[index++] = (value >>> (bits - 8)) & 255;
|
|
1339
|
+
bits -= 8;
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
return output;
|
|
1343
|
+
}
|
|
1473
1344
|
/**
|
|
1474
|
-
*
|
|
1475
|
-
* @param
|
|
1476
|
-
* @
|
|
1477
|
-
* @param properties Any additional information for the error.
|
|
1478
|
-
* @param inner The inner error if we have wrapped another error.
|
|
1345
|
+
* Convert a byte array to base 32.
|
|
1346
|
+
* @param bytes The byte array to convert.
|
|
1347
|
+
* @returns The data as base32 string.
|
|
1479
1348
|
*/
|
|
1480
|
-
|
|
1481
|
-
|
|
1349
|
+
static encode(bytes) {
|
|
1350
|
+
Guards.uint8Array(Base32._CLASS_NAME, "bytes", bytes);
|
|
1351
|
+
let bits = 0;
|
|
1352
|
+
let value = 0;
|
|
1353
|
+
let output = "";
|
|
1354
|
+
for (let i = 0; i < bytes.byteLength; i++) {
|
|
1355
|
+
value = (value << 8) | bytes[i];
|
|
1356
|
+
bits += 8;
|
|
1357
|
+
while (bits >= 5) {
|
|
1358
|
+
output += Base32._ALPHABET[(value >>> (bits - 5)) & 31];
|
|
1359
|
+
bits -= 5;
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
if (bits > 0) {
|
|
1363
|
+
output += Base32._ALPHABET[(value << (5 - bits)) & 31];
|
|
1364
|
+
}
|
|
1365
|
+
while (output.length % 8 !== 0) {
|
|
1366
|
+
output += "=";
|
|
1367
|
+
}
|
|
1368
|
+
return output;
|
|
1482
1369
|
}
|
|
1483
1370
|
}
|
|
1484
1371
|
|
|
1485
1372
|
/**
|
|
1486
|
-
* Class to
|
|
1373
|
+
* Class to help with base58 Encoding/Decoding.
|
|
1487
1374
|
*/
|
|
1488
|
-
class
|
|
1375
|
+
class Base58 {
|
|
1489
1376
|
/**
|
|
1490
|
-
* Runtime name for the class.
|
|
1377
|
+
* Runtime name for the class.
|
|
1378
|
+
* @internal
|
|
1491
1379
|
*/
|
|
1492
|
-
static
|
|
1380
|
+
static _CLASS_NAME = "Base58";
|
|
1493
1381
|
/**
|
|
1494
|
-
*
|
|
1495
|
-
* @
|
|
1496
|
-
* @param validationObject The object that failed validation.
|
|
1497
|
-
* @param validationFailures The validation failures.
|
|
1382
|
+
* Alphabet table for encoding.
|
|
1383
|
+
* @internal
|
|
1498
1384
|
*/
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
validationFailures
|
|
1503
|
-
});
|
|
1504
|
-
}
|
|
1505
|
-
}
|
|
1506
|
-
|
|
1507
|
-
/**
|
|
1508
|
-
* Class to help with arrays.
|
|
1509
|
-
*/
|
|
1510
|
-
class ArrayHelper {
|
|
1385
|
+
static _ALPHABET =
|
|
1386
|
+
// cspell:disable-next-line
|
|
1387
|
+
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
1511
1388
|
/**
|
|
1512
|
-
*
|
|
1513
|
-
* @
|
|
1514
|
-
* @param arr2 The second array.
|
|
1515
|
-
* @returns True if both arrays are empty of have the same values.
|
|
1389
|
+
* Reverse map for decoding.
|
|
1390
|
+
* @internal
|
|
1516
1391
|
*/
|
|
1517
|
-
static
|
|
1518
|
-
|
|
1519
|
-
|
|
1392
|
+
static _ALPHABET_REVERSE = [
|
|
1393
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
1394
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
1395
|
+
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -1, -1, -1, -1, -1, -1, 9, 10, 11, 12, 13, 14, 15, 16, -1,
|
|
1396
|
+
17, 18, 19, 20, 21, -1, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1, -1, 33,
|
|
1397
|
+
34, 35, 36, 37, 38, 39, 40, 41, 42, 43, -1, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
|
|
1398
|
+
57, -1, -1, -1, -1, -1
|
|
1399
|
+
];
|
|
1400
|
+
/**
|
|
1401
|
+
* Convert the base 58 string to a byte array.
|
|
1402
|
+
* @param base58 The base58 string to convert.
|
|
1403
|
+
* @returns The byte array.
|
|
1404
|
+
* @throws If the input string contains a character not in the Base58 alphabet.
|
|
1405
|
+
*/
|
|
1406
|
+
static decode(base58) {
|
|
1407
|
+
Guards.string(Base58._CLASS_NAME, "base58", base58);
|
|
1408
|
+
let zeroes = 0;
|
|
1409
|
+
for (let i = 0; i < base58.length; i++) {
|
|
1410
|
+
if (base58[i] !== "1") {
|
|
1411
|
+
break;
|
|
1412
|
+
}
|
|
1413
|
+
zeroes += 1;
|
|
1520
1414
|
}
|
|
1521
|
-
|
|
1522
|
-
|
|
1415
|
+
const size = Math.trunc((base58.length * 733) / 1000) + 1;
|
|
1416
|
+
const b256 = new Uint8Array(size).fill(0);
|
|
1417
|
+
let length = 0;
|
|
1418
|
+
for (let i = zeroes; i < base58.length; i++) {
|
|
1419
|
+
const ch = base58.charCodeAt(i);
|
|
1420
|
+
if (ch & 0xff80) {
|
|
1421
|
+
throw new GeneralError(Base58._CLASS_NAME, "invalidCharacter", { invalidCharacter: ch });
|
|
1422
|
+
}
|
|
1423
|
+
const val = Base58._ALPHABET_REVERSE[ch];
|
|
1424
|
+
if (val === -1) {
|
|
1425
|
+
throw new GeneralError(Base58._CLASS_NAME, "invalidCharacter", { invalidCharacter: ch });
|
|
1426
|
+
}
|
|
1427
|
+
let carry = val;
|
|
1428
|
+
let j = 0;
|
|
1429
|
+
for (let k = size - 1; k >= 0; k--, j++) {
|
|
1430
|
+
if (carry === 0 && j >= length) {
|
|
1431
|
+
break;
|
|
1432
|
+
}
|
|
1433
|
+
carry += b256[k] * 58;
|
|
1434
|
+
b256[k] = carry;
|
|
1435
|
+
carry >>>= 8;
|
|
1436
|
+
}
|
|
1437
|
+
length = j;
|
|
1523
1438
|
}
|
|
1524
|
-
|
|
1525
|
-
|
|
1439
|
+
const out = new Uint8Array(zeroes + length);
|
|
1440
|
+
let j;
|
|
1441
|
+
for (j = 0; j < zeroes; j++) {
|
|
1442
|
+
out[j] = 0;
|
|
1526
1443
|
}
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
}
|
|
1444
|
+
let i = size - length;
|
|
1445
|
+
while (i < size) {
|
|
1446
|
+
out[j++] = b256[i++];
|
|
1531
1447
|
}
|
|
1532
|
-
return
|
|
1448
|
+
return out;
|
|
1533
1449
|
}
|
|
1534
1450
|
/**
|
|
1535
|
-
* Convert
|
|
1536
|
-
* @param
|
|
1537
|
-
* @returns The
|
|
1451
|
+
* Convert a byte array to base 58.
|
|
1452
|
+
* @param bytes The byte array to encode.
|
|
1453
|
+
* @returns The data as base58 string.
|
|
1538
1454
|
*/
|
|
1539
|
-
static
|
|
1540
|
-
|
|
1541
|
-
|
|
1455
|
+
static encode(bytes) {
|
|
1456
|
+
Guards.uint8Array(Base58._CLASS_NAME, "bytes", bytes);
|
|
1457
|
+
let zeroes = 0;
|
|
1458
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
1459
|
+
if (bytes[i] !== 0) {
|
|
1460
|
+
break;
|
|
1461
|
+
}
|
|
1462
|
+
zeroes += 1;
|
|
1542
1463
|
}
|
|
1543
|
-
|
|
1544
|
-
|
|
1464
|
+
const size = Math.trunc(((bytes.length - zeroes) * 138) / 100) + 1;
|
|
1465
|
+
const b58 = new Uint8Array(size).fill(0);
|
|
1466
|
+
let length = 0;
|
|
1467
|
+
for (let i = zeroes; i < bytes.length; i++) {
|
|
1468
|
+
let carry = bytes[i];
|
|
1469
|
+
let j = 0;
|
|
1470
|
+
for (let k = size - 1; k >= 0; k--, j++) {
|
|
1471
|
+
if (carry === 0 && j >= length) {
|
|
1472
|
+
break;
|
|
1473
|
+
}
|
|
1474
|
+
carry += b58[k] * 256;
|
|
1475
|
+
b58[k] = carry % 58;
|
|
1476
|
+
carry = Math.trunc(carry / 58);
|
|
1477
|
+
}
|
|
1478
|
+
length = j;
|
|
1545
1479
|
}
|
|
1546
|
-
|
|
1480
|
+
let i = size - length;
|
|
1481
|
+
while (i < size && b58[i] === 0) {
|
|
1482
|
+
i += 1;
|
|
1483
|
+
}
|
|
1484
|
+
let str = "";
|
|
1485
|
+
for (let j = 0; j < zeroes; j++) {
|
|
1486
|
+
str += "1";
|
|
1487
|
+
}
|
|
1488
|
+
while (i < size) {
|
|
1489
|
+
str += Base58._ALPHABET[b58[i++]];
|
|
1490
|
+
}
|
|
1491
|
+
return str;
|
|
1547
1492
|
}
|
|
1548
1493
|
}
|
|
1549
1494
|
|
|
1550
1495
|
// Copyright 2024 IOTA Stiftung.
|
|
1551
1496
|
// SPDX-License-Identifier: Apache-2.0.
|
|
1497
|
+
/* eslint-disable no-bitwise */
|
|
1498
|
+
/* eslint-disable no-mixed-operators */
|
|
1552
1499
|
/**
|
|
1553
|
-
* Class to
|
|
1500
|
+
* Class to help with base64 Encoding/Decoding.
|
|
1501
|
+
* Sourced from https://github.com/beatgammit/base64-js.
|
|
1554
1502
|
*/
|
|
1555
|
-
class
|
|
1503
|
+
class Base64 {
|
|
1556
1504
|
/**
|
|
1557
|
-
*
|
|
1558
|
-
* @
|
|
1559
|
-
* @param property The name of the property.
|
|
1560
|
-
* @param value The value to test.
|
|
1561
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1505
|
+
* Runtime name for the class.
|
|
1506
|
+
* @internal
|
|
1562
1507
|
*/
|
|
1563
|
-
static
|
|
1564
|
-
if (Is.undefined(value)) {
|
|
1565
|
-
throw new GuardError(source, "guard.undefined", property, value);
|
|
1566
|
-
}
|
|
1567
|
-
}
|
|
1508
|
+
static _CLASS_NAME = "Base64";
|
|
1568
1509
|
/**
|
|
1569
|
-
*
|
|
1570
|
-
* @
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1510
|
+
* Alphabet table for encoding.
|
|
1511
|
+
* @internal
|
|
1512
|
+
*/
|
|
1513
|
+
static _LOOKUP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
1514
|
+
/**
|
|
1515
|
+
* Alphabet table for decoding.
|
|
1516
|
+
* @internal
|
|
1517
|
+
*/
|
|
1518
|
+
static _REVERSE_LOOKUP = {
|
|
1519
|
+
"43": 62,
|
|
1520
|
+
"45": 62,
|
|
1521
|
+
"47": 63,
|
|
1522
|
+
"48": 52,
|
|
1523
|
+
"49": 53,
|
|
1524
|
+
"50": 54,
|
|
1525
|
+
"51": 55,
|
|
1526
|
+
"52": 56,
|
|
1527
|
+
"53": 57,
|
|
1528
|
+
"54": 58,
|
|
1529
|
+
"55": 59,
|
|
1530
|
+
"56": 60,
|
|
1531
|
+
"57": 61,
|
|
1532
|
+
"65": 0,
|
|
1533
|
+
"66": 1,
|
|
1534
|
+
"67": 2,
|
|
1535
|
+
"68": 3,
|
|
1536
|
+
"69": 4,
|
|
1537
|
+
"70": 5,
|
|
1538
|
+
"71": 6,
|
|
1539
|
+
"72": 7,
|
|
1540
|
+
"73": 8,
|
|
1541
|
+
"74": 9,
|
|
1542
|
+
"75": 10,
|
|
1543
|
+
"76": 11,
|
|
1544
|
+
"77": 12,
|
|
1545
|
+
"78": 13,
|
|
1546
|
+
"79": 14,
|
|
1547
|
+
"80": 15,
|
|
1548
|
+
"81": 16,
|
|
1549
|
+
"82": 17,
|
|
1550
|
+
"83": 18,
|
|
1551
|
+
"84": 19,
|
|
1552
|
+
"85": 20,
|
|
1553
|
+
"86": 21,
|
|
1554
|
+
"87": 22,
|
|
1555
|
+
"88": 23,
|
|
1556
|
+
"89": 24,
|
|
1557
|
+
"90": 25,
|
|
1558
|
+
"95": 63,
|
|
1559
|
+
"97": 26,
|
|
1560
|
+
"98": 27,
|
|
1561
|
+
"99": 28,
|
|
1562
|
+
"100": 29,
|
|
1563
|
+
"101": 30,
|
|
1564
|
+
"102": 31,
|
|
1565
|
+
"103": 32,
|
|
1566
|
+
"104": 33,
|
|
1567
|
+
"105": 34,
|
|
1568
|
+
"106": 35,
|
|
1569
|
+
"107": 36,
|
|
1570
|
+
"108": 37,
|
|
1571
|
+
"109": 38,
|
|
1572
|
+
"110": 39,
|
|
1573
|
+
"111": 40,
|
|
1574
|
+
"112": 41,
|
|
1575
|
+
"113": 42,
|
|
1576
|
+
"114": 43,
|
|
1577
|
+
"115": 44,
|
|
1578
|
+
"116": 45,
|
|
1579
|
+
"117": 46,
|
|
1580
|
+
"118": 47,
|
|
1581
|
+
"119": 48,
|
|
1582
|
+
"120": 49,
|
|
1583
|
+
"121": 50,
|
|
1584
|
+
"122": 51
|
|
1585
|
+
};
|
|
1586
|
+
/**
|
|
1587
|
+
* Get the byte length of the data.
|
|
1588
|
+
* @param base64 The base64 string.
|
|
1589
|
+
* @returns The byte length of the data.
|
|
1574
1590
|
*/
|
|
1575
|
-
static
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
}
|
|
1591
|
+
static byteLength(base64) {
|
|
1592
|
+
const lens = Base64.getLengths(base64);
|
|
1593
|
+
return Base64.calcByteLength(lens[0], lens[1]);
|
|
1579
1594
|
}
|
|
1580
1595
|
/**
|
|
1581
|
-
*
|
|
1582
|
-
* @param
|
|
1583
|
-
* @
|
|
1584
|
-
* @param value The value to test.
|
|
1585
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1596
|
+
* Convert the base 64 string to a byte array.
|
|
1597
|
+
* @param base64 The base64 string to convert.
|
|
1598
|
+
* @returns The byte array.
|
|
1586
1599
|
*/
|
|
1587
|
-
static
|
|
1588
|
-
|
|
1589
|
-
|
|
1600
|
+
static decode(base64) {
|
|
1601
|
+
Guards.string(Base64._CLASS_NAME, "base64", base64);
|
|
1602
|
+
let tmp;
|
|
1603
|
+
const lens = Base64.getLengths(base64);
|
|
1604
|
+
const validLen = lens[0];
|
|
1605
|
+
const placeHoldersLen = lens[1];
|
|
1606
|
+
const arr = new Uint8Array(Base64.calcByteLength(validLen, placeHoldersLen));
|
|
1607
|
+
let curByte = 0;
|
|
1608
|
+
// if there are placeholders, only get up to the last complete 4 chars
|
|
1609
|
+
const len = placeHoldersLen > 0 ? validLen - 4 : validLen;
|
|
1610
|
+
let i;
|
|
1611
|
+
for (i = 0; i < len; i += 4) {
|
|
1612
|
+
tmp =
|
|
1613
|
+
(Base64._REVERSE_LOOKUP[base64.charCodeAt(i)] << 18) |
|
|
1614
|
+
(Base64._REVERSE_LOOKUP[base64.charCodeAt(i + 1)] << 12) |
|
|
1615
|
+
(Base64._REVERSE_LOOKUP[base64.charCodeAt(i + 2)] << 6) |
|
|
1616
|
+
Base64._REVERSE_LOOKUP[base64.charCodeAt(i + 3)];
|
|
1617
|
+
arr[curByte++] = (tmp >> 16) & 0xff;
|
|
1618
|
+
arr[curByte++] = (tmp >> 8) & 0xff;
|
|
1619
|
+
arr[curByte++] = tmp & 0xff;
|
|
1590
1620
|
}
|
|
1591
|
-
if (
|
|
1592
|
-
|
|
1621
|
+
if (placeHoldersLen === 2) {
|
|
1622
|
+
tmp =
|
|
1623
|
+
(Base64._REVERSE_LOOKUP[base64.charCodeAt(i)] << 2) |
|
|
1624
|
+
(Base64._REVERSE_LOOKUP[base64.charCodeAt(i + 1)] >> 4);
|
|
1625
|
+
arr[curByte++] = tmp & 0xff;
|
|
1626
|
+
}
|
|
1627
|
+
if (placeHoldersLen === 1) {
|
|
1628
|
+
tmp =
|
|
1629
|
+
(Base64._REVERSE_LOOKUP[base64.charCodeAt(i)] << 10) |
|
|
1630
|
+
(Base64._REVERSE_LOOKUP[base64.charCodeAt(i + 1)] << 4) |
|
|
1631
|
+
(Base64._REVERSE_LOOKUP[base64.charCodeAt(i + 2)] >> 2);
|
|
1632
|
+
arr[curByte++] = (tmp >> 8) & 0xff;
|
|
1633
|
+
arr[curByte++] = tmp & 0xff;
|
|
1593
1634
|
}
|
|
1635
|
+
return arr;
|
|
1594
1636
|
}
|
|
1595
1637
|
/**
|
|
1596
|
-
*
|
|
1597
|
-
* @param
|
|
1598
|
-
* @
|
|
1599
|
-
* @param value The value to test.
|
|
1600
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1638
|
+
* Convert a byte array to base 64.
|
|
1639
|
+
* @param bytes The byte array to convert.
|
|
1640
|
+
* @returns The data as base64 string.
|
|
1601
1641
|
*/
|
|
1602
|
-
static
|
|
1603
|
-
|
|
1604
|
-
|
|
1642
|
+
static encode(bytes) {
|
|
1643
|
+
Guards.uint8Array(Base64._CLASS_NAME, "bytes", bytes);
|
|
1644
|
+
let tmp;
|
|
1645
|
+
const len = bytes.length;
|
|
1646
|
+
const extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes
|
|
1647
|
+
const parts = [];
|
|
1648
|
+
const maxChunkLength = 16383; // must be multiple of 3
|
|
1649
|
+
// go through the array every three bytes, we'll deal with trailing stuff later
|
|
1650
|
+
for (let i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
|
|
1651
|
+
parts.push(Base64.encodeChunk(bytes, i, Math.min(i + maxChunkLength, len2)));
|
|
1652
|
+
}
|
|
1653
|
+
// pad the end with zeros, but make sure to not forget the extra bytes
|
|
1654
|
+
if (extraBytes === 1) {
|
|
1655
|
+
tmp = bytes[len - 1];
|
|
1656
|
+
parts.push(`${Base64._LOOKUP[tmp >> 2] + Base64._LOOKUP[(tmp << 4) & 0x3f]}==`);
|
|
1657
|
+
}
|
|
1658
|
+
else if (extraBytes === 2) {
|
|
1659
|
+
tmp = (bytes[len - 2] << 8) + bytes[len - 1];
|
|
1660
|
+
parts.push(`${Base64._LOOKUP[tmp >> 10] + Base64._LOOKUP[(tmp >> 4) & 0x3f] + Base64._LOOKUP[(tmp << 2) & 0x3f]}=`);
|
|
1605
1661
|
}
|
|
1662
|
+
return parts.join("");
|
|
1606
1663
|
}
|
|
1607
1664
|
/**
|
|
1608
|
-
*
|
|
1609
|
-
* @param
|
|
1610
|
-
* @param
|
|
1611
|
-
* @
|
|
1612
|
-
* @
|
|
1665
|
+
* Calculate the byte length.
|
|
1666
|
+
* @param validLen The valid length.
|
|
1667
|
+
* @param placeHoldersLen The placeholder length.
|
|
1668
|
+
* @returns The length.
|
|
1669
|
+
* @internal
|
|
1613
1670
|
*/
|
|
1614
|
-
static
|
|
1615
|
-
|
|
1616
|
-
throw new GuardError(source, "guard.base64", property, value);
|
|
1617
|
-
}
|
|
1671
|
+
static calcByteLength(validLen, placeHoldersLen) {
|
|
1672
|
+
return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen;
|
|
1618
1673
|
}
|
|
1619
1674
|
/**
|
|
1620
|
-
*
|
|
1621
|
-
* @param
|
|
1622
|
-
* @
|
|
1623
|
-
* @
|
|
1624
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1675
|
+
* Get the valid and placeholder lengths from a bas64 string.
|
|
1676
|
+
* @param base64 The base64 string.
|
|
1677
|
+
* @returns The lengths.
|
|
1678
|
+
* @internal
|
|
1625
1679
|
*/
|
|
1626
|
-
static
|
|
1627
|
-
|
|
1628
|
-
|
|
1680
|
+
static getLengths(base64) {
|
|
1681
|
+
const len = base64.length;
|
|
1682
|
+
if (len % 4 > 0) {
|
|
1683
|
+
throw new GeneralError(Base64._CLASS_NAME, "length4Multiple", { value: len });
|
|
1684
|
+
}
|
|
1685
|
+
// Trim off extra bytes after placeholder bytes are found
|
|
1686
|
+
// See: https://github.com/beatgammit/base64-js/issues/42
|
|
1687
|
+
let validLen = base64.indexOf("=");
|
|
1688
|
+
if (validLen === -1) {
|
|
1689
|
+
validLen = len;
|
|
1629
1690
|
}
|
|
1691
|
+
const placeHoldersLen = validLen === len ? 0 : 4 - (validLen % 4);
|
|
1692
|
+
return [validLen, placeHoldersLen];
|
|
1630
1693
|
}
|
|
1631
1694
|
/**
|
|
1632
|
-
*
|
|
1633
|
-
* @param
|
|
1634
|
-
* @
|
|
1635
|
-
* @
|
|
1636
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1695
|
+
* Convert the triplet to base 64.
|
|
1696
|
+
* @param num The number to convert.
|
|
1697
|
+
* @returns The base64 encoding.
|
|
1698
|
+
* @internal
|
|
1637
1699
|
*/
|
|
1638
|
-
static
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1700
|
+
static tripletToBase64(num) {
|
|
1701
|
+
return (Base64._LOOKUP[(num >> 18) & 0x3f] +
|
|
1702
|
+
Base64._LOOKUP[(num >> 12) & 0x3f] +
|
|
1703
|
+
Base64._LOOKUP[(num >> 6) & 0x3f] +
|
|
1704
|
+
Base64._LOOKUP[num & 0x3f]);
|
|
1642
1705
|
}
|
|
1643
1706
|
/**
|
|
1644
|
-
*
|
|
1645
|
-
* @param
|
|
1646
|
-
* @param
|
|
1647
|
-
* @param
|
|
1648
|
-
* @
|
|
1649
|
-
* @
|
|
1707
|
+
* Encode a chunk.
|
|
1708
|
+
* @param bytes The byte array.
|
|
1709
|
+
* @param start The start index in the buffer.
|
|
1710
|
+
* @param end The end index in the buffer.
|
|
1711
|
+
* @returns The encoded chunk.
|
|
1712
|
+
* @internal
|
|
1650
1713
|
*/
|
|
1651
|
-
static
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1714
|
+
static encodeChunk(bytes, start, end) {
|
|
1715
|
+
let tmp;
|
|
1716
|
+
const output = [];
|
|
1717
|
+
for (let i = start; i < end; i += 3) {
|
|
1718
|
+
tmp = ((bytes[i] << 16) & 0xff0000) + ((bytes[i + 1] << 8) & 0xff00) + (bytes[i + 2] & 0xff);
|
|
1719
|
+
output.push(Base64.tripletToBase64(tmp));
|
|
1655
1720
|
}
|
|
1721
|
+
return output.join("");
|
|
1656
1722
|
}
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
/**
|
|
1726
|
+
* Class to help with base64 URL Encoding/Decoding.
|
|
1727
|
+
* https://www.rfc-editor.org/rfc/rfc4648#section-5.
|
|
1728
|
+
*/
|
|
1729
|
+
class Base64Url {
|
|
1657
1730
|
/**
|
|
1658
|
-
*
|
|
1659
|
-
* @
|
|
1660
|
-
* @param property The name of the property.
|
|
1661
|
-
* @param value The value to test.
|
|
1662
|
-
* @param length The length of the string to match.
|
|
1663
|
-
* @param allowPrefix Allow the hex to have the 0x prefix.
|
|
1664
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1731
|
+
* Runtime name for the class.
|
|
1732
|
+
* @internal
|
|
1665
1733
|
*/
|
|
1666
|
-
static
|
|
1667
|
-
Guards.stringHex(source, property, value, allowPrefix);
|
|
1668
|
-
if (HexHelper.stripPrefix(value).length !== length) {
|
|
1669
|
-
throw new GuardError(source, "guard.stringHexLength", property, value.length, length.toString());
|
|
1670
|
-
}
|
|
1671
|
-
}
|
|
1734
|
+
static _CLASS_NAME = "Base64";
|
|
1672
1735
|
/**
|
|
1673
|
-
*
|
|
1674
|
-
* @param
|
|
1675
|
-
* @
|
|
1676
|
-
* @param value The value to test.
|
|
1677
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1736
|
+
* Convert the base 64 string to a byte array.
|
|
1737
|
+
* @param base64Url The base64 url string to convert.
|
|
1738
|
+
* @returns The byte array.
|
|
1678
1739
|
*/
|
|
1679
|
-
static
|
|
1680
|
-
|
|
1681
|
-
|
|
1740
|
+
static decode(base64Url) {
|
|
1741
|
+
Guards.string(Base64Url._CLASS_NAME, "base64Url", base64Url);
|
|
1742
|
+
let base64 = base64Url;
|
|
1743
|
+
// Base 64 url can have padding removed, so add it back if it is missing.
|
|
1744
|
+
if (base64.length > 0 && !base64.endsWith("=")) {
|
|
1745
|
+
const placeHoldersLen = 4 - (base64.length % 4);
|
|
1746
|
+
if (placeHoldersLen > 0 && placeHoldersLen < 4) {
|
|
1747
|
+
base64 = base64.padEnd(base64.length + placeHoldersLen, "=");
|
|
1748
|
+
}
|
|
1682
1749
|
}
|
|
1750
|
+
base64 = base64.replace(/-/g, "+").replace(/_/g, "/");
|
|
1751
|
+
return Base64.decode(base64);
|
|
1683
1752
|
}
|
|
1684
1753
|
/**
|
|
1685
|
-
*
|
|
1686
|
-
* @param
|
|
1687
|
-
* @
|
|
1688
|
-
* @param value The value to test.
|
|
1689
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1754
|
+
* Convert a byte array to base 64 url.
|
|
1755
|
+
* @param bytes The byte array to convert.
|
|
1756
|
+
* @returns The data as base64 url string.
|
|
1690
1757
|
*/
|
|
1691
|
-
static
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1758
|
+
static encode(bytes) {
|
|
1759
|
+
Guards.uint8Array(Base64Url._CLASS_NAME, "bytes", bytes);
|
|
1760
|
+
const base64 = Base64.encode(bytes);
|
|
1761
|
+
// Base 64 url can have padding removed, so remove it.
|
|
1762
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
1695
1763
|
}
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
/**
|
|
1767
|
+
* Class to handle errors which are triggered by data already existing.
|
|
1768
|
+
*/
|
|
1769
|
+
class AlreadyExistsError extends BaseError {
|
|
1696
1770
|
/**
|
|
1697
|
-
*
|
|
1698
|
-
* @param source The source of the error.
|
|
1699
|
-
* @param property The name of the property.
|
|
1700
|
-
* @param value The value to test.
|
|
1701
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1771
|
+
* Runtime name for the class.
|
|
1702
1772
|
*/
|
|
1703
|
-
static
|
|
1704
|
-
if (!Is.bigint(value)) {
|
|
1705
|
-
throw new GuardError(source, "guard.bigint", property, value);
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1773
|
+
static CLASS_NAME = "AlreadyExistsError";
|
|
1708
1774
|
/**
|
|
1709
|
-
*
|
|
1775
|
+
* Create a new instance of AlreadyExistsError.
|
|
1710
1776
|
* @param source The source of the error.
|
|
1711
|
-
* @param
|
|
1712
|
-
* @param
|
|
1713
|
-
* @
|
|
1777
|
+
* @param message The message as a code.
|
|
1778
|
+
* @param existingId The id for the item.
|
|
1779
|
+
* @param inner The inner error if we have wrapped another error.
|
|
1714
1780
|
*/
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
throw new GuardError(source, "guard.boolean", property, value);
|
|
1718
|
-
}
|
|
1781
|
+
constructor(source, message, existingId, inner) {
|
|
1782
|
+
super(AlreadyExistsError.CLASS_NAME, source, message, { existingId }, inner);
|
|
1719
1783
|
}
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1786
|
+
/**
|
|
1787
|
+
* Class to handle errors which are triggered by conflicting data.
|
|
1788
|
+
*/
|
|
1789
|
+
class ConflictError extends BaseError {
|
|
1720
1790
|
/**
|
|
1721
|
-
*
|
|
1722
|
-
* @param source The source of the error.
|
|
1723
|
-
* @param property The name of the property.
|
|
1724
|
-
* @param value The value to test.
|
|
1725
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1791
|
+
* Runtime name for the class.
|
|
1726
1792
|
*/
|
|
1727
|
-
static
|
|
1728
|
-
if (!Is.date(value)) {
|
|
1729
|
-
throw new GuardError(source, "guard.date", property, value);
|
|
1730
|
-
}
|
|
1731
|
-
}
|
|
1793
|
+
static CLASS_NAME = "ConflictError";
|
|
1732
1794
|
/**
|
|
1733
|
-
*
|
|
1795
|
+
* Create a new instance of ConflictError.
|
|
1734
1796
|
* @param source The source of the error.
|
|
1735
|
-
* @param
|
|
1736
|
-
* @param
|
|
1737
|
-
* @
|
|
1797
|
+
* @param message The message as a code.
|
|
1798
|
+
* @param conflictId The id that has conflicts.
|
|
1799
|
+
* @param conflicts The conflicts that occurred.
|
|
1800
|
+
* @param inner The inner error if we have wrapped another error.
|
|
1738
1801
|
*/
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
throw new GuardError(source, "guard.timestampMilliseconds", property, value);
|
|
1742
|
-
}
|
|
1802
|
+
constructor(source, message, conflictId, conflicts, inner) {
|
|
1803
|
+
super(ConflictError.CLASS_NAME, source, message, { conflictId, conflicts }, inner);
|
|
1743
1804
|
}
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
/**
|
|
1808
|
+
* Class to handle errors which are triggered by data not being found.
|
|
1809
|
+
*/
|
|
1810
|
+
class NotFoundError extends BaseError {
|
|
1744
1811
|
/**
|
|
1745
|
-
*
|
|
1746
|
-
* @param source The source of the error.
|
|
1747
|
-
* @param property The name of the property.
|
|
1748
|
-
* @param value The value to test.
|
|
1749
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1812
|
+
* Runtime name for the class.
|
|
1750
1813
|
*/
|
|
1751
|
-
static
|
|
1752
|
-
if (!Is.timestampSeconds(value)) {
|
|
1753
|
-
throw new GuardError(source, "guard.timestampSeconds", property, value);
|
|
1754
|
-
}
|
|
1755
|
-
}
|
|
1814
|
+
static CLASS_NAME = "NotFoundError";
|
|
1756
1815
|
/**
|
|
1757
|
-
*
|
|
1816
|
+
* Create a new instance of NotFoundError.
|
|
1758
1817
|
* @param source The source of the error.
|
|
1759
|
-
* @param
|
|
1760
|
-
* @param
|
|
1761
|
-
* @
|
|
1818
|
+
* @param message The message as a code.
|
|
1819
|
+
* @param notFoundId The id for the item.
|
|
1820
|
+
* @param inner The inner error if we have wrapped another error.
|
|
1762
1821
|
*/
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
throw new GuardError(source, "guard.objectUndefined", property, value);
|
|
1766
|
-
}
|
|
1767
|
-
if (!Is.object(value)) {
|
|
1768
|
-
throw new GuardError(source, "guard.object", property, value);
|
|
1769
|
-
}
|
|
1822
|
+
constructor(source, message, notFoundId, inner) {
|
|
1823
|
+
super(NotFoundError.CLASS_NAME, source, message, { notFoundId }, inner);
|
|
1770
1824
|
}
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
/**
|
|
1828
|
+
* Class to handle errors.
|
|
1829
|
+
*/
|
|
1830
|
+
class NotImplementedError extends BaseError {
|
|
1771
1831
|
/**
|
|
1772
|
-
*
|
|
1773
|
-
* @param source The source of the error.
|
|
1774
|
-
* @param property The name of the property.
|
|
1775
|
-
* @param value The value to test.
|
|
1776
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1832
|
+
* Runtime name for the class.
|
|
1777
1833
|
*/
|
|
1778
|
-
static
|
|
1779
|
-
if (Is.undefined(value)) {
|
|
1780
|
-
throw new GuardError(source, "guard.objectUndefined", property, value);
|
|
1781
|
-
}
|
|
1782
|
-
if (!Is.object(value)) {
|
|
1783
|
-
throw new GuardError(source, "guard.object", property, value);
|
|
1784
|
-
}
|
|
1785
|
-
if (Object.keys(value || {}).length === 0) {
|
|
1786
|
-
throw new GuardError(source, "guard.objectValue", property, value);
|
|
1787
|
-
}
|
|
1788
|
-
}
|
|
1834
|
+
static CLASS_NAME = "NotImplementedError";
|
|
1789
1835
|
/**
|
|
1790
|
-
*
|
|
1836
|
+
* Create a new instance of NotImplementedError.
|
|
1791
1837
|
* @param source The source of the error.
|
|
1792
|
-
* @param
|
|
1793
|
-
* @param value The value to test.
|
|
1794
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1838
|
+
* @param method The method for the error.
|
|
1795
1839
|
*/
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
}
|
|
1840
|
+
constructor(source, method) {
|
|
1841
|
+
super(NotImplementedError.CLASS_NAME, source, "common.notImplementedMethod", {
|
|
1842
|
+
method
|
|
1843
|
+
});
|
|
1800
1844
|
}
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
/**
|
|
1848
|
+
* Class to handle errors when a feature is unsupported.
|
|
1849
|
+
*/
|
|
1850
|
+
class NotSupportedError extends BaseError {
|
|
1801
1851
|
/**
|
|
1802
|
-
*
|
|
1803
|
-
* @param source The source of the error.
|
|
1804
|
-
* @param property The name of the property.
|
|
1805
|
-
* @param value The value to test.
|
|
1806
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1852
|
+
* Runtime name for the class.
|
|
1807
1853
|
*/
|
|
1808
|
-
static
|
|
1809
|
-
if (!Is.array(value)) {
|
|
1810
|
-
throw new GuardError(source, "guard.array", property, value);
|
|
1811
|
-
}
|
|
1812
|
-
if (value.length === 0) {
|
|
1813
|
-
throw new GuardError(source, "guard.arrayValue", property, value);
|
|
1814
|
-
}
|
|
1815
|
-
}
|
|
1854
|
+
static CLASS_NAME = "NotSupportedError";
|
|
1816
1855
|
/**
|
|
1817
|
-
*
|
|
1856
|
+
* Create a new instance of NotSupportedError.
|
|
1818
1857
|
* @param source The source of the error.
|
|
1819
|
-
* @param
|
|
1820
|
-
* @param
|
|
1821
|
-
* @param options The options the value must be one of.
|
|
1822
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1858
|
+
* @param message The message as a code.
|
|
1859
|
+
* @param inner The inner error if we have wrapped another error.
|
|
1823
1860
|
*/
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
throw new GuardError(source, "guard.array", property, value);
|
|
1827
|
-
}
|
|
1828
|
-
if (!options.includes(value)) {
|
|
1829
|
-
throw new GuardError(source, "guard.arrayOneOf", property, value, options.join(", "));
|
|
1830
|
-
}
|
|
1861
|
+
constructor(source, message, inner) {
|
|
1862
|
+
super(NotSupportedError.CLASS_NAME, source, message, undefined, inner);
|
|
1831
1863
|
}
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1866
|
+
/**
|
|
1867
|
+
* Class to handle errors which are triggered by access not being unauthorized.
|
|
1868
|
+
*/
|
|
1869
|
+
class UnauthorizedError extends BaseError {
|
|
1832
1870
|
/**
|
|
1833
|
-
*
|
|
1834
|
-
* @param source The source of the error.
|
|
1835
|
-
* @param property The name of the property.
|
|
1836
|
-
* @param value The value to test.
|
|
1837
|
-
* @param startValues The values that must start the array.
|
|
1838
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1871
|
+
* Runtime name for the class.
|
|
1839
1872
|
*/
|
|
1840
|
-
static
|
|
1841
|
-
if (!Is.arrayValue(value)) {
|
|
1842
|
-
throw new GuardError(source, "guard.array", property, value);
|
|
1843
|
-
}
|
|
1844
|
-
const startValuesArray = ArrayHelper.fromObjectOrArray(startValues);
|
|
1845
|
-
if (!Is.arrayValue(startValuesArray)) {
|
|
1846
|
-
throw new GuardError(source, "guard.array", property, startValuesArray);
|
|
1847
|
-
}
|
|
1848
|
-
for (let i = 0; i < startValuesArray.length; i++) {
|
|
1849
|
-
if (value[i] !== startValuesArray[i]) {
|
|
1850
|
-
throw new GuardError(source, "guard.arrayStartsWith", property, value, startValuesArray.join(", "));
|
|
1851
|
-
}
|
|
1852
|
-
}
|
|
1853
|
-
}
|
|
1873
|
+
static CLASS_NAME = "UnauthorizedError";
|
|
1854
1874
|
/**
|
|
1855
|
-
*
|
|
1875
|
+
* Create a new instance of UnauthorizedError.
|
|
1856
1876
|
* @param source The source of the error.
|
|
1857
|
-
* @param
|
|
1858
|
-
* @param
|
|
1859
|
-
* @param endValues The values that must end the array.
|
|
1860
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1877
|
+
* @param message The message as a code.
|
|
1878
|
+
* @param inner The inner error if we have wrapped another error.
|
|
1861
1879
|
*/
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
throw new GuardError(source, "guard.array", property, value);
|
|
1865
|
-
}
|
|
1866
|
-
const endValuesArray = ArrayHelper.fromObjectOrArray(endValues);
|
|
1867
|
-
if (!Is.arrayValue(endValuesArray)) {
|
|
1868
|
-
throw new GuardError(source, "guard.array", property, endValuesArray);
|
|
1869
|
-
}
|
|
1870
|
-
for (let i = 0; i < endValuesArray.length; i++) {
|
|
1871
|
-
if (value[value.length - i - 1] !== endValuesArray[endValuesArray.length - i - 1]) {
|
|
1872
|
-
throw new GuardError(source, "guard.arrayEndsWith", property, value, endValuesArray.join(", "));
|
|
1873
|
-
}
|
|
1874
|
-
}
|
|
1880
|
+
constructor(source, message, inner) {
|
|
1881
|
+
super(UnauthorizedError.CLASS_NAME, source, message, undefined, inner);
|
|
1875
1882
|
}
|
|
1883
|
+
}
|
|
1884
|
+
|
|
1885
|
+
/**
|
|
1886
|
+
* Class to handle errors when some data can not be processed.
|
|
1887
|
+
*/
|
|
1888
|
+
class UnprocessableError extends BaseError {
|
|
1876
1889
|
/**
|
|
1877
|
-
*
|
|
1878
|
-
* @param source The source of the error.
|
|
1879
|
-
* @param property The name of the property.
|
|
1880
|
-
* @param value The value to test.
|
|
1881
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1890
|
+
* Runtime name for the class.
|
|
1882
1891
|
*/
|
|
1883
|
-
static
|
|
1884
|
-
if (!Is.uint8Array(value)) {
|
|
1885
|
-
throw new GuardError(source, "guard.uint8Array", property, value);
|
|
1886
|
-
}
|
|
1887
|
-
}
|
|
1892
|
+
static CLASS_NAME = "UnprocessableError";
|
|
1888
1893
|
/**
|
|
1889
|
-
*
|
|
1894
|
+
* Create a new instance of UnprocessableError.
|
|
1890
1895
|
* @param source The source of the error.
|
|
1891
|
-
* @param
|
|
1892
|
-
* @param
|
|
1893
|
-
* @
|
|
1894
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1896
|
+
* @param message The message as a code.
|
|
1897
|
+
* @param properties Any additional information for the error.
|
|
1898
|
+
* @param inner The inner error if we have wrapped another error.
|
|
1895
1899
|
*/
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
throw new GuardError(source, "guard.function", property, value);
|
|
1899
|
-
}
|
|
1900
|
-
return true;
|
|
1900
|
+
constructor(source, message, properties, inner) {
|
|
1901
|
+
super(UnprocessableError.CLASS_NAME, source, message, properties, inner);
|
|
1901
1902
|
}
|
|
1903
|
+
}
|
|
1904
|
+
|
|
1905
|
+
/**
|
|
1906
|
+
* Class to handle errors which are triggered by entity validation.
|
|
1907
|
+
*/
|
|
1908
|
+
class ValidationError extends BaseError {
|
|
1902
1909
|
/**
|
|
1903
|
-
*
|
|
1910
|
+
* Runtime name for the class.s
|
|
1911
|
+
*/
|
|
1912
|
+
static CLASS_NAME = "ValidationError";
|
|
1913
|
+
/**
|
|
1914
|
+
* Create a new instance of ValidationError.
|
|
1904
1915
|
* @param source The source of the error.
|
|
1905
|
-
* @param
|
|
1906
|
-
* @param
|
|
1907
|
-
* @throws GuardError If the value does not match the assertion.
|
|
1916
|
+
* @param validationObject The object that failed validation.
|
|
1917
|
+
* @param validationFailures The validation failures.
|
|
1908
1918
|
*/
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1919
|
+
constructor(source, validationObject, validationFailures) {
|
|
1920
|
+
super(ValidationError.CLASS_NAME, source, "common.validation", {
|
|
1921
|
+
validationObject,
|
|
1922
|
+
validationFailures
|
|
1923
|
+
});
|
|
1913
1924
|
}
|
|
1914
1925
|
}
|
|
1915
1926
|
|