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