skapi-js 0.0.3 → 0.0.41

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/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "skapi-js",
3
- "version": "0.0.3",
4
- "description": "skapi javascript library",
5
- "main": "./dist/skapi.js",
3
+ "version": "0.0.41",
4
+ "description": "skapi serverless cloud javascript library",
5
+ "main": "./dist/skapi.module.js",
6
6
  "scripts": {
7
7
  "build": "npx tsc ; npx webpack --config webpack.config.js ; npx typedoc"
8
8
  },
@@ -27,7 +27,8 @@
27
27
  "backend",
28
28
  "serverless",
29
29
  "skapi",
30
- "api"
30
+ "api",
31
+ "cloud"
31
32
  ],
32
33
  "dependencies": {
33
34
  "amazon-cognito-identity-js": "^5.2.12"
package/src/decorators.ts CHANGED
@@ -29,7 +29,8 @@ function formResponse() {
29
29
 
30
30
  // form element action
31
31
  let href = new URL(form.action);
32
- let response_key = sha256(form.action);
32
+ // let response_key = sha256(form.action);
33
+ let response_key = form.action;
33
34
  let timestamp = Date.now().toString();
34
35
 
35
36
  window.sessionStorage.setItem(response_key, JSON.stringify({ [timestamp]: response }));
package/src/skapi.ts CHANGED
@@ -110,7 +110,21 @@ export default class Skapi {
110
110
  // public
111
111
 
112
112
  /** Current logged in user object. null if not logged. */
113
- user: User | null = null;
113
+ __user: User | null = null;
114
+
115
+ get user() {
116
+ if (this.__user && Object.keys(this.__user).length) {
117
+ return JSON.parse(JSON.stringify(this.__user));
118
+ }
119
+ else {
120
+ return null;
121
+ }
122
+ }
123
+
124
+ set user(value) {
125
+ // setting user is bypassed
126
+ }
127
+
114
128
  /** Connected service object. null if connection failed. */
115
129
  connection: Connection | null = null;
116
130
  host: string = 'skapi';
@@ -411,7 +425,7 @@ export default class Skapi {
411
425
  user.access_group = Number(this.session.idToken.payload.access_group);
412
426
  user.user_id = user.sub;
413
427
  delete user.sub;
414
- this.user = user;
428
+ this.__user = user;
415
429
  res(user);
416
430
  }
417
431
  });
@@ -577,6 +591,10 @@ export default class Skapi {
577
591
  return await this.request(p.url, option || null, { method: 'get', auth: p.url.includes('/auth/'), contentType: null, responseType: 'blob' });
578
592
  }
579
593
 
594
+ async mock(data, options) {
595
+ return this.request('test-api', data, options);
596
+ }
597
+
580
598
  /**
581
599
  * Sends post request to your custom server using Skapi's secure API layer.</br>
582
600
  * You must set your secret API key from the Skapi's admin page.</br>
@@ -735,7 +753,7 @@ export default class Skapi {
735
753
  * Retrives respond data from form request.
736
754
  *
737
755
  * ```
738
- * let respond = skapi.getResponse();
756
+ * let respond = skapi.getFormResponse();
739
757
  * ```
740
758
  * @category Connection
741
759
  */
@@ -835,6 +853,7 @@ export default class Skapi {
835
853
  case 'signup':
836
854
  case 'confirm-signup':
837
855
  case 'recover-account':
856
+ case 'test-api':
838
857
  case 'service':
839
858
  return {
840
859
  public: admin.admin_public,
@@ -1008,11 +1027,11 @@ export default class Skapi {
1008
1027
  }
1009
1028
 
1010
1029
  let requestKey = this.load_startKey_keys({
1011
- params: Object.assign(isForm || (data || {}), required || {}),
1030
+ params: data,
1012
1031
  url: isExternalUrl || url,
1013
1032
  refresh: isForm ? true : refresh // should not use startKey when post is a form
1014
1033
  }); // returns requrestKey | cached data
1015
-
1034
+
1016
1035
  if (requestKey && typeof requestKey === 'object') {
1017
1036
  return requestKey;
1018
1037
  }
@@ -1093,7 +1112,7 @@ export default class Skapi {
1093
1112
  }): string | FetchResponse {
1094
1113
 
1095
1114
  let { params = {}, url, refresh = false } = option || {};
1096
-
1115
+
1097
1116
  if (params.hasOwnProperty('startKey')) {
1098
1117
  if (
1099
1118
  typeof params.startKey !== 'object' && !Object.keys(params.startKey).length ||
@@ -1118,41 +1137,10 @@ export default class Skapi {
1118
1137
  }
1119
1138
  }
1120
1139
 
1121
- let toHash = (() => {
1122
- if (params && typeof params === 'object' && Object.keys(params).length) {
1123
- // hash request parameters
1124
- let paramsHash = JSON.parse(JSON.stringify(params));
1125
-
1126
- function orderObjectKeys(obj: Record<string, any>) {
1127
- function sortObject(obj: Record<string, any>): Record<string, any> {
1128
- if (typeof obj === 'object' && obj) {
1129
- return Object.keys(obj).sort().reduce((res, key) => ((res as any)[key] = obj[key], res), {});
1130
- }
1131
- return obj;
1132
- };
1133
-
1134
- let _obj = sortObject(obj);
1135
- for (let k in _obj) {
1136
- if (_obj[k] && typeof _obj[k] === 'object') {
1137
- _obj[k] = sortObject(obj[k]);
1138
- }
1139
- }
1140
-
1141
- return _obj;
1142
- }
1143
-
1144
- return JSON.stringify(orderObjectKeys(paramsHash)) + url + this.service;
1145
- }
1146
-
1147
- return url + this.service;
1148
- })();
1149
-
1150
1140
  // let hashedParams = createHash('sha256').update(toHash).digest('hex');
1151
- let hashedParams = sha256((() => {
1141
+ let hashedParams = (() => {
1152
1142
  if (params && typeof params === 'object' && Object.keys(params).length) {
1153
1143
  // hash request parameters
1154
- let paramsHash = JSON.parse(JSON.stringify(params));
1155
-
1156
1144
  function orderObjectKeys(obj: Record<string, any>) {
1157
1145
  function sortObject(obj: Record<string, any>): Record<string, any> {
1158
1146
  if (typeof obj === 'object' && obj) {
@@ -1171,11 +1159,12 @@ export default class Skapi {
1171
1159
  return _obj;
1172
1160
  }
1173
1161
 
1174
- return JSON.stringify(orderObjectKeys(paramsHash)) + url + this.service;
1162
+ return url + '/' + JSON.stringify(orderObjectKeys(params));
1175
1163
  }
1176
1164
 
1177
- return url + this.service;
1178
- })());
1165
+ return url + '/' + this.service;
1166
+
1167
+ })();
1179
1168
 
1180
1169
  if (refresh && this.__startKey_keys?.[url]?.[hashedParams]) {
1181
1170
  // init cache, init startKey
@@ -1188,7 +1177,8 @@ export default class Skapi {
1188
1177
  if (Array.isArray(this.__startKey_keys[url][hashedParams]) && this.__startKey_keys[url][hashedParams].length) {
1189
1178
  // delete cache of all startkeys
1190
1179
  for (let p of this.__startKey_keys[url][hashedParams]) {
1191
- let hashedParams_cached = hashedParams + sha256(JSON.stringify(p));
1180
+ // let hashedParams_cached = hashedParams + '/' + sha256(JSON.stringify(p));
1181
+ let hashedParams_cached = hashedParams + '/' + JSON.stringify(p);
1192
1182
  // let hashedParams_cached = hashedParams + createHash('sha256').update(JSON.stringify(p)).digest('hex');
1193
1183
 
1194
1184
  if (this.__cached_requests?.[url] && this.__cached_requests?.[url]?.[hashedParams_cached]) {
@@ -1216,7 +1206,7 @@ export default class Skapi {
1216
1206
  if (last_startKey_key) {
1217
1207
  // use last start key
1218
1208
 
1219
- if (last_startKey_key === 'end') {
1209
+ if (last_startKey_key === '"end"') { // cached startKeys are stringified
1220
1210
  return {
1221
1211
  list: [],
1222
1212
  startKey: 'end',
@@ -1226,7 +1216,8 @@ export default class Skapi {
1226
1216
 
1227
1217
  else {
1228
1218
  // cache_hashedParams += createHash('sha256').update(last_startKey_key).digest('hex');
1229
- cache_hashedParams += sha256(last_startKey_key);
1219
+ // cache_hashedParams += sha256(last_startKey_key);
1220
+ cache_hashedParams += ('/' + last_startKey_key);
1230
1221
  params.startKey = JSON.parse(last_startKey_key);
1231
1222
  }
1232
1223
  }
@@ -1456,13 +1447,9 @@ export default class Skapi {
1456
1447
  option = checkParams(option || {}, {
1457
1448
  record_id: 'string',
1458
1449
  access_group: ['number', 'private'],
1459
- table: ['string', () => {
1460
- if (!option?.record_id) {
1461
- throw new SkapiError('Either "record_id" or "table" should have a value.', { code: 'INVALID_PARAMETER' });
1462
- }
1463
- }],
1450
+ table: 'string',
1464
1451
  subscription_group: 'number',
1465
- reference: 'string',
1452
+ reference: ['string', null],
1466
1453
  index: {
1467
1454
  name: 'string',
1468
1455
  value: ['string', 'number', 'boolean']
@@ -1488,11 +1475,33 @@ export default class Skapi {
1488
1475
  throw new SkapiError(`"tags" should be type: <string | string[]>`, { code: 'INVALID_PARAMETER' });
1489
1476
  },
1490
1477
  config: {
1491
- reference_limit: ['number', null],
1478
+ reference_limit: (v: number) => {
1479
+ if (v === null) {
1480
+ return null;
1481
+ }
1482
+
1483
+ else if (typeof v === 'number') {
1484
+ if (0 > v) {
1485
+ throw new SkapiError(`"reference_limit" should be >= 0`, { code: 'INVALID_PARAMETER' });
1486
+ }
1487
+
1488
+ if (v > 4503599627370546) {
1489
+ throw new SkapiError(`"reference_limit" should be <= 4503599627370546`, { code: 'INVALID_PARAMETER' });
1490
+ }
1491
+
1492
+ return v;
1493
+ }
1494
+
1495
+ throw new SkapiError(`"reference_limit" should be type: <number | null>`, { code: 'INVALID_PARAMETER' });
1496
+ },
1492
1497
  allow_multiple_reference: 'boolean',
1493
1498
  private_access: (v: string | string[]) => {
1494
1499
  let param = 'config.private_access';
1495
1500
 
1501
+ if (v === null) {
1502
+ return null;
1503
+ }
1504
+
1496
1505
  if (v && typeof v === 'string') {
1497
1506
  v = [v];
1498
1507
  }
@@ -1501,7 +1510,7 @@ export default class Skapi {
1501
1510
  for (let u of v) {
1502
1511
  validateUserId(u, `User ID in "${param}"`);
1503
1512
 
1504
- if (this.user && u === this.user.user_id) {
1513
+ if (this.__user && u === this.__user.user_id) {
1505
1514
  throw new SkapiError(`"${param}" should not be the uploader's user ID.`, { code: 'INVALID_PARAMETER' });
1506
1515
  }
1507
1516
  }
@@ -1521,6 +1530,10 @@ export default class Skapi {
1521
1530
  delete option.formData;
1522
1531
  delete option.onerror;
1523
1532
 
1533
+ if (!option?.table && !option?.record_id) {
1534
+ throw new SkapiError('Either "record_id" or "table" should have a value.', { code: 'INVALID_PARAMETER' });
1535
+ }
1536
+
1524
1537
  if (option?.index) {
1525
1538
  // index name allows periods. white space is invalid.
1526
1539
  if (!option.index?.name || typeof option.index?.name !== 'string') {
@@ -1545,7 +1558,6 @@ export default class Skapi {
1545
1558
  }
1546
1559
  }
1547
1560
 
1548
-
1549
1561
  if (is_admin) {
1550
1562
  if (option?.access_group === 'private') {
1551
1563
  throw new SkapiError('Service owner cannot write private records.', { code: 'INVALID_REQUEST' });
@@ -1656,22 +1668,7 @@ export default class Skapi {
1656
1668
  return v;
1657
1669
  }
1658
1670
  },
1659
- tags: (v: string | string[]) => {
1660
- if (typeof v === 'string') {
1661
- return [v];
1662
- }
1663
- else if (Array.isArray(v)) {
1664
- if (v.length > 10) {
1665
- throw new SkapiError('Cannot query more than 10 tags at once.', { code: 'INVALID_REQUEST' });
1666
- }
1667
- for (let s of v) {
1668
- if (typeof s !== 'string') {
1669
- throw new SkapiError('Tags should be type: <string | string[]>', { code: 'INVALID_PARAMETER' });
1670
- }
1671
- }
1672
- return v;
1673
- }
1674
- }
1671
+ tags: 'string'
1675
1672
  };
1676
1673
 
1677
1674
  params = checkParams(params || {}, struct, ['table']);
@@ -1680,73 +1677,11 @@ export default class Skapi {
1680
1677
  throw new SkapiError('Requires login.', { code: 'INVALID_REQUEST' });
1681
1678
  }
1682
1679
 
1683
- if (params?.tags) {
1684
- let tagFetch = [];
1685
- let getStartKey = fetchOptions?.startKey || null;
1686
-
1687
- for (let t of params.tags) {
1688
- let params_copy = JSON.parse(JSON.stringify(params));
1689
- params_copy.tag = t;
1690
- delete params_copy.tags;
1691
-
1692
- let fetchOpt = fetchOptions ? JSON.parse(JSON.stringify(fetchOptions)) : null;
1693
- if (fetchOpt) {
1694
- delete fetchOpt.startKey;
1695
-
1696
- if (getStartKey && getStartKey?.[t]) {
1697
- fetchOpt.startKey = getStartKey[t];
1698
- }
1699
- }
1700
-
1701
- tagFetch.push(this.request(
1702
- 'get-records',
1703
- params_copy,
1704
- Object.assign(
1705
- { auth: params.hasOwnProperty('access_group') && (params.access_group === 'private' || params.access_group > 0) ? true : !!this.session },
1706
- { fetchOptions: fetchOpt }
1707
- )));
1708
- }
1709
-
1710
- let list = [];
1711
- let startKey = {};
1712
- let res_all = await Promise.all(tagFetch);
1713
-
1714
- for (let res of res_all) {
1715
- for (let i in res.list) {
1716
- if (tagFetch.includes(res.list[i].rec)) {
1717
- continue;
1718
- }
1719
- tagFetch.push(res.list[i]);
1720
- list.push(normalize_record_data(res.list[i]));
1721
- };
1722
- if (res.startKey) {
1723
- if (Array.isArray(params.tags)) {
1724
- let tag = params.tags.splice(0, 1);
1725
- startKey[tag[0]] = res.startKey;
1726
- }
1727
- }
1728
- }
1729
-
1730
- let endOfList = true;
1731
- for (let k in startKey) {
1732
- if (startKey[k] && startKey[k] !== 'end') {
1733
- endOfList = false;
1734
- break;
1735
- }
1736
- }
1737
-
1738
- return {
1739
- list,
1740
- endOfList,
1741
- startKey
1742
- };
1743
- }
1744
-
1745
1680
  let result = await this.request(
1746
1681
  'get-records',
1747
1682
  params,
1748
1683
  Object.assign(
1749
- { auth: params.hasOwnProperty('access_group') && (params.access_group === 'private' || params.access_group > 0) ? true : !!this.user },
1684
+ { auth: params.hasOwnProperty('access_group') && (params.access_group === 'private' || params.access_group > 0) ? true : !!this.__user },
1750
1685
  { fetchOptions }
1751
1686
  )
1752
1687
  );
@@ -2205,7 +2140,7 @@ export default class Skapi {
2205
2140
  }
2206
2141
  }, ['user_id', 'group']);
2207
2142
 
2208
- if (this.user && option.user_id === this.user.user_id) {
2143
+ if (this.__user && option.user_id === this.__user.user_id) {
2209
2144
  throw new SkapiError(`"user_id" cannot be the user's own ID.`, { code: 'INVALID_PARAMETER' });
2210
2145
  }
2211
2146
 
@@ -2330,7 +2265,7 @@ export default class Skapi {
2330
2265
  }) || {};
2331
2266
 
2332
2267
  return this.getSubscriptions({
2333
- subscriber: option.user_id || this.user?.user_id,
2268
+ subscriber: option.user_id || this.__user?.user_id,
2334
2269
  group: option.group
2335
2270
  });
2336
2271
  }
@@ -2348,7 +2283,7 @@ export default class Skapi {
2348
2283
  }) || {};
2349
2284
 
2350
2285
  let subParams = {
2351
- subscription: option.user_id || this.user?.user_id,
2286
+ subscription: option.user_id || this.__user?.user_id,
2352
2287
  group: option.group
2353
2288
  };
2354
2289
 
@@ -2722,18 +2657,14 @@ export default class Skapi {
2722
2657
  */
2723
2658
  async resendSignupConfirmation(
2724
2659
  /** Redirect url on confirmation success. */
2725
- redirect: boolean | string = false
2660
+ redirect: string
2726
2661
  ): Promise<string> {
2727
- if (redirect && typeof redirect === 'string') {
2728
- redirect = (validateUrl(redirect) as string);
2729
- }
2730
-
2731
- else if (typeof redirect !== 'boolean') {
2732
- throw new SkapiError('Argument should be type: <boolean | string>.', { code: 'INVALID_REQUEST' });
2662
+ if (!this.__request_signup_confirmation) {
2663
+ throw new SkapiError('Least one login attempt is required.', { code: 'INVALID_REQUEST' });
2733
2664
  }
2734
2665
 
2735
- if (!this.__request_signup_confirmation) {
2736
- throw new SkapiError('Least one signin attempt is required.', { code: 'INVALID_REQUEST' });
2666
+ if (redirect) {
2667
+ validateUrl(redirect);
2737
2668
  }
2738
2669
 
2739
2670
  let resend = await this.request("confirm-signup", {
@@ -2742,7 +2673,7 @@ export default class Skapi {
2742
2673
  });
2743
2674
 
2744
2675
  this.__request_signup_confirmation = null;
2745
- return resend;
2676
+ return resend; // 'SUCCESS: Signup confirmation E-Mail has been sent.'
2746
2677
  }
2747
2678
 
2748
2679
  /**
@@ -2834,8 +2765,8 @@ export default class Skapi {
2834
2765
  if (code) {
2835
2766
  this.authentication().updateSession({ refreshToken: true }).then(
2836
2767
  () => {
2837
- if (this.user) {
2838
- this.user[attribute + '_verified'] = true;
2768
+ if (this.__user) {
2769
+ this.__user[attribute + '_verified'] = true;
2839
2770
  }
2840
2771
  res(`SUCCESS: "${attribute}" is verified.`);
2841
2772
  }
@@ -3049,8 +2980,8 @@ export default class Skapi {
3049
2980
  async disableAccount(): Promise<string> {
3050
2981
  await this.__connection;
3051
2982
 
3052
- if (this.user && Array.isArray(this.user.services)) {
3053
- for (let s of this.user.services) {
2983
+ if (this.__user && Array.isArray(this.__user.services)) {
2984
+ for (let s of this.__user.services) {
3054
2985
  if (s.active) {
3055
2986
  throw new SkapiError('All services needs to be disabled.', { code: 'INVALID_REQUEST' });
3056
2987
  }
@@ -3115,7 +3046,7 @@ export default class Skapi {
3115
3046
  });
3116
3047
 
3117
3048
  if (params && typeof params === 'object' && !Object.keys(params).length) {
3118
- return this.user;
3049
+ return this.__user;
3119
3050
  }
3120
3051
 
3121
3052
  if (params.new_password || params.current_password) {
@@ -3158,10 +3089,10 @@ export default class Skapi {
3158
3089
  ['phone_number_public', 'phone_number_verified', "User's phone number should be verified to set"]
3159
3090
  ];
3160
3091
 
3161
- if (this.user) {
3092
+ if (this.__user) {
3162
3093
  for (let c of collision) {
3163
- if (params[c[0]] && !this.user[c[1]]) {
3164
- throw new SkapiError(`${c[2]} "${c[0]}" to true.`, { code: 'INVALID_PARAMETER' });
3094
+ if (params[c[0]] && !this.__user[c[1]]) {
3095
+ throw new SkapiError(`${c[2]} "${c[0]}" to true.`, { code: 'INVALID_REQUEST' });
3165
3096
  }
3166
3097
  }
3167
3098
  }
@@ -3220,7 +3151,7 @@ export default class Skapi {
3220
3151
  await this.authentication().updateSession({ refreshToken: true });
3221
3152
  }
3222
3153
 
3223
- return this.user;
3154
+ return this.__user;
3224
3155
  }
3225
3156
 
3226
3157
 
@@ -3265,13 +3196,13 @@ export default class Skapi {
3265
3196
  auth: true
3266
3197
  };
3267
3198
 
3268
- if (option.private) {
3199
+ if (option?.private) {
3269
3200
  Object.assign(opt, { meta: { '__private__': option.private } });
3270
3201
  }
3271
3202
 
3272
3203
  await this.request('post-userdata', form, opt);
3273
3204
  await this.authentication().updateSession();
3274
- return this.user;
3205
+ return this.__user;
3275
3206
  }
3276
3207
 
3277
3208
  /**
@@ -3507,7 +3438,7 @@ export default class Skapi {
3507
3438
 
3508
3439
  let user = result.list[0];
3509
3440
  // append user session data
3510
- Object.assign(user, this.user);
3441
+ Object.assign(user, this.__user);
3511
3442
 
3512
3443
  user._what_public_see = JSON.parse(JSON.stringify(user));
3513
3444
 
package/src/utils.ts CHANGED
@@ -1,36 +1,34 @@
1
1
  import SkapiError from "./skapi_error";
2
2
  import { RecordData, Form } from "./Types";
3
3
 
4
- const sha256: any = function (ascii) {
5
- // author: https://geraintluff.github.io/sha256/
6
-
4
+ const sha256: any = function sha256(ascii) {
7
5
  function rightRotate(value, amount) {
8
6
  return (value >>> amount) | (value << (32 - amount));
9
7
  };
10
8
 
11
- var mathPow = Math.pow;
12
- var maxWord = mathPow(2, 32);
13
- var lengthProperty = 'length';
14
- var i, j; // Used as a counter across the whole file
15
- var result = '';
9
+ let mathPow = Math.pow;
10
+ let maxWord = mathPow(2, 32);
11
+ let lengthProperty = 'length';
12
+ let i, j; // Used as a counter across the whole file
13
+ let result = '';
16
14
 
17
- var words = [];
18
- var asciiBitLength = ascii[lengthProperty] * 8;
15
+ let words = [];
16
+ let asciiBitLength = ascii[lengthProperty] * 8;
19
17
 
20
18
  //* caching results is optional - remove/add slash from front of this line to toggle
21
19
  // Initial hash value: first 32 bits of the fractional parts of the square roots of the first 8 primes
22
20
  // (we actually calculate the first 64, but extra values are just ignored)
23
- var hash = sha256.h = sha256.h || [];
21
+ let hash = (sha256 as any).h = (sha256 as any).h || [];
24
22
  // Round constants: first 32 bits of the fractional parts of the cube roots of the first 64 primes
25
- var k = sha256.k = sha256.k || [];
26
- var primeCounter = k[lengthProperty];
23
+ let k = (sha256 as any).k = (sha256 as any).k || [];
24
+ let primeCounter = k[lengthProperty];
27
25
  /*/
28
- var hash = [], k = [];
29
- var primeCounter = 0;
26
+ let hash = [], k = [];
27
+ let primeCounter = 0;
30
28
  //*/
31
29
 
32
- var isComposite = {};
33
- for (var candidate = 2; primeCounter < 64; candidate++) {
30
+ let isComposite = {};
31
+ for (let candidate = 2; primeCounter < 64; candidate++) {
34
32
  if (!isComposite[candidate]) {
35
33
  for (i = 0; i < 313; i += candidate) {
36
34
  isComposite[i] = candidate;
@@ -44,7 +42,9 @@ const sha256: any = function (ascii) {
44
42
  while (ascii[lengthProperty] % 64 - 56) ascii += '\x00'; // More zero padding
45
43
  for (i = 0; i < ascii[lengthProperty]; i++) {
46
44
  j = ascii.charCodeAt(i);
47
- if (j >> 8) return; // ASCII check: only accept characters in range 0-255
45
+ if (j >> 8) {
46
+ return; // ASCII check: only accept characters in range 0-255
47
+ }
48
48
  words[i >> 2] |= j << ((3 - i) % 4) * 8;
49
49
  }
50
50
  words[words[lengthProperty]] = ((asciiBitLength / maxWord) | 0);
@@ -52,21 +52,21 @@ const sha256: any = function (ascii) {
52
52
 
53
53
  // process each chunk
54
54
  for (j = 0; j < words[lengthProperty];) {
55
- var w = words.slice(j, j += 16); // The message is expanded into 64 words as part of the iteration
56
- var oldHash = hash;
55
+ let w = words.slice(j, j += 16); // The message is expanded into 64 words as part of the iteration
56
+ let oldHash = hash;
57
57
  // This is now the undefinedworking hash", often labelled as variables a...g
58
58
  // (we have to truncate as well, otherwise extra entries at the end accumulate
59
59
  hash = hash.slice(0, 8);
60
60
 
61
61
  for (i = 0; i < 64; i++) {
62
- var i2 = i + j;
62
+ let i2 = i + j;
63
63
  // Expand the message into 64 words
64
64
  // Used below if
65
- var w15 = w[i - 15], w2 = w[i - 2];
65
+ let w15 = w[i - 15], w2 = w[i - 2];
66
66
 
67
67
  // Iterate
68
- var a = hash[0], e = hash[4];
69
- var temp1 = hash[7]
68
+ let a = hash[0], e = hash[4];
69
+ let temp1 = hash[7]
70
70
  + (rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25)) // S1
71
71
  + ((e & hash[5]) ^ ((~e) & hash[6])) // ch
72
72
  + k[i]
@@ -79,7 +79,7 @@ const sha256: any = function (ascii) {
79
79
  ) | 0
80
80
  );
81
81
  // This is only used once, so *could* be moved below, but it only saves 4 bytes and makes things unreadble
82
- var temp2 = (rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22)) // S0
82
+ let temp2 = (rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22)) // S0
83
83
  + ((a & hash[1]) ^ (a & hash[2]) ^ (hash[1] & hash[2])); // maj
84
84
 
85
85
  hash = [(temp1 + temp2) | 0].concat(hash); // We don't bother trimming off the extra ones, they're harmless as long as we're truncating when we do the slice()
@@ -93,10 +93,11 @@ const sha256: any = function (ascii) {
93
93
 
94
94
  for (i = 0; i < 8; i++) {
95
95
  for (j = 3; j + 1; j--) {
96
- var b = (hash[i] >> (j * 8)) & 255;
96
+ let b = (hash[i] >> (j * 8)) & 255;
97
97
  result += ((b < 16) ? 0 : '') + b.toString(16);
98
98
  }
99
99
  }
100
+
100
101
  return result;
101
102
  };
102
103
 
@@ -236,7 +237,7 @@ function checkParams(
236
237
  } catch (err) {
237
238
  if (typeof err === 'string' && err.substring(0, 6) === 'BREAK:') {
238
239
  // break on BREAK message
239
- err = err.substring(5);
240
+ err = err.substring(6);
240
241
  let errMsg = (err as string).split(':');
241
242
  errToThrow = new SkapiError(errMsg[1], { code: errMsg[0] });
242
243
  break;
@@ -291,6 +292,9 @@ function checkParams(
291
292
 
292
293
  val = _params;
293
294
  }
295
+ else {
296
+ throw new SkapiError(`Value: ${_params}${isInvalid}`, { code: 'INVALID_PARAMETER' });
297
+ }
294
298
  }
295
299
 
296
300
  else if (struct === null) {
package/tsconfig.json CHANGED
@@ -23,7 +23,7 @@
23
23
  // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
24
24
  // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
25
25
  /* Language and Environment */
26
- "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
26
+ "target": "ES2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
27
27
  // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
28
28
  // "jsx": "preserve", /* Specify what JSX code is generated. */
29
29
  // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
@@ -37,7 +37,7 @@
37
37
  // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
38
38
  // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
39
39
  /* Modules */
40
- "module": "commonjs", /* Specify what module code is generated. */
40
+ "module": "ES2020", /* Specify what module code is generated. */
41
41
  // "rootDir": "./", /* Specify the root folder within your source files. */
42
42
  // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
43
43
  "moduleResolution": "node",