diff --git a/docz/docs/03-demos/02-frontend/19-bundler/05-webpack.md b/docz/docs/03-demos/02-frontend/19-bundler/05-webpack.md
index da8cc60..109f17f 100644
--- a/docz/docs/03-demos/02-frontend/19-bundler/05-webpack.md
+++ b/docz/docs/03-demos/02-frontend/19-bundler/05-webpack.md
@@ -41,10 +41,10 @@ This demo was tested in the following environments:
| Version | Date | Required Workarounds |
|:---------|:-----------|:------------------------------------|
-| `2.7.0` | 2023-10-17 | Import `xlsx/dist/xlsx.full.min.js` |
-| `3.12.0` | 2023-10-17 | Import `xlsx/dist/xlsx.full.min.js` |
-| `4.47.0` | 2023-10-17 | Downgrade NodeJS (tested v16.20.2) |
-| `5.89.0` | 2023-12-04 | |
+| `2.7.0` | 2024-03-16 | Import `xlsx/dist/xlsx.full.min.js` |
+| `3.12.0` | 2024-03-16 | Import `xlsx/dist/xlsx.full.min.js` |
+| `4.47.0` | 2024-03-16 | Downgrade NodeJS (tested v16.20.2) |
+| `5.90.3` | 2024-03-16 | |
:::
@@ -271,8 +271,13 @@ version above 4.0 can be pinned by locally installing webpack and the CLI tool.
:::info pass
-Webpack 4 is incompatible with Node 18+. When this demo was last tested, NodeJS
-was locally downgraded to 16.20.2
+Webpack 4 is incompatible with Node 18+. It will elicit the following error:
+
+```
+Error: error:0308010C:digital envelope routines::unsupported
+```
+
+When this demo was last tested, NodeJS was locally downgraded to 16.20.2
:::
diff --git a/docz/docs/03-demos/03-net/03-server/04-drash.md b/docz/docs/03-demos/03-net/03-server/04-drash.md
index 3b3fc40..be1c051 100644
--- a/docz/docs/03-demos/03-net/03-server/04-drash.md
+++ b/docz/docs/03-demos/03-net/03-server/04-drash.md
@@ -28,7 +28,7 @@ This demo was last tested on 2024 March 11 against Drash 2.8.1 and Deno 1.41.2.
## Integration Details
-The [SheetJS Deno module](/docs/getting-started/installation/nodejs) can be
+The [SheetJS Deno module](/docs/getting-started/installation/deno) can be
imported from Drash server scripts.
### Reading Data
diff --git a/docz/docs/03-demos/12-static/01-lume.md b/docz/docs/03-demos/12-static/01-lume.md
index 2bf6b58..4f0ab81 100644
--- a/docz/docs/03-demos/12-static/01-lume.md
+++ b/docz/docs/03-demos/12-static/01-lume.md
@@ -129,7 +129,12 @@ site.use(sheets({
:::note Tested Deployments
-This demo was last tested against Lume `v1.19.4` on 2023 December 04.
+This demo was tested in the following environments:
+
+| Lume | Date |
+|:---------|:-----------|
+| `1.19.4` | 2024-03-16 |
+| `2.1.2` | 2024-03-16 |
This example uses the Nunjucks template format. Lume plugins support additional
template formats, including Markdown and JSX.
@@ -145,17 +150,24 @@ template formats, including Markdown and JSX.
```bash
mkdir -p sheetjs-lume
cd sheetjs-lume
-deno run -Ar https://deno.land/x/lume/init.ts
+deno run -Ar https://deno.land/x/lume@v2.1.2/init.ts
```
When prompted, enter the following options:
- `Choose the configuration file format`: select `_config.ts`
- `Do you want to install some plugins now?`: select `Yes`
-- `Select the plugins to install`: scroll down, select `sheets`, and submit
+- `Select the plugins to install`: select `sheets` and `nunjucks`
+- `Do you want to setup a CMS?`: select `Maybe later`
The project will be configured and modules will be installed.
+:::note pass
+
+The `nunjucks` plugin was included by default in Lume version 1.
+
+:::
+
2) Download and place in a `_data` subfolder:
```bash
diff --git a/docz/docs/03-demos/19-desktop/01-electron.md b/docz/docs/03-demos/19-desktop/01-electron.md
index 5e96dd4..a011c76 100644
--- a/docz/docs/03-demos/19-desktop/01-electron.md
+++ b/docz/docs/03-demos/19-desktop/01-electron.md
@@ -1,7 +1,7 @@
---
title: Electron
pagination_prev: demos/mobile/index
-pagination_next: demos/data/index
+pagination_next: demos/cli/index
sidebar_position: 1
sidebar_custom_props:
summary: Embedded NodeJS + Chromium
diff --git a/docz/docs/03-demos/19-desktop/02-nwjs.md b/docz/docs/03-demos/19-desktop/02-nwjs.md
index 7eabd1f..ee37f3e 100644
--- a/docz/docs/03-demos/19-desktop/02-nwjs.md
+++ b/docz/docs/03-demos/19-desktop/02-nwjs.md
@@ -1,7 +1,7 @@
---
title: NW.js
pagination_prev: demos/mobile/index
-pagination_next: demos/data/index
+pagination_next: demos/cli/index
sidebar_position: 2
sidebar_custom_props:
summary: Embedded Chromium + NodeJS
diff --git a/docz/docs/03-demos/19-desktop/03-wails.md b/docz/docs/03-demos/19-desktop/03-wails.md
index 5f7a8ff..0927de3 100644
--- a/docz/docs/03-demos/19-desktop/03-wails.md
+++ b/docz/docs/03-demos/19-desktop/03-wails.md
@@ -3,7 +3,7 @@ title: Spreadsheet-Powered Wails Apps
sidebar_label: Wails
description: Build data-intensive desktop apps using Wails. Seamlessly integrate spreadsheets into your app using SheetJS. Modernize Excel-powered business processes with confidence.
pagination_prev: demos/mobile/index
-pagination_next: demos/data/index
+pagination_next: demos/cli/index
sidebar_position: 3
sidebar_custom_props:
summary: Webview + Go Backend
diff --git a/docz/docs/03-demos/19-desktop/04-tauri.md b/docz/docs/03-demos/19-desktop/04-tauri.md
index 4fbe5de..6a568f9 100644
--- a/docz/docs/03-demos/19-desktop/04-tauri.md
+++ b/docz/docs/03-demos/19-desktop/04-tauri.md
@@ -3,7 +3,7 @@ title: Data Wrangling in Tauri Apps
sidebar_label: Tauri
description: Build data-intensive desktop apps using Tauri. Seamlessly integrate spreadsheets into your app using SheetJS. Modernize Excel-powered business processes with confidence.
pagination_prev: demos/mobile/index
-pagination_next: demos/data/index
+pagination_next: demos/cli/index
sidebar_position: 4
sidebar_custom_props:
summary: Webview + Rust Backend
diff --git a/docz/docs/03-demos/19-desktop/05-neutralino.md b/docz/docs/03-demos/19-desktop/05-neutralino.md
index b6a09d9..0c494a2 100644
--- a/docz/docs/03-demos/19-desktop/05-neutralino.md
+++ b/docz/docs/03-demos/19-desktop/05-neutralino.md
@@ -3,7 +3,7 @@ title: Data Munging in NeutralinoJS
sidebar_label: NeutralinoJS
description: Build data-intensive desktop apps using NeutralinoJS. Seamlessly integrate spreadsheets into your app using SheetJS. Quickly modernize Excel-powered business processes.
pagination_prev: demos/mobile/index
-pagination_next: demos/data/index
+pagination_next: demos/cli/index
sidebar_position: 5
sidebar_custom_props:
summary: Webview + Lightweight Extensions
diff --git a/docz/docs/03-demos/19-desktop/06-reactnative.md b/docz/docs/03-demos/19-desktop/06-reactnative.md
index 296d55f..047eb9b 100644
--- a/docz/docs/03-demos/19-desktop/06-reactnative.md
+++ b/docz/docs/03-demos/19-desktop/06-reactnative.md
@@ -3,7 +3,7 @@ title: Sheets on the Desktop with React Native
sidebar_label: React Native
description: Build data-intensive desktop apps with React Native. Seamlessly integrate spreadsheets into your app using SheetJS. Securely process and generate Excel files at the desk.
pagination_prev: demos/mobile/index
-pagination_next: demos/data/index
+pagination_next: demos/cli/index
sidebar_position: 6
sidebar_custom_props:
summary: Native Components with React
diff --git a/docz/docs/03-demos/19-desktop/_category_.json b/docz/docs/03-demos/19-desktop/_category_.json
index a78039b..b85604e 100644
--- a/docz/docs/03-demos/19-desktop/_category_.json
+++ b/docz/docs/03-demos/19-desktop/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "Desktop and CLI Tools",
+ "label": "Desktop Apps",
"position": 19
}
diff --git a/docz/docs/03-demos/19-desktop/index.md b/docz/docs/03-demos/19-desktop/index.md
index 801382c..f61da32 100644
--- a/docz/docs/03-demos/19-desktop/index.md
+++ b/docz/docs/03-demos/19-desktop/index.md
@@ -1,7 +1,7 @@
---
-title: Desktop and CLI Tools
+title: Desktop Applications
pagination_prev: demos/mobile/index
-pagination_next: demos/data/index
+pagination_next: demos/cli/index
---
import DocCardList from '@theme/DocCardList';
@@ -40,16 +40,4 @@ Frameworks like React Native generate applications that use native UI elements.
## Command-Line Tools
-Command-line tools bundle a JavaScript engine and a system runtime. The runtime
-provides low-level access to computer resources.
-
-Demos for common command-line tools are included in separate pages:
-
-
+**[The exposition has been moved to a separate page.](/docs/demos/cli)**
diff --git a/docz/docs/03-demos/20-cli/09-nodesea.md b/docz/docs/03-demos/20-cli/09-nodesea.md
new file mode 100644
index 0000000..9421471
--- /dev/null
+++ b/docz/docs/03-demos/20-cli/09-nodesea.md
@@ -0,0 +1,346 @@
+---
+title: NodeJS SEA
+pagination_prev: demos/desktop/index
+pagination_next: demos/data/index
+sidebar_custom_props:
+ summary: Single Executable Applications
+---
+
+import current from '/version.js';
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+import CodeBlock from '@theme/CodeBlock';
+
+NodeJS "Single Executable Applications"[^1] are standalone CLI tools that embed
+bundled scripts in a special standalone copy of the NodeJS binary.
+
+[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
+data from spreadsheets.
+
+This demo uses NodeJS SEA and SheetJS to create a standalone CLI tool for
+parsing spreadsheets and generating CSV rows.
+
+:::info pass
+
+It is strongly recommended to install NodeJS on systems using SheetJS libraries
+in command-line tools. This workaround should only be considered if a standalone
+binary is considered desirable.
+
+:::
+
+:::caution NodeJS SEA support is considered experimental.
+
+Great open source software grows with user tests and reports. Any issues should
+be reported to the NodeJS single-executable project for further diagnosis.
+
+:::
+
+## Integration Details
+
+The [SheetJS NodeJS module](/docs/getting-started/installation/nodejs) can be
+required from NodeJS SEA base scripts.
+
+:::info pass
+
+**NodeJS SEA does not support ECMAScript Modules!**
+
+A CommonJS script is conveniently included in the SheetJS NodeJS module package.
+
+:::
+
+At a high level, single-executable applications are constructed in four steps:
+
+1) Pre-process an existing NodeJS script, creating a SEA bundle.
+
+2) Copy the NodeJS binary and remove any signatures.
+
+3) Inject the SEA bundle into the unsigned NodeJS binary.
+
+4) Re-sign the binary.
+
+:::note pass
+
+macOS and Windows enforce digital signatures. Both operating systems will warn
+users if a signed program is modified.
+
+Existing signatures should be removed *before* injecting the SEA bundle. After
+injecting the SEA bundle, the binary should be resigned.
+
+:::
+
+### Script Requirements
+
+Scripts that exclusively use SheetJS libraries and NodeJS built-in modules can
+be bundled using NodeJS SEA. Due to limitations in the SEA bundler, a special
+`require` function must be created manually:
+
+```js
+const { createRequire } = require('node:module');
+require = createRequire(__filename);
+const { readFile, utils } = require("xlsx");
+```
+
+For example, the following script accepts one command line argument, parses the
+specified file using the SheetJS `readFile` method[^2], generates CSV text from
+the first worksheet using `sheet_to_csv`[^3], and prints to terminal:
+
+```js title="sheet2csv.js"
+// For NodeJS SEA, the CommonJS `require` must be used
+const { createRequire } = require('node:module');
+require = createRequire(__filename);
+const { readFile, utils } = require("xlsx");
+
+// argv[2] is the first argument to the script
+const filename = process.argv[2];
+
+// read file
+const wb = readFile(filename);
+
+// generate CSV of first sheet
+const ws = wb.Sheets[wb.SheetNames[0]];
+const csv = utils.sheet_to_csv(ws);
+
+// print to terminal
+console.log(csv);
+```
+
+### SEA Bundles
+
+SEA Bundles are blobs that represent the script and supporting libraries.
+
+#### Configuration
+
+SEA configuration is specified using a special JSON file. Assuming no special
+assets are bundled with the script, there are two relevant fields:
+
+- `main` is a relative path to the entry script.
+- `output` is a relative path to the output file (typically ending in `.blob`)
+
+For example, the following configuration specifies `sheet2csv.js` as the entry
+script and `sheet2csv.blob` as the output blob:
+
+```js title="sheet2csv.json"
+{
+ "main": "sheet2csv.js",
+ "output": "sheet2csv.blob"
+}
+```
+
+#### Construction
+
+The main `node` program, with the command-line flag `--experimental-sea-config`,
+will generate a SEA bundle:
+
+```bash
+node --experimental-sea-config sheet2csv.json
+```
+
+The bundle will be written to the file specified in the `output` field of the
+SEA configuration file.
+
+#### Injection
+
+A special `postject` utility is used to add the SEA bundle to the NodeJS binary.
+The specific command depends on the operating system.
+
+On macOS, assuming the copy of the NodeJS binary is named `sheet2csv` and the
+SEA bundle is named `sheet2csv.blob`, the following command injects the bundle:
+
+```bash
+npx -y postject --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 --macho-segment-name NODE_SEA sheet2csv NODE_SEA_BLOB sheet2csv.blob
+```
+
+## Complete Example
+
+:::note Tested Deployments
+
+This demo was tested in the following deployments:
+
+| Architecture | NodeJS | Date |
+|:-------------|:----------|:-----------|
+| `darwin-x64` | `20.11.1` | 2024-03-17 |
+| `linux-x64` | `20.11.1` | 2024-03-18 |
+
+:::
+
+0) Ensure NodeJS version 20 or later is installed.
+
+:::note pass
+
+To display the current version, run the following command:
+
+```bash
+node --version
+```
+
+The major version number starts after the `v` and ends before the first `.`
+
+If the version number is 19 or earlier, upgrade NodeJS before proceeding.
+
+:::
+
+### Project Setup
+
+1) Create a new project folder:
+
+```bash
+mkdir sheetjs-sea
+cd sheetjs-sea
+npm init -y
+```
+
+2) Save the [contents of the `sheet2csv.js` code block](#script-requirements)
+to `sheet2csv.js` in the project folder.
+
+3) Install the SheetJS dependency:
+
+
+
+{`\
+npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
+
+
+
+{`\
+pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
+
+
+
+{`\
+yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
+
+
+
+
+### Script Test
+
+:::caution pass
+
+Before building the standalone app, the base script should be tested using the
+local NodeJS platform.
+
+:::
+
+4) Download the test file :
+
+```bash
+curl -LO https://sheetjs.com/pres.numbers
+```
+
+5) Run the script and pass `pres.numbers` as the first argument:
+
+```bash
+node sheet2csv.js pres.numbers
+```
+
+The script should display CSV contents from the first sheet:
+
+```
+Name,Index
+Bill Clinton,42
+GeorgeW Bush,43
+Barack Obama,44
+Donald Trump,45
+Joseph Biden,46
+```
+
+### SEA Bundle
+
+6) Save the [contents of the `sheet2csv.json` code block](#configuration) to
+`sheet2csv.json` in the project folder.
+
+7) Generate the SEA bundle:
+
+```bash
+node --experimental-sea-config sheet2csv.json
+```
+
+### SEA Injection
+
+8) Create a local copy of the NodeJS binary. On macOS and Linux:
+
+```bash
+cp `which node` sheet2csv
+```
+
+
+
+
+9) Remove the code signature.
+
+```bash
+codesign --remove-signature ./sheet2csv
+```
+
+
+
+
+9) Observe that many Linux distributions do not enforce code signatures.
+
+
+
+
+10) Inject the SEA bundle.
+
+
+
+
+```bash
+npx -y postject --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 --macho-segment-name NODE_SEA sheet2csv NODE_SEA_BLOB sheet2csv.blob
+```
+
+11) Resign the binary. The following command performs macOS ad-hoc signing:
+
+```bash
+codesign -s - ./sheet2csv
+```
+
+
+
+
+```bash
+npx -y postject --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 sheet2csv NODE_SEA_BLOB sheet2csv.blob
+```
+
+11) Observe that many Linux distributions do not enforce code signatures.
+
+
+
+
+
+### Standalone Test
+
+12) Run the command and pass `pres.numbers` as the first argument:
+
+```bash
+./sheet2csv pres.numbers
+```
+
+The program should display the same CSV contents as the script (from step 5)
+
+
+
+
+13) Validate the binary signature. On macOS:
+
+```bash
+codesign -dv ./sheet2csv
+```
+
+Inspecting the output, the following line confirms ad-hoc signing was used:
+
+```
+Signature=adhoc
+```
+
+
+
+
+13) Observe that many Linux distributions do not enforce code signatures.
+
+
+
+
+[^1]: See ["Single Executable Applications"](https://nodejs.org/api/single-executable-applications.html) in the NodeJS documentation.
+[^2]: See [`readFile` in "Reading Files"](/docs/api/parse-options)
+[^3]: See [`sheet_to_csv` in "CSV and Text"](/docs/api/utilities/csv#delimiter-separated-output)
diff --git a/docz/docs/03-demos/20-cli/23-deno.md b/docz/docs/03-demos/20-cli/23-deno.md
new file mode 100644
index 0000000..179edca
--- /dev/null
+++ b/docz/docs/03-demos/20-cli/23-deno.md
@@ -0,0 +1,151 @@
+---
+title: Deno Compiler
+pagination_prev: demos/desktop/index
+pagination_next: demos/data/index
+sidebar_custom_props:
+ summary: Deno Standalone Binaries
+---
+
+import current from '/version.js';
+import CodeBlock from '@theme/CodeBlock';
+
+[Deno](https://docs.deno.com/runtime/manual/tools/compiler) is a JavaScript
+runtime with support for compiling scripts into self-contained executables.
+
+[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
+data from spreadsheets.
+
+This demo uses the Deno compiler and SheetJS to create a standalone CLI tool for
+parsing spreadsheets and generating CSV rows.
+
+:::info pass
+
+It is strongly recommended to install Deno on systems using SheetJS libraries in
+command-line tools. This workaround should only be considered if a standalone
+binary is considered desirable.
+
+:::
+
+:::caution Deno support is considered experimental.
+
+Great open source software grows with user tests and reports. Any issues should
+be reported to the Deno project for further diagnosis.
+
+:::
+
+## Integration Details
+
+The [SheetJS Deno module](/docs/getting-started/installation/deno) can be
+imported from Deno scripts.
+
+`deno compile` generates a standalone executable that includes the entire JS
+runtime as well as user JS code.
+
+### Script Requirements
+
+Scripts that exclusively use SheetJS libraries and Deno built-in modules can be
+bundled using `deno compile`. The ESM script should be imported directly:
+
+{`\
+// @deno-types="https://cdn.sheetjs.com/xlsx-${current}/package/types/index.d.ts"
+import * as XLSX from 'https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs';`}
+
+
+For example, the following script accepts one command line argument, parses the
+specified file using the SheetJS `readFile` method[^1], generates CSV text from
+the first worksheet using `sheet_to_csv`[^2], and prints to terminal:
+
+{`\
+// @deno-types="https://cdn.sheetjs.com/xlsx-${current}/package/types/index.d.ts"
+import * as XLSX from 'https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs';
+import * as cptable from 'https://cdn.sheetjs.com/xlsx-${current}/package/dist/cpexcel.full.mjs';
+XLSX.set_cptable(cptable);
+\n\
+/* Deno.args[0] is the first argument to the script */
+const filename = Deno.args[0];
+\n\
+/* read file */
+const wb = XLSX.readFile(filename);
+\n\
+/* generate CSV of first sheet */
+const ws = wb.Sheets[wb.SheetNames[0]];
+const csv = utils.sheet_to_csv(ws);
+\n\
+/* print to terminal */
+console.log(csv);`}
+
+
+### Deno Permissions
+
+The same permissions that apply to normal Deno scripts apply to the compiler:
+
+- The `--allow-read` option must be specified to allow the program to read files
+ from the filesystem with the SheetJS `readFile` [^3] method.
+
+- The `--allow-write` option must be specified to allow the program to write
+ files to the filesystem with the SheetJS `writeFile` [^4] method.
+
+- The `--allow-net` option must be specified to allow the program to download
+ and upload spreadsheets.
+
+More flags can be found in the official permissions list[^5]
+
+
+## Complete Example
+
+:::note Tested Deployments
+
+This demo was last tested in the following deployments:
+
+| Architecture | Deno | Date |
+|:-------------|:---------|:-----------|
+| `darwin-x64` | `1.41.3` | 2024-03-15 |
+| `darwin-arm` | `1.37.2` | 2023-10-18 |
+| `win10-x64` | `1.37.1` | 2023-10-09 |
+| `win11-x64` | `1.37.2` | 2023-10-14 |
+| `win11-arm` | `1.38.4` | 2023-12-01 |
+| `linux-x64` | `1.41.3` | 2024-03-18 |
+| `linux-arm` | `1.38.4` | 2023-12-01 |
+
+:::
+
+0) Install Deno.[^6]
+
+1) Download the test file :
+
+```bash
+curl -LO https://sheetjs.com/pres.numbers
+```
+
+2) Test the script with `deno run`:
+
+```bash
+deno run -r --allow-read https://docs.sheetjs.com/cli/sheet2csv.ts pres.numbers
+```
+
+The script should display CSV contents from the first sheet:
+
+```
+Name,Index
+Bill Clinton,42
+GeorgeW Bush,43
+Barack Obama,44
+Donald Trump,45
+Joseph Biden,46
+```
+
+3) Compile and run `sheet2csv`:
+
+```bash
+deno compile -r --allow-read https://docs.sheetjs.com/cli/sheet2csv.ts
+./sheet2csv pres.numbers
+```
+
+The program should display the same CSV contents as the script (from step 2)
+
+[^1]: See [`readFile` in "Reading Files"](/docs/api/parse-options)
+[^2]: See [`sheet_to_csv` in "CSV and Text"](/docs/api/utilities/csv#delimiter-separated-output)
+[^3]: See [`readFile` in "Reading Files"](/docs/api/parse-options)
+[^4]: See [`writeFile` in "Writing Files"](/docs/api/write-options)
+[^5]: See ["Permissions list"](https://docs.deno.com/runtime/manual/basics/permissions#permissions-list) in the official Deno documentation
+[^6]: [The official instructions](https://docs.deno.com/runtime/manual/getting_started/installation) cover most platforms. Deno does not provide official Linux ARM64 builds, but [there are unofficial community builds](https://github.com/LukeChannings/deno-arm64).
\ No newline at end of file
diff --git a/docz/docs/03-demos/20-cli/_category_.json b/docz/docs/03-demos/20-cli/_category_.json
new file mode 100644
index 0000000..e90f116
--- /dev/null
+++ b/docz/docs/03-demos/20-cli/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "Command-Line Tools",
+ "position": 20
+}
diff --git a/docz/docs/03-demos/19-desktop/09-cli.md b/docz/docs/03-demos/20-cli/index.md
similarity index 84%
rename from docz/docs/03-demos/19-desktop/09-cli.md
rename to docz/docs/03-demos/20-cli/index.md
index 9dee21c..86ec1a2 100644
--- a/docz/docs/03-demos/19-desktop/09-cli.md
+++ b/docz/docs/03-demos/20-cli/index.md
@@ -1,21 +1,47 @@
---
title: Command-Line Tools
-pagination_prev: demos/mobile/index
+pagination_prev: demos/desktop/index
pagination_next: demos/data/index
-sidebar_custom_props:
- cli: true
---
import current from '/version.js';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import CodeBlock from '@theme/CodeBlock';
+import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
With the availability of JS engines and the success of server-side platforms,
-it is feasible to build command-line tools for various workflows.
+it is possible to build standalone command-line tools from JavaScript code.
-This demo covers a number of strategies for building standalone processors. The
-goal is to generate CSV output from an arbitrary spreadsheet file.
+[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
+data from spreadsheets.
+
+This demo covers a number of strategies for building standalone spreadsheet
+processors. The ultimate goal is to use SheetJS libraries to generate CSV output
+from arbitrary spreadsheet files. The generated command-line tool will accept an
+argument, parse the specified workbook, and print CSV rows to the terminal.
+
+>**Sample terminal session**
+```bash
+$ xlsx-cli.exe pres.numbers
+Name,Index
+Bill Clinton,42
+GeorgeW Bush,43
+Barack Obama,44
+Donald Trump,45
+Joseph Biden,46
+```
+
+Demos for common standalone CLI tools are included in separate pages:
+
+
:::tip pass
@@ -25,6 +51,18 @@ translating files between supported spreadsheet file formats.
:::
+:::caution pass
+
+For most common deployment scenarios, it is possible to install a server-side
+platform such as [NodeJS](/docs/getting-started/installation/nodejs).
+
+**It is strongly recommended to use a dedicated platform when possible.**
+
+The standalone programs generated in this demo are useful when a dedicated
+server-side scripting platform cannot be installed on the target computer.
+
+:::
+
## NodeJS
There are a few popular tools for compiling NodeJS scripts to CLI programs.
@@ -309,7 +347,7 @@ This demo was last tested in the following deployments:
| `darwin-arm` | `11.8.172.13` | `0.79.2` | 2023-10-18 |
| `win10-x64` | `11.8.172.13` | `0.79.2` | 2023-10-09 |
| `win11-x64` | `11.8.172.13` | `0.79.2` | 2023-10-14 |
-| `linux-x64` | `12.0.267.8` | `0.83.1` | 2024-01-26 |
+| `linux-x64` | `12.3.219.9` | `0.88.0` | 2024-03-18 |
| `linux-arm` | `12.0.267.8` | `0.82.0` | 2023-12-01 |
:::
@@ -400,54 +438,9 @@ mv target/release/sheet2csv.exe .
-## Deno
+#### Deno
-`deno compile` generates a standalone executable that includes the entire JS
-runtime as well as user JS code.
-
-When compiling, the `--allow-read` option must be specified to allow the script
-to read files from the filesystem with `Deno.readFileSync`.
-
- can be compiled and run from Deno.
-
-:::note Tested Deployments
-
-This demo was last tested in the following deployments:
-
-| Architecture | Version | Date |
-|:-------------|:---------|:-----------|
-| `darwin-x64` | `1.41.3` | 2024-03-15 |
-| `darwin-arm` | `1.37.2` | 2023-10-18 |
-| `win10-x64` | `1.37.1` | 2023-10-09 |
-| `win11-x64` | `1.37.2` | 2023-10-14 |
-| `win11-arm` | `1.38.4` | 2023-12-01 |
-| `linux-x64` | `1.39.4` | 2024-01-22 |
-| `linux-arm` | `1.38.4` | 2023-12-01 |
-
-:::
-
-0) Install Deno.[^2]
-
-1) Download the test file :
-
-```bash
-curl -LO https://sheetjs.com/pres.numbers
-```
-
-2) Test the script with `deno run`:
-
-```bash
-deno run -r --allow-read https://docs.sheetjs.com/cli/sheet2csv.ts pres.numbers
-```
-
-If this worked, the program will print a CSV of the first worksheet.
-
-3) Compile and run `sheet2csv`:
-
-```bash
-deno compile -r --allow-read https://docs.sheetjs.com/cli/sheet2csv.ts
-./sheet2csv pres.numbers
-```
+**[The exposition has been moved to a separate page.](/docs/demos/cli/deno)**
## Dedicated Engines
@@ -459,5 +452,4 @@ The following demos for JS engines produce standalone programs:
- [Goja](/docs/demos/engines/goja)
- [JavaScriptCore](/docs/demos/engines/jsc)
-[^1]: Downloads can be found [at the main NASM project website](https://www.nasm.us/)
-[^2]: [The official instructions](https://docs.deno.com/runtime/manual/getting_started/installation) cover most platforms. Deno does not provide official Linux ARM64 builds, but [there are unofficial community builds](https://github.com/LukeChannings/deno-arm64).
\ No newline at end of file
+[^1]: Downloads can be found [at the main NASM project website](https://www.nasm.us/)
\ No newline at end of file
diff --git a/docz/docs/03-demos/23-data/10-sql.md b/docz/docs/03-demos/23-data/10-sql.md
index 958d2ff..00de992 100644
--- a/docz/docs/03-demos/23-data/10-sql.md
+++ b/docz/docs/03-demos/23-data/10-sql.md
@@ -1,6 +1,6 @@
---
title: SQL Connectors
-pagination_prev: demos/desktop/index
+pagination_prev: demos/cli/index
pagination_next: demos/local/index
sidebar_custom_props:
sql: true
diff --git a/docz/docs/03-demos/23-data/11-sqlite.md b/docz/docs/03-demos/23-data/11-sqlite.md
index 2761943..d6d4207 100644
--- a/docz/docs/03-demos/23-data/11-sqlite.md
+++ b/docz/docs/03-demos/23-data/11-sqlite.md
@@ -1,7 +1,7 @@
---
title: Sheets with SQLite
sidebar_label: SQLite
-pagination_prev: demos/desktop/index
+pagination_prev: demos/cli/index
pagination_next: demos/local/index
sidebar_custom_props:
sql: true
diff --git a/docz/docs/03-demos/23-data/14-knex.md b/docz/docs/03-demos/23-data/14-knex.md
index 9c4b9f9..cb11f28 100644
--- a/docz/docs/03-demos/23-data/14-knex.md
+++ b/docz/docs/03-demos/23-data/14-knex.md
@@ -1,6 +1,6 @@
---
title: Knex SQL Builder
-pagination_prev: demos/desktop/index
+pagination_prev: demos/cli/index
pagination_next: demos/local/index
sidebar_custom_props:
sql: true
diff --git a/docz/docs/03-demos/23-data/16-postgresql.md b/docz/docs/03-demos/23-data/16-postgresql.md
index fbae1a6..d15a6e4 100644
--- a/docz/docs/03-demos/23-data/16-postgresql.md
+++ b/docz/docs/03-demos/23-data/16-postgresql.md
@@ -1,7 +1,7 @@
---
title: Sheets with PostgreSQL
sidebar_label: PostgreSQL
-pagination_prev: demos/desktop/index
+pagination_prev: demos/cli/index
pagination_next: demos/local/index
sidebar_custom_props:
sql: true
diff --git a/docz/docs/03-demos/23-data/17-mariadb.md b/docz/docs/03-demos/23-data/17-mariadb.md
index 6bf631d..a59e60c 100644
--- a/docz/docs/03-demos/23-data/17-mariadb.md
+++ b/docz/docs/03-demos/23-data/17-mariadb.md
@@ -1,7 +1,7 @@
---
title: Sheets with MariaDB and MySQL
sidebar_label: MariaDB / MySQL
-pagination_prev: demos/desktop/index
+pagination_prev: demos/cli/index
pagination_next: demos/local/index
sidebar_custom_props:
sql: true
diff --git a/docz/docs/03-demos/23-data/19-alasql.md b/docz/docs/03-demos/23-data/19-alasql.md
index 56dda08..3d8d66e 100644
--- a/docz/docs/03-demos/23-data/19-alasql.md
+++ b/docz/docs/03-demos/23-data/19-alasql.md
@@ -1,7 +1,7 @@
---
title: Sheets with AlaSQL
sidebar_label: AlaSQL
-pagination_prev: demos/desktop/index
+pagination_prev: demos/cli/index
pagination_next: demos/local/index
sidebar_custom_props:
sql: true
diff --git a/docz/docs/03-demos/23-data/25-mongodb.md b/docz/docs/03-demos/23-data/25-mongodb.md
index 6a62928..b43bc1f 100644
--- a/docz/docs/03-demos/23-data/25-mongodb.md
+++ b/docz/docs/03-demos/23-data/25-mongodb.md
@@ -1,7 +1,7 @@
---
title: Sheets with MongoDB
sidebar_label: MongoDB
-pagination_prev: demos/desktop/index
+pagination_prev: demos/cli/index
pagination_next: demos/local/index
sidebar_custom_props:
type: document
diff --git a/docz/docs/03-demos/23-data/26-redis.md b/docz/docs/03-demos/23-data/26-redis.md
index 5ba4edb..bf71c57 100644
--- a/docz/docs/03-demos/23-data/26-redis.md
+++ b/docz/docs/03-demos/23-data/26-redis.md
@@ -2,7 +2,7 @@
title: Redis Databases Wrapped in Sheets
sidebar_label: Redis
description: Store complex datasets in Redis. Seamlessly save data to spreadsheets and read data from sheets using SheetJS. Enable Excel spreadsheet experts to update content.
-pagination_prev: demos/desktop/index
+pagination_prev: demos/cli/index
pagination_next: demos/local/index
sidebar_custom_props:
type: nosql
diff --git a/docz/docs/03-demos/23-data/29-pouchdb.md b/docz/docs/03-demos/23-data/29-pouchdb.md
index 472906f..7884c46 100644
--- a/docz/docs/03-demos/23-data/29-pouchdb.md
+++ b/docz/docs/03-demos/23-data/29-pouchdb.md
@@ -1,7 +1,7 @@
---
title: Sheets in PouchDB
sidebar_label: PouchDB
-pagination_prev: demos/desktop/index
+pagination_prev: demos/cli/index
pagination_next: demos/local/index
sidebar_custom_props:
type: nosql
diff --git a/docz/docs/03-demos/23-data/index.md b/docz/docs/03-demos/23-data/index.md
index d55842f..011f0de 100644
--- a/docz/docs/03-demos/23-data/index.md
+++ b/docz/docs/03-demos/23-data/index.md
@@ -1,6 +1,6 @@
---
title: Databases and Stores
-pagination_prev: demos/desktop/index
+pagination_prev: demos/cli/index
pagination_next: demos/local/index
---
diff --git a/docz/docs/03-demos/27-local/01-file.md b/docz/docs/03-demos/27-local/01-file.md
index 6d04a9f..1e090e6 100644
--- a/docz/docs/03-demos/27-local/01-file.md
+++ b/docz/docs/03-demos/27-local/01-file.md
@@ -28,7 +28,8 @@ Some snippets are also available in the "Common Use Cases" section:
Other demos cover APIs for local file access on special platforms:
- ["iOS and Android Apps"](/docs/demos/mobile/) covers mobile app frameworks
-- ["Desktop and CLI Tools"](/docs/demos/desktop/) covers desktop apps and CLIs
+- ["Desktop Apps"](/docs/demos/desktop/) covers desktop apps
+- ["Command-Line Tools"](/docs/demos/cli) covers standalone command-line tools
:::
diff --git a/docz/docs/03-demos/30-cloud/19-deno.md b/docz/docs/03-demos/30-cloud/19-deno.md
index cab3826..3984d65 100644
--- a/docz/docs/03-demos/30-cloud/19-deno.md
+++ b/docz/docs/03-demos/30-cloud/19-deno.md
@@ -33,7 +33,7 @@ This demo was last tested by SheetJS users on 2023 October 18.
## Integration Details
-The [SheetJS Deno module](/docs/getting-started/installation/nodejs) can be
+The [SheetJS Deno module](/docs/getting-started/installation/deno) can be
imported from Deno Deploy server scripts.
### Supported Frameworks
diff --git a/docz/docs/03-demos/32-extensions/09-mathematica.md b/docz/docs/03-demos/32-extensions/09-mathematica.md
index 8043d16..7e517b7 100644
--- a/docz/docs/03-demos/32-extensions/09-mathematica.md
+++ b/docz/docs/03-demos/32-extensions/09-mathematica.md
@@ -197,7 +197,7 @@ SheetJSImportFileEE["pres.numbers"]
### Command-Line Tools
-The ["Command-Line Tools" demo](/docs/demos/desktop/cli) creates `xlsx-cli`, a
+The ["Command-Line Tools" demo](/docs/demos/cli) creates `xlsx-cli`, a
command-line tool that reads a spreadsheet file and generates CSV rows from the
first worksheet.
@@ -354,5 +354,5 @@ data = SheetJSImportURL["https://sheetjs.com/pres.numbers"]
[^11]: See [`ImportString`](https://reference.wolfram.com/language/ref/ImportString.html) in the Mathematica documentation.
[^12]: A [`Dataset`](https://reference.wolfram.com/language/ref/Dataset.html) will be created when using the [`"Dataset"` element in `ImportString`](https://reference.wolfram.com/language/ref/format/CSV.html)
[^13]: See [`HeaderLines`](https://reference.wolfram.com/language/ref/HeaderLines.html) in the Mathematica documentation.
-[^14]: See ["Command-line Tools"](/docs/demos/desktop/cli) for more details.
+[^14]: See ["Command-line Tools"](/docs/demos/cli) for more details.
[^15]: Mathematica 11 introduced new methods including [`URLRead`](https://reference.wolfram.com/language/ref/URLRead.html).
\ No newline at end of file
diff --git a/docz/docs/03-demos/32-extensions/11-matlab.md b/docz/docs/03-demos/32-extensions/11-matlab.md
index f036331..6b1d951 100644
--- a/docz/docs/03-demos/32-extensions/11-matlab.md
+++ b/docz/docs/03-demos/32-extensions/11-matlab.md
@@ -55,7 +55,7 @@ loaded in NodeJS scripts and bundled in standalone command-line tools.
### Command-Line Tools
-The ["Command-Line Tools" demo](/docs/demos/desktop/cli) creates `xlsx-cli`, a
+The ["Command-Line Tools" demo](/docs/demos/cli) creates `xlsx-cli`, a
command-line tool that reads a spreadsheet file and generates output. The
examples in the "NodeJS" section are able to generate XLSX spreadsheets using
the `--xlsx` command line flag:
@@ -265,5 +265,5 @@ matlab -batch SheetJSMATLAB
[^4]: See [`writeFile` in "Writing Files"](/docs/api/write-options)
[^5]: See [`system`](https://www.mathworks.com/help/matlab/ref/system.html) in the MATLAB documentation.
[^6]: See ["MATLAB Operators and Special Characters](https://www.mathworks.com/help/matlab/matlab_prog/matlab-operators-and-special-characters.html) in the MATLAB documentation.
-[^7]: See ["Command-line Tools"](/docs/demos/desktop/cli) for more details.
+[^7]: See ["Command-line Tools"](/docs/demos/cli) for more details.
diff --git a/docz/docs/03-demos/index.md b/docz/docs/03-demos/index.md
index 52ad9df..d795b10 100644
--- a/docz/docs/03-demos/index.md
+++ b/docz/docs/03-demos/index.md
@@ -106,7 +106,7 @@ in the [issue tracker](https://git.sheetjs.com/sheetjs/docs.sheetjs.com/issues)
### Platforms and Integrations
-- [`Command-Line Tools`](/docs/demos/desktop/cli)
+- [`Command-Line Tools`](/docs/demos/cli)
- [`NodeJS Server-Side Processing`](/docs/demos/net/server#nodejs)
- [`Deno Server-Side Processing`](/docs/demos/net/server#deno)
- [`Headless Automation`](/docs/demos/net/headless)
diff --git a/docz/docs/07-csf/07-features/01-dates.md b/docz/docs/07-csf/07-features/01-dates.md
index 72bc2eb..760419c 100644
--- a/docz/docs/07-csf/07-features/01-dates.md
+++ b/docz/docs/07-csf/07-features/01-dates.md
@@ -1,8 +1,10 @@
---
+title: Dates and Times
sidebar_position: 1
---
-# Dates and Times
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
File Format Support (click to show)
@@ -70,7 +72,10 @@ recommended to [upgrade](/docs/getting-started/installation/).
:::
The following example exports the current time to XLSX spreadsheet. The time
-shown on this page will be the time displayed in Excel
+shown on this page will be the time displayed in Excel.
+
+
+
```jsx live
function SheetJSNow() {
@@ -87,8 +92,7 @@ function SheetJSNow() {
ws["!cols"] = [{wch: 20}];
/* generate workbook and export */
- const wb = XLSX.utils.book_new();
- XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
+ const wb = XLSX.utils.book_new(ws, "Sheet1");
XLSX.writeFile(wb, "SheetJSNow.xlsx");
}, []);
return ( <>
@@ -97,10 +101,71 @@ function SheetJSNow() {
- > )
+ > );
}
```
+
+
+
+:::note pass
+
+1) Create a new Date object and set milliseconds to 0 (to avoid date rounding):
+
+```js
+/* starting date */
+const date = new Date();
+/* to avoid confusion, set milliseconds to 0 */
+date.setMilliseconds(0);
+```
+
+2) Construct an array of arrays to store the date. It will be placed in cell A1:
+
+```js
+/* generate array of arrays */
+const aoa = [[date]];
+```
+
+3) [Create a worksheet](/docs/api/utilities/array#array-of-arrays-input):
+
+```js
+/* generate workbook */
+const ws = XLSX.utils.aoa_to_sheet(aoa, {dense: true});
+```
+
+4) Adjust the date format using a [custom number format](/docs/csf/features/nf):
+
+```js
+/* set cell A1 number format */
+ws["!data"][0][0].z = "yyyy-mm-dd hh:mm:ss"
+```
+
+5) Adjust the [column width](/docs/csf/features/colprops)
+
+```js
+/* adjust column width */
+ws["!cols"] = [{wch: 20}];
+```
+
+6) [Create a workbook](/docs/api/utilities/wb):
+
+```js
+/* create workbook object */
+const wb = XLSX.utils.book_new(ws, "Sheet1");
+```
+
+7) [Write XLSX file](/docs/api/write-options):
+
+```js
+/* generate XLSX workbook and attempt to download */
+XLSX.writeFile(wb, "SheetJSNow.xlsx");
+```
+
+:::
+
+
+
+
## How Spreadsheets Understand Time
Excel stores dates as numbers. When displaying dates, the format code should
@@ -500,3 +565,71 @@ function SSFIsDate() {
```
+
+## How JSON and APIs Understand Time
+
+JSON does not have a native representation for JavaScript Date objects.
+
+Starting from a Date object, the `JSON.stringify` method will encode the object
+as a ISO 8601 date string. Applying `JSON.parse` to the result will return the
+string rather than a proper Date object.
+
+```mermaid
+flowchart LR
+ ws(("new Date#40;#41;"\nObject))
+ jstr[["'#quot;2001-01-01T00:00:00.000Z#quot;'"\nEncoded String]]
+ js[["#quot;2001-01-01T00:00:00.000Z#quot;"\nJavaScript String]]
+ ws --> |JSON\nstringify| jstr
+ jstr --> |JSON.parse\n\n| js
+ js --> |\nJSON.stringify| jstr
+```
+
+SheetJS utility functions will not try to interpret those strings as dates.
+Instead, the strings will be translated to text.
+
+In the following example, the "ISO Text" data will be converted to a string cell
+while the "Date Obj" data will be converted to a spreadsheet date.
+
+```jsx live
+function SheetJSONDates() { return ( ); }
+```
+
+:::caution pass
+
+Many API wrapper libraries return dates as strings instead of Date objects.
+
+If the SheetJS operations generate string cells, review the documentation for
+the wrapper library to ensure the other library is properly handling dates.
+
+:::
+
+### Fixing Arrays of Objects
+
+Many APIs will return data as JSON objects. When particular fields are known to
+contain date strings, they can be manually fixed.
+
+For example, the [Export Tutorial](/docs/getting-started/examples/export) makes
+a final array of objects with birthdays stored as strings:
+
+```js
+const rows = [
+ { name: "George Washington", birthday: "1732-02-22" },
+ { name: "John Adams", birthday: "1735-10-19" },
+ // ... one row per President
+];
+```
+
+If this dataset is exported, the `birthday` column will contain raw text values.
+A single `Array#map` operation can create a fixed dataset:
+
+```js
+const new_rows = rows.map(({birthday, ...rest}) => ({birthday: new Date(birthday), ...rest}))
+```
\ No newline at end of file
diff --git a/docz/docusaurus.config.js b/docz/docusaurus.config.js
index bb2596a..1e56632 100644
--- a/docz/docusaurus.config.js
+++ b/docz/docusaurus.config.js
@@ -269,9 +269,10 @@ const config = {
{ from: '/docs/demos/data/storageapi', to: '/docs/demos/local/storageapi/' },
{ from: '/docs/demos/data/websql', to: '/docs/demos/local/websql/' },
/* desktop */
- { from: '/docs/demos/cli', to: '/docs/demos/desktop/cli/' },
- { from: '/docs/getting-started/demos/cli', to: '/docs/demos/desktop/cli/' },
{ from: '/docs/getting-started/demos/desktop', to: '/docs/demos/desktop/' },
+ /* cli */
+ { from: '/docs/getting-started/demos/cli', to: '/docs/demos/cli/' },
+ { from: '/docs/demos/desktop/cli', to: '/docs/demos/cli/' },
/* bigdata */
{ from: '/docs/demos/worker', to: '/docs/demos/bigdata/worker/' },
{ from: '/docs/demos/stream', to: '/docs/demos/bigdata/stream/' },