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