Repository: algorand/js-algorand-sdk
Pull request #603 (2022-07-05 15:15:05)

FOR REVIEW ONLY - Release v1.18.1
## What's Changed

* Properly set maxWidth in trace by @joe-p in https://github.com/algorand/js-algorand-sdk/pull/593
* fix: safe intDecoding by @AlgoDoggo in https://github.com/algorand/js-algorand-sdk/pull/599
* Remove code that relies on node's path module by @bmdelacruz in https://github.com/algorand/js-algorand-sdk/pull/598

## New Contributors

* @AlgoDoggo made their first contribution in https://github.com/algorand/js-algorand-sdk/pull/599
* @bmdelacruz made their first contribution in https://github.com/algorand/js-algorand-sdk/pull/598

**Full Changelog**: https://github.com/algorand/js-algorand-sdk/compare/v1.18.0...v1.18.1


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 98c3e44..627093a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,16 @@
+# v1.18.1
+
+## What's Changed
+
+- Properly set maxWidth in trace by @joe-p in https://github.com/algorand/js-algorand-sdk/pull/593
+- fix: safe intDecoding by @AlgoDoggo in https://github.com/algorand/js-algorand-sdk/pull/599
+- Remove code that relies on node's path module by @bmdelacruz in https://github.com/algorand/js-algorand-sdk/pull/598
+
+## New Contributors
+
+- @AlgoDoggo made their first contribution in https://github.com/algorand/js-algorand-sdk/pull/599
+- @bmdelacruz made their first contribution in https://github.com/algorand/js-algorand-sdk/pull/598
+
 # v1.18.0
 
 ## What's Changed
diff --git a/FAQ.md b/FAQ.md
index dafc8f2..43b3108 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -33,17 +33,7 @@ With Vite, you would see:
 Uncaught ReferenceError: Buffer is not defined
 ```
 
-You will have to install `buffer` and `path-browserify` as dependencies.
-
-In `vite.config.js`, specify:
-
-```js
-resolve: {
-  alias: {
-    path: 'path-browserify';
-  }
-}
-```
+You will have to install `buffer` as dependency.
 
 In `index.html`, add the following:
 
diff --git a/README.md b/README.md
index 55beaf8..8082304 100644
--- a/README.md
+++ b/README.md
@@ -22,8 +22,8 @@ Include a minified browser bundle directly in your HTML like so:
 
 ```html
 <script
-  src="https://unpkg.com/algosdk@v1.18.0/dist/browser/algosdk.min.js"
-  integrity="sha384-sUsnfiP7rGkgddTfqUUdb66b2cVxVmYkCyrJBCcWWSmpccI73Vm9wkUrCLsEcG6f"
+  src="https://unpkg.com/algosdk@v1.18.1/dist/browser/algosdk.min.js"
+  integrity="sha384-XUkDNLM09jpiPklD96D68Y77m6KhnWov0ZKy8xtca/UO8HIQ0f9OzI05Jxkt+ozd"
   crossorigin="anonymous"
 ></script>
 ```
@@ -32,8 +32,8 @@ or
 
 ```html
 <script
-  src="https://cdn.jsdelivr.net/npm/algosdk@v1.18.0/dist/browser/algosdk.min.js"
-  integrity="sha384-sUsnfiP7rGkgddTfqUUdb66b2cVxVmYkCyrJBCcWWSmpccI73Vm9wkUrCLsEcG6f"
+  src="https://cdn.jsdelivr.net/npm/algosdk@v1.18.1/dist/browser/algosdk.min.js"
+  integrity="sha384-XUkDNLM09jpiPklD96D68Y77m6KhnWov0ZKy8xtca/UO8HIQ0f9OzI05Jxkt+ozd"
   crossorigin="anonymous"
 ></script>
 ```
diff --git a/package-lock.json b/package-lock.json
index 6d02ed5..c965daf 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "algosdk",
-  "version": "1.18.0",
+  "version": "1.18.1",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "algosdk",
-      "version": "1.18.0",
+      "version": "1.18.1",
       "license": "MIT",
       "dependencies": {
         "algo-msgpack-with-bigint": "^2.1.1",
@@ -17,8 +17,7 @@
         "js-sha512": "^0.8.0",
         "json-bigint": "^1.0.0",
         "superagent": "^6.1.0",
-        "tweetnacl": "^1.0.3",
-        "url-parse": "^1.5.1"
+        "tweetnacl": "^1.0.3"
       },
       "devDependencies": {
         "@types/json-bigint": "^1.0.0",
@@ -45,7 +44,6 @@
         "mocha": "^9.0.0",
         "mocha-lcov-reporter": "^1.3.0",
         "mock-http-server": "^1.4.3",
-        "path-browserify": "^1.0.1",
         "prettier": "2.2.1",
         "selenium-webdriver": "^4.2.0",
         "source-map-loader": "^2.0.2",
@@ -5782,12 +5780,6 @@
         "node": ">= 0.8"
       }
     },
-    "node_modules/path-browserify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
-      "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
-      "dev": true
-    },
     "node_modules/path-exists": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
@@ -5997,11 +5989,6 @@
         "node": ">=0.6"
       }
     },
-    "node_modules/querystringify": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
-      "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
-    },
     "node_modules/queue-microtask": {
       "version": "1.2.3",
       "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -6252,11 +6239,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/requires-port": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
-      "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
-    },
     "node_modules/resolve": {
       "version": "1.20.0",
       "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
@@ -7691,15 +7673,6 @@
         "punycode": "^2.1.0"
       }
     },
-    "node_modules/url-parse": {
-      "version": "1.5.8",
-      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.8.tgz",
-      "integrity": "sha512-9JZ5zDrn9wJoOy/t+rH00HHejbU8dq9VsOYVu272TYDrCiyVAgHKUSpPh3ruZIpv8PMVR+NXLZvfRPJv8xAcQw==",
-      "dependencies": {
-        "querystringify": "^2.1.1",
-        "requires-port": "^1.0.0"
-      }
-    },
     "node_modules/util": {
       "version": "0.12.4",
       "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz",
@@ -12757,12 +12730,6 @@
       "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
       "dev": true
     },
-    "path-browserify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
-      "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
-      "dev": true
-    },
     "path-exists": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
@@ -12924,11 +12891,6 @@
       "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
       "dev": true
     },
-    "querystringify": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
-      "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
-    },
     "queue-microtask": {
       "version": "1.2.3",
       "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -13116,11 +13078,6 @@
       "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
       "dev": true
     },
-    "requires-port": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
-      "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
-    },
     "resolve": {
       "version": "1.20.0",
       "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
@@ -14232,15 +14189,6 @@
         "punycode": "^2.1.0"
       }
     },
-    "url-parse": {
-      "version": "1.5.8",
-      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.8.tgz",
-      "integrity": "sha512-9JZ5zDrn9wJoOy/t+rH00HHejbU8dq9VsOYVu272TYDrCiyVAgHKUSpPh3ruZIpv8PMVR+NXLZvfRPJv8xAcQw==",
-      "requires": {
-        "querystringify": "^2.1.1",
-        "requires-port": "^1.0.0"
-      }
-    },
     "util": {
       "version": "0.12.4",
       "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz",
diff --git a/package.json b/package.json
index 85eb906..95aca53 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "algosdk",
-  "version": "1.18.0",
+  "version": "1.18.1",
   "description": "The official JavaScript SDK for Algorand",
   "main": "dist/cjs/index.js",
   "module": "dist/esm/index.js",
@@ -25,8 +25,7 @@
     "js-sha512": "^0.8.0",
     "json-bigint": "^1.0.0",
     "superagent": "^6.1.0",
-    "tweetnacl": "^1.0.3",
-    "url-parse": "^1.5.1"
+    "tweetnacl": "^1.0.3"
   },
   "devDependencies": {
     "@types/json-bigint": "^1.0.0",
@@ -53,7 +52,6 @@
     "mocha": "^9.0.0",
     "mocha-lcov-reporter": "^1.3.0",
     "mock-http-server": "^1.4.3",
-    "path-browserify": "^1.0.1",
     "prettier": "2.2.1",
     "selenium-webdriver": "^4.2.0",
     "source-map-loader": "^2.0.2",
diff --git a/src/client/urlTokenBaseHTTPClient.ts b/src/client/urlTokenBaseHTTPClient.ts
index f54ef8b..157b8d5 100644
--- a/src/client/urlTokenBaseHTTPClient.ts
+++ b/src/client/urlTokenBaseHTTPClient.ts
@@ -1,5 +1,3 @@
-import Url from 'url-parse';
-import path from 'path';
 import * as request from 'superagent';
 import {
   BaseHTTPClient,
@@ -35,7 +33,7 @@ export type TokenHeader =
  * This is the default implementation of BaseHTTPClient.
  */
 export class URLTokenBaseHTTPClient implements BaseHTTPClient {
-  private readonly baseURL: Url;
+  private readonly baseURL: URL;
   private readonly tokenHeader: TokenHeader;
 
   constructor(
@@ -44,9 +42,15 @@ export class URLTokenBaseHTTPClient implements BaseHTTPClient {
     port?: string | number,
     private defaultHeaders: Record<string, any> = {}
   ) {
-    const baseServerURL = new Url(baseServer, {});
+    // Append a trailing slash so we can use relative paths. Without the trailing
+    // slash, the last path segment will be replaced by the relative path. See
+    // usage in `addressWithPath`.
+    const fixedBaseServer = baseServer.endsWith('/')
+      ? baseServer
+      : `${baseServer}/`;
+    const baseServerURL = new URL(fixedBaseServer);
     if (typeof port !== 'undefined') {
-      baseServerURL.set('port', port.toString());
+      baseServerURL.port = port.toString();
     }
 
     if (baseServerURL.protocol.length === 0) {
@@ -63,10 +67,15 @@ export class URLTokenBaseHTTPClient implements BaseHTTPClient {
    * @returns A URL string
    */
   private addressWithPath(relativePath: string) {
-    const address = new Url(
-      path.posix.join(this.baseURL.pathname, relativePath),
-      this.baseURL
-    );
+    let fixedRelativePath: string;
+    if (relativePath.startsWith('./')) {
+      fixedRelativePath = relativePath;
+    } else if (relativePath.startsWith('/')) {
+      fixedRelativePath = `.${relativePath}`;
+    } else {
+      fixedRelativePath = `./${relativePath}`;
+    }
+    const address = new URL(fixedRelativePath, this.baseURL);
     return address.toString();
   }
 
diff --git a/src/dryrun.ts b/src/dryrun.ts
index f80a04c..aa222d1 100644
--- a/src/dryrun.ts
+++ b/src/dryrun.ts
@@ -365,8 +365,7 @@ class DryrunTransactionResult {
     disassembly: string[],
     spc: StackPrinterConfig
   ): string {
-    let maxWidth = defaultMaxWidth;
-    if (spc.maxValueWidth === undefined) maxWidth = spc.maxValueWidth;
+    const maxWidth = spc.maxValueWidth || defaultMaxWidth;
 
     // Create the array of arrays, each sub array contains N columns
     const lines = [['pc#', 'ln#', 'source', 'scratch', 'stack']];
diff --git a/src/utils/utils.ts b/src/utils/utils.ts
index 611a78c..c504a09 100644
--- a/src/utils/utils.ts
+++ b/src/utils/utils.ts
@@ -10,7 +10,6 @@ export interface JSONOptions {
 /**
  * Parse JSON with additional options.
  * @param str - The JSON string to parse.
- * @param options - Parsing options.
  * @param options - Options object to configure how integers in
  *   this request's JSON response will be decoded. Use the `intDecoding`
  *   property with one of the following options:
@@ -28,34 +27,32 @@ export interface JSONOptions {
 export function parseJSON(str: string, options?: JSONOptions) {
   const intDecoding =
     options && options.intDecoding ? options.intDecoding : IntDecoding.DEFAULT;
-  const parsed = JSONbig.parse(str, (_, value) => {
+  return JSONbig.parse(str, (_, value) => {
     if (
       value != null &&
       typeof value === 'object' &&
       Object.getPrototypeOf(value) == null
     ) {
-      // for some reason the Objects returned by JSONbig.parse have a null prototype, so we
-      // need to fix that.
+      // JSONbig.parse objects are created with Object.create(null) and thus have a null prototype
+      // let us remedy that
       Object.setPrototypeOf(value, Object.prototype);
     }
 
     if (typeof value === 'bigint') {
+      if (intDecoding === 'safe' && value > Number.MAX_SAFE_INTEGER) {
+        throw new Error(
+          `Integer exceeds maximum safe integer: ${value.toString()}. Try parsing with a different intDecoding option.`
+        );
+      }
       if (
         intDecoding === 'bigint' ||
         (intDecoding === 'mixed' && value > Number.MAX_SAFE_INTEGER)
       ) {
         return value;
       }
-
       // JSONbig.parse converts number to BigInts if they are >= 10**15. This is smaller than
       // Number.MAX_SAFE_INTEGER, so we can convert some BigInts back to normal numbers.
-      if (intDecoding === 'default' || intDecoding === 'mixed') {
-        return Number(value);
-      }
-
-      throw new Error(
-        `Integer exceeds maximum safe integer: ${value.toString()}. Try parsing with a different intDecoding option.`
-      );
+      return Number(value);
     }
 
     if (typeof value === 'number') {
@@ -66,7 +63,6 @@ export function parseJSON(str: string, options?: JSONOptions) {
 
     return value;
   });
-  return parsed;
 }
 
 /**
diff --git a/webpack.config.js b/webpack.config.js
index 1bd1259..c22e0e4 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -16,11 +16,6 @@ module.exports = {
   resolve: {
     // Add '.ts' as resolvable extensions
     extensions: ['.ts', '.js'],
-
-    // Support `path` in the browser
-    fallback: {
-      path: require.resolve('path-browserify'),
-    },
   },
   plugins: [
     new webpack.ProvidePlugin({


Test patch:
diff --git a/tests/2.Encoding.js b/tests/2.Encoding.js
index 25d011c..57d1452 100644
--- a/tests/2.Encoding.js
+++ b/tests/2.Encoding.js
@@ -354,17 +354,18 @@ describe('encoding', () => {
     });
 
     it('should parse number', () => {
-      const input = '17';
-
-      for (const intDecoding of ['default', 'safe', 'mixed', 'bigint']) {
-        const actual = utils.parseJSON(input, { intDecoding });
-        const expected = intDecoding === 'bigint' ? 17n : 17;
-
-        assert.deepStrictEqual(
-          actual,
-          expected,
-          `Error when intDecoding = ${intDecoding}`
-        );
+      const inputs = ['17', '9007199254740991'];
+      for (const input of inputs) {
+        for (const intDecoding of ['default', 'safe', 'mixed', 'bigint']) {
+          const actual = utils.parseJSON(input, { intDecoding });
+          const expected =
+            intDecoding === 'bigint' ? BigInt(input) : Number(input);
+          assert.deepStrictEqual(
+            actual,
+            expected,
+            `Error when intDecoding = ${intDecoding}`
+          );
+        }
       }
     });