diff --git a/.eslintrc b/.eslintrc
index 924f042..c13def9 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,18 +1,16 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
- "plugins": [
- "@typescript-eslint",
- "prettier"
- ],
+ "plugins": ["@typescript-eslint", "prettier", "jsdoc"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
+ "plugin:jsdoc/recommended",
"prettier"
],
"rules": {
- "no-console": 1, // Means warning
+ "no-console": 1, // Means warning
"prettier/prettier": 2 // Means error
}
-}
\ No newline at end of file
+}
diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
index 54d52e2..37c2c0d 100644
--- a/.github/workflows/pages.yml
+++ b/.github/workflows/pages.yml
@@ -33,9 +33,10 @@ jobs:
- name: Install Node modules
run: |
npm install
- - name: Build project
+ - name: Build example project and copy docs
run: |
npm run build
+ npm run genDocs
cd examples/typescript
npm install
npm run build
diff --git a/.gitignore b/.gitignore
index 05532d3..b7fac20 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
node_modules
lib
bundle.js
+docs
esptool-js-*.tgz
.vscode/settings.json
.parcel-cache
diff --git a/examples/typescript/.parcelrc b/examples/typescript/.parcelrc
new file mode 100644
index 0000000..853a724
--- /dev/null
+++ b/examples/typescript/.parcelrc
@@ -0,0 +1,7 @@
+{
+ "extends": "@parcel/config-default",
+ "resolvers": [
+ "parcel-resolver-ignore",
+ "..."
+ ]
+ }
\ No newline at end of file
diff --git a/examples/typescript/README.md b/examples/typescript/README.md
index 05a6ecb..4627d85 100644
--- a/examples/typescript/README.md
+++ b/examples/typescript/README.md
@@ -1,6 +1,8 @@
# Using Esptool-JS in a Typescript environment
-This example has example code in `src/index.ts` which is called in the `index.html`. We are using Parcel to do bundle mechanism for the resulting JavaScript for simplicity here.
+This example has example code in `src/index.ts` which is called in the `index.html`. We are using Parcel to bundle resulting files for simplicity here.
+
+**NOTE:** This example is linked to the documentation generated from the source code. You could remove such dependency if necessary by remove `./docs/index.html` from `src/index.html` if you need so. NPM commands used below will generate documentation as well.
## Testing it locally
@@ -9,4 +11,13 @@ npm install
npm run dev
```
-Then open http://localhost:1234 in Chrome or Edge. The `npm run dev` step will call Parcel which start a local http server serving `index.html` with compiled `index.ts`.
\ No newline at end of file
+Then open http://localhost:1234 in Chrome or Edge. The `npm run dev` step will call Parcel which start a local http server serving `index.html` with compiled `index.ts`.
+
+## Generate build to publish
+
+```
+npm install
+npm run build
+```
+
+Copy the content of `dist` to your static pages service like Github pages.
\ No newline at end of file
diff --git a/examples/typescript/package.json b/examples/typescript/package.json
index 190bf6f..1b17df5 100644
--- a/examples/typescript/package.json
+++ b/examples/typescript/package.json
@@ -4,15 +4,20 @@
"description": "This an example of using esptool-js with parcel and typescript",
"source": "src/index.html",
"scripts": {
- "dev": "parcel src/index.html",
- "build": "npm run clean && parcel build src/index.html --no-optimize --public-url ./",
+ "genDocs": "cd ../.. && npm run genDocs && mkdir -p examples/typescript/dist && cp -r docs examples/typescript/dist && cd examples/typescript",
+ "dev": "npm run genDocs && parcel src/index.html",
+ "build": "npm run clean && npm run genDocs && parcel build src/index.html --no-optimize --public-url ./",
"clean": "rimraf dist .parcel-cache",
"test": "echo \"Error: no test specified\" && exit 1"
},
+ "parcelIgnore": [
+ "./docs/.+"
+ ],
"author": "",
"license": "ISC",
"devDependencies": {
"parcel": "^2.8.3",
+ "parcel-resolver-ignore": "^2.1.5",
"rimraf": "^4.1.2",
"typescript": "^4.9.4"
}
diff --git a/examples/typescript/src/index.html b/examples/typescript/src/index.html
index 6ac92f5..4910600 100644
--- a/examples/typescript/src/index.html
+++ b/examples/typescript/src/index.html
@@ -20,6 +20,9 @@
diff --git a/examples/typescript/src/index.ts b/examples/typescript/src/index.ts
index 751e399..b5979bb 100644
--- a/examples/typescript/src/index.ts
+++ b/examples/typescript/src/index.ts
@@ -38,6 +38,16 @@ eraseButton.style.display = "none";
consoleStopButton.style.display = "none";
filesDiv.style.display = "none";
+/**
+ * The built in Event object.
+ * @external Event
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Event}
+ */
+
+/**
+ * File reader handler to read given local file.
+ * @param {Event} evt File Select event
+ */
function handleFileSelect(evt) {
const file = evt.target.files[0];
@@ -78,10 +88,10 @@ connectButton.onclick = async () => {
} as LoaderOptions;
esploader = new ESPLoader(flashOptions);
- chip = await esploader.main_fn();
+ chip = await esploader.main();
// Temporarily broken
- // await esploader.flash_id();
+ // await esploader.flashId();
} catch (e) {
console.error(e);
term.writeln(`Error: ${e.message}`);
@@ -113,7 +123,7 @@ resetButton.onclick = async () => {
eraseButton.onclick = async () => {
eraseButton.disabled = true;
try {
- await esploader.erase_flash();
+ await esploader.eraseFlash();
} catch (e) {
console.error(e);
term.writeln(`Error: ${e.message}`);
@@ -166,12 +176,24 @@ addFileButton.onclick = () => {
}
};
-function removeRow(row) {
+/**
+ * The built in HTMLTableRowElement object.
+ * @external HTMLTableRowElement
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableRowElement}
+ */
+
+/**
+ * Remove file row from HTML Table
+ * @param {HTMLTableRowElement} row Table row element to remove
+ */
+function removeRow(row: HTMLTableRowElement) {
const rowIndex = Array.from(table.rows).indexOf(row);
table.deleteRow(rowIndex);
}
-// to be called on disconnect - remove any stale references of older connections if any
+/**
+ * Clean devices variables on chip disconnect. Remove stale references if any.
+ */
function cleanUp() {
device = null;
transport = null;
@@ -228,7 +250,11 @@ consoleStopButton.onclick = async () => {
programDiv.style.display = "initial";
};
-function validate_program_inputs() {
+/**
+ * Validate the provided files images and offset to see if they're valid.
+ * @returns {string} Program input validation result
+ */
+function validateProgramInputs() {
const offsetArr = [];
const rowCount = table.rows.length;
let row;
@@ -258,7 +284,7 @@ function validate_program_inputs() {
programButton.onclick = async () => {
const alertMsg = document.getElementById("alertmsg");
- const err = validate_program_inputs();
+ const err = validateProgramInputs();
if (err != "success") {
alertMsg.innerHTML = "" + err + "";
@@ -301,7 +327,7 @@ programButton.onclick = async () => {
},
calculateMD5Hash: (image) => CryptoJS.MD5(CryptoJS.enc.Latin1.parse(image)),
} as FlashOptions;
- await esploader.write_flash(flashOptions);
+ await esploader.writeFlash(flashOptions);
} catch (e) {
console.error(e);
term.writeln(`Error: ${e.message}`);
diff --git a/package-lock.json b/package-lock.json
index 36cf82c..7ca8cab 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -23,12 +23,15 @@
"@typescript-eslint/eslint-plugin": "^5.43.0",
"@typescript-eslint/parser": "^5.43.0",
"babel-loader": "^9.1.0",
+ "buffer": "^5.7.1",
"eslint": "^8.28.0",
"eslint-config-prettier": "^8.5.0",
+ "eslint-plugin-jsdoc": "^46.4.5",
"eslint-plugin-prettier": "^4.2.1",
"prettier": "^2.7.1",
"rimraf": "^3.0.2",
"rollup": "^3.3.0",
+ "typedoc": "^0.25.2",
"typescript": "^4.8.4"
}
},
@@ -115,9 +118,9 @@
}
},
"node_modules/@babel/core/node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"peer": true,
"bin": {
@@ -159,9 +162,9 @@
}
},
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"peer": true,
"bin": {
@@ -390,9 +393,9 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.20.3",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.3.tgz",
- "integrity": "sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==",
+ "version": "7.22.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz",
+ "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==",
"dev": true,
"peer": true,
"bin": {
@@ -453,6 +456,20 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@es-joy/jsdoccomment": {
+ "version": "0.39.4",
+ "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.39.4.tgz",
+ "integrity": "sha512-Jvw915fjqQct445+yron7Dufix9A+m9j1fCJYlCo1FWlRvTxa3pjJelxdSTdaLWcTwRU6vbL+NYjO4YuNIS5Qg==",
+ "dev": true,
+ "dependencies": {
+ "comment-parser": "1.3.1",
+ "esquery": "^1.5.0",
+ "jsdoc-type-pratt-parser": "~4.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
"node_modules/@eslint/eslintrc": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz",
@@ -557,9 +574,9 @@
}
},
"node_modules/@jridgewell/source-map": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
- "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
+ "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
"dev": true,
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.0",
@@ -795,12 +812,6 @@
}
}
},
- "node_modules/@rollup/pluginutils/node_modules/@types/estree": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
- "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==",
- "dev": true
- },
"node_modules/@types/eslint": {
"version": "8.4.10",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz",
@@ -824,9 +835,9 @@
}
},
"node_modules/@types/estree": {
- "version": "0.0.51",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz",
- "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
+ "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
"dev": true
},
"node_modules/@types/json-schema": {
@@ -836,9 +847,9 @@
"dev": true
},
"node_modules/@types/node": {
- "version": "18.11.9",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz",
- "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==",
+ "version": "20.4.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz",
+ "integrity": "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==",
"dev": true,
"peer": true
},
@@ -1054,73 +1065,73 @@
}
},
"node_modules/@webassemblyjs/ast": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
- "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
+ "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
"dev": true,
"peer": true,
"dependencies": {
- "@webassemblyjs/helper-numbers": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1"
+ "@webassemblyjs/helper-numbers": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6"
}
},
"node_modules/@webassemblyjs/floating-point-hex-parser": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
- "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
+ "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
"dev": true,
"peer": true
},
"node_modules/@webassemblyjs/helper-api-error": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
- "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
+ "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
"dev": true,
"peer": true
},
"node_modules/@webassemblyjs/helper-buffer": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
- "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
+ "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
"dev": true,
"peer": true
},
"node_modules/@webassemblyjs/helper-numbers": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
- "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
+ "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
"dev": true,
"peer": true,
"dependencies": {
- "@webassemblyjs/floating-point-hex-parser": "1.11.1",
- "@webassemblyjs/helper-api-error": "1.11.1",
+ "@webassemblyjs/floating-point-hex-parser": "1.11.6",
+ "@webassemblyjs/helper-api-error": "1.11.6",
"@xtuc/long": "4.2.2"
}
},
"node_modules/@webassemblyjs/helper-wasm-bytecode": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
- "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
+ "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
"dev": true,
"peer": true
},
"node_modules/@webassemblyjs/helper-wasm-section": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
- "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
+ "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
"dev": true,
"peer": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-buffer": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
- "@webassemblyjs/wasm-gen": "1.11.1"
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6"
}
},
"node_modules/@webassemblyjs/ieee754": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
- "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
+ "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
"dev": true,
"peer": true,
"dependencies": {
@@ -1128,9 +1139,9 @@
}
},
"node_modules/@webassemblyjs/leb128": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
- "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
+ "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
"dev": true,
"peer": true,
"dependencies": {
@@ -1138,79 +1149,79 @@
}
},
"node_modules/@webassemblyjs/utf8": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
- "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
+ "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
"dev": true,
"peer": true
},
"node_modules/@webassemblyjs/wasm-edit": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
- "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
+ "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
"dev": true,
"peer": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-buffer": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
- "@webassemblyjs/helper-wasm-section": "1.11.1",
- "@webassemblyjs/wasm-gen": "1.11.1",
- "@webassemblyjs/wasm-opt": "1.11.1",
- "@webassemblyjs/wasm-parser": "1.11.1",
- "@webassemblyjs/wast-printer": "1.11.1"
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/helper-wasm-section": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6",
+ "@webassemblyjs/wasm-opt": "1.11.6",
+ "@webassemblyjs/wasm-parser": "1.11.6",
+ "@webassemblyjs/wast-printer": "1.11.6"
}
},
"node_modules/@webassemblyjs/wasm-gen": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
- "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
+ "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
"dev": true,
"peer": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
- "@webassemblyjs/ieee754": "1.11.1",
- "@webassemblyjs/leb128": "1.11.1",
- "@webassemblyjs/utf8": "1.11.1"
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/ieee754": "1.11.6",
+ "@webassemblyjs/leb128": "1.11.6",
+ "@webassemblyjs/utf8": "1.11.6"
}
},
"node_modules/@webassemblyjs/wasm-opt": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
- "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
+ "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
"dev": true,
"peer": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-buffer": "1.11.1",
- "@webassemblyjs/wasm-gen": "1.11.1",
- "@webassemblyjs/wasm-parser": "1.11.1"
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6",
+ "@webassemblyjs/wasm-parser": "1.11.6"
}
},
"node_modules/@webassemblyjs/wasm-parser": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
- "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
+ "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
"dev": true,
"peer": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-api-error": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
- "@webassemblyjs/ieee754": "1.11.1",
- "@webassemblyjs/leb128": "1.11.1",
- "@webassemblyjs/utf8": "1.11.1"
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-api-error": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/ieee754": "1.11.6",
+ "@webassemblyjs/leb128": "1.11.6",
+ "@webassemblyjs/utf8": "1.11.6"
}
},
"node_modules/@webassemblyjs/wast-printer": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
- "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
+ "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
"dev": true,
"peer": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/ast": "1.11.6",
"@xtuc/long": "4.2.2"
}
},
@@ -1229,9 +1240,9 @@
"peer": true
},
"node_modules/acorn": {
- "version": "8.8.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
- "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
+ "version": "8.10.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
+ "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
@@ -1241,9 +1252,9 @@
}
},
"node_modules/acorn-import-assertions": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
- "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
+ "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
"dev": true,
"peer": true,
"peerDependencies": {
@@ -1333,6 +1344,12 @@
"node": ">=8"
}
},
+ "node_modules/ansi-sequence-parser": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz",
+ "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==",
+ "dev": true
+ },
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@@ -1348,6 +1365,15 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/are-docs-informative": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz",
+ "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -1439,6 +1465,26 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -1490,6 +1536,30 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@@ -1572,6 +1642,15 @@
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true
},
+ "node_modules/comment-parser": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz",
+ "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ }
+ },
"node_modules/commondir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
@@ -1669,9 +1748,9 @@
"peer": true
},
"node_modules/enhanced-resolve": {
- "version": "5.10.0",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz",
- "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==",
+ "version": "5.15.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
+ "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
"dev": true,
"peer": true,
"dependencies": {
@@ -1683,9 +1762,9 @@
}
},
"node_modules/es-module-lexer": {
- "version": "0.9.3",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz",
- "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz",
+ "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==",
"dev": true,
"peer": true
},
@@ -1777,6 +1856,41 @@
"eslint": ">=7.0.0"
}
},
+ "node_modules/eslint-plugin-jsdoc": {
+ "version": "46.4.5",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.4.5.tgz",
+ "integrity": "sha512-HjTuxqDYplAQFu29F3MHFCDDBgeqOxPXI6TyBhL0u2rr4XntJ0z3C9PmJvpjFscKdHwkZDN/0l1QCG0QwyRi4g==",
+ "dev": true,
+ "dependencies": {
+ "@es-joy/jsdoccomment": "~0.39.4",
+ "are-docs-informative": "^0.0.2",
+ "comment-parser": "1.3.1",
+ "debug": "^4.3.4",
+ "escape-string-regexp": "^4.0.0",
+ "esquery": "^1.5.0",
+ "is-builtin-module": "^3.2.1",
+ "semver": "^7.5.4",
+ "spdx-expression-parse": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-jsdoc/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/eslint-plugin-prettier": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz",
@@ -1975,9 +2089,9 @@
}
},
"node_modules/esquery": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
- "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+ "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
"dev": true,
"dependencies": {
"estraverse": "^5.1.0"
@@ -2323,6 +2437,26 @@
"node": ">=8"
}
},
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
"node_modules/ignore": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
@@ -2374,9 +2508,9 @@
"dev": true
},
"node_modules/is-builtin-module": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz",
- "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz",
+ "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==",
"dev": true,
"dependencies": {
"builtin-modules": "^3.3.0"
@@ -2532,6 +2666,15 @@
"js-yaml": "bin/js-yaml.js"
}
},
+ "node_modules/jsdoc-type-pratt-parser": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz",
+ "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
"node_modules/jsesc": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
@@ -2577,6 +2720,12 @@
"node": ">=6"
}
},
+ "node_modules/jsonc-parser": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
+ "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
+ "dev": true
+ },
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -2630,6 +2779,12 @@
"node": ">=10"
}
},
+ "node_modules/lunr": {
+ "version": "2.3.9",
+ "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
+ "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
+ "dev": true
+ },
"node_modules/magic-string": {
"version": "0.26.7",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz",
@@ -2658,14 +2813,26 @@
}
},
"node_modules/make-dir/node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
+ "node_modules/marked": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
+ "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
+ "dev": true,
+ "bin": {
+ "marked": "bin/marked.js"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -3122,9 +3289,9 @@
"peer": true
},
"node_modules/schema-utils": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
- "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+ "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
"peer": true,
"dependencies": {
@@ -3141,9 +3308,9 @@
}
},
"node_modules/semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -3156,9 +3323,9 @@
}
},
"node_modules/serialize-javascript": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
- "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz",
+ "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==",
"dev": true,
"peer": true,
"dependencies": {
@@ -3186,6 +3353,18 @@
"node": ">=8"
}
},
+ "node_modules/shiki": {
+ "version": "0.14.4",
+ "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.4.tgz",
+ "integrity": "sha512-IXCRip2IQzKwxArNNq1S+On4KPML3Yyn8Zzs/xRgcgOWIr8ntIK3IKzjFPfjy/7kt9ZMjc+FItfqHRBg8b6tNQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-sequence-parser": "^1.1.0",
+ "jsonc-parser": "^3.2.0",
+ "vscode-oniguruma": "^1.7.0",
+ "vscode-textmate": "^8.0.0"
+ }
+ },
"node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -3220,6 +3399,28 @@
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"dev": true
},
+ "node_modules/spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+ "dev": true
+ },
+ "node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-license-ids": {
+ "version": "3.0.13",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz",
+ "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==",
+ "dev": true
+ },
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -3279,13 +3480,13 @@
}
},
"node_modules/terser": {
- "version": "5.15.1",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz",
- "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==",
+ "version": "5.19.2",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz",
+ "integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==",
"dev": true,
"dependencies": {
- "@jridgewell/source-map": "^0.3.2",
- "acorn": "^8.5.0",
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.8.2",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},
@@ -3297,17 +3498,17 @@
}
},
"node_modules/terser-webpack-plugin": {
- "version": "5.3.6",
- "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz",
- "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==",
+ "version": "5.3.9",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz",
+ "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==",
"dev": true,
"peer": true,
"dependencies": {
- "@jridgewell/trace-mapping": "^0.3.14",
+ "@jridgewell/trace-mapping": "^0.3.17",
"jest-worker": "^27.4.5",
"schema-utils": "^3.1.1",
- "serialize-javascript": "^6.0.0",
- "terser": "^5.14.1"
+ "serialize-javascript": "^6.0.1",
+ "terser": "^5.16.8"
},
"engines": {
"node": ">= 10.13.0"
@@ -3408,6 +3609,51 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/typedoc": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.2.tgz",
+ "integrity": "sha512-286F7BeATBiWe/qC4PCOCKlSTwfnsLbC/4cZ68oGBbvAqb9vV33quEOXx7q176OXotD+JdEerdQ1OZGJ818lnA==",
+ "dev": true,
+ "dependencies": {
+ "lunr": "^2.3.9",
+ "marked": "^4.3.0",
+ "minimatch": "^9.0.3",
+ "shiki": "^0.14.1"
+ },
+ "bin": {
+ "typedoc": "bin/typedoc"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "peerDependencies": {
+ "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x"
+ }
+ },
+ "node_modules/typedoc/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/typedoc/node_modules/minimatch": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+ "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/typescript": {
"version": "4.8.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
@@ -3457,6 +3703,18 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/vscode-oniguruma": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
+ "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==",
+ "dev": true
+ },
+ "node_modules/vscode-textmate": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz",
+ "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==",
+ "dev": true
+ },
"node_modules/watchpack": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
@@ -3472,23 +3730,23 @@
}
},
"node_modules/webpack": {
- "version": "5.75.0",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz",
- "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==",
+ "version": "5.88.2",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz",
+ "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==",
"dev": true,
"peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.3",
- "@types/estree": "^0.0.51",
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/wasm-edit": "1.11.1",
- "@webassemblyjs/wasm-parser": "1.11.1",
+ "@types/estree": "^1.0.0",
+ "@webassemblyjs/ast": "^1.11.5",
+ "@webassemblyjs/wasm-edit": "^1.11.5",
+ "@webassemblyjs/wasm-parser": "^1.11.5",
"acorn": "^8.7.1",
- "acorn-import-assertions": "^1.7.6",
+ "acorn-import-assertions": "^1.9.0",
"browserslist": "^4.14.5",
"chrome-trace-event": "^1.0.2",
- "enhanced-resolve": "^5.10.0",
- "es-module-lexer": "^0.9.0",
+ "enhanced-resolve": "^5.15.0",
+ "es-module-lexer": "^1.2.1",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
"glob-to-regexp": "^0.4.1",
@@ -3497,9 +3755,9 @@
"loader-runner": "^4.2.0",
"mime-types": "^2.1.27",
"neo-async": "^2.6.2",
- "schema-utils": "^3.1.0",
+ "schema-utils": "^3.2.0",
"tapable": "^2.1.1",
- "terser-webpack-plugin": "^5.1.3",
+ "terser-webpack-plugin": "^5.3.7",
"watchpack": "^2.4.0",
"webpack-sources": "^3.2.3"
},
@@ -3545,9 +3803,9 @@
}
},
"node_modules/word-wrap": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
- "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
@@ -3645,9 +3903,9 @@
},
"dependencies": {
"semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"peer": true
}
@@ -3679,9 +3937,9 @@
},
"dependencies": {
"semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"peer": true
}
@@ -3863,9 +4121,9 @@
}
},
"@babel/parser": {
- "version": "7.20.3",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.3.tgz",
- "integrity": "sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==",
+ "version": "7.22.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz",
+ "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==",
"dev": true,
"peer": true
},
@@ -3911,6 +4169,17 @@
"to-fast-properties": "^2.0.0"
}
},
+ "@es-joy/jsdoccomment": {
+ "version": "0.39.4",
+ "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.39.4.tgz",
+ "integrity": "sha512-Jvw915fjqQct445+yron7Dufix9A+m9j1fCJYlCo1FWlRvTxa3pjJelxdSTdaLWcTwRU6vbL+NYjO4YuNIS5Qg==",
+ "dev": true,
+ "requires": {
+ "comment-parser": "1.3.1",
+ "esquery": "^1.5.0",
+ "jsdoc-type-pratt-parser": "~4.0.0"
+ }
+ },
"@eslint/eslintrc": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz",
@@ -3986,9 +4255,9 @@
"dev": true
},
"@jridgewell/source-map": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
- "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
+ "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
"dev": true,
"requires": {
"@jridgewell/gen-mapping": "^0.3.0",
@@ -4135,14 +4404,6 @@
"@types/estree": "^1.0.0",
"estree-walker": "^2.0.2",
"picomatch": "^2.3.1"
- },
- "dependencies": {
- "@types/estree": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
- "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==",
- "dev": true
- }
}
},
"@types/eslint": {
@@ -4168,9 +4429,9 @@
}
},
"@types/estree": {
- "version": "0.0.51",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz",
- "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
+ "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
"dev": true
},
"@types/json-schema": {
@@ -4180,9 +4441,9 @@
"dev": true
},
"@types/node": {
- "version": "18.11.9",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz",
- "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==",
+ "version": "20.4.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.5.tgz",
+ "integrity": "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==",
"dev": true,
"peer": true
},
@@ -4309,73 +4570,73 @@
}
},
"@webassemblyjs/ast": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
- "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
+ "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
"dev": true,
"peer": true,
"requires": {
- "@webassemblyjs/helper-numbers": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1"
+ "@webassemblyjs/helper-numbers": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6"
}
},
"@webassemblyjs/floating-point-hex-parser": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
- "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
+ "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
"dev": true,
"peer": true
},
"@webassemblyjs/helper-api-error": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
- "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
+ "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
"dev": true,
"peer": true
},
"@webassemblyjs/helper-buffer": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
- "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
+ "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
"dev": true,
"peer": true
},
"@webassemblyjs/helper-numbers": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
- "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
+ "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
"dev": true,
"peer": true,
"requires": {
- "@webassemblyjs/floating-point-hex-parser": "1.11.1",
- "@webassemblyjs/helper-api-error": "1.11.1",
+ "@webassemblyjs/floating-point-hex-parser": "1.11.6",
+ "@webassemblyjs/helper-api-error": "1.11.6",
"@xtuc/long": "4.2.2"
}
},
"@webassemblyjs/helper-wasm-bytecode": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
- "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
+ "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
"dev": true,
"peer": true
},
"@webassemblyjs/helper-wasm-section": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
- "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
+ "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
"dev": true,
"peer": true,
"requires": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-buffer": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
- "@webassemblyjs/wasm-gen": "1.11.1"
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6"
}
},
"@webassemblyjs/ieee754": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
- "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
+ "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
"dev": true,
"peer": true,
"requires": {
@@ -4383,9 +4644,9 @@
}
},
"@webassemblyjs/leb128": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
- "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
+ "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
"dev": true,
"peer": true,
"requires": {
@@ -4393,79 +4654,79 @@
}
},
"@webassemblyjs/utf8": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
- "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
+ "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
"dev": true,
"peer": true
},
"@webassemblyjs/wasm-edit": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
- "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
+ "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
"dev": true,
"peer": true,
"requires": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-buffer": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
- "@webassemblyjs/helper-wasm-section": "1.11.1",
- "@webassemblyjs/wasm-gen": "1.11.1",
- "@webassemblyjs/wasm-opt": "1.11.1",
- "@webassemblyjs/wasm-parser": "1.11.1",
- "@webassemblyjs/wast-printer": "1.11.1"
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/helper-wasm-section": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6",
+ "@webassemblyjs/wasm-opt": "1.11.6",
+ "@webassemblyjs/wasm-parser": "1.11.6",
+ "@webassemblyjs/wast-printer": "1.11.6"
}
},
"@webassemblyjs/wasm-gen": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
- "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
+ "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
"dev": true,
"peer": true,
"requires": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
- "@webassemblyjs/ieee754": "1.11.1",
- "@webassemblyjs/leb128": "1.11.1",
- "@webassemblyjs/utf8": "1.11.1"
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/ieee754": "1.11.6",
+ "@webassemblyjs/leb128": "1.11.6",
+ "@webassemblyjs/utf8": "1.11.6"
}
},
"@webassemblyjs/wasm-opt": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
- "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
+ "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
"dev": true,
"peer": true,
"requires": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-buffer": "1.11.1",
- "@webassemblyjs/wasm-gen": "1.11.1",
- "@webassemblyjs/wasm-parser": "1.11.1"
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-buffer": "1.11.6",
+ "@webassemblyjs/wasm-gen": "1.11.6",
+ "@webassemblyjs/wasm-parser": "1.11.6"
}
},
"@webassemblyjs/wasm-parser": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
- "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
+ "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
"dev": true,
"peer": true,
"requires": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-api-error": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
- "@webassemblyjs/ieee754": "1.11.1",
- "@webassemblyjs/leb128": "1.11.1",
- "@webassemblyjs/utf8": "1.11.1"
+ "@webassemblyjs/ast": "1.11.6",
+ "@webassemblyjs/helper-api-error": "1.11.6",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
+ "@webassemblyjs/ieee754": "1.11.6",
+ "@webassemblyjs/leb128": "1.11.6",
+ "@webassemblyjs/utf8": "1.11.6"
}
},
"@webassemblyjs/wast-printer": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
- "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
+ "version": "1.11.6",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
+ "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
"dev": true,
"peer": true,
"requires": {
- "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/ast": "1.11.6",
"@xtuc/long": "4.2.2"
}
},
@@ -4484,15 +4745,15 @@
"peer": true
},
"acorn": {
- "version": "8.8.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
- "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
+ "version": "8.10.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
+ "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
"dev": true
},
"acorn-import-assertions": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz",
- "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
+ "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
"dev": true,
"peer": true,
"requires": {}
@@ -4559,6 +4820,12 @@
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true
},
+ "ansi-sequence-parser": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz",
+ "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==",
+ "dev": true
+ },
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@@ -4568,6 +4835,12 @@
"color-convert": "^2.0.1"
}
},
+ "are-docs-informative": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz",
+ "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==",
+ "dev": true
+ },
"argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -4637,6 +4910,12 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
+ "base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "dev": true
+ },
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -4669,6 +4948,16 @@
"update-browserslist-db": "^1.0.9"
}
},
+ "buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
"buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@@ -4726,6 +5015,12 @@
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true
},
+ "comment-parser": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz",
+ "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==",
+ "dev": true
+ },
"commondir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
@@ -4803,9 +5098,9 @@
"peer": true
},
"enhanced-resolve": {
- "version": "5.10.0",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz",
- "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==",
+ "version": "5.15.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
+ "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
"dev": true,
"peer": true,
"requires": {
@@ -4814,9 +5109,9 @@
}
},
"es-module-lexer": {
- "version": "0.9.3",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz",
- "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz",
+ "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==",
"dev": true,
"peer": true
},
@@ -4958,6 +5253,31 @@
"dev": true,
"requires": {}
},
+ "eslint-plugin-jsdoc": {
+ "version": "46.4.5",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.4.5.tgz",
+ "integrity": "sha512-HjTuxqDYplAQFu29F3MHFCDDBgeqOxPXI6TyBhL0u2rr4XntJ0z3C9PmJvpjFscKdHwkZDN/0l1QCG0QwyRi4g==",
+ "dev": true,
+ "requires": {
+ "@es-joy/jsdoccomment": "~0.39.4",
+ "are-docs-informative": "^0.0.2",
+ "comment-parser": "1.3.1",
+ "debug": "^4.3.4",
+ "escape-string-regexp": "^4.0.0",
+ "esquery": "^1.5.0",
+ "is-builtin-module": "^3.2.1",
+ "semver": "^7.5.4",
+ "spdx-expression-parse": "^3.0.1"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true
+ }
+ }
+ },
"eslint-plugin-prettier": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz",
@@ -5012,9 +5332,9 @@
}
},
"esquery": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
- "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+ "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
"dev": true,
"requires": {
"estraverse": "^5.1.0"
@@ -5287,6 +5607,12 @@
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
+ "ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "dev": true
+ },
"ignore": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
@@ -5326,9 +5652,9 @@
"dev": true
},
"is-builtin-module": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz",
- "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz",
+ "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==",
"dev": true,
"requires": {
"builtin-modules": "^3.3.0"
@@ -5445,6 +5771,12 @@
"argparse": "^2.0.1"
}
},
+ "jsdoc-type-pratt-parser": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz",
+ "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==",
+ "dev": true
+ },
"jsesc": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
@@ -5478,6 +5810,12 @@
"dev": true,
"peer": true
},
+ "jsonc-parser": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
+ "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
+ "dev": true
+ },
"levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -5519,6 +5857,12 @@
"yallist": "^4.0.0"
}
},
+ "lunr": {
+ "version": "2.3.9",
+ "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
+ "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
+ "dev": true
+ },
"magic-string": {
"version": "0.26.7",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz",
@@ -5538,13 +5882,19 @@
},
"dependencies": {
"semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
}
}
},
+ "marked": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
+ "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
+ "dev": true
+ },
"merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -5852,9 +6202,9 @@
"peer": true
},
"schema-utils": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
- "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+ "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
"peer": true,
"requires": {
@@ -5864,18 +6214,18 @@
}
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
},
"serialize-javascript": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
- "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz",
+ "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==",
"dev": true,
"peer": true,
"requires": {
@@ -5897,6 +6247,18 @@
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
+ "shiki": {
+ "version": "0.14.4",
+ "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.4.tgz",
+ "integrity": "sha512-IXCRip2IQzKwxArNNq1S+On4KPML3Yyn8Zzs/xRgcgOWIr8ntIK3IKzjFPfjy/7kt9ZMjc+FItfqHRBg8b6tNQ==",
+ "dev": true,
+ "requires": {
+ "ansi-sequence-parser": "^1.1.0",
+ "jsonc-parser": "^3.2.0",
+ "vscode-oniguruma": "^1.7.0",
+ "vscode-textmate": "^8.0.0"
+ }
+ },
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -5925,6 +6287,28 @@
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"dev": true
},
+ "spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+ "dev": true
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.13",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz",
+ "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==",
+ "dev": true
+ },
"strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -5963,29 +6347,29 @@
"peer": true
},
"terser": {
- "version": "5.15.1",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz",
- "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==",
+ "version": "5.19.2",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz",
+ "integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==",
"dev": true,
"requires": {
- "@jridgewell/source-map": "^0.3.2",
- "acorn": "^8.5.0",
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.8.2",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
}
},
"terser-webpack-plugin": {
- "version": "5.3.6",
- "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz",
- "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==",
+ "version": "5.3.9",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz",
+ "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==",
"dev": true,
"peer": true,
"requires": {
- "@jridgewell/trace-mapping": "^0.3.14",
+ "@jridgewell/trace-mapping": "^0.3.17",
"jest-worker": "^27.4.5",
"schema-utils": "^3.1.1",
- "serialize-javascript": "^6.0.0",
- "terser": "^5.14.1"
+ "serialize-javascript": "^6.0.1",
+ "terser": "^5.16.8"
}
},
"text-table": {
@@ -6046,6 +6430,38 @@
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
"dev": true
},
+ "typedoc": {
+ "version": "0.25.2",
+ "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.2.tgz",
+ "integrity": "sha512-286F7BeATBiWe/qC4PCOCKlSTwfnsLbC/4cZ68oGBbvAqb9vV33quEOXx7q176OXotD+JdEerdQ1OZGJ818lnA==",
+ "dev": true,
+ "requires": {
+ "lunr": "^2.3.9",
+ "marked": "^4.3.0",
+ "minimatch": "^9.0.3",
+ "shiki": "^0.14.1"
+ },
+ "dependencies": {
+ "brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "minimatch": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+ "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^2.0.1"
+ }
+ }
+ }
+ },
"typescript": {
"version": "4.8.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
@@ -6072,6 +6488,18 @@
"punycode": "^2.1.0"
}
},
+ "vscode-oniguruma": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
+ "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==",
+ "dev": true
+ },
+ "vscode-textmate": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz",
+ "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==",
+ "dev": true
+ },
"watchpack": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
@@ -6084,23 +6512,23 @@
}
},
"webpack": {
- "version": "5.75.0",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz",
- "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==",
+ "version": "5.88.2",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz",
+ "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==",
"dev": true,
"peer": true,
"requires": {
"@types/eslint-scope": "^3.7.3",
- "@types/estree": "^0.0.51",
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/wasm-edit": "1.11.1",
- "@webassemblyjs/wasm-parser": "1.11.1",
+ "@types/estree": "^1.0.0",
+ "@webassemblyjs/ast": "^1.11.5",
+ "@webassemblyjs/wasm-edit": "^1.11.5",
+ "@webassemblyjs/wasm-parser": "^1.11.5",
"acorn": "^8.7.1",
- "acorn-import-assertions": "^1.7.6",
+ "acorn-import-assertions": "^1.9.0",
"browserslist": "^4.14.5",
"chrome-trace-event": "^1.0.2",
- "enhanced-resolve": "^5.10.0",
- "es-module-lexer": "^0.9.0",
+ "enhanced-resolve": "^5.15.0",
+ "es-module-lexer": "^1.2.1",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
"glob-to-regexp": "^0.4.1",
@@ -6109,9 +6537,9 @@
"loader-runner": "^4.2.0",
"mime-types": "^2.1.27",
"neo-async": "^2.6.2",
- "schema-utils": "^3.1.0",
+ "schema-utils": "^3.2.0",
"tapable": "^2.1.1",
- "terser-webpack-plugin": "^5.1.3",
+ "terser-webpack-plugin": "^5.3.7",
"watchpack": "^2.4.0",
"webpack-sources": "^3.2.3"
}
@@ -6133,9 +6561,9 @@
}
},
"word-wrap": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
- "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
"dev": true
},
"wrappy": {
diff --git a/package.json b/package.json
index 5cbd77d..7c6279a 100644
--- a/package.json
+++ b/package.json
@@ -11,8 +11,9 @@
],
"scripts": {
"build": "npm run clean && tsc && rollup --config",
- "clean": "rimraf lib bundle.js",
+ "clean": "rimraf lib bundle.js .parcel-cache",
"format": "prettier --write \"src/**/*.ts\"",
+ "genDocs": "rimraf docs && typedoc",
"lint": "eslint . --ext .ts",
"lintAndFix": "eslint . --ext .ts --fix",
"prepare": "npm run build",
@@ -41,12 +42,15 @@
"@typescript-eslint/eslint-plugin": "^5.43.0",
"@typescript-eslint/parser": "^5.43.0",
"babel-loader": "^9.1.0",
+ "buffer": "^5.7.1",
"eslint": "^8.28.0",
"eslint-config-prettier": "^8.5.0",
+ "eslint-plugin-jsdoc": "^46.4.5",
"eslint-plugin-prettier": "^4.2.1",
"prettier": "^2.7.1",
"rimraf": "^3.0.2",
"rollup": "^3.3.0",
+ "typedoc": "^0.25.2",
"typescript": "^4.8.4"
}
}
diff --git a/src/error.ts b/src/error.ts
index fe5ec18..e5ed8cf 100644
--- a/src/error.ts
+++ b/src/error.ts
@@ -1,5 +1,11 @@
+/**
+ * Represents a Espressif chip error.
+ */
class ESPError extends Error {}
+/**
+ * Represents a Espressif timeout chip error.
+ */
class TimeoutError extends ESPError {}
export { ESPError, TimeoutError };
diff --git a/src/esploader.ts b/src/esploader.ts
index 7ca159c..255d9d1 100644
--- a/src/esploader.ts
+++ b/src/esploader.ts
@@ -4,29 +4,117 @@ import { Transport, SerialOptions } from "./webserial";
import { ROM } from "./targets/rom";
import { customReset, usbJTAGSerialReset } from "./reset";
+/* global SerialPort */
+
+/**
+ * Options for flashing a device with firmware.
+ * @interface FlashOptions
+ */
export interface FlashOptions {
+ /**
+ * An array of file objects representing the data to be flashed.
+ * @type {Array<{ data: string; address: number }>}
+ */
fileArray: { data: string; address: number }[];
+
+ /**
+ * The size of the flash memory to be used.
+ * @type {string}
+ */
flashSize: string;
+
+ /**
+ * The flash mode to be used (e.g., QIO, QOUT, DIO, DOUT).
+ * @type {string}
+ */
flashMode: string;
+
+ /**
+ * The flash frequency to be used (e.g., 40MHz, 80MHz).
+ * @type {string}
+ */
flashFreq: string;
+
+ /**
+ * Flag indicating whether to erase all existing data in the flash memory before flashing.
+ * @type {boolean}
+ */
eraseAll: boolean;
+
+ /**
+ * Flag indicating whether to compress the data before flashing.
+ * @type {boolean}
+ */
compress: boolean;
+
+ /**
+ * A function to report the progress of the flashing operation (optional).
+ * @type {(fileIndex: number, written: number, total: number) => void}
+ */
reportProgress?: (fileIndex: number, written: number, total: number) => void;
+
+ /**
+ * A function to calculate the MD5 hash of the firmware image (optional).
+ * @type {(image: string) => string}
+ */
calculateMD5Hash?: (image: string) => string;
}
+/**
+ * Options to configure ESPLoader.
+ * @interface LoaderOptions
+ */
export interface LoaderOptions {
+ /**
+ * The transport mechanism to communicate with the device.
+ * @type {Transport}
+ */
transport: Transport;
+
+ /**
+ * The port to initialize the transport class.
+ * @type {SerialPort}
+ */
port?: SerialPort;
- baudrate: number;
+
+ /**
+ * Set of options for SerialPort class.
+ * @type {Transport}
+ */
serialOptions?: SerialOptions;
+
+ /**
+ * The baud rate to be used for communication with the device.
+ * @type {number}
+ */
+ baudrate: number;
+
+ /**
+ * An optional terminal interface to interact with the loader during the process.
+ * @type {IEspLoaderTerminal}
+ */
terminal?: IEspLoaderTerminal;
+
+ /**
+ * The baud rate to be used during the initial ROM communication with the device.
+ * @type {number}
+ */
romBaudrate: number;
+
+ /**
+ * Flag indicating whether to enable debug logging for the loader (optional).
+ * @type {boolean}
+ */
debugLogging?: boolean;
}
type FlashReadCallback = ((packet: Uint8Array, progress: number, totalSize: number) => void) | null;
+/**
+ * Return the chip ROM based on the given magic number
+ * @param {number} magic - magic hex number to select ROM.
+ * @returns {ROM} The chip ROM class related to given magic hex number.
+ */
async function magic2Chip(magic: number): Promise {
switch (magic) {
case 0x00f01d83: {
@@ -63,9 +151,26 @@ async function magic2Chip(magic: number): Promise {
}
}
+/**
+ * A wrapper around your implementation of a terminal by
+ * implementing the clean, write and writeLine methods
+ * which are called by the ESPLoader class.
+ * @interface IEspLoaderTerminal
+ */
export interface IEspLoaderTerminal {
+ /**
+ * Execute a terminal clean command.
+ */
clean: () => void;
+ /**
+ * Write a string of data that include a line terminator.
+ * @param {string} data - The string to write with line terminator.
+ */
writeLine: (data: string) => void;
+ /**
+ * Write a string of data.
+ * @param {string} data - The string to write.
+ */
write: (data: string) => void;
}
@@ -141,6 +246,14 @@ export class ESPLoader {
private romBaudrate = 115200;
private debugLogging = false;
+ /**
+ * Create a new ESPLoader to perform serial communication
+ * such as read/write flash memory and registers using a LoaderOptions object.
+ * @param {LoaderOptions} options - LoaderOptions object argument for ESPLoader.
+ * ```
+ * const myLoader = new ESPLoader({ transport: Transport, baudrate: number, terminal?: IEspLoaderTerminal });
+ * ```
+ */
constructor(options: LoaderOptions) {
this.IS_STUB = false;
this.FLASH_WRITE_SIZE = 0x4000;
@@ -165,13 +278,18 @@ export class ESPLoader {
}
this.info("esptool.js");
- this.info("Serial port " + this.transport.get_info());
+ this.info("Serial port " + this.transport.getInfo());
}
_sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
+ /**
+ * Write to ESP Loader constructor's terminal with or without new line.
+ * @param {string} str - String to write.
+ * @param {boolean} withNewline - Add new line at the end ?
+ */
write(str: string, withNewline = true) {
if (this.terminal) {
if (withNewline) {
@@ -185,36 +303,81 @@ export class ESPLoader {
}
}
+ /**
+ * Write error message to ESP Loader constructor's terminal with or without new line.
+ * @param {string} str - String to write.
+ * @param {boolean} withNewline - Add new line at the end ?
+ */
error(str: string, withNewline = true) {
this.write(`Error: ${str}`, withNewline);
}
+ /**
+ * Write information message to ESP Loader constructor's terminal with or without new line.
+ * @param {string} str - String to write.
+ * @param {boolean} withNewline - Add new line at the end ?
+ */
info(str: string, withNewline = true) {
this.write(str, withNewline);
}
+ /**
+ * Write debug message to ESP Loader constructor's terminal with or without new line.
+ * @param {string} str - String to write.
+ * @param {boolean} withNewline - Add new line at the end ?
+ */
debug(str: string, withNewline = true) {
if (this.debugLogging) {
this.write(`Debug: ${str}`, withNewline);
}
}
- _short_to_bytearray(i: number) {
+ /**
+ * Convert short integer to byte array
+ * @param {number} i - Number to convert.
+ * @returns {Uint8Array} Byte array.
+ */
+ _shortToBytearray(i: number) {
return new Uint8Array([i & 0xff, (i >> 8) & 0xff]);
}
- _int_to_bytearray(i: number): Uint8Array {
+ /**
+ * Convert an integer to byte array
+ * @param {number} i - Number to convert.
+ * @returns {ROM} The chip ROM class related to given magic hex number.
+ */
+ _intToByteArray(i: number): Uint8Array {
return new Uint8Array([i & 0xff, (i >> 8) & 0xff, (i >> 16) & 0xff, (i >> 24) & 0xff]);
}
- _bytearray_to_short(i: number, j: number) {
+ /**
+ * Convert a byte array to short integer.
+ * @param {number} i - Number to convert.
+ * @param {number} j - Number to convert.
+ * @returns {number} Return a short integer number.
+ */
+ _byteArrayToShort(i: number, j: number) {
return i | (j >> 8);
}
- _bytearray_to_int(i: number, j: number, k: number, l: number) {
+ /**
+ * Convert a byte array to integer.
+ * @param {number} i - Number to convert.
+ * @param {number} j - Number to convert.
+ * @param {number} k - Number to convert.
+ * @param {number} l - Number to convert.
+ * @returns {number} Return a integer number.
+ */
+ _byteArrayToInt(i: number, j: number, k: number, l: number) {
return i | (j << 8) | (k << 16) | (l << 24);
}
+ /**
+ * Append a buffer array after another buffer array
+ * @param {ArrayBuffer} buffer1 - First array buffer.
+ * @param {ArrayBuffer} buffer2 - magic hex number to select ROM.
+ * @returns {ArrayBufferLike} Return an array buffer.
+ */
_appendBuffer(buffer1: ArrayBuffer, buffer2: ArrayBuffer) {
const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
tmp.set(new Uint8Array(buffer1), 0);
@@ -222,6 +385,12 @@ export class ESPLoader {
return tmp.buffer;
}
+ /**
+ * Append a buffer array after another buffer array
+ * @param {Uint8Array} arr1 - First array buffer.
+ * @param {Uint8Array} arr2 - magic hex number to select ROM.
+ * @returns {Uint8Array} Return a 8 bit unsigned array.
+ */
_appendArray(arr1: Uint8Array, arr2: Uint8Array) {
const c = new Uint8Array(arr1.length + arr2.length);
c.set(arr1, 0);
@@ -229,23 +398,36 @@ export class ESPLoader {
return c;
}
+ /**
+ * Convert a unsigned 8 bit integer array to byte string.
+ * @param {Uint8Array} u8Array - magic hex number to select ROM.
+ * @returns {string} Return the equivalent string.
+ */
ui8ToBstr(u8Array: Uint8Array) {
- let b_str = "";
+ let bStr = "";
for (let i = 0; i < u8Array.length; i++) {
- b_str += String.fromCharCode(u8Array[i]);
+ bStr += String.fromCharCode(u8Array[i]);
}
- return b_str;
+ return bStr;
}
+ /**
+ * Convert a byte string to unsigned 8 bit integer array.
+ * @param {string} bStr - binary string input
+ * @returns {Uint8Array} Return a 8 bit unsigned integer array.
+ */
bstrToUi8(bStr: string) {
- const u8_array = new Uint8Array(bStr.length);
+ const u8Array = new Uint8Array(bStr.length);
for (let i = 0; i < bStr.length; i++) {
- u8_array[i] = bStr.charCodeAt(i);
+ u8Array[i] = bStr.charCodeAt(i);
}
- return u8_array;
+ return u8Array;
}
- async flush_input() {
+ /**
+ * Flush the serial input by raw read with 200 ms timeout.
+ */
+ async flushInput() {
try {
await this.transport.rawRead(200);
} catch (e) {
@@ -253,19 +435,25 @@ export class ESPLoader {
}
}
- async read_packet(op: number | null = null, timeout = 3000): Promise<[number, Uint8Array]> {
+ /**
+ * Use the device serial port read function with given timeout to create a valid packet.
+ * @param {number} op Operation number
+ * @param {number} timeout timeout number in milliseconds
+ * @returns {[number, Uint8Array]} valid response packet.
+ */
+ async readPacket(op: number | null = null, timeout = 3000): Promise<[number, Uint8Array]> {
// Check up-to next 100 packets for valid response packet
for (let i = 0; i < 100; i++) {
const p = await this.transport.read(timeout);
const resp = p[0];
- const op_ret = p[1];
- const val = this._bytearray_to_int(p[4], p[5], p[6], p[7]);
+ const opRet = p[1];
+ const val = this._byteArrayToInt(p[4], p[5], p[6], p[7]);
const data = p.slice(8);
if (resp == 1) {
- if (op == null || op_ret == op) {
+ if (op == null || opRet == op) {
return [val, data];
} else if (data[0] != 0 && data[1] == this.ROM_INVALID_RECV_MSG) {
- await this.flush_input();
+ await this.flushInput();
throw new ESPError("unsupported command error");
}
}
@@ -273,6 +461,15 @@ export class ESPLoader {
throw new ESPError("invalid response");
}
+ /**
+ * Write a serial command to the chip
+ * @param {number} op - Operation number
+ * @param {Uint8Array} data - Unsigned 8 bit array
+ * @param {number} chk - channel number
+ * @param {boolean} waitResponse - wait for response ?
+ * @param {number} timeout - timeout number in milliseconds
+ * @returns {Promise<[number, Uint8Array]>} Return a number and a 8 bit unsigned integer array.
+ */
async command(
op: number | null = null,
data: Uint8Array = new Uint8Array(0),
@@ -284,12 +481,12 @@ export class ESPLoader {
const pkt = new Uint8Array(8 + data.length);
pkt[0] = 0x00;
pkt[1] = op;
- pkt[2] = this._short_to_bytearray(data.length)[0];
- pkt[3] = this._short_to_bytearray(data.length)[1];
- pkt[4] = this._int_to_bytearray(chk)[0];
- pkt[5] = this._int_to_bytearray(chk)[1];
- pkt[6] = this._int_to_bytearray(chk)[2];
- pkt[7] = this._int_to_bytearray(chk)[3];
+ pkt[2] = this._shortToBytearray(data.length)[0];
+ pkt[3] = this._shortToBytearray(data.length)[1];
+ pkt[4] = this._intToByteArray(chk)[0];
+ pkt[5] = this._intToByteArray(chk)[1];
+ pkt[6] = this._intToByteArray(chk)[2];
+ pkt[7] = this._intToByteArray(chk)[3];
let i;
for (i = 0; i < data.length; i++) {
@@ -302,30 +499,48 @@ export class ESPLoader {
return [0, new Uint8Array(0)];
}
- return this.read_packet(op, timeout);
+ return this.readPacket(op, timeout);
}
- async read_reg(addr: number, timeout = 3000) {
- const pkt = this._int_to_bytearray(addr);
+ /**
+ * Read a register from chip.
+ * @param {number} addr - Register address number
+ * @param {number} timeout - Timeout in milliseconds (Default: 3000ms)
+ * @returns {number} - Command number value
+ */
+ async readReg(addr: number, timeout = 3000) {
+ const pkt = this._intToByteArray(addr);
const val = await this.command(this.ESP_READ_REG, pkt, undefined, undefined, timeout);
return val[0];
}
- async write_reg(addr: number, value: number, mask = 0xffffffff, delay_us = 0, delay_after_us = 0) {
- let pkt = this._appendArray(this._int_to_bytearray(addr), this._int_to_bytearray(value));
- pkt = this._appendArray(pkt, this._int_to_bytearray(mask));
- pkt = this._appendArray(pkt, this._int_to_bytearray(delay_us));
-
- if (delay_after_us > 0) {
- pkt = this._appendArray(pkt, this._int_to_bytearray(this.chip.UART_DATE_REG_ADDR));
- pkt = this._appendArray(pkt, this._int_to_bytearray(0));
- pkt = this._appendArray(pkt, this._int_to_bytearray(0));
- pkt = this._appendArray(pkt, this._int_to_bytearray(delay_after_us));
- }
-
- await this.check_command("write target memory", this.ESP_WRITE_REG, pkt);
+ /**
+ * Write a number value to register address in chip.
+ * @param {number} addr - Register address number
+ * @param {number} value - Number value to write in register
+ * @param {number} mask - Hex number for mask
+ * @param {number} delayUs Delay number
+ * @param {number} delayAfterUs Delay after previous delay
+ */
+ async writeReg(addr: number, value: number, mask = 0xffffffff, delayUs = 0, delayAfterUs = 0) {
+ let pkt = this._appendArray(this._intToByteArray(addr), this._intToByteArray(value));
+ pkt = this._appendArray(pkt, this._intToByteArray(mask));
+ pkt = this._appendArray(pkt, this._intToByteArray(delayUs));
+
+ if (delayAfterUs > 0) {
+ pkt = this._appendArray(pkt, this._intToByteArray(this.chip.UART_DATE_REG_ADDR));
+ pkt = this._appendArray(pkt, this._intToByteArray(0));
+ pkt = this._appendArray(pkt, this._intToByteArray(0));
+ pkt = this._appendArray(pkt, this._intToByteArray(delayAfterUs));
+ }
+
+ await this.checkCommand("write target memory", this.ESP_WRITE_REG, pkt);
}
+ /**
+ * Sync chip by sending sync command.
+ * @returns {[number, Uint8Array]} Command result
+ */
async sync() {
this.debug("Sync");
const cmd = new Uint8Array(36);
@@ -347,15 +562,21 @@ export class ESPLoader {
}
}
- async _connect_attempt(mode = "default_reset", esp32r0_delay = false) {
- this.debug("_connect_attempt " + mode + " " + esp32r0_delay);
+ /**
+ * Attempt to connect to the chip by sending a reset sequence and later a sync command.
+ * @param {string} mode - Reset mode to use
+ * @param {boolean} esp32r0Delay - Enable delay for ESP32 R0
+ * @returns {string} - Returns 'success' or 'error' message.
+ */
+ async _connectAttempt(mode = "default_reset", esp32r0Delay = false) {
+ this.debug("_connect_attempt " + mode + " " + esp32r0Delay);
if (mode !== "no_reset") {
- if (this.transport.get_pid() === this.USB_JTAG_SERIAL_PID) {
+ if (this.transport.getPid() === this.USB_JTAG_SERIAL_PID) {
// Custom reset sequence, which is required when the device
// is connecting via its USB-JTAG-Serial peripheral
await usbJTAGSerialReset(this.transport);
} else {
- const strSequence = esp32r0_delay ? "D0|R1|W100|W2000|D1|R0|W50|D0" : "D0|R1|W100|D1|R0|W50|D0";
+ const strSequence = esp32r0Delay ? "D0|R1|W100|W2000|D1|R0|W50|D0" : "D0|R1|W100|D1|R0|W50|D0";
await customReset(this.transport, strSequence);
}
}
@@ -374,7 +595,7 @@ export class ESPLoader {
}
await this._sleep(50);
}
- this.transport.slip_reader_enabled = true;
+ this.transport.slipReaderEnabled = true;
i = 7;
while (i--) {
try {
@@ -383,7 +604,7 @@ export class ESPLoader {
return "success";
} catch (error) {
if (error instanceof Error) {
- if (esp32r0_delay) {
+ if (esp32r0Delay) {
this.info("_", false);
} else {
this.info(".", false);
@@ -395,17 +616,23 @@ export class ESPLoader {
return "error";
}
+ /**
+ * Perform a connection to chip.
+ * @param {string} mode - Reset mode to use. Example: 'default_reset' | 'no_reset'
+ * @param {number} attempts - Number of connection attempts
+ * @param {boolean} detecting - Detect the connected chip
+ */
async connect(mode = "default_reset", attempts = 7, detecting = false) {
let i;
let resp;
this.info("Connecting...", false);
await this.transport.connect(this.romBaudrate, this.serialOptions);
for (i = 0; i < attempts; i++) {
- resp = await this._connect_attempt(mode, false);
+ resp = await this._connectAttempt(mode, false);
if (resp === "success") {
break;
}
- resp = await this._connect_attempt(mode, true);
+ resp = await this._connectAttempt(mode, true);
if (resp === "success") {
break;
}
@@ -416,18 +643,22 @@ export class ESPLoader {
this.info("\n\r", false);
if (!detecting) {
- const chip_magic_value = (await this.read_reg(0x40001000)) >>> 0;
- this.debug("Chip Magic " + chip_magic_value.toString(16));
- const chip = await magic2Chip(chip_magic_value);
+ const chipMagicValue = (await this.readReg(0x40001000)) >>> 0;
+ this.debug("Chip Magic " + chipMagicValue.toString(16));
+ const chip = await magic2Chip(chipMagicValue);
if (this.chip === null) {
- throw new ESPError(`Unexpected CHIP magic value ${chip_magic_value}. Failed to autodetect chip type.`);
+ throw new ESPError(`Unexpected CHIP magic value ${chipMagicValue}. Failed to autodetect chip type.`);
} else {
this.chip = chip as ROM;
}
}
}
- async detect_chip(mode = "default_reset") {
+ /**
+ * Connect and detect the existing chip.
+ * @param {string} mode Reset mode to use for connection.
+ */
+ async detectChip(mode = "default_reset") {
await this.connect(mode);
this.info("Detecting chip type... ", false);
if (this.chip != null) {
@@ -437,14 +668,23 @@ export class ESPLoader {
}
}
- async check_command(
- op_description = "",
+ /**
+ * Execute the command and check the command response.
+ * @param {string} opDescription Command operation description.
+ * @param {number} op Command operation number
+ * @param {Uint8Array} data Command value
+ * @param {number} chk Checksum to use
+ * @param {number} timeout TImeout number in milliseconds (ms)
+ * @returns {number} Command result
+ */
+ async checkCommand(
+ opDescription = "",
op: number | null = null,
data: Uint8Array = new Uint8Array(0),
chk = 0,
timeout = 3000,
) {
- this.debug("check_command " + op_description);
+ this.debug("check_command " + opDescription);
const resp = await this.command(op, data, chk, undefined, timeout);
if (resp[1].length > 4) {
return resp[1];
@@ -453,15 +693,27 @@ export class ESPLoader {
}
}
- async mem_begin(size: number, blocks: number, blocksize: number, offset: number) {
+ /**
+ * Start downloading an application image to RAM
+ * @param {number} size Image size number
+ * @param {number} blocks Number of data blocks
+ * @param {number} blocksize Size of each data block
+ * @param {number} offset Image offset number
+ */
+ async memBegin(size: number, blocks: number, blocksize: number, offset: number) {
/* XXX: Add check to ensure that STUB is not getting overwritten */
this.debug("mem_begin " + size + " " + blocks + " " + blocksize + " " + offset.toString(16));
- let pkt = this._appendArray(this._int_to_bytearray(size), this._int_to_bytearray(blocks));
- pkt = this._appendArray(pkt, this._int_to_bytearray(blocksize));
- pkt = this._appendArray(pkt, this._int_to_bytearray(offset));
- await this.check_command("enter RAM download mode", this.ESP_MEM_BEGIN, pkt);
+ let pkt = this._appendArray(this._intToByteArray(size), this._intToByteArray(blocks));
+ pkt = this._appendArray(pkt, this._intToByteArray(blocksize));
+ pkt = this._appendArray(pkt, this._intToByteArray(offset));
+ await this.checkCommand("enter RAM download mode", this.ESP_MEM_BEGIN, pkt);
}
+ /**
+ * Get the checksum for given unsigned 8-bit array
+ * @param {Uint8Array} data Unsigned 8-bit integer array
+ * @returns {number} - Array checksum
+ */
checksum = function (data: Uint8Array) {
let i;
let chk = 0xef;
@@ -472,28 +724,47 @@ export class ESPLoader {
return chk;
};
- async mem_block(buffer: Uint8Array, seq: number) {
- let pkt = this._appendArray(this._int_to_bytearray(buffer.length), this._int_to_bytearray(seq));
- pkt = this._appendArray(pkt, this._int_to_bytearray(0));
- pkt = this._appendArray(pkt, this._int_to_bytearray(0));
+ /**
+ * Send a block of image to RAM
+ * @param {Uint8Array} buffer Unsigned 8-bit array
+ * @param {number} seq Sequence number
+ */
+ async memBlock(buffer: Uint8Array, seq: number) {
+ let pkt = this._appendArray(this._intToByteArray(buffer.length), this._intToByteArray(seq));
+ pkt = this._appendArray(pkt, this._intToByteArray(0));
+ pkt = this._appendArray(pkt, this._intToByteArray(0));
pkt = this._appendArray(pkt, buffer);
const checksum = this.checksum(buffer);
- await this.check_command("write to target RAM", this.ESP_MEM_DATA, pkt, checksum);
+ await this.checkCommand("write to target RAM", this.ESP_MEM_DATA, pkt, checksum);
}
- async mem_finish(entrypoint: number) {
- const is_entry = entrypoint === 0 ? 1 : 0;
- const pkt = this._appendArray(this._int_to_bytearray(is_entry), this._int_to_bytearray(entrypoint));
- await this.check_command("leave RAM download mode", this.ESP_MEM_END, pkt, undefined, 50); // XXX: handle non-stub with diff timeout
+ /**
+ * Leave RAM download mode and run application
+ * @param {number} entrypoint - Entrypoint number
+ */
+ async memFinish(entrypoint: number) {
+ const isEntry = entrypoint === 0 ? 1 : 0;
+ const pkt = this._appendArray(this._intToByteArray(isEntry), this._intToByteArray(entrypoint));
+ await this.checkCommand("leave RAM download mode", this.ESP_MEM_END, pkt, undefined, 50); // XXX: handle non-stub with diff timeout
}
- async flash_spi_attach(hspi_arg: number) {
- const pkt = this._int_to_bytearray(hspi_arg);
- await this.check_command("configure SPI flash pins", this.ESP_SPI_ATTACH, pkt);
+ /**
+ * Configure SPI flash pins
+ * @param {number} hspiArg - Argument for SPI attachment
+ */
+ async flashSpiAttach(hspiArg: number) {
+ const pkt = this._intToByteArray(hspiArg);
+ await this.checkCommand("configure SPI flash pins", this.ESP_SPI_ATTACH, pkt);
}
- timeout_per_mb = function (seconds_per_mb: number, size_bytes: number) {
- const result = seconds_per_mb * (size_bytes / 1000000);
+ /**
+ * Scale timeouts which are size-specific.
+ * @param {number} secondsPerMb Seconds per megabytes as number
+ * @param {number} sizeBytes Size bytes number
+ * @returns {number} - Scaled timeout for specified size.
+ */
+ timeoutPerMb = function (secondsPerMb: number, sizeBytes: number) {
+ const result = secondsPerMb * (sizeBytes / 1000000);
if (result < 3000) {
return 3000;
} else {
@@ -501,57 +772,68 @@ export class ESPLoader {
}
};
- async flash_begin(size: number, offset: number) {
- const num_blocks = Math.floor((size + this.FLASH_WRITE_SIZE - 1) / this.FLASH_WRITE_SIZE);
- const erase_size = this.chip.get_erase_size(offset, size);
+ /**
+ * Start downloading to Flash (performs an erase)
+ * @param {number} size Size to erase
+ * @param {number} offset Offset to erase
+ * @returns {number} Number of blocks (of size self.FLASH_WRITE_SIZE) to write.
+ */
+ async flashBegin(size: number, offset: number) {
+ const numBlocks = Math.floor((size + this.FLASH_WRITE_SIZE - 1) / this.FLASH_WRITE_SIZE);
+ const eraseSize = this.chip.getEraseSize(offset, size);
const d = new Date();
const t1 = d.getTime();
let timeout = 3000;
if (this.IS_STUB == false) {
- timeout = this.timeout_per_mb(this.ERASE_REGION_TIMEOUT_PER_MB, size);
+ timeout = this.timeoutPerMb(this.ERASE_REGION_TIMEOUT_PER_MB, size);
}
- this.debug(
- "flash begin " + erase_size + " " + num_blocks + " " + this.FLASH_WRITE_SIZE + " " + offset + " " + size,
- );
- let pkt = this._appendArray(this._int_to_bytearray(erase_size), this._int_to_bytearray(num_blocks));
- pkt = this._appendArray(pkt, this._int_to_bytearray(this.FLASH_WRITE_SIZE));
- pkt = this._appendArray(pkt, this._int_to_bytearray(offset));
+ this.debug("flash begin " + eraseSize + " " + numBlocks + " " + this.FLASH_WRITE_SIZE + " " + offset + " " + size);
+ let pkt = this._appendArray(this._intToByteArray(eraseSize), this._intToByteArray(numBlocks));
+ pkt = this._appendArray(pkt, this._intToByteArray(this.FLASH_WRITE_SIZE));
+ pkt = this._appendArray(pkt, this._intToByteArray(offset));
if (this.IS_STUB == false) {
- pkt = this._appendArray(pkt, this._int_to_bytearray(0)); // XXX: Support encrypted
+ pkt = this._appendArray(pkt, this._intToByteArray(0)); // XXX: Support encrypted
}
- await this.check_command("enter Flash download mode", this.ESP_FLASH_BEGIN, pkt, undefined, timeout);
+ await this.checkCommand("enter Flash download mode", this.ESP_FLASH_BEGIN, pkt, undefined, timeout);
const t2 = d.getTime();
if (size != 0 && this.IS_STUB == false) {
this.info("Took " + (t2 - t1) / 1000 + "." + ((t2 - t1) % 1000) + "s to erase flash block");
}
- return num_blocks;
+ return numBlocks;
}
- async flash_defl_begin(size: number, compsize: number, offset: number) {
- const num_blocks = Math.floor((compsize + this.FLASH_WRITE_SIZE - 1) / this.FLASH_WRITE_SIZE);
- const erase_blocks = Math.floor((size + this.FLASH_WRITE_SIZE - 1) / this.FLASH_WRITE_SIZE);
+ /**
+ * Start downloading compressed data to Flash (performs an erase)
+ * @param {number} size Write size
+ * @param {number} compsize Compressed size
+ * @param {number} offset Offset for write
+ * @returns {number} Returns number of blocks (size self.FLASH_WRITE_SIZE) to write.
+ */
+ async flashDeflBegin(size: number, compsize: number, offset: number) {
+ const numBlocks = Math.floor((compsize + this.FLASH_WRITE_SIZE - 1) / this.FLASH_WRITE_SIZE);
+ const eraseBlocks = Math.floor((size + this.FLASH_WRITE_SIZE - 1) / this.FLASH_WRITE_SIZE);
const d = new Date();
const t1 = d.getTime();
- let write_size, timeout;
+ let writeSize, timeout;
if (this.IS_STUB) {
- write_size = size;
+ writeSize = size;
timeout = 3000;
} else {
- write_size = erase_blocks * this.FLASH_WRITE_SIZE;
- timeout = this.timeout_per_mb(this.ERASE_REGION_TIMEOUT_PER_MB, write_size);
+ writeSize = eraseBlocks * this.FLASH_WRITE_SIZE;
+ timeout = this.timeoutPerMb(this.ERASE_REGION_TIMEOUT_PER_MB, writeSize);
}
this.info("Compressed " + size + " bytes to " + compsize + "...");
- let pkt = this._appendArray(this._int_to_bytearray(write_size), this._int_to_bytearray(num_blocks));
- pkt = this._appendArray(pkt, this._int_to_bytearray(this.FLASH_WRITE_SIZE));
- pkt = this._appendArray(pkt, this._int_to_bytearray(offset));
+ let pkt = this._appendArray(this._intToByteArray(writeSize), this._intToByteArray(numBlocks));
+ pkt = this._appendArray(pkt, this._intToByteArray(this.FLASH_WRITE_SIZE));
+ pkt = this._appendArray(pkt, this._intToByteArray(offset));
if (
(this.chip.CHIP_NAME === "ESP32-S2" ||
@@ -559,37 +841,49 @@ export class ESPLoader {
this.chip.CHIP_NAME === "ESP32-C3") &&
this.IS_STUB === false
) {
- pkt = this._appendArray(pkt, this._int_to_bytearray(0));
+ pkt = this._appendArray(pkt, this._intToByteArray(0));
}
- await this.check_command("enter compressed flash mode", this.ESP_FLASH_DEFL_BEGIN, pkt, undefined, timeout);
+ await this.checkCommand("enter compressed flash mode", this.ESP_FLASH_DEFL_BEGIN, pkt, undefined, timeout);
const t2 = d.getTime();
if (size != 0 && this.IS_STUB === false) {
this.info("Took " + (t2 - t1) / 1000 + "." + ((t2 - t1) % 1000) + "s to erase flash block");
}
- return num_blocks;
+ return numBlocks;
}
- async flash_block(data: Uint8Array, seq: number, timeout: number) {
- let pkt = this._appendArray(this._int_to_bytearray(data.length), this._int_to_bytearray(seq));
- pkt = this._appendArray(pkt, this._int_to_bytearray(0));
- pkt = this._appendArray(pkt, this._int_to_bytearray(0));
+ /**
+ * Write block to flash, retry if fail
+ * @param {Uint8Array} data Unsigned 8-bit array data.
+ * @param {number} seq Sequence number
+ * @param {number} timeout Timeout in milliseconds (ms)
+ */
+ async flashBlock(data: Uint8Array, seq: number, timeout: number) {
+ let pkt = this._appendArray(this._intToByteArray(data.length), this._intToByteArray(seq));
+ pkt = this._appendArray(pkt, this._intToByteArray(0));
+ pkt = this._appendArray(pkt, this._intToByteArray(0));
pkt = this._appendArray(pkt, data);
const checksum = this.checksum(data);
- await this.check_command("write to target Flash after seq " + seq, this.ESP_FLASH_DATA, pkt, checksum, timeout);
+ await this.checkCommand("write to target Flash after seq " + seq, this.ESP_FLASH_DATA, pkt, checksum, timeout);
}
- async flash_defl_block(data: Uint8Array, seq: number, timeout: number) {
- let pkt = this._appendArray(this._int_to_bytearray(data.length), this._int_to_bytearray(seq));
- pkt = this._appendArray(pkt, this._int_to_bytearray(0));
- pkt = this._appendArray(pkt, this._int_to_bytearray(0));
+ /**
+ * Write block to flash, send compressed, retry if fail
+ * @param {Uint8Array} data Unsigned int 8-bit array data to write
+ * @param {number} seq Sequence number
+ * @param {number} timeout Timeout in milliseconds (ms)
+ */
+ async flashDeflBlock(data: Uint8Array, seq: number, timeout: number) {
+ let pkt = this._appendArray(this._intToByteArray(data.length), this._intToByteArray(seq));
+ pkt = this._appendArray(pkt, this._intToByteArray(0));
+ pkt = this._appendArray(pkt, this._intToByteArray(0));
pkt = this._appendArray(pkt, data);
const checksum = this.checksum(data);
this.debug("flash_defl_block " + data[0].toString(16) + " " + data[1].toString(16));
- await this.check_command(
+ await this.checkCommand(
"write compressed data to flash after seq " + seq,
this.ESP_FLASH_DEFL_DATA,
pkt,
@@ -598,21 +892,44 @@ export class ESPLoader {
);
}
- async flash_finish(reboot = false) {
+ /**
+ * Leave flash mode and run/reboot
+ * @param {boolean} reboot Reboot after leaving flash mode ?
+ */
+ async flashFinish(reboot = false) {
const val = reboot ? 0 : 1;
- const pkt = this._int_to_bytearray(val);
+ const pkt = this._intToByteArray(val);
- await this.check_command("leave Flash mode", this.ESP_FLASH_END, pkt);
+ await this.checkCommand("leave Flash mode", this.ESP_FLASH_END, pkt);
}
- async flash_defl_finish(reboot = false) {
+ /**
+ * Leave compressed flash mode and run/reboot
+ * @param {boolean} reboot Reboot after leaving flash mode ?
+ */
+ async flashDeflFinish(reboot = false) {
const val = reboot ? 0 : 1;
- const pkt = this._int_to_bytearray(val);
+ const pkt = this._intToByteArray(val);
- await this.check_command("leave compressed flash mode", this.ESP_FLASH_DEFL_END, pkt);
+ await this.checkCommand("leave compressed flash mode", this.ESP_FLASH_DEFL_END, pkt);
}
- async run_spiflash_command(spiflash_command: number, data: Uint8Array, read_bits: number) {
+ /**
+ * Run an arbitrary SPI flash command.
+ *
+ * This function uses the "USR_COMMAND" functionality in the ESP
+ * SPI hardware, rather than the precanned commands supported by
+ * hardware. So the value of spiflashCommand is an actual command
+ * byte, sent over the wire.
+ *
+ * After writing command byte, writes 'data' to MOSI and then
+ * reads back 'readBits' of reply on MISO. Result is a number.
+ * @param {number} spiflashCommand Command to execute in SPI
+ * @param {Uint8Array} data Data to send
+ * @param {number} readBits Number of bits to read
+ * @returns {number} Register SPI_W0_REG value
+ */
+ async runSpiflashCommand(spiflashCommand: number, data: Uint8Array, readBits: number) {
// SPI_USR register flags
const SPI_USR_COMMAND = 1 << 31;
const SPI_USR_MISO = 1 << 28;
@@ -626,71 +943,71 @@ export class ESPLoader {
const SPI_USR2_REG = base + this.chip.SPI_USR2_OFFS;
const SPI_W0_REG = base + this.chip.SPI_W0_OFFS;
- let set_data_lengths;
+ let setDataLengths;
if (this.chip.SPI_MOSI_DLEN_OFFS != null) {
- set_data_lengths = async (mosi_bits: number, miso_bits: number) => {
+ setDataLengths = async (mosiBits: number, misoBits: number) => {
const SPI_MOSI_DLEN_REG = base + this.chip.SPI_MOSI_DLEN_OFFS;
const SPI_MISO_DLEN_REG = base + this.chip.SPI_MISO_DLEN_OFFS;
- if (mosi_bits > 0) {
- await this.write_reg(SPI_MOSI_DLEN_REG, mosi_bits - 1);
+ if (mosiBits > 0) {
+ await this.writeReg(SPI_MOSI_DLEN_REG, mosiBits - 1);
}
- if (miso_bits > 0) {
- await this.write_reg(SPI_MISO_DLEN_REG, miso_bits - 1);
+ if (misoBits > 0) {
+ await this.writeReg(SPI_MISO_DLEN_REG, misoBits - 1);
}
};
} else {
- set_data_lengths = async (mosi_bits: number, miso_bits: number) => {
+ setDataLengths = async (mosiBits: number, misoBits: number) => {
const SPI_DATA_LEN_REG = SPI_USR1_REG;
const SPI_MOSI_BITLEN_S = 17;
const SPI_MISO_BITLEN_S = 8;
- const mosi_mask = mosi_bits === 0 ? 0 : mosi_bits - 1;
- const miso_mask = miso_bits === 0 ? 0 : miso_bits - 1;
- const val = (miso_mask << SPI_MISO_BITLEN_S) | (mosi_mask << SPI_MOSI_BITLEN_S);
- await this.write_reg(SPI_DATA_LEN_REG, val);
+ const mosiMask = mosiBits === 0 ? 0 : mosiBits - 1;
+ const misoMask = misoBits === 0 ? 0 : misoBits - 1;
+ const val = (misoMask << SPI_MISO_BITLEN_S) | (mosiMask << SPI_MOSI_BITLEN_S);
+ await this.writeReg(SPI_DATA_LEN_REG, val);
};
}
const SPI_CMD_USR = 1 << 18;
const SPI_USR2_COMMAND_LEN_SHIFT = 28;
- if (read_bits > 32) {
+ if (readBits > 32) {
throw new ESPError("Reading more than 32 bits back from a SPI flash operation is unsupported");
}
if (data.length > 64) {
throw new ESPError("Writing more than 64 bytes of data with one SPI command is unsupported");
}
- const data_bits = data.length * 8;
- const old_spi_usr = await this.read_reg(SPI_USR_REG);
- const old_spi_usr2 = await this.read_reg(SPI_USR2_REG);
+ const dataBits = data.length * 8;
+ const oldSpiUsr = await this.readReg(SPI_USR_REG);
+ const oldSpiUsr2 = await this.readReg(SPI_USR2_REG);
let flags = SPI_USR_COMMAND;
let i;
- if (read_bits > 0) {
+ if (readBits > 0) {
flags |= SPI_USR_MISO;
}
- if (data_bits > 0) {
+ if (dataBits > 0) {
flags |= SPI_USR_MOSI;
}
- await set_data_lengths(data_bits, read_bits);
- await this.write_reg(SPI_USR_REG, flags);
- let val = (7 << SPI_USR2_COMMAND_LEN_SHIFT) | spiflash_command;
- await this.write_reg(SPI_USR2_REG, val);
- if (data_bits == 0) {
- await this.write_reg(SPI_W0_REG, 0);
+ await setDataLengths(dataBits, readBits);
+ await this.writeReg(SPI_USR_REG, flags);
+ let val = (7 << SPI_USR2_COMMAND_LEN_SHIFT) | spiflashCommand;
+ await this.writeReg(SPI_USR2_REG, val);
+ if (dataBits == 0) {
+ await this.writeReg(SPI_W0_REG, 0);
} else {
if (data.length % 4 != 0) {
const padding = new Uint8Array(data.length % 4);
data = this._appendArray(data, padding);
}
- let next_reg = SPI_W0_REG;
+ let nextReg = SPI_W0_REG;
for (i = 0; i < data.length - 4; i += 4) {
- val = this._bytearray_to_int(data[i], data[i + 1], data[i + 2], data[i + 3]);
- await this.write_reg(next_reg, val);
- next_reg += 4;
+ val = this._byteArrayToInt(data[i], data[i + 1], data[i + 2], data[i + 3]);
+ await this.writeReg(nextReg, val);
+ nextReg += 4;
}
}
- await this.write_reg(SPI_CMD_REG, SPI_CMD_USR);
+ await this.writeReg(SPI_CMD_REG, SPI_CMD_USR);
for (i = 0; i < 10; i++) {
- val = (await this.read_reg(SPI_CMD_REG)) & SPI_CMD_USR;
+ val = (await this.readReg(SPI_CMD_REG)) & SPI_CMD_USR;
if (val == 0) {
break;
}
@@ -698,23 +1015,31 @@ export class ESPLoader {
if (i === 10) {
throw new ESPError("SPI command did not complete in time");
}
- const stat = await this.read_reg(SPI_W0_REG);
- await this.write_reg(SPI_USR_REG, old_spi_usr);
- await this.write_reg(SPI_USR2_REG, old_spi_usr2);
+ const stat = await this.readReg(SPI_W0_REG);
+ await this.writeReg(SPI_USR_REG, oldSpiUsr);
+ await this.writeReg(SPI_USR2_REG, oldSpiUsr2);
return stat;
}
- async read_flash_id() {
+ /**
+ * Read flash id by executing the SPIFLASH_RDID flash command.
+ * @returns {Promise} Register SPI_W0_REG value
+ */
+ async readFlashId() {
const SPIFLASH_RDID = 0x9f;
const pkt = new Uint8Array(0);
- return await this.run_spiflash_command(SPIFLASH_RDID, pkt, 24);
+ return await this.runSpiflashCommand(SPIFLASH_RDID, pkt, 24);
}
- async erase_flash() {
+ /**
+ * Execute the erase flash command
+ * @returns {Promise} Erase flash command result
+ */
+ async eraseFlash(): Promise {
this.info("Erasing flash (this may take a while)...");
let d = new Date();
const t1 = d.getTime();
- const ret = await this.check_command(
+ const ret = await this.checkCommand(
"erase flash",
this.ESP_ERASE_FLASH,
undefined,
@@ -727,17 +1052,28 @@ export class ESPLoader {
return ret;
}
- toHex(buffer: number | Uint8Array) {
+ /**
+ * Convert a number or unsigned 8-bit array to hex string
+ * @param {number | Uint8Array } buffer Data to convert to hex string.
+ * @returns {string} A hex string
+ */
+ toHex(buffer: number | Uint8Array): string {
return Array.prototype.map.call(buffer, (x) => ("00" + x.toString(16)).slice(-2)).join("");
}
- async flash_md5sum(addr: number, size: number) {
- const timeout = this.timeout_per_mb(this.MD5_TIMEOUT_PER_MB, size);
- let pkt = this._appendArray(this._int_to_bytearray(addr), this._int_to_bytearray(size));
- pkt = this._appendArray(pkt, this._int_to_bytearray(0));
- pkt = this._appendArray(pkt, this._int_to_bytearray(0));
-
- let res = await this.check_command("calculate md5sum", this.ESP_SPI_FLASH_MD5, pkt, undefined, timeout);
+ /**
+ * Calculate the MD5 Checksum command
+ * @param {number} addr Address number
+ * @param {number} size Package size
+ * @returns {string} MD5 Checksum string
+ */
+ async flashMd5sum(addr: number, size: number): Promise {
+ const timeout = this.timeoutPerMb(this.MD5_TIMEOUT_PER_MB, size);
+ let pkt = this._appendArray(this._intToByteArray(addr), this._intToByteArray(size));
+ pkt = this._appendArray(pkt, this._intToByteArray(0));
+ pkt = this._appendArray(pkt, this._intToByteArray(0));
+
+ let res = await this.checkCommand("calculate md5sum", this.ESP_SPI_FLASH_MD5, pkt, undefined, timeout);
if (res instanceof Uint8Array && res.length > 16) {
res = res.slice(0, 16);
}
@@ -745,12 +1081,12 @@ export class ESPLoader {
return strmd5;
}
- async read_flash(addr: number, size: number, onPacketReceived: FlashReadCallback = null) {
- let pkt = this._appendArray(this._int_to_bytearray(addr), this._int_to_bytearray(size));
- pkt = this._appendArray(pkt, this._int_to_bytearray(0x1000));
- pkt = this._appendArray(pkt, this._int_to_bytearray(1024));
+ async readFlash(addr: number, size: number, onPacketReceived: FlashReadCallback = null) {
+ let pkt = this._appendArray(this._intToByteArray(addr), this._intToByteArray(size));
+ pkt = this._appendArray(pkt, this._intToByteArray(0x1000));
+ pkt = this._appendArray(pkt, this._intToByteArray(1024));
- const res = await this.check_command("read flash", this.ESP_READ_FLASH, pkt);
+ const res = await this.checkCommand("read flash", this.ESP_READ_FLASH, pkt);
if (res != 0) {
throw new ESPError("Failed to read memory: " + res);
@@ -763,7 +1099,7 @@ export class ESPLoader {
if (packet instanceof Uint8Array) {
if (packet.length > 0) {
resp = this._appendArray(resp, packet);
- await this.transport.write(this._int_to_bytearray(resp.length));
+ await this.transport.write(this._intToByteArray(resp.length));
if (onPacketReceived) {
onPacketReceived(packet, resp.length, size);
@@ -777,16 +1113,20 @@ export class ESPLoader {
return resp;
}
- async run_stub() {
+ /**
+ * Upload the flasher ROM bootloader (flasher stub) to the chip.
+ * @returns {ROM} The Chip ROM
+ */
+ async runStub() {
this.info("Uploading stub...");
- let decoded = atob(this.chip.ROM_TEXT);
+ let decoded = Buffer.from(this.chip.ROM_TEXT).toString("base64");
let chardata = decoded.split("").map(function (x) {
return x.charCodeAt(0);
});
const text = new Uint8Array(chardata);
- decoded = atob(this.chip.ROM_DATA);
+ decoded = Buffer.from(this.chip.ROM_DATA).toString("base64");
chardata = decoded.split("").map(function (x) {
return x.charCodeAt(0);
});
@@ -795,23 +1135,23 @@ export class ESPLoader {
let blocks = Math.floor((text.length + this.ESP_RAM_BLOCK - 1) / this.ESP_RAM_BLOCK);
let i;
- await this.mem_begin(text.length, blocks, this.ESP_RAM_BLOCK, this.chip.TEXT_START);
+ await this.memBegin(text.length, blocks, this.ESP_RAM_BLOCK, this.chip.TEXT_START);
for (i = 0; i < blocks; i++) {
- const from_offs = i * this.ESP_RAM_BLOCK;
- const to_offs = from_offs + this.ESP_RAM_BLOCK;
- await this.mem_block(text.slice(from_offs, to_offs), i);
+ const fromOffs = i * this.ESP_RAM_BLOCK;
+ const toOffs = fromOffs + this.ESP_RAM_BLOCK;
+ await this.memBlock(text.slice(fromOffs, toOffs), i);
}
blocks = Math.floor((data.length + this.ESP_RAM_BLOCK - 1) / this.ESP_RAM_BLOCK);
- await this.mem_begin(data.length, blocks, this.ESP_RAM_BLOCK, this.chip.DATA_START);
+ await this.memBegin(data.length, blocks, this.ESP_RAM_BLOCK, this.chip.DATA_START);
for (i = 0; i < blocks; i++) {
- const from_offs = i * this.ESP_RAM_BLOCK;
- const to_offs = from_offs + this.ESP_RAM_BLOCK;
- await this.mem_block(data.slice(from_offs, to_offs), i);
+ const fromOffs = i * this.ESP_RAM_BLOCK;
+ const toOffs = fromOffs + this.ESP_RAM_BLOCK;
+ await this.memBlock(data.slice(fromOffs, toOffs), i);
}
this.info("Running stub...");
- await this.mem_finish(this.chip.ENTRY);
+ await this.memFinish(this.chip.ENTRY);
// Check up-to next 100 packets to see if stub is running
for (let i = 0; i < 100; i++) {
@@ -826,10 +1166,13 @@ export class ESPLoader {
throw new ESPError("Failed to start stub. Unexpected response");
}
- async change_baud() {
+ /**
+ * Change the chip baudrate.
+ */
+ async changeBaud() {
this.info("Changing baudrate to " + this.baudrate);
- const second_arg = this.IS_STUB ? this.transport.baudrate : 0;
- const pkt = this._appendArray(this._int_to_bytearray(this.baudrate), this._int_to_bytearray(second_arg));
+ const secondArg = this.IS_STUB ? this.transport.baudrate : 0;
+ const pkt = this._appendArray(this._intToByteArray(this.baudrate), this._intToByteArray(secondArg));
const resp = await this.command(this.ESP_CHANGE_BAUDRATE, pkt);
this.debug(resp[0].toString());
this.info("Changed");
@@ -854,39 +1197,54 @@ export class ESPLoader {
}
}
- async main_fn(mode = "default_reset") {
- await this.detect_chip(mode);
+ /**
+ * Execute the main function of ESPLoader.
+ * @param {string} mode Reset mode to use
+ * @returns {ROM} chip ROM
+ */
+ async main(mode = "default_reset") {
+ await this.detectChip(mode);
- const chip = await this.chip.get_chip_description(this);
+ const chip = await this.chip.getChipDescription(this);
this.info("Chip is " + chip);
- this.info("Features: " + (await this.chip.get_chip_features(this)));
- this.info("Crystal is " + (await this.chip.get_crystal_freq(this)) + "MHz");
- this.info("MAC: " + (await this.chip.read_mac(this)));
- await this.chip.read_mac(this);
+ this.info("Features: " + (await this.chip.getChipFeatures(this)));
+ this.info("Crystal is " + (await this.chip.getCrystalFreq(this)) + "MHz");
+ this.info("MAC: " + (await this.chip.readMac(this)));
+ await this.chip.readMac(this);
- if (typeof this.chip._post_connect != "undefined") {
- await this.chip._post_connect(this);
+ if (typeof this.chip.postConnect != "undefined") {
+ await this.chip.postConnect(this);
}
- await this.run_stub();
+ await this.runStub();
if (this.romBaudrate !== this.baudrate) {
- await this.change_baud();
+ await this.changeBaud();
}
return chip;
}
- flash_size_bytes = function (flash_size: string) {
- let flash_size_b = -1;
- if (flash_size.indexOf("KB") !== -1) {
- flash_size_b = parseInt(flash_size.slice(0, flash_size.indexOf("KB"))) * 1024;
- } else if (flash_size.indexOf("MB") !== -1) {
- flash_size_b = parseInt(flash_size.slice(0, flash_size.indexOf("MB"))) * 1024 * 1024;
- }
- return flash_size_b;
+ /**
+ * Get flash size bytes from flash size string.
+ * @param {string} flashSize Flash Size string
+ * @returns {number} Flash size bytes
+ */
+ flashSizeBytes = function (flashSize: string) {
+ let flashSizeB = -1;
+ if (flashSize.indexOf("KB") !== -1) {
+ flashSizeB = parseInt(flashSize.slice(0, flashSize.indexOf("KB"))) * 1024;
+ } else if (flashSize.indexOf("MB") !== -1) {
+ flashSizeB = parseInt(flashSize.slice(0, flashSize.indexOf("MB"))) * 1024 * 1024;
+ }
+ return flashSizeB;
};
- parse_flash_size_arg(flsz: string) {
+ /**
+ * Parse a given flash size string to a number
+ * @param {string} flsz Flash size to request
+ * @returns {number} Flash size number
+ */
+ parseFlashSizeArg(flsz: string) {
if (typeof this.chip.FLASH_SIZES[flsz] === "undefined") {
throw new ESPError(
"Flash size " + flsz + " is not supported by this chip type. Supported sizes: " + this.chip.FLASH_SIZES,
@@ -895,28 +1253,31 @@ export class ESPLoader {
return this.chip.FLASH_SIZES[flsz];
}
- _update_image_flash_params(
- image: string,
- address: number,
- flash_size: string,
- flash_mode: string,
- flash_freq: string,
- ) {
- this.debug("_update_image_flash_params " + flash_size + " " + flash_mode + " " + flash_freq);
+ /**
+ * Update the image flash parameters with given arguments.
+ * @param {string} image binary image as string
+ * @param {number} address flash address number
+ * @param {string} flashSize Flash size string
+ * @param {string} flashMode Flash mode string
+ * @param {string} flashFreq Flash frequency string
+ * @returns {string} modified image string
+ */
+ _updateImageFlashParams(image: string, address: number, flashSize: string, flashMode: string, flashFreq: string) {
+ this.debug("_update_image_flash_params " + flashSize + " " + flashMode + " " + flashFreq);
if (image.length < 8) {
return image;
}
if (address != this.chip.BOOTLOADER_FLASH_OFFSET) {
return image;
}
- if (flash_size === "keep" && flash_mode === "keep" && flash_freq === "keep") {
+ if (flashSize === "keep" && flashMode === "keep" && flashFreq === "keep") {
this.info("Not changing the image");
return image;
}
const magic = parseInt(image[0]);
- let a_flash_mode = parseInt(image[2]);
- const flash_size_freq = parseInt(image[3]);
+ let aFlashMode = parseInt(image[2]);
+ const flashSizeFreq = parseInt(image[3]);
if (magic !== this.ESP_IMAGE_MAGIC) {
this.info(
"Warning: Image file at 0x" +
@@ -928,44 +1289,48 @@ export class ESPLoader {
/* XXX: Yet to implement actual image verification */
- if (flash_mode !== "keep") {
- const flash_modes: { [key: string]: number } = { qio: 0, qout: 1, dio: 2, dout: 3 };
- a_flash_mode = flash_modes[flash_mode];
+ if (flashMode !== "keep") {
+ const flashModes: { [key: string]: number } = { qio: 0, qout: 1, dio: 2, dout: 3 };
+ aFlashMode = flashModes[flashMode];
}
- let a_flash_freq = flash_size_freq & 0x0f;
- if (flash_freq !== "keep") {
- const flash_freqs: { [key: string]: number } = { "40m": 0, "26m": 1, "20m": 2, "80m": 0xf };
- a_flash_freq = flash_freqs[flash_freq];
+ let aFlashFreq = flashSizeFreq & 0x0f;
+ if (flashFreq !== "keep") {
+ const flashFreqs: { [key: string]: number } = { "40m": 0, "26m": 1, "20m": 2, "80m": 0xf };
+ aFlashFreq = flashFreqs[flashFreq];
}
- let a_flash_size = flash_size_freq & 0xf0;
- if (flash_size !== "keep") {
- a_flash_size = this.parse_flash_size_arg(flash_size);
+ let aFlashSize = flashSizeFreq & 0xf0;
+ if (flashSize !== "keep") {
+ aFlashSize = this.parseFlashSizeArg(flashSize);
}
- const flash_params = (a_flash_mode << 8) | (a_flash_freq + a_flash_size);
- this.info("Flash params set to " + flash_params.toString(16));
- if (parseInt(image[2]) !== a_flash_mode << 8) {
- image = image.substring(0, 2) + (a_flash_mode << 8).toString() + image.substring(2 + 1);
+ const flashParams = (aFlashMode << 8) | (aFlashFreq + aFlashSize);
+ this.info("Flash params set to " + flashParams.toString(16));
+ if (parseInt(image[2]) !== aFlashMode << 8) {
+ image = image.substring(0, 2) + (aFlashMode << 8).toString() + image.substring(2 + 1);
}
- if (parseInt(image[3]) !== a_flash_freq + a_flash_size) {
- image = image.substring(0, 3) + (a_flash_freq + a_flash_size).toString() + image.substring(3 + 1);
+ if (parseInt(image[3]) !== aFlashFreq + aFlashSize) {
+ image = image.substring(0, 3) + (aFlashFreq + aFlashSize).toString() + image.substring(3 + 1);
}
return image;
}
- async write_flash(options: FlashOptions) {
+ /**
+ * Write set of file images into given address based on given FlashOptions object.
+ * @param {FlashOptions} options FlashOptions to configure how and what to write into flash.
+ */
+ async writeFlash(options: FlashOptions) {
this.debug("EspLoader program");
if (options.flashSize !== "keep") {
- const flash_end = this.flash_size_bytes(options.flashSize);
+ const flashEnd = this.flashSizeBytes(options.flashSize);
for (let i = 0; i < options.fileArray.length; i++) {
- if (options.fileArray[i].data.length + options.fileArray[i].address > flash_end) {
+ if (options.fileArray[i].data.length + options.fileArray[i].address > flashEnd) {
throw new ESPError(`File ${i + 1} doesn't fit in the available flash`);
}
}
}
if (this.IS_STUB === true && options.eraseAll === true) {
- await this.erase_flash();
+ await this.eraseFlash();
}
let image: string, address: number;
for (let i = 0; i < options.fileArray.length; i++) {
@@ -979,7 +1344,7 @@ export class ESPLoader {
this.debug("Warning: File is empty");
continue;
}
- image = this._update_image_flash_params(image, address, options.flashSize, options.flashMode, options.flashFreq);
+ image = this._updateImageFlashParams(image, address, options.flashSize, options.flashMode, options.flashFreq);
let calcmd5: string | null = null;
if (options.calculateMD5Hash) {
calcmd5 = options.calculateMD5Hash(image);
@@ -990,12 +1355,12 @@ export class ESPLoader {
if (options.compress) {
const uncimage = this.bstrToUi8(image);
image = this.ui8ToBstr(deflate(uncimage, { level: 9 }));
- blocks = await this.flash_defl_begin(uncsize, image.length, address);
+ blocks = await this.flashDeflBegin(uncsize, image.length, address);
} else {
- blocks = await this.flash_begin(uncsize, address);
+ blocks = await this.flashBegin(uncsize, address);
}
let seq = 0;
- let bytes_sent = 0;
+ let bytesSent = 0;
const totalBytes = image.length;
if (options.reportProgress) options.reportProgress(i, 0, totalBytes);
@@ -1006,15 +1371,15 @@ export class ESPLoader {
// Create a decompressor to keep track of the size of uncompressed data
// to be written in each chunk.
const inflate = new Inflate({ chunkSize: 1 });
- let total_len_uncompressed = 0;
+ let totalLenUncompressed = 0;
inflate.onData = function (chunk: Data): void {
- total_len_uncompressed += chunk.byteLength;
+ totalLenUncompressed += chunk.byteLength;
};
while (image.length > 0) {
this.debug("Write loop " + address + " " + seq + " " + blocks);
this.info(
"Writing at 0x" +
- (address + total_len_uncompressed).toString(16) +
+ (address + totalLenUncompressed).toString(16) +
"... (" +
Math.floor((100 * (seq + 1)) / blocks) +
"%)",
@@ -1022,32 +1387,32 @@ export class ESPLoader {
const block = this.bstrToUi8(image.slice(0, this.FLASH_WRITE_SIZE));
if (options.compress) {
- const len_uncompressed_previous = total_len_uncompressed;
+ const lenUncompressedPrevious = totalLenUncompressed;
inflate.push(block, false);
- const block_uncompressed = total_len_uncompressed - len_uncompressed_previous;
- let block_timeout = 3000;
- if (this.timeout_per_mb(this.ERASE_WRITE_TIMEOUT_PER_MB, block_uncompressed) > 3000) {
- block_timeout = this.timeout_per_mb(this.ERASE_WRITE_TIMEOUT_PER_MB, block_uncompressed);
+ const blockUncompressed = totalLenUncompressed - lenUncompressedPrevious;
+ let blockTimeout = 3000;
+ if (this.timeoutPerMb(this.ERASE_WRITE_TIMEOUT_PER_MB, blockUncompressed) > 3000) {
+ blockTimeout = this.timeoutPerMb(this.ERASE_WRITE_TIMEOUT_PER_MB, blockUncompressed);
}
if (this.IS_STUB === false) {
// ROM code writes block to flash before ACKing
- timeout = block_timeout;
+ timeout = blockTimeout;
}
- await this.flash_defl_block(block, seq, timeout);
+ await this.flashDeflBlock(block, seq, timeout);
if (this.IS_STUB) {
// Stub ACKs when block is received, then writes to flash while receiving the block after it
- timeout = block_timeout;
+ timeout = blockTimeout;
}
} else {
throw new ESPError("Yet to handle Non Compressed writes");
}
- bytes_sent += block.length;
+ bytesSent += block.length;
image = image.slice(this.FLASH_WRITE_SIZE, image.length);
seq++;
- if (options.reportProgress) options.reportProgress(i, bytes_sent, totalBytes);
+ if (options.reportProgress) options.reportProgress(i, bytesSent, totalBytes);
}
if (this.IS_STUB) {
- await this.read_reg(this.CHIP_DETECT_MAGIC_REG_ADDR, timeout);
+ await this.readReg(this.CHIP_DETECT_MAGIC_REG_ADDR, timeout);
}
d = new Date();
const t = d.getTime() - t1;
@@ -1056,7 +1421,7 @@ export class ESPLoader {
"Wrote " +
uncsize +
" bytes (" +
- bytes_sent +
+ bytesSent +
" compressed) at 0x" +
address.toString(16) +
" in " +
@@ -1065,7 +1430,7 @@ export class ESPLoader {
);
}
if (calcmd5) {
- const res = await this.flash_md5sum(address, uncsize);
+ const res = await this.flashMd5sum(address, uncsize);
if (new String(res).valueOf() != new String(calcmd5).valueOf()) {
this.info("File md5: " + calcmd5);
this.info("Flash md5: " + res);
@@ -1078,42 +1443,51 @@ export class ESPLoader {
this.info("Leaving...");
if (this.IS_STUB) {
- await this.flash_begin(0, 0);
+ await this.flashBegin(0, 0);
if (options.compress) {
- await this.flash_defl_finish();
+ await this.flashDeflFinish();
} else {
- await this.flash_finish();
+ await this.flashFinish();
}
}
}
- async flash_id() {
+ /**
+ * Read SPI flash manufacturer and device id.
+ */
+ async flashId() {
this.debug("flash_id");
- const flashid = await this.read_flash_id();
+ const flashid = await this.readFlashId();
this.info("Manufacturer: " + (flashid & 0xff).toString(16));
- const flid_lowbyte = (flashid >> 16) & 0xff;
- this.info("Device: " + ((flashid >> 8) & 0xff).toString(16) + flid_lowbyte.toString(16));
- this.info("Detected flash size: " + this.DETECTED_FLASH_SIZES[flid_lowbyte]);
+ const flidLowbyte = (flashid >> 16) & 0xff;
+ this.info("Device: " + ((flashid >> 8) & 0xff).toString(16) + flidLowbyte.toString(16));
+ this.info("Detected flash size: " + this.DETECTED_FLASH_SIZES[flidLowbyte]);
}
- async get_flash_size() {
+ async getFlashSize() {
this.debug("flash_id");
- const flashid = await this.read_flash_id();
- const flid_lowbyte = (flashid >> 16) & 0xff;
- return this.DETECTED_FLASH_SIZES_NUM[flid_lowbyte];
+ const flashid = await this.readFlashId();
+ const flidLowbyte = (flashid >> 16) & 0xff;
+ return this.DETECTED_FLASH_SIZES_NUM[flidLowbyte];
}
- async hard_reset() {
+ /**
+ * Perform a chip hard reset by setting RTS to LOW and then HIGH.
+ */
+ async hardReset() {
await this.transport.setRTS(true); // EN->LOW
await this._sleep(100);
await this.transport.setRTS(false);
}
- async soft_reset() {
+ /**
+ * Soft reset the device chip. Soft reset with run user code is the closest.
+ */
+ async softReset() {
if (!this.IS_STUB) {
// "run user code" is as close to a soft reset as we can do
- await this.flash_begin(0, 0);
- await this.flash_finish(false);
+ await this.flashBegin(0, 0);
+ await this.flashFinish(false);
} else if (this.chip.CHIP_NAME != "ESP8266") {
throw new ESPError("Soft resetting is currently only supported on ESP8266");
} else {
diff --git a/src/index.ts b/src/index.ts
index 66af3ec..2287878 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,2 +1,4 @@
export { IEspLoaderTerminal, ESPLoader, FlashOptions, LoaderOptions } from "./esploader";
-export { Transport } from "./webserial";
+export { classicReset, customReset, hardReset, usbJTAGSerialReset, validateCustomResetStringSequence } from "./reset";
+export { ROM } from "./targets/rom";
+export { Transport, SerialOptions } from "./webserial";
diff --git a/src/reset.ts b/src/reset.ts
index 850e4d9..267e666 100644
--- a/src/reset.ts
+++ b/src/reset.ts
@@ -2,10 +2,32 @@ import { Transport } from "./webserial";
const DEFAULT_RESET_DELAY = 50;
+/**
+ * Sleep for ms milliseconds
+ * @param {number} ms Milliseconds to wait
+ * @returns {Promise}
+ */
function sleep(ms: number): Promise {
return new Promise((resolve) => setTimeout(resolve, ms));
}
+/**
+ * Execute a classic set of commands that will reset the chip.
+ *
+ * Commands (e.g. R0) are defined by a code (R) and an argument (0).
+ *
+ * The commands are:
+ *
+ * D: setDTR - 1=True / 0=False
+ *
+ * R: setRTS - 1=True / 0=False
+ *
+ * W: Wait (time delay) - positive integer number (miliseconds)
+ *
+ * "D0|R1|W100|D1|R0|W50|D0" represents the classic reset strategy
+ * @param {Transport} transport Transport class to perform serial communication.
+ * @param {number} resetDelay Delay in milliseconds for reset.
+ */
export async function classicReset(transport: Transport, resetDelay = DEFAULT_RESET_DELAY) {
await transport.setDTR(false);
await transport.setRTS(true);
@@ -16,6 +38,20 @@ export async function classicReset(transport: Transport, resetDelay = DEFAULT_RE
await transport.setDTR(false);
}
+/**
+ * Execute a set of commands for USB JTAG serial reset.
+ *
+ * Commands (e.g. R0) are defined by a code (R) and an argument (0).
+ *
+ * The commands are:
+ *
+ * D: setDTR - 1=True / 0=False
+ *
+ * R: setRTS - 1=True / 0=False
+ *
+ * W: Wait (time delay) - positive integer number (miliseconds)
+ * @param {Transport} transport Transport class to perform serial communication.
+ */
export async function usbJTAGSerialReset(transport: Transport) {
await transport.setRTS(false);
await transport.setDTR(false);
@@ -34,6 +70,21 @@ export async function usbJTAGSerialReset(transport: Transport) {
await transport.setDTR(false);
}
+/**
+ * Execute a set of commands that will hard reset the chip.
+ *
+ * Commands (e.g. R0) are defined by a code (R) and an argument (0).
+ *
+ * The commands are:
+ *
+ * D: setDTR - 1=True / 0=False
+ *
+ * R: setRTS - 1=True / 0=False
+ *
+ * W: Wait (time delay) - positive integer number (miliseconds)
+ * @param {Transport} transport Transport class to perform serial communication.
+ * @param {boolean} usingUsbOtg is it using USB-OTG ?
+ */
export async function hardReset(transport: Transport, usingUsbOtg = false) {
if (usingUsbOtg) {
await sleep(200);
@@ -51,6 +102,21 @@ type CmdsArgsTypes = {
W: number;
};
+/**
+ * Validate a sequence string based on the following format:
+ *
+ * Commands (e.g. R0) are defined by a code (R) and an argument (0).
+ *
+ * The commands are:
+ *
+ * D: setDTR - 1=True / 0=False
+ *
+ * R: setRTS - 1=True / 0=False
+ *
+ * W: Wait (time delay) - positive integer number (miliseconds)
+ * @param {string} seqStr Sequence string to validate
+ * @returns {boolean} Is the sequence string valid ?
+ */
export function validateCustomResetStringSequence(seqStr: string): boolean {
const commands: (keyof CmdsArgsTypes)[] = ["D", "R", "W"];
@@ -94,6 +160,8 @@ export function validateCustomResetStringSequence(seqStr: string): boolean {
* W: Wait (time delay) - positive integer number (miliseconds)
*
* "D0|R1|W100|D1|R0|W50|D0" represents the classic reset strategy
+ * @param {Transport} transport Transport class to perform serial communication.
+ * @param {string} sequenceString Custom string sequence for reset strategy
*/
export async function customReset(transport: Transport, sequenceString: string) {
const resetDictionary: { [K in keyof CmdsArgsTypes]: (arg: CmdsArgsTypes[K]) => Promise } = {
diff --git a/src/targets/esp32.ts b/src/targets/esp32.ts
index a052f82..a1b7593 100644
--- a/src/targets/esp32.ts
+++ b/src/targets/esp32.ts
@@ -37,30 +37,30 @@ export class ESP32ROM extends ROM {
public ROM_DATA = ESP32_STUB.data;
public ROM_TEXT = ESP32_STUB.text;
- public async read_efuse(loader: ESPLoader, offset: number) {
+ public async readEfuse(loader: ESPLoader, offset: number): Promise {
const addr = this.EFUSE_RD_REG_BASE + 4 * offset;
loader.debug("Read efuse " + addr);
- return await loader.read_reg(addr);
+ return await loader.readReg(addr);
}
- public async get_pkg_version(loader: ESPLoader) {
- const word3 = await this.read_efuse(loader, 3);
- let pkg_version = (word3 >> 9) & 0x07;
- pkg_version += ((word3 >> 2) & 0x1) << 3;
- return pkg_version;
+ public async getPkgVersion(loader: ESPLoader): Promise {
+ const word3 = await this.readEfuse(loader, 3);
+ let pkgVersion = (word3 >> 9) & 0x07;
+ pkgVersion += ((word3 >> 2) & 0x1) << 3;
+ return pkgVersion;
}
- public async get_chip_revision(loader: ESPLoader) {
- const word3 = await this.read_efuse(loader, 3);
- const word5 = await this.read_efuse(loader, 5);
- const apb_ctl_date = await loader.read_reg(this.DR_REG_SYSCON_BASE + 0x7c);
-
- const rev_bit0 = (word3 >> 15) & 0x1;
- const rev_bit1 = (word5 >> 20) & 0x1;
- const rev_bit2 = (apb_ctl_date >> 31) & 0x1;
- if (rev_bit0 != 0) {
- if (rev_bit1 != 0) {
- if (rev_bit2 != 0) {
+ public async getChipRevision(loader: ESPLoader): Promise {
+ const word3 = await this.readEfuse(loader, 3);
+ const word5 = await this.readEfuse(loader, 5);
+ const apbCtlDate = await loader.readReg(this.DR_REG_SYSCON_BASE + 0x7c);
+
+ const revBit0 = (word3 >> 15) & 0x1;
+ const revBit1 = (word5 >> 20) & 0x1;
+ const revBit2 = (apbCtlDate >> 31) & 0x1;
+ if (revBit0 != 0) {
+ if (revBit1 != 0) {
+ if (revBit2 != 0) {
return 3;
} else {
return 2;
@@ -72,8 +72,8 @@ export class ESP32ROM extends ROM {
return 0;
}
- public async get_chip_description(loader: ESPLoader) {
- const chip_desc = [
+ public async getChipDescription(loader: ESPLoader) {
+ const chipDesc = [
"ESP32-D0WDQ6",
"ESP32-D0WD",
"ESP32-D2WD",
@@ -82,98 +82,98 @@ export class ESP32ROM extends ROM {
"ESP32-PICO-D4",
"ESP32-PICO-V3-02",
];
- let chip_name = "";
- const pkg_version = await this.get_pkg_version(loader);
- const chip_revision = await this.get_chip_revision(loader);
- const rev3 = chip_revision == 3;
- const single_core = (await this.read_efuse(loader, 3)) & (1 << 0);
+ let chipName = "";
+ const pkgVersion = await this.getPkgVersion(loader);
+ const chipRevision = await this.getChipRevision(loader);
+ const rev3 = chipRevision == 3;
+ const single_core = (await this.readEfuse(loader, 3)) & (1 << 0);
if (single_core != 0) {
- chip_desc[0] = "ESP32-S0WDQ6";
- chip_desc[1] = "ESP32-S0WD";
+ chipDesc[0] = "ESP32-S0WDQ6";
+ chipDesc[1] = "ESP32-S0WD";
}
if (rev3) {
- chip_desc[5] = "ESP32-PICO-V3";
+ chipDesc[5] = "ESP32-PICO-V3";
}
- if (pkg_version >= 0 && pkg_version <= 6) {
- chip_name = chip_desc[pkg_version];
+ if (pkgVersion >= 0 && pkgVersion <= 6) {
+ chipName = chipDesc[pkgVersion];
} else {
- chip_name = "Unknown ESP32";
+ chipName = "Unknown ESP32";
}
- if (rev3 && (pkg_version === 0 || pkg_version === 1)) {
- chip_name += "-V3";
+ if (rev3 && (pkgVersion === 0 || pkgVersion === 1)) {
+ chipName += "-V3";
}
- return chip_name + " (revision " + chip_revision + ")";
+ return chipName + " (revision " + chipRevision + ")";
}
- public async get_chip_features(loader: ESPLoader) {
+ public async getChipFeatures(loader: ESPLoader) {
const features = ["Wi-Fi"];
- const word3 = await this.read_efuse(loader, 3);
+ const word3 = await this.readEfuse(loader, 3);
- const chip_ver_dis_bt = word3 & (1 << 1);
- if (chip_ver_dis_bt === 0) {
+ const chipVerDisBt = word3 & (1 << 1);
+ if (chipVerDisBt === 0) {
features.push(" BT");
}
- const chip_ver_dis_app_cpu = word3 & (1 << 0);
- if (chip_ver_dis_app_cpu !== 0) {
+ const chipVerDisAppCpu = word3 & (1 << 0);
+ if (chipVerDisAppCpu !== 0) {
features.push(" Single Core");
} else {
features.push(" Dual Core");
}
- const chip_cpu_freq_rated = word3 & (1 << 13);
- if (chip_cpu_freq_rated !== 0) {
- const chip_cpu_freq_low = word3 & (1 << 12);
- if (chip_cpu_freq_low !== 0) {
+ const chipCpuFreqRated = word3 & (1 << 13);
+ if (chipCpuFreqRated !== 0) {
+ const chipCpuFreqLow = word3 & (1 << 12);
+ if (chipCpuFreqLow !== 0) {
features.push(" 160MHz");
} else {
features.push(" 240MHz");
}
}
- const pkg_version = await this.get_pkg_version(loader);
- if ([2, 4, 5, 6].indexOf(pkg_version) !== -1) {
+ const pkgVersion = await this.getPkgVersion(loader);
+ if ([2, 4, 5, 6].indexOf(pkgVersion) !== -1) {
features.push(" Embedded Flash");
}
- if (pkg_version === 6) {
+ if (pkgVersion === 6) {
features.push(" Embedded PSRAM");
}
- const word4 = await this.read_efuse(loader, 4);
- const adc_vref = (word4 >> 8) & 0x1f;
- if (adc_vref !== 0) {
+ const word4 = await this.readEfuse(loader, 4);
+ const adcVref = (word4 >> 8) & 0x1f;
+ if (adcVref !== 0) {
features.push(" VRef calibration in efuse");
}
- const blk3_part_res = (word3 >> 14) & 0x1;
- if (blk3_part_res !== 0) {
+ const blk3PartRes = (word3 >> 14) & 0x1;
+ if (blk3PartRes !== 0) {
features.push(" BLK3 partially reserved");
}
- const word6 = await this.read_efuse(loader, 6);
- const coding_scheme = word6 & 0x3;
- const coding_scheme_arr = ["None", "3/4", "Repeat (UNSUPPORTED)", "Invalid"];
- features.push(" Coding Scheme " + coding_scheme_arr[coding_scheme]);
+ const word6 = await this.readEfuse(loader, 6);
+ const codingScheme = word6 & 0x3;
+ const codingSchemeArr = ["None", "3/4", "Repeat (UNSUPPORTED)", "Invalid"];
+ features.push(" Coding Scheme " + codingSchemeArr[codingScheme]);
return features;
}
- public async get_crystal_freq(loader: ESPLoader) {
- const uart_div = (await loader.read_reg(this.UART_CLKDIV_REG)) & this.UART_CLKDIV_MASK;
- const ets_xtal = (loader.transport.baudrate * uart_div) / 1000000 / this.XTAL_CLK_DIVIDER;
- let norm_xtal;
- if (ets_xtal > 33) {
- norm_xtal = 40;
+ public async getCrystalFreq(loader: ESPLoader) {
+ const uartDiv = (await loader.readReg(this.UART_CLKDIV_REG)) & this.UART_CLKDIV_MASK;
+ const etsXtal = (loader.transport.baudrate * uartDiv) / 1000000 / this.XTAL_CLK_DIVIDER;
+ let normXtal;
+ if (etsXtal > 33) {
+ normXtal = 40;
} else {
- norm_xtal = 26;
+ normXtal = 26;
}
- if (Math.abs(norm_xtal - ets_xtal) > 1) {
+ if (Math.abs(normXtal - etsXtal) > 1) {
loader.info("WARNING: Unsupported crystal in use");
}
- return norm_xtal;
+ return normXtal;
}
public _d2h(d: number) {
@@ -181,10 +181,10 @@ export class ESP32ROM extends ROM {
return h.length === 1 ? "0" + h : h;
}
- public async read_mac(loader: ESPLoader) {
- let mac0 = await this.read_efuse(loader, 1);
+ public async readMac(loader: ESPLoader) {
+ let mac0 = await this.readEfuse(loader, 1);
mac0 = mac0 >>> 0;
- let mac1 = await this.read_efuse(loader, 2);
+ let mac1 = await this.readEfuse(loader, 2);
mac1 = mac1 >>> 0;
const mac = new Uint8Array(6);
mac[0] = (mac1 >> 8) & 0xff;
diff --git a/src/targets/esp32c3.ts b/src/targets/esp32c3.ts
index 0a3bc6c..1f281ef 100644
--- a/src/targets/esp32c3.ts
+++ b/src/targets/esp32c3.ts
@@ -36,42 +36,42 @@ export class ESP32C3ROM extends ROM {
public ROM_DATA = ESP32C3_STUB.data;
public ROM_TEXT = ESP32C3_STUB.text;
- public async get_pkg_version(loader: ESPLoader) {
- const num_word = 3;
- const block1_addr = this.EFUSE_BASE + 0x044;
- const addr = block1_addr + 4 * num_word;
- const word3 = await loader.read_reg(addr);
- const pkg_version = (word3 >> 21) & 0x07;
- return pkg_version;
+ public async getPkgVersion(loader: ESPLoader): Promise {
+ const numWord = 3;
+ const block1Addr = this.EFUSE_BASE + 0x044;
+ const addr = block1Addr + 4 * numWord;
+ const word3 = await loader.readReg(addr);
+ const pkgVersion = (word3 >> 21) & 0x07;
+ return pkgVersion;
}
- public async get_chip_revision(loader: ESPLoader) {
- const block1_addr = this.EFUSE_BASE + 0x044;
- const num_word = 3;
+ public async getChipRevision(loader: ESPLoader): Promise {
+ const block1Addr = this.EFUSE_BASE + 0x044;
+ const numWord = 3;
const pos = 18;
- const addr = block1_addr + 4 * num_word;
- const ret = ((await loader.read_reg(addr)) & (0x7 << pos)) >> pos;
+ const addr = block1Addr + 4 * numWord;
+ const ret = ((await loader.readReg(addr)) & (0x7 << pos)) >> pos;
return ret;
}
- public async get_chip_description(loader: ESPLoader) {
+ public async getChipDescription(loader: ESPLoader) {
let desc: string;
- const pkg_ver = await this.get_pkg_version(loader);
- if (pkg_ver === 0) {
+ const pkgVer = await this.getPkgVersion(loader);
+ if (pkgVer === 0) {
desc = "ESP32-C3";
} else {
desc = "unknown ESP32-C3";
}
- const chip_rev = await this.get_chip_revision(loader);
+ const chip_rev = await this.getChipRevision(loader);
desc += " (revision " + chip_rev + ")";
return desc;
}
- public async get_chip_features(loader: ESPLoader) {
+ public async getChipFeatures(loader: ESPLoader) {
return ["Wi-Fi"];
}
- public async get_crystal_freq(loader: ESPLoader) {
+ public async getCrystalFreq(loader: ESPLoader) {
return 40;
}
@@ -80,10 +80,10 @@ export class ESP32C3ROM extends ROM {
return h.length === 1 ? "0" + h : h;
}
- public async read_mac(loader: ESPLoader) {
- let mac0 = await loader.read_reg(this.MAC_EFUSE_REG);
+ public async readMac(loader: ESPLoader) {
+ let mac0 = await loader.readReg(this.MAC_EFUSE_REG);
mac0 = mac0 >>> 0;
- let mac1 = await loader.read_reg(this.MAC_EFUSE_REG + 4);
+ let mac1 = await loader.readReg(this.MAC_EFUSE_REG + 4);
mac1 = (mac1 >>> 0) & 0x0000ffff;
const mac = new Uint8Array(6);
mac[0] = (mac1 >> 8) & 0xff;
@@ -108,7 +108,7 @@ export class ESP32C3ROM extends ROM {
);
}
- public get_erase_size(offset: number, size: number) {
+ public getEraseSize(offset: number, size: number) {
return size;
}
}
diff --git a/src/targets/esp32c6.ts b/src/targets/esp32c6.ts
index 514a325..8480e15 100644
--- a/src/targets/esp32c6.ts
+++ b/src/targets/esp32c6.ts
@@ -36,42 +36,42 @@ export class ESP32C6ROM extends ROM {
public ROM_DATA = ESP32C6_STUB.data;
public ROM_TEXT = ESP32C6_STUB.text;
- public async get_pkg_version(loader: ESPLoader) {
- const num_word = 3;
- const block1_addr = this.EFUSE_BASE + 0x044;
- const addr = block1_addr + 4 * num_word;
- const word3 = await loader.read_reg(addr);
- const pkg_version = (word3 >> 21) & 0x07;
- return pkg_version;
+ public async getPkgVersion(loader: ESPLoader) {
+ const numWord = 3;
+ const block1Addr = this.EFUSE_BASE + 0x044;
+ const addr = block1Addr + 4 * numWord;
+ const word3 = await loader.readReg(addr);
+ const pkgVersion = (word3 >> 21) & 0x07;
+ return pkgVersion;
}
- public async get_chip_revision(loader: ESPLoader) {
- const block1_addr = this.EFUSE_BASE + 0x044;
- const num_word = 3;
+ public async getChipRevision(loader: ESPLoader) {
+ const block1Addr = this.EFUSE_BASE + 0x044;
+ const numWord = 3;
const pos = 18;
- const addr = block1_addr + 4 * num_word;
- const ret = ((await loader.read_reg(addr)) & (0x7 << pos)) >> pos;
+ const addr = block1Addr + 4 * numWord;
+ const ret = ((await loader.readReg(addr)) & (0x7 << pos)) >> pos;
return ret;
}
- public async get_chip_description(loader: ESPLoader) {
+ public async getChipDescription(loader: ESPLoader) {
let desc: string;
- const pkg_ver = await this.get_pkg_version(loader);
- if (pkg_ver === 0) {
+ const pkgVer = await this.getPkgVersion(loader);
+ if (pkgVer === 0) {
desc = "ESP32-C6";
} else {
desc = "unknown ESP32-C6";
}
- const chip_rev = await this.get_chip_revision(loader);
- desc += " (revision " + chip_rev + ")";
+ const chipRev = await this.getChipRevision(loader);
+ desc += " (revision " + chipRev + ")";
return desc;
}
- public async get_chip_features(loader: ESPLoader) {
+ public async getChipFeatures(loader: ESPLoader) {
return ["Wi-Fi"];
}
- public async get_crystal_freq(loader: ESPLoader) {
+ public async getCrystalFreq(loader: ESPLoader) {
return 40;
}
@@ -80,10 +80,10 @@ export class ESP32C6ROM extends ROM {
return h.length === 1 ? "0" + h : h;
}
- public async read_mac(loader: ESPLoader) {
- let mac0 = await loader.read_reg(this.MAC_EFUSE_REG);
+ public async readMac(loader: ESPLoader) {
+ let mac0 = await loader.readReg(this.MAC_EFUSE_REG);
mac0 = mac0 >>> 0;
- let mac1 = await loader.read_reg(this.MAC_EFUSE_REG + 4);
+ let mac1 = await loader.readReg(this.MAC_EFUSE_REG + 4);
mac1 = (mac1 >>> 0) & 0x0000ffff;
const mac = new Uint8Array(6);
mac[0] = (mac1 >> 8) & 0xff;
@@ -108,7 +108,7 @@ export class ESP32C6ROM extends ROM {
);
}
- public get_erase_size(offset: number, size: number) {
+ public getEraseSize(offset: number, size: number) {
return size;
}
}
diff --git a/src/targets/esp32h2.ts b/src/targets/esp32h2.ts
index cb9005e..294d3ab 100644
--- a/src/targets/esp32h2.ts
+++ b/src/targets/esp32h2.ts
@@ -40,15 +40,15 @@ export class ESP32H2ROM extends ROM {
public ROM_DATA = ESP32H2_STUB.data;
public ROM_TEXT = ESP32H2_STUB.text;
- public async get_chip_description(loader: ESPLoader) {
+ public async getChipDescription(loader: ESPLoader) {
return this.CHIP_NAME;
}
- public async get_chip_features(loader: ESPLoader) {
+ public async getChipFeatures(loader: ESPLoader) {
return ["BLE", "IEEE802.15.4"];
}
- public async get_crystal_freq(loader: ESPLoader) {
+ public async getCrystalFreq(loader: ESPLoader) {
// ESP32H2 XTAL is fixed to 32MHz
return 32;
}
@@ -58,18 +58,18 @@ export class ESP32H2ROM extends ROM {
return h.length === 1 ? "0" + h : h;
}
- public async _post_connect(loader: ESPLoader) {
- const buf_no = (await loader.read_reg(this.UARTDEV_BUF_NO)) & 0xff;
- loader.debug("In _post_connect " + buf_no);
- if (buf_no == this.UARTDEV_BUF_NO_USB) {
+ public async postConnect(loader: ESPLoader) {
+ const bufNo = (await loader.readReg(this.UARTDEV_BUF_NO)) & 0xff;
+ loader.debug("In _post_connect " + bufNo);
+ if (bufNo == this.UARTDEV_BUF_NO_USB) {
loader.ESP_RAM_BLOCK = this.USB_RAM_BLOCK;
}
}
- public async read_mac(loader: ESPLoader) {
- let mac0 = await loader.read_reg(this.MAC_EFUSE_REG);
+ public async readMac(loader: ESPLoader) {
+ let mac0 = await loader.readReg(this.MAC_EFUSE_REG);
mac0 = mac0 >>> 0;
- let mac1 = await loader.read_reg(this.MAC_EFUSE_REG + 4);
+ let mac1 = await loader.readReg(this.MAC_EFUSE_REG + 4);
mac1 = (mac1 >>> 0) & 0x0000ffff;
const mac = new Uint8Array(6);
mac[0] = (mac1 >> 8) & 0xff;
@@ -94,7 +94,7 @@ export class ESP32H2ROM extends ROM {
);
}
- public get_erase_size(offset: number, size: number) {
+ public getEraseSize(offset: number, size: number) {
return size;
}
}
diff --git a/src/targets/esp32s2.ts b/src/targets/esp32s2.ts
index f736e39..1d7f2c4 100644
--- a/src/targets/esp32s2.ts
+++ b/src/targets/esp32s2.ts
@@ -36,56 +36,56 @@ export class ESP32S2ROM extends ROM {
public ROM_DATA = ESP32S2_STUB.data;
public ROM_TEXT = ESP32S2_STUB.text;
- public async get_pkg_version(loader: ESPLoader) {
- const num_word = 3;
- const block1_addr = this.EFUSE_BASE + 0x044;
- const addr = block1_addr + 4 * num_word;
- const word3 = await loader.read_reg(addr);
- const pkg_version = (word3 >> 21) & 0x0f;
- return pkg_version;
+ public async getPkgVersion(loader: ESPLoader): Promise {
+ const numWord = 3;
+ const block1Addr = this.EFUSE_BASE + 0x044;
+ const addr = block1Addr + 4 * numWord;
+ const word3 = await loader.readReg(addr);
+ const pkgVersion = (word3 >> 21) & 0x0f;
+ return pkgVersion;
}
- public async get_chip_description(loader: ESPLoader) {
- const chip_desc = ["ESP32-S2", "ESP32-S2FH16", "ESP32-S2FH32"];
- const pkg_ver = await this.get_pkg_version(loader);
- if (pkg_ver >= 0 && pkg_ver <= 2) {
- return chip_desc[pkg_ver];
+ public async getChipDescription(loader: ESPLoader) {
+ const chipDesc = ["ESP32-S2", "ESP32-S2FH16", "ESP32-S2FH32"];
+ const pkgVer = await this.getPkgVersion(loader);
+ if (pkgVer >= 0 && pkgVer <= 2) {
+ return chipDesc[pkgVer];
} else {
return "unknown ESP32-S2";
}
}
- public async get_chip_features(loader: ESPLoader) {
+ public async getChipFeatures(loader: ESPLoader) {
const features = ["Wi-Fi"];
- const pkg_ver = await this.get_pkg_version(loader);
- if (pkg_ver == 1) {
+ const pkgVer = await this.getPkgVersion(loader);
+ if (pkgVer == 1) {
features.push("Embedded 2MB Flash");
- } else if (pkg_ver == 2) {
+ } else if (pkgVer == 2) {
features.push("Embedded 4MB Flash");
}
- const num_word = 4;
- const block2_addr = this.EFUSE_BASE + 0x05c;
- const addr = block2_addr + 4 * num_word;
- const word4 = await loader.read_reg(addr);
- const block2_ver = (word4 >> 4) & 0x07;
+ const numWord = 4;
+ const block2Addr = this.EFUSE_BASE + 0x05c;
+ const addr = block2Addr + 4 * numWord;
+ const word4 = await loader.readReg(addr);
+ const block2Ver = (word4 >> 4) & 0x07;
- if (block2_ver == 1) {
+ if (block2Ver == 1) {
features.push("ADC and temperature sensor calibration in BLK2 of efuse");
}
return features;
}
- public async get_crystal_freq(loader: ESPLoader) {
+ public async getCrystalFreq(loader: ESPLoader) {
return 40;
}
public _d2h(d: number) {
const h = (+d).toString(16);
return h.length === 1 ? "0" + h : h;
}
- public async read_mac(loader: ESPLoader) {
- let mac0 = await loader.read_reg(this.MAC_EFUSE_REG);
+ public async readMac(loader: ESPLoader) {
+ let mac0 = await loader.readReg(this.MAC_EFUSE_REG);
mac0 = mac0 >>> 0;
- let mac1 = await loader.read_reg(this.MAC_EFUSE_REG + 4);
+ let mac1 = await loader.readReg(this.MAC_EFUSE_REG + 4);
mac1 = (mac1 >>> 0) & 0x0000ffff;
const mac = new Uint8Array(6);
mac[0] = (mac1 >> 8) & 0xff;
@@ -110,7 +110,7 @@ export class ESP32S2ROM extends ROM {
);
}
- public get_erase_size(offset: number, size: number) {
+ public getEraseSize(offset: number, size: number) {
return size;
}
}
diff --git a/src/targets/esp32s3.ts b/src/targets/esp32s3.ts
index 6e6b3d6..4749243 100644
--- a/src/targets/esp32s3.ts
+++ b/src/targets/esp32s3.ts
@@ -40,13 +40,13 @@ export class ESP32S3ROM extends ROM {
public ROM_DATA = ESP32S3_STUB.data;
public ROM_TEXT = ESP32S3_STUB.text;
- public async get_chip_description(loader: ESPLoader) {
+ public async getChipDescription(loader: ESPLoader) {
return "ESP32-S3";
}
- public async get_chip_features(loader: ESPLoader) {
+ public async getChipFeatures(loader: ESPLoader) {
return ["Wi-Fi", "BLE"];
}
- public async get_crystal_freq(loader: ESPLoader) {
+ public async getCrystalFreq(loader: ESPLoader) {
return 40;
}
public _d2h(d: number) {
@@ -54,18 +54,18 @@ export class ESP32S3ROM extends ROM {
return h.length === 1 ? "0" + h : h;
}
- public async _post_connect(loader: ESPLoader) {
- const buf_no = (await loader.read_reg(this.UARTDEV_BUF_NO)) & 0xff;
- loader.debug("In _post_connect " + buf_no);
- if (buf_no == this.UARTDEV_BUF_NO_USB) {
+ public async postConnect(loader: ESPLoader) {
+ const bufNo = (await loader.readReg(this.UARTDEV_BUF_NO)) & 0xff;
+ loader.debug("In _post_connect " + bufNo);
+ if (bufNo == this.UARTDEV_BUF_NO_USB) {
loader.ESP_RAM_BLOCK = this.USB_RAM_BLOCK;
}
}
- public async read_mac(loader: ESPLoader) {
- let mac0 = await loader.read_reg(this.MAC_EFUSE_REG);
+ public async readMac(loader: ESPLoader) {
+ let mac0 = await loader.readReg(this.MAC_EFUSE_REG);
mac0 = mac0 >>> 0;
- let mac1 = await loader.read_reg(this.MAC_EFUSE_REG + 4);
+ let mac1 = await loader.readReg(this.MAC_EFUSE_REG + 4);
mac1 = (mac1 >>> 0) & 0x0000ffff;
const mac = new Uint8Array(6);
mac[0] = (mac1 >> 8) & 0xff;
@@ -90,7 +90,7 @@ export class ESP32S3ROM extends ROM {
);
}
- public get_erase_size(offset: number, size: number) {
+ public getEraseSize(offset: number, size: number) {
return size;
}
}
diff --git a/src/targets/esp8266.ts b/src/targets/esp8266.ts
index 6f3389e..e446118 100644
--- a/src/targets/esp8266.ts
+++ b/src/targets/esp8266.ts
@@ -42,45 +42,45 @@ export class ESP8266ROM extends ROM {
public ROM_DATA = ESP8266_STUB.data;
public ROM_TEXT = ESP8266_STUB.text;
- public async read_efuse(loader: ESPLoader, offset: number) {
+ public async readEfuse(loader: ESPLoader, offset: number): Promise {
const addr = this.EFUSE_RD_REG_BASE + 4 * offset;
loader.debug("Read efuse " + addr);
- return await loader.read_reg(addr);
+ return await loader.readReg(addr);
}
- public async get_chip_description(loader: ESPLoader) {
- const efuse3 = await this.read_efuse(loader, 2);
- const efuse0 = await this.read_efuse(loader, 0);
+ public async getChipDescription(loader: ESPLoader) {
+ const efuse3 = await this.readEfuse(loader, 2);
+ const efuse0 = await this.readEfuse(loader, 0);
- const is_8285 = ((efuse0 & (1 << 4)) | (efuse3 & (1 << 16))) != 0; // One or the other efuse bit is set for ESP8285
- return is_8285 ? "ESP8285" : "ESP8266EX";
+ const is8285 = ((efuse0 & (1 << 4)) | (efuse3 & (1 << 16))) != 0; // One or the other efuse bit is set for ESP8285
+ return is8285 ? "ESP8285" : "ESP8266EX";
}
- public get_chip_features = async (loader: ESPLoader) => {
+ public getChipFeatures = async (loader: ESPLoader) => {
const features = ["WiFi"];
- if ((await this.get_chip_description(loader)) == "ESP8285") features.push("Embedded Flash");
+ if ((await this.getChipDescription(loader)) == "ESP8285") features.push("Embedded Flash");
return features;
};
- public async get_crystal_freq(loader: ESPLoader) {
- const uart_div = (await loader.read_reg(this.UART_CLKDIV_REG)) & this.UART_CLKDIV_MASK;
- const ets_xtal = (loader.transport.baudrate * uart_div) / 1000000 / this.XTAL_CLK_DIVIDER;
- let norm_xtal;
- if (ets_xtal > 33) {
- norm_xtal = 40;
+ public async getCrystalFreq(loader: ESPLoader) {
+ const uartDiv = (await loader.readReg(this.UART_CLKDIV_REG)) & this.UART_CLKDIV_MASK;
+ const etsXtal = (loader.transport.baudrate * uartDiv) / 1000000 / this.XTAL_CLK_DIVIDER;
+ let normXtal;
+ if (etsXtal > 33) {
+ normXtal = 40;
} else {
- norm_xtal = 26;
+ normXtal = 26;
}
- if (Math.abs(norm_xtal - ets_xtal) > 1) {
+ if (Math.abs(normXtal - etsXtal) > 1) {
loader.info(
"WARNING: Detected crystal freq " +
- ets_xtal +
+ etsXtal +
"MHz is quite different to normalized freq " +
- norm_xtal +
+ normXtal +
"MHz. Unsupported crystal in use?",
);
}
- return norm_xtal;
+ return normXtal;
}
public _d2h(d: number) {
@@ -88,12 +88,12 @@ export class ESP8266ROM extends ROM {
return h.length === 1 ? "0" + h : h;
}
- public async read_mac(loader: ESPLoader) {
- let mac0 = await this.read_efuse(loader, 0);
+ public async readMac(loader: ESPLoader) {
+ let mac0 = await this.readEfuse(loader, 0);
mac0 = mac0 >>> 0;
- let mac1 = await this.read_efuse(loader, 1);
+ let mac1 = await this.readEfuse(loader, 1);
mac1 = mac1 >>> 0;
- let mac3 = await this.read_efuse(loader, 3);
+ let mac3 = await this.readEfuse(loader, 3);
mac3 = mac3 >>> 0;
const mac = new Uint8Array(6);
@@ -132,7 +132,7 @@ export class ESP8266ROM extends ROM {
);
}
- public get_erase_size(offset: number, size: number) {
+ public getEraseSize(offset: number, size: number) {
return size;
}
}
diff --git a/src/targets/rom.ts b/src/targets/rom.ts
index b055ed3..2591b6b 100644
--- a/src/targets/rom.ts
+++ b/src/targets/rom.ts
@@ -1,25 +1,77 @@
import { ESPLoader } from "../esploader";
+/**
+ * Represents a chip ROM with basic registers field and abstract functions.
+ */
export abstract class ROM {
- // abstract read_efuse(loader: ESPLoader, offset: number): Promise; //esp32
+ /**
+ * Read ESP32 eFuse.
+ * @param {ESPLoader} loader - Loader class to communicate with chip.
+ * @param {number} offset - Offset to start erase.
+ * @returns {number} The eFuse number.
+ */
+ protected readEfuse?(loader: ESPLoader, offset: number): Promise;
- // abstract get_pkg_version(loader: ESPLoader): Promise; // not in esp32s3
+ /**
+ * Get the package version number.
+ * @param {ESPLoader} loader - Loader class to communicate with chip.
+ * @returns {number} The package version number.
+ */
+ protected getPkgVersion?(loader: ESPLoader): Promise;
- // abstract get_chip_revision(loader: ESPLoader): Promise; esp32
+ /**
+ * Get the chip revision number.
+ * @param {ESPLoader} loader - Loader class to communicate with chip.
+ * @returns {number} The chip revision number.
+ */
+ protected getChipRevision?(loader: ESPLoader): Promise;
- abstract get_chip_description(loader: ESPLoader): Promise;
-
- abstract get_chip_features(loader: ESPLoader): Promise;
-
- abstract get_crystal_freq(loader: ESPLoader): Promise;
+ /**
+ * Get the chip description.
+ * @param {ESPLoader} loader - Loader class to communicate with chip.
+ * @returns {string} The chip description as string.
+ */
+ abstract getChipDescription(loader: ESPLoader): Promise;
+ /**
+ * Get the chip features.
+ * @param {ESPLoader} loader - Loader class to communicate with chip.
+ * @returns {string} The chip features as string.
+ */
+ abstract getChipFeatures(loader: ESPLoader): Promise;
+ /**
+ * Get the crystal frequency for the chip.
+ * @param {ESPLoader} loader - Loader class to communicate with chip.
+ * @returns {string} The crystal frequency as number.
+ */
+ abstract getCrystalFreq(loader: ESPLoader): Promise;
+ /**
+ * Convert a number to hex string.
+ * @param {number} d - Number to convert to hex string.
+ * @returns {string} The hex string.
+ */
abstract _d2h(d: number): string;
- abstract read_mac(loader: ESPLoader): Promise;
+ /**
+ * Get the chip mac address.
+ * @param {ESPLoader} loader - Loader class to communicate with chip.
+ * @returns {string} The mac address string.
+ */
+ abstract readMac(loader: ESPLoader): Promise;
- _post_connect?(loader: ESPLoader): Promise;
+ /**
+ * Function to be executed after chip connection
+ * @param {ESPLoader} loader - Loader class to communicate with chip.
+ */
+ postConnect?(loader: ESPLoader): Promise;
- get_erase_size(offset: number, size: number) {
+ /**
+ * Get the chip erase size.
+ * @param {number} offset - Offset to start erase.
+ * @param {number} size - Size to erase.
+ * @returns {number} The erase size of the chip as number.
+ */
+ getEraseSize(offset: number, size: number): number {
return size;
}
diff --git a/src/webserial.ts b/src/webserial.ts
index acd5759..f4b16d7 100644
--- a/src/webserial.ts
+++ b/src/webserial.ts
@@ -1,77 +1,143 @@
+/* global SerialPort, ParityType, FlowControlType */
+
+/**
+ * Options for device serialPort.
+ * @interface SerialOptions
+ *
+ * Note: According to the documentation of the Web Serial API, 'baudRate' is a
+ * 'required' field as part of serial options. However, we are currently
+ * maintaining 'baudRate' as a separate parameter outside the options
+ * dictionary, and it is effectively used in the code. For now, we are
+ * keeping it optional in the dictionary to avoid conflicts.
+ */
export interface SerialOptions {
- /*
- Note: According to the documentation of the Web Serial API, 'baudRate' is a
- 'required' field as part of serial options. However, we are currently
- maintaining 'baudRate' as a separate parameter outside the options
- dictionary, and it is effectively used in the code. For now, we are
- keeping it optional in the dictionary to avoid conflicts.
- */
+ /**
+ * A positive, non-zero value indicating the baud rate at which serial communication should be established.
+ * @type {number | undefined}
+ */
baudRate?: number | undefined;
+
+ /**
+ * The number of data bits per frame. Either 7 or 8.
+ * @type {number | undefined}
+ */
dataBits?: number | undefined;
+
+ /**
+ * The number of stop bits at the end of a frame. Either 1 or 2.
+ * @type {number | undefined}
+ */
stopBits?: number | undefined;
+
+ /**
+ * The parity mode: none, even or odd
+ * @type {ParityType | undefined}
+ */
parity?: ParityType | undefined;
+
+ /**
+ * A positive, non-zero value indicating the size of the read and write buffers that should be created.
+ * @type {number | undefined}
+ */
bufferSize?: number | undefined;
+
+ /**
+ * The flow control mode: none or hardware.
+ * @type {FlowControlType | undefined}
+ */
flowControl?: FlowControlType | undefined;
}
+
+/**
+ * Wrapper class around Webserial API to communicate with the serial device.
+ * @param {typeof import("w3c-web-serial").SerialPort} device - Requested device prompted by the browser.
+ *
+ * ```
+ * const port = await navigator.serial.requestPort();
+ * ```
+ */
class Transport {
- public slip_reader_enabled = false;
- public left_over = new Uint8Array(0);
+ public slipReaderEnabled = false;
+ public leftOver = new Uint8Array(0);
public baudrate = 0;
constructor(public device: SerialPort) {}
- get_info() {
+ /**
+ * Request the serial device vendor ID and Product ID as string.
+ * @returns {string} Return the device VendorID and ProductID from SerialPortInfo as formatted string.
+ */
+ getInfo() {
const info = this.device.getInfo();
return info.usbVendorId && info.usbProductId
? `WebSerial VendorID 0x${info.usbVendorId.toString(16)} ProductID 0x${info.usbProductId.toString(16)}`
: "";
}
- get_pid() {
+ /**
+ * Request the serial device product id from SerialPortInfo.
+ * @returns {string} Return the product ID.
+ */
+ getPid() {
return this.device.getInfo().usbProductId;
}
- slip_writer(data: Uint8Array) {
- let count_esc = 0;
+ /**
+ * Format data packet using the Serial Line Internet Protocol (SLIP).
+ * @param {Uint8Array} data Binary unsigned 8 bit array data to format.
+ * @returns {Uint8Array} Formatted unsigned 8 bit data array.
+ */
+ slipWriter(data: Uint8Array) {
+ let countEsc = 0;
let i = 0,
j = 0;
for (i = 0; i < data.length; i++) {
if (data[i] === 0xc0 || data[i] === 0xdb) {
- count_esc++;
+ countEsc++;
}
}
- const out_data = new Uint8Array(2 + count_esc + data.length);
- out_data[0] = 0xc0;
+ const outData = new Uint8Array(2 + countEsc + data.length);
+ outData[0] = 0xc0;
j = 1;
for (i = 0; i < data.length; i++, j++) {
if (data[i] === 0xc0) {
- out_data[j++] = 0xdb;
- out_data[j] = 0xdc;
+ outData[j++] = 0xdb;
+ outData[j] = 0xdc;
continue;
}
if (data[i] === 0xdb) {
- out_data[j++] = 0xdb;
- out_data[j] = 0xdd;
+ outData[j++] = 0xdb;
+ outData[j] = 0xdd;
continue;
}
- out_data[j] = data[i];
+ outData[j] = data[i];
}
- out_data[j] = 0xc0;
- return out_data;
+ outData[j] = 0xc0;
+ return outData;
}
+ /**
+ * Write binary data to device using the WebSerial device writable stream.
+ * @param {Uint8Array} data 8 bit unsigned data array to write to device.
+ */
async write(data: Uint8Array) {
- const out_data = this.slip_writer(data);
+ const outData = this.slipWriter(data);
if (this.device.writable) {
const writer = this.device.writable.getWriter();
- await writer.write(out_data);
+ await writer.write(outData);
writer.releaseLock();
}
}
+ /**
+ * Concatenate buffer2 to buffer1 and return the resulting ArrayBuffer.
+ * @param {ArrayBuffer} buffer1 First buffer to concatenate.
+ * @param {ArrayBuffer} buffer2 Second buffer to concatenate.
+ * @returns {ArrayBuffer} Result Array buffer.
+ */
_appendBuffer(buffer1: ArrayBuffer, buffer2: ArrayBuffer) {
const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
tmp.set(new Uint8Array(buffer1), 0);
@@ -79,66 +145,76 @@ class Transport {
return tmp.buffer;
}
- /* this function expects complete packet (hence reader reads for atleast 8 bytes. This function is
- * stateless and returns the first wellformed packet only after replacing escape sequence */
- slip_reader(data: Uint8Array) {
+ /**
+ * Take a data array and return the first well formed packet after
+ * replacing the escape sequence. Reads at least 8 bytes.
+ * @param {Uint8Array} data Unsigned 8 bit array from the device read stream.
+ * @returns {Uint8Array} Formatted packet using SLIP escape sequences.
+ */
+ slipReader(data: Uint8Array) {
let i = 0;
- let data_start = 0,
- data_end = 0;
+ let dataStart = 0,
+ dataEnd = 0;
let state = "init";
while (i < data.length) {
if (state === "init" && data[i] == 0xc0) {
- data_start = i + 1;
+ dataStart = i + 1;
state = "valid_data";
i++;
continue;
}
if (state === "valid_data" && data[i] == 0xc0) {
- data_end = i - 1;
+ dataEnd = i - 1;
state = "packet_complete";
break;
}
i++;
}
if (state !== "packet_complete") {
- this.left_over = data;
+ this.leftOver = data;
return new Uint8Array(0);
}
- this.left_over = data.slice(data_end + 2);
- const temp_pkt = new Uint8Array(data_end - data_start + 1);
+ this.leftOver = data.slice(dataEnd + 2);
+ const tempPkt = new Uint8Array(dataEnd - dataStart + 1);
let j = 0;
- for (i = data_start; i <= data_end; i++, j++) {
+ for (i = dataStart; i <= dataEnd; i++, j++) {
if (data[i] === 0xdb && data[i + 1] === 0xdc) {
- temp_pkt[j] = 0xc0;
+ tempPkt[j] = 0xc0;
i++;
continue;
}
if (data[i] === 0xdb && data[i + 1] === 0xdd) {
- temp_pkt[j] = 0xdb;
+ tempPkt[j] = 0xdb;
i++;
continue;
}
- temp_pkt[j] = data[i];
+ tempPkt[j] = data[i];
}
- const packet = temp_pkt.slice(0, j); /* Remove unused bytes due to escape seq */
+ const packet = tempPkt.slice(0, j); /* Remove unused bytes due to escape seq */
return packet;
}
- async read(timeout = 0, min_data = 12) {
+ /**
+ * Read from serial device using the device ReadableStream.
+ * @param {number} timeout Read timeout number
+ * @param {number} minData Minimum packet array length
+ * @returns {Uint8Array} 8 bit unsigned data array read from device.
+ */
+ async read(timeout = 0, minData = 12) {
let t;
- let packet = this.left_over;
- this.left_over = new Uint8Array(0);
- if (this.slip_reader_enabled) {
- const val_final = this.slip_reader(packet);
- if (val_final.length > 0) {
- return val_final;
+ let packet = this.leftOver;
+ this.leftOver = new Uint8Array(0);
+ if (this.slipReaderEnabled) {
+ const valFinal = this.slipReader(packet);
+ if (valFinal.length > 0) {
+ return valFinal;
}
- packet = this.left_over;
- this.left_over = new Uint8Array(0);
+ packet = this.leftOver;
+ this.leftOver = new Uint8Array(0);
}
if (this.device.readable == null) {
- return this.left_over;
+ return this.leftOver;
}
const reader = this.device.readable.getReader();
@@ -151,32 +227,37 @@ class Transport {
do {
const { value, done } = await reader.read();
if (done) {
- this.left_over = packet;
+ this.leftOver = packet;
throw new Error("Timeout");
}
const p = new Uint8Array(this._appendBuffer(packet.buffer, value.buffer));
packet = p;
- } while (packet.length < min_data);
+ } while (packet.length < minData);
} finally {
if (timeout > 0) {
clearTimeout(t);
}
reader.releaseLock();
}
- if (this.slip_reader_enabled) {
- return this.slip_reader(packet);
+ if (this.slipReaderEnabled) {
+ return this.slipReader(packet);
}
return packet;
}
+ /**
+ * Read from serial device without slip formatting.
+ * @param {number} timeout Read timeout in milliseconds (ms)
+ * @returns {Uint8Array} 8 bit unsigned data array read from device.
+ */
async rawRead(timeout = 0) {
- if (this.left_over.length != 0) {
- const p = this.left_over;
- this.left_over = new Uint8Array(0);
+ if (this.leftOver.length != 0) {
+ const p = this.leftOver;
+ this.leftOver = new Uint8Array(0);
return p;
}
if (!this.device.readable) {
- return this.left_over;
+ return this.leftOver;
}
const reader = this.device.readable.getReader();
let t;
@@ -200,6 +281,11 @@ class Transport {
}
_DTR_state = false;
+ /**
+ * Send the RequestToSend (RTS) signal to given state
+ * # True for EN=LOW, chip in reset and False EN=HIGH, chip out of reset
+ * @param {boolean} state Boolean state to set the signal
+ */
async setRTS(state: boolean) {
await this.device.setSignals({ requestToSend: state });
// # Work-around for adapters on Windows using the usbser.sys driver:
@@ -209,11 +295,21 @@ class Transport {
await this.setDTR(this._DTR_state);
}
+ /**
+ * Send the dataTerminalReady (DTS) signal to given state
+ * # True for IO0=LOW, chip in reset and False IO0=HIGH
+ * @param {boolean} state Boolean state to set the signal
+ */
async setDTR(state: boolean) {
this._DTR_state = state;
await this.device.setSignals({ dataTerminalReady: state });
}
+ /**
+ * Connect to serial device using the Webserial open method.
+ * @param {number} baud Number baud rate for serial connection.
+ * @param {typeof import("w3c-web-serial").SerialOptions} serialOptions Serial Options for WebUSB SerialPort class.
+ */
async connect(baud = 115200, serialOptions: SerialOptions = {}) {
await this.device.open({
baudRate: baud,
@@ -224,13 +320,17 @@ class Transport {
flowControl: serialOptions?.flowControl,
});
this.baudrate = baud;
- this.left_over = new Uint8Array(0);
+ this.leftOver = new Uint8Array(0);
}
async sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
+ /**
+ * Wait for a given timeout ms for serial device unlock.
+ * @param {number} timeout Timeout time in milliseconds (ms) to sleep
+ */
async waitForUnlock(timeout: number) {
while (
(this.device.readable && this.device.readable.locked) ||
@@ -240,6 +340,9 @@ class Transport {
}
}
+ /**
+ * Disconnect from serial device by running SerialPort.close() after streams unlock.
+ */
async disconnect() {
await this.waitForUnlock(400);
await this.device.close();
diff --git a/tsconfig.json b/tsconfig.json
index ff66898..c6fc028 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -15,5 +15,9 @@
"resolveJsonModule": true,
"strict": true
},
+ "typedocOptions": {
+ "entryPoints": ["src/index.ts"],
+ "out": "docs"
+ },
"include": ["src/**/*"]
}