diff --git a/docz/docs/02-getting-started/01-installation/07-bun.md b/docz/docs/02-getting-started/01-installation/07-bun.md index 2a247e6..d535f41 100644 --- a/docz/docs/02-getting-started/01-installation/07-bun.md +++ b/docz/docs/02-getting-started/01-installation/07-bun.md @@ -123,7 +123,7 @@ This demo was last tested in the following deployments: |:-------------|:---------|:-----------| | `darwin-x64` | `1.3.6` | 2026-01-20 | | `darwin-arm` | `1.3.6` | 2026-01-19 | -| `win11-x64` | `1.2.8` | 2025-04-17 | +| `win11-x64` | `1.3.6` | 2026-01-28 | | `win11-arm` | `1.2.3` | 2025-02-23 | | `linux-x64` | `1.3.6` | 2026-01-18 | | `linux-arm` | `1.2.2` | 2025-02-16 | @@ -137,42 +137,9 @@ BunJS on Windows on ARM uses the X64 compatibility layer. ```bash mkdir sheetjs-bun-dle cd sheetjs-bun-dle -echo "{}" > package.json +bun init -y ``` -:::caution PowerShell Encoding Errors - -The PowerShell file redirect will use the `UTF-16 LE` encoding. Bun does not -support the encoding and will fail to install the package: - -``` -bun add v1.1.42 (50eec002) -1 | �� - ^ -error: Unexpected �� - at ���������������������������������������������:1:1 -``` - -The file must be resaved in UTF8 (without BOM) or ASCII. - -0) Open `package.json` in VSCodium. - -The current encoding is displayed in the lower-right corner: - -![VSCodium status bar](pathname:///files/encodium.png) - -1) Click the displayed encoding. - -2) In the "Select Action" popup, select "Save with Encoding" - -3) In the new list, select `UTF-8 utf8`: - -![VSCodium encoding](pathname:///files/vscutf8.png) - -VSCodium will automatically re-save the file. - -::: - 1) Install the SheetJS package tarball: {`\ diff --git a/docz/docs/03-demos/01-math/11-tensorflow.md b/docz/docs/03-demos/01-math/11-tensorflow.md index 2951eb2..91c8dd1 100644 --- a/docz/docs/03-demos/01-math/11-tensorflow.md +++ b/docz/docs/03-demos/01-math/11-tensorflow.md @@ -44,9 +44,9 @@ The NodeJS demo was tested in the following environments: | NodeJS | TF.js | Date | |:------------|:----------|:-----------| -| `24.11.1` | `4.22.0` | 2025-11-15 | -| `22.21.1` | `4.22.0` | 2025-11-15 | -| `20.18.0` | `4.22.0` | 2025-11-15 | +| `24.13.0` | `4.22.0` | 2026-01-28 | +| `22.22.0` | `4.22.0` | 2026-01-28 | +| `20.20.0` | `4.22.0` | 2026-01-28 | The Kaioken demo was tested in the following environments: diff --git a/docz/docs/03-demos/02-frontend/19-bundler/03-vitejs.md b/docz/docs/03-demos/02-frontend/19-bundler/03-vitejs.md index b33fdd6..6473361 100644 --- a/docz/docs/03-demos/02-frontend/19-bundler/03-vitejs.md +++ b/docz/docs/03-demos/02-frontend/19-bundler/03-vitejs.md @@ -41,11 +41,11 @@ This demo was tested in the following environments: | ViteJS | Date | |:---------|:-----------| -| `7.2.2` | 2025-11-15 | -| `6.4.1` | 2025-11-15 | -| `5.4.21` | 2025-11-15 | -| `4.5.14` | 2025-11-15 | -| `3.2.11` | 2025-11-15 | +| `7.3.1` | 2026-01-28 | +| `6.4.1` | 2026-01-28 | +| `5.4.21` | 2026-01-28 | +| `4.5.14` | 2026-01-28 | +| `3.2.11` | 2026-01-28 | ::: diff --git a/docz/docs/03-demos/02-frontend/19-bundler/04-esbuild.md b/docz/docs/03-demos/02-frontend/19-bundler/04-esbuild.md index 27a4f10..2cdabe2 100644 --- a/docz/docs/03-demos/02-frontend/19-bundler/04-esbuild.md +++ b/docz/docs/03-demos/02-frontend/19-bundler/04-esbuild.md @@ -47,25 +47,25 @@ This demo was tested in the following environments: | ESBuild | Date | |:----------|:-----------| -| `0.27.0` | 2025-11-15 | -| `0.26.0` | 2025-11-15 | -| `0.25.12` | 2025-11-15 | -| `0.24.2` | 2025-11-15 | -| `0.23.1` | 2025-11-15 | -| `0.22.0` | 2025-11-15 | -| `0.21.5` | 2025-11-15 | -| `0.20.2` | 2025-11-15 | -| `0.19.12` | 2025-11-15 | -| `0.18.20` | 2025-11-15 | -| `0.17.19` | 2025-11-15 | -| `0.16.17` | 2025-11-15 | -| `0.15.18` | 2025-11-15 | -| `0.14.54` | 2025-11-15 | -| `0.13.15` | 2025-11-15 | -| `0.12.29` | 2025-11-15 | -| `0.11.23` | 2025-11-15 | -| `0.10.2` | 2025-11-15 | -| `0.9.7` | 2025-11-15 | +| `0.27.2` | 2026-01-28 | +| `0.26.0` | 2026-01-28 | +| `0.25.12` | 2026-01-28 | +| `0.24.2` | 2026-01-28 | +| `0.23.1` | 2026-01-28 | +| `0.22.0` | 2026-01-28 | +| `0.21.5` | 2026-01-28 | +| `0.20.2` | 2026-01-28 | +| `0.19.12` | 2026-01-28 | +| `0.18.20` | 2026-01-28 | +| `0.17.19` | 2026-01-28 | +| `0.16.17` | 2026-01-28 | +| `0.15.18` | 2026-01-28 | +| `0.14.54` | 2026-01-28 | +| `0.13.15` | 2026-01-28 | +| `0.12.29` | 2026-01-28 | +| `0.11.23` | 2026-01-28 | +| `0.10.2` | 2026-01-28 | +| `0.9.7` | 2026-01-28 | ::: 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 40dbb18..1f73ebf 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 | |:----------|:-----------|:------------------------------------| -| `5.102.1` | 2025-11-15 | | -| `4.47.0` | 2025-11-15 | | -| `3.12.0` | 2025-11-15 | Import `xlsx/dist/xlsx.full.min.js` | -| `2.7.0` | 2025-11-15 | Import `xlsx/dist/xlsx.full.min.js` | +| `5.104.1` | 2026-01-28 | | +| `4.47.0` | 2026-01-28 | | +| `3.12.0` | 2026-01-28 | Import `xlsx/dist/xlsx.full.min.js` | +| `2.7.0` | 2026-01-28 | Import `xlsx/dist/xlsx.full.min.js` | ::: diff --git a/docz/docs/03-demos/02-frontend/19-bundler/09-browserify.md b/docz/docs/03-demos/02-frontend/19-bundler/09-browserify.md index 74824f9..d7d0c3d 100644 --- a/docz/docs/03-demos/02-frontend/19-bundler/09-browserify.md +++ b/docz/docs/03-demos/02-frontend/19-bundler/09-browserify.md @@ -34,21 +34,21 @@ This demo was tested in the following environments: | Browserify | Date | |:-----------|:-----------| -| `17.0.1` | 2025-11-15 | -| `16.5.2` | 2025-11-15 | -| `15.2.0` | 2025-11-15 | -| `14.5.0` | 2025-11-15 | -| `13.3.0` | 2025-11-15 | -| `12.0.2` | 2025-11-15 | -| `11.2.0` | 2025-11-15 | -| `10.2.6` | 2025-11-15 | -| `9.0.8` | 2025-11-15 | -| `8.1.3` | 2025-11-15 | -| `7.1.0` | 2025-11-15 | -| `6.3.4` | 2025-11-15 | -| `5.13.1` | 2025-11-15 | -| `4.2.3` | 2025-11-15 | -| `3.46.1` | 2025-11-15 | +| `17.0.1` | 2026-01-28 | +| `16.5.2` | 2026-01-28 | +| `15.2.0` | 2026-01-28 | +| `14.5.0` | 2026-01-28 | +| `13.3.0` | 2026-01-28 | +| `12.0.2` | 2026-01-28 | +| `11.2.0` | 2026-01-28 | +| `10.2.6` | 2026-01-28 | +| `9.0.8` | 2026-01-28 | +| `8.1.3` | 2026-01-28 | +| `7.1.0` | 2026-01-28 | +| `6.3.4` | 2026-01-28 | +| `5.13.1` | 2026-01-28 | +| `4.2.3` | 2026-01-28 | +| `3.46.1` | 2026-01-28 | ::: diff --git a/docz/docs/03-demos/02-frontend/19-bundler/11-requirejs.md b/docz/docs/03-demos/02-frontend/19-bundler/11-requirejs.md index f3cdbe9..0d9de03 100644 --- a/docz/docs/03-demos/02-frontend/19-bundler/11-requirejs.md +++ b/docz/docs/03-demos/02-frontend/19-bundler/11-requirejs.md @@ -40,8 +40,8 @@ This demo was tested in the following environments: | RequireJS | Date | |:----------|:-----------| -| `2.3.7` | 2025-11-15 | -| `2.1.22` | 2025-11-15 | +| `2.3.7` | 2026-01-25 | +| `2.1.22` | 2026-01-25 | ::: diff --git a/docz/docs/03-demos/02-frontend/19-bundler/12-systemjs.md b/docz/docs/03-demos/02-frontend/19-bundler/12-systemjs.md index 6766541..0f19e42 100644 --- a/docz/docs/03-demos/02-frontend/19-bundler/12-systemjs.md +++ b/docz/docs/03-demos/02-frontend/19-bundler/12-systemjs.md @@ -46,11 +46,11 @@ This demo was tested in the following environments: | Version | Platform | Date | |:----------|:---------|:-----------| -| `0.19.47` | NodeJS | 2025-11-15 | -| `0.20.16` | Browser | 2025-11-15 | -| `0.20.19` | NodeJS | 2025-11-15 | -| `0.21.6` | NodeJS | 2025-11-15 | -| `6.15.1` | NodeJS | 2025-11-15 | +| `6.15.1` | NodeJS | 2026-01-28 | +| `0.21.6` | NodeJS | 2026-01-28 | +| `0.20.19` | NodeJS | 2026-01-28 | +| `0.19.47` | NodeJS | 2026-01-28 | +| `0.20.16` | Browser | 2026-01-28 | ::: diff --git a/docz/docs/03-demos/02-frontend/19-bundler/14-rollup.md b/docz/docs/03-demos/02-frontend/19-bundler/14-rollup.md index 537b1f0..00fd9d4 100644 --- a/docz/docs/03-demos/02-frontend/19-bundler/14-rollup.md +++ b/docz/docs/03-demos/02-frontend/19-bundler/14-rollup.md @@ -34,10 +34,10 @@ This demo was tested in the following environments: | Version | Date | |:---------|:-----------| -| `4.53.2` | 2025-11-15 | -| `3.29.5` | 2025-11-15 | -| `2.79.2` | 2025-11-15 | -| `1.32.1` | 2025-11-15 | +| `4.57.0` | 2026-01-28 | +| `3.29.5` | 2026-01-28 | +| `2.79.2` | 2026-01-28 | +| `1.32.1` | 2026-01-28 | ::: diff --git a/docz/docs/03-demos/02-frontend/19-bundler/18-rspack.md b/docz/docs/03-demos/02-frontend/19-bundler/18-rspack.md index 14036ad..ead75ad 100644 --- a/docz/docs/03-demos/02-frontend/19-bundler/18-rspack.md +++ b/docz/docs/03-demos/02-frontend/19-bundler/18-rspack.md @@ -34,7 +34,7 @@ This demo was tested in the following environments: | Rspack | Date | |:--------|:-----------| -| `1.6.3` | 2025-11-15 | +| `1.7.4` | 2026-01-28 | ::: diff --git a/docz/docs/03-demos/02-frontend/19-bundler/20-parcel.md b/docz/docs/03-demos/02-frontend/19-bundler/20-parcel.md index 2b071ba..4aa69f7 100644 --- a/docz/docs/03-demos/02-frontend/19-bundler/20-parcel.md +++ b/docz/docs/03-demos/02-frontend/19-bundler/20-parcel.md @@ -34,8 +34,8 @@ This demo was tested in the following environments: | Version | Date | |:---------|:-----------| -| `2.16.1` | 2025-11-15 | -| `1.12.3` | 2025-11-15 | +| `2.16.1` | 2026-01-28 | +| `1.12.3` | 2026-01-28 | ::: diff --git a/docz/docs/03-demos/02-frontend/19-bundler/21-swcpack.md b/docz/docs/03-demos/02-frontend/19-bundler/21-swcpack.md index ad30718..f20a431 100644 --- a/docz/docs/03-demos/02-frontend/19-bundler/21-swcpack.md +++ b/docz/docs/03-demos/02-frontend/19-bundler/21-swcpack.md @@ -35,7 +35,7 @@ This demo was tested in the following environments: | Version | Date | |:----------|:-----------| -| `1.15.2` | 2025-11-15 | +| `1.15.11` | 2026-01-28 | ::: diff --git a/docz/docs/03-demos/02-frontend/19-bundler/index.md b/docz/docs/03-demos/02-frontend/19-bundler/index.md index 3bdd820..f09e6e3 100644 --- a/docz/docs/03-demos/02-frontend/19-bundler/index.md +++ b/docz/docs/03-demos/02-frontend/19-bundler/index.md @@ -62,7 +62,7 @@ This demo was tested in the following environments: | Version | Date | |:--------|:-----------| -| `3.8.8` | 2025-11-15 | +| `3.8.8` | 2026-01-28 | ::: @@ -194,7 +194,7 @@ This demo was tested in the following environments: | Version | Date | |:--------|:-----------| -| `3.8.0` | 2025-11-15 | +| `3.8.0` | 2026-01-28 | ::: diff --git a/docz/docs/03-demos/03-net/09-dom.md b/docz/docs/03-demos/03-net/09-dom.md index 3321e59..011316b 100644 --- a/docz/docs/03-demos/03-net/09-dom.md +++ b/docz/docs/03-demos/03-net/09-dom.md @@ -296,9 +296,9 @@ features to ensure that SheetJS DOM methods can process TABLE elements. This demo was tested in the following deployments: -| CheerioJS | Date | -|:--------------|:-----------| -| `1.1.2` | 2026-01-12 | +| CheerioJS | Date | +|:----------|:-----------| +| `1.2.0` | 2026-01-28 | ::: diff --git a/docz/docs/03-demos/12-static/04-esbuild.md b/docz/docs/03-demos/12-static/04-esbuild.md index 88cbe93..9d4c05e 100644 --- a/docz/docs/03-demos/12-static/04-esbuild.md +++ b/docz/docs/03-demos/12-static/04-esbuild.md @@ -204,24 +204,26 @@ This demo was tested in the following environments: | `esbuild` | Date | |:----------|:-----------| -| `0.25.5` | 2025-06-20 | -| `0.24.2` | 2025-06-20 | -| `0.23.1` | 2025-06-20 | -| `0.22.0` | 2025-06-20 | -| `0.21.5` | 2025-06-20 | -| `0.20.2` | 2025-06-20 | -| `0.19.12` | 2025-06-20 | -| `0.18.20` | 2025-06-20 | -| `0.17.19` | 2025-06-20 | -| `0.16.17` | 2025-06-20 | -| `0.15.18` | 2025-06-20 | -| `0.14.54` | 2025-06-20 | -| `0.13.15` | 2025-06-20 | -| `0.12.29` | 2025-06-20 | -| `0.11.23` | 2025-06-20 | -| `0.10.2` | 2025-06-20 | -| `0.9.7` | 2025-06-20 | -| `0.9.1` | 2025-06-20 | +| `0.27.2` | 2026-01-28 | +| `0.26.0` | 2026-01-28 | +| `0.25.5` | 2026-01-28 | +| `0.24.2` | 2026-01-28 | +| `0.23.1` | 2026-01-28 | +| `0.22.0` | 2026-01-28 | +| `0.21.5` | 2026-01-28 | +| `0.20.2` | 2026-01-28 | +| `0.19.12` | 2026-01-28 | +| `0.18.20` | 2026-01-28 | +| `0.17.19` | 2026-01-28 | +| `0.16.17` | 2026-01-28 | +| `0.15.18` | 2026-01-28 | +| `0.14.54` | 2026-01-28 | +| `0.13.15` | 2026-01-28 | +| `0.12.29` | 2026-01-28 | +| `0.11.23` | 2026-01-28 | +| `0.10.2` | 2026-01-28 | +| `0.9.7` | 2026-01-28 | +| `0.9.1` | 2026-01-28 | ::: diff --git a/docz/docs/03-demos/12-static/07-eleventy.md b/docz/docs/03-demos/12-static/07-eleventy.md index e315dd5..7e95a16 100644 --- a/docz/docs/03-demos/12-static/07-eleventy.md +++ b/docz/docs/03-demos/12-static/07-eleventy.md @@ -115,10 +115,11 @@ accessed using the variable `pres` in a template: This demo was tested in the following environments: -| Eleventy | Date | -|:---------------|:-----------| -| `2.0.1` | 2026-01-12 | -| `3.1.2` | 2026-01-12 | +| Eleventy | Date | +|:----------------|:-----------| +| `4.0.0-alpha.6` | 2026-01-28 | +| `3.1.2` | 2026-01-28 | +| `2.0.1` | 2026-01-28 | ::: diff --git a/docz/docs/03-demos/42-engines/01-duktape.md b/docz/docs/03-demos/42-engines/01-duktape.md index 90a85d0..bfca571 100644 --- a/docz/docs/03-demos/42-engines/01-duktape.md +++ b/docz/docs/03-demos/42-engines/01-duktape.md @@ -145,7 +145,8 @@ The [flow diagram is displayed after the example steps](#flow-diagram) :::note pass The Windows build requires Visual Studio with "Desktop development with C++". -Commands must be run in a "Native Tools Command Prompt" session. + +**Commands must be run in a "Native Tools Command Prompt" session.** ::: @@ -549,6 +550,7 @@ This demo was tested in the following deployments: |:-------------|:--------|:---------|:-----------| | `darwin-x64` | `2.7.0` | `3.13.7` | 2026-01-21 | | `darwin-arm` | `2.7.0` | `3.12.3` | 2026-01-23 | +| `win11-x64` | `2.7.0` | `3.11.9` | 2026-01-28 | | `linux-x64` | `2.7.0` | `3.12.3` | 2025-04-21 | | `linux-arm` | `2.7.0` | `3.11.2` | 2025-02-15 | diff --git a/docz/static/duk/main.rs b/docz/static/duk/main.rs index bb2c3c1..3043174 100644 --- a/docz/static/duk/main.rs +++ b/docz/static/duk/main.rs @@ -45,7 +45,7 @@ fn main() { let csv: ducc::Value = ctx.compile("XLSX.utils.sheet_to_csv(ws)", None).unwrap().call(()).unwrap(); println!("{}", get_string(csv)); } - + /* write file */ { /* due to issues with the duktape crate, it is easier to pass a base64-encoded string and decode in Rust */ diff --git a/docz/static/ghidra/sheetjs-ghidra.js b/docz/static/ghidra/sheetjs-ghidra.js index 0eee406..9705f97 100644 --- a/docz/static/ghidra/sheetjs-ghidra.js +++ b/docz/static/ghidra/sheetjs-ghidra.js @@ -66,5 +66,5 @@ const aoo = offset.map((name, idx) => ({ const ws = json_to_sheet(aoo); /* write workbook */ const wb = book_new(ws, "Offsets"); -/* write to XLSX */ +/* write to XLSX */ writeFileXLSX(wb, "SheetJSGhidraTSTCell.xlsx"); diff --git a/docz/static/jsc/main.rs b/docz/static/jsc/main.rs index 5f10ec6..c5431e3 100644 --- a/docz/static/jsc/main.rs +++ b/docz/static/jsc/main.rs @@ -61,7 +61,7 @@ const kJSTypedArrayTypeUint8Array: u32 = 3; type JSPropertyAttributes = u32; unsafe extern "C" { - pub unsafe fn JSEvaluateScript(ctx: JSContextRef, script: JSStringRef, thisObject: JSObjectRef, sourceURL: JSStringRef, startingLineNumber: i32, exception: JSValueRefRef) -> JSValueRef; + pub unsafe fn JSEvaluateScript(ctx: JSContextRef, script: JSStringRef, thisObject: JSObjectRef, sourceURL: JSStringRef, startingLineNumber: i32, exception: JSValueRefRef) -> JSValueRef; pub unsafe fn JSGlobalContextCreate(string: JSClassRef) -> JSGlobalContextRef; pub unsafe fn JSGlobalContextRelease(ctx: JSGlobalContextRef); @@ -89,7 +89,7 @@ pub struct JSC; impl JSC { pub fn JSEval(ctx: JSContextRef, script: &str) -> JSValueRef { unsafe { let script: JSStringRef = JSStringCreateWithUTF8CString(std::ffi::CString::new(script.as_bytes()).unwrap().as_ptr() as *const u8); - let result: JSValueRef = JSEvaluateScript(ctx, script, NULL!(), NULL!(), 0, NULL!()); + let result: JSValueRef = JSEvaluateScript(ctx, script, NULL!(), NULL!(), 0, NULL!()); JSStringRelease(script); result } } @@ -131,7 +131,7 @@ impl JSC { } } } - pub fn JSObjectSetProperty(ctx: JSContextRef, object: JSObjectRef, propertyName: JSStringRef, value: JSValueRef, attributes: JSPropertyAttributes, exception: JSValueRefRef) { unsafe { + pub fn JSObjectSetProperty(ctx: JSContextRef, object: JSObjectRef, propertyName: JSStringRef, value: JSValueRef, attributes: JSPropertyAttributes, exception: JSValueRefRef) { unsafe { JSObjectSetProperty(ctx, object, propertyName, value, attributes, exception) } } pub fn JSObjectMakeUint8Array(ctx: JSContextRef, data: Vec) -> JSObjectRef { unsafe { @@ -173,10 +173,10 @@ fn main() { let ctx: JSGlobalContextRef = JSC::JSGlobalContextCreate(NULL!()); /* JSC does not expose a standard "global" by default */ - JSC::JSEval(ctx, "var global = (function(){ return this; }).call(null);"); + JSC::JSEval(ctx, "var global = (function(){ return this; }).call(null);"); /* load library */ - JSC::JSEval(ctx, include_str!("xlsx.full.min.js")); + JSC::JSEval(ctx, include_str!("xlsx.full.min.js")); /* get version string */ match JSC::JSEvalStr(ctx, "XLSX.version") { @@ -194,7 +194,7 @@ fn main() { let path: String = iter.nth(1).expect("must specify a file name"); let file: Vec = std::fs::read(path.clone()).unwrap(); - + /* push data to JSC */ let u8: JSObjectRef = JSC::JSObjectMakeUint8Array(ctx, file); diff --git a/misc/coarsify.js b/misc/coarsify.js index f21d008..a30ed41 100644 --- a/misc/coarsify.js +++ b/misc/coarsify.js @@ -1,13 +1,13 @@ /* based on the `coarse` project README */ const fs = require('fs'); const coarse = require('coarse'); - + const svg = fs.readFileSync(process.argv[2], "utf8"); let roughened = coarse(svg); const viewbox = roughened.match(/viewBox="(.*?)"/)[1].split(/\s+/); const v = viewbox.map(x => parseFloat(x)); v[0] -= 40; v[1] += 40; v[2] += 80; v[3] += 80; roughened = roughened.replace(/G<\/title>/, `$&<polygon fill="white" stroke="" points="${v[0]},${v[1]} ${v[0]},${v[1]-v[3]} ${v[0]+v[2]},${v[1]-v[3]} ${v[0]+v[2]},${v[1]} ${v[0]},${v[1]}"/>`); - + fs.writeFileSync(process.argv[3], roughened); diff --git a/package.json b/package.json index f0ea631..faed8f7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,8 @@ { "private": true, "scripts": { - "dev": "cd docz && npm run start -- --host=0.0.0.0 --no-open" + "init": "cd docz && npm i --legacy-peer-deps", + "dev": "cd docz && npm run start -- --host=0.0.0.0 --port 6996 --no-open" }, "alex": { "allow": [ diff --git a/tests/bigdata/stream-bun.ps1 b/tests/bigdata/stream-bun.ps1 new file mode 100644 index 0000000..76bd191 --- /dev/null +++ b/tests/bigdata/stream-bun.ps1 @@ -0,0 +1,20 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/bigdata/stream#nodejs + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-stream" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +bun init -y +bun i xlsx@https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/stream/SheetJSNodeJStream.js" -OutFile "SheetJSNodeJStream.js" +Invoke-WebRequest -Uri "https://docs.sheetjs.com/pres.xlsx" -OutFile "pres.xlsx" + +bun --version +bun SheetJSNodeJStream.js pres.xlsx + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/bigdata/stream-bun.sh b/tests/bigdata/stream-bun.sh index 3d4b98d..74bae31 100755 --- a/tests/bigdata/stream-bun.sh +++ b/tests/bigdata/stream-bun.sh @@ -7,10 +7,10 @@ rm -rf sheetjs-stream mkdir sheetjs-stream cd sheetjs-stream +bun init -y bun i xlsx@https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz curl -LO https://docs.sheetjs.com/stream/SheetJSNodeJStream.js - curl -LO https://docs.sheetjs.com/pres.xlsx bun --version diff --git a/tests/bigdata/stream-nodejs.ps1 b/tests/bigdata/stream-nodejs.ps1 new file mode 100644 index 0000000..621cede --- /dev/null +++ b/tests/bigdata/stream-nodejs.ps1 @@ -0,0 +1,20 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/bigdata/stream#nodejs + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-stream" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/stream/SheetJSNodeJStream.js" -OutFile "SheetJSNodeJStream.js" +Invoke-WebRequest -Uri "https://docs.sheetjs.com/pres.xlsx" -OutFile "pres.xlsx" + +# Test with current Node.js version +node --version +node SheetJSNodeJStream.js pres.xlsx + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/bigdata/stream-nodejs.sh b/tests/bigdata/stream-nodejs.sh index 7f3d0d1..d8854af 100755 --- a/tests/bigdata/stream-nodejs.sh +++ b/tests/bigdata/stream-nodejs.sh @@ -11,7 +11,6 @@ cd sheetjs-stream npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz curl -LO https://docs.sheetjs.com/stream/SheetJSNodeJStream.js - curl -LO https://docs.sheetjs.com/pres.xlsx # this version uses `nvm` to cycle through node versions diff --git a/tests/bundler/browserify.ps1 b/tests/bundler/browserify.ps1 new file mode 100644 index 0000000..be4f36a --- /dev/null +++ b/tests/bundler/browserify.ps1 @@ -0,0 +1,108 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/frontend/bundler/browserify + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-browserify-tests" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +for ($n = 3; $n -le 17; $n++) { + $subDir = Join-Path -Path $tempDir -ChildPath "sheetjs-browserify-$n" + New-Item -ItemType Directory -Path $subDir | Out-Null + Set-Location -Path $subDir + + npm init -y + npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz puppeteer express@4 + + @' +const { utils, version, writeFileXLSX } = require('xlsx'); + +document.getElementById("xport").addEventListener("click", function() { + /* fetch JSON data and parse */ + var url = "https://sheetjs.com/data/executive.json"; + fetch(url).then(function(res) { return res.json(); }).then(function(raw_data) { + + /* filter for the Presidents */ + var prez = raw_data.filter(function(row) { return row.terms.some(function(term) { return term.type === "prez"; }); }); + + /* sort by first presidential term */ + prez.forEach(function(row) { + row.start = row.terms.find(function(term) { + return term.type === "prez"; + }).start; + }); + prez.sort(function(l,r) { return l.start.localeCompare(r.start); }); + + /* flatten objects */ + var rows = prez.map(function(row) { return { + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday + }; }); + + /* generate worksheet and workbook */ + var worksheet = utils.json_to_sheet(rows); + var workbook = utils.book_new(); + utils.book_append_sheet(workbook, worksheet, "Dates"); + + /* fix headers */ + utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + + /* calculate column width */ + var max_width = rows.reduce(function(w, r) { return Math.max(w, r.name.length); }, 10); + worksheet["!cols"] = [ { wch: max_width } ]; + + /* create an XLSX file and try to save to Presidents.xlsx */ + writeFileXLSX(workbook, "Presidents.xlsx"); + }); +}); +'@ | Out-File -FilePath "index.js" -Encoding utf8 + + npm install --save browserify@$n + npm ls | Select-String "browserify" + npx browserify@$n index.js > index.min.js + + @' +<!DOCTYPE html> +<html lang="en"> + <head></head> + <body> + <h1>SheetJS Presidents Demo</h1> + <button id="xport">Click here to export</button> + <script src="./index.min.js"></script> + </body> +</html> +'@ | Out-File -FilePath "index.html" -Encoding utf8 + + @' +const puppeteer = require('puppeteer'); +const express = require('express'); +const app = express(); +app.use(express.static('./')); +app.listen(7262, async() => { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + await page.goto('http://localhost:7262/'); + await page.click("#xport"); + await new Promise((res,rej) => setTimeout(res, 1000)); + await browser.close(); + process.exit(); +}); +'@ | Out-File -FilePath "test.js" -Encoding utf8 + + node test.js + npx -y xlsx-cli Presidents.xlsx | Select-Object -First 3 + + Set-Location -Path $tempDir +} + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/bundler/esbuild.ps1 b/tests/bundler/esbuild.ps1 new file mode 100644 index 0000000..b485a6a --- /dev/null +++ b/tests/bundler/esbuild.ps1 @@ -0,0 +1,65 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/frontend/bundler/esbuild + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-esbrowser" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +npm init -y + +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz +npm i --save puppeteer express +Invoke-WebRequest -Uri "https://docs.sheetjs.com/esbuild/esbrowser.js" -OutFile "esbrowser.js" +Invoke-WebRequest -Uri "https://docs.sheetjs.com/esbuild/esbnode.js" -OutFile "esbnode.js" + +@' +<body><script src="esb.browser.js"></script></body> +'@ | Out-File -FilePath "index.html" -Encoding utf8 + +@' +const puppeteer = require('puppeteer'); +const express = require('express'); +const app = express(); +app.use(express.static('./')); +app.listen(7262, async() => { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + page.on('request', req => console.log(req.url())); + await page.goto('http://localhost:7262/'); + await new Promise((res,rej) => setTimeout(res, 1000)); + await browser.close(); + process.exit(); +}); +'@ | Out-File -FilePath "test.js" -Encoding utf8 + +for ($i = 9; $i -le 27; $i++) { + $n = "0.$i" + npx -y esbuild@$n --version + + ## Browser Test + npx -y esbuild@$n esbrowser.js --bundle --outfile=esb.browser.js + node test.js + npx -y xlsx-cli Presidents.xlsx | Select-Object -First 3 + if (Test-Path -Path "esb.browser.js") { Remove-Item -Path "esb.browser.js" -Force } + if (Test-Path -Path "Presidents.xlsx") { Remove-Item -Path "Presidents.xlsx" -Force } + + ## Node test + npx -y esbuild@$n esbnode.js --bundle --platform=node --outfile=esb.node.js + node esb.node.js + npx -y xlsx-cli Presidents.xlsx | Select-Object -First 3 + if (Test-Path -Path "esb.node.js") { Remove-Item -Path "esb.node.js" -Force } + if (Test-Path -Path "Presidents.xlsx") { Remove-Item -Path "Presidents.xlsx" -Force } +} + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/bundler/esbuild.sh b/tests/bundler/esbuild.sh index 3f75bcd..3408380 100755 --- a/tests/bundler/esbuild.sh +++ b/tests/bundler/esbuild.sh @@ -49,6 +49,7 @@ for n in 0.{9..27}; do npx -y xlsx-cli Presidents.xlsx | head -n 3 rm -f esb.browser.js Presidents.xlsx + ## Node test npx -y esbuild@$n esbnode.js --bundle --platform=node --outfile=esb.node.js node esb.node.js npx -y xlsx-cli Presidents.xlsx | head -n 3 diff --git a/tests/bundler/parcel.ps1 b/tests/bundler/parcel.ps1 new file mode 100644 index 0000000..77d7d69 --- /dev/null +++ b/tests/bundler/parcel.ps1 @@ -0,0 +1,102 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/frontend/bundler/parcel + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-parceljs" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +npm init -y + +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz + +@' +<body> +<h3>SheetJS <span id="vers"></span> export demo</h3> +<button id="xport">Click to Export!</button> +<script src="index.js" type="module"></script> +<body> +'@ | Out-File -FilePath "index.html" -Encoding utf8 + +@' +// ESM-style import from "xlsx" +import { utils, version, writeFileXLSX } from 'xlsx'; + +document.getElementById("vers").innerText = version; +document.getElementById("xport").onclick = async() => { + /* fetch JSON data and parse */ + const url = "https://docs.sheetjs.com/executive.json"; + const raw_data = await (await fetch(url)).json(); + + /* filter for the Presidents */ + const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); + + /* sort by first presidential term */ + prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start); + prez.sort((l,r) => l.start.localeCompare(r.start)); + + /* flatten objects */ + const rows = prez.map(row => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday + })); + + /* generate worksheet and workbook */ + const worksheet = utils.json_to_sheet(rows); + const workbook = utils.book_new(); + utils.book_append_sheet(workbook, worksheet, "Dates"); + + /* fix headers */ + utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + + /* calculate column width */ + const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); + worksheet["!cols"] = [ { wch: max_width } ]; + + /* create an XLSX file and try to save to Presidents.xlsx */ + writeFileXLSX(workbook, "Presidents.xlsx"); +}; +'@ | Out-File -FilePath "index.js" -Encoding utf8 + +@' +const puppeteer = require('puppeteer'); +const express = require('express'); +const app = express(); +app.use(express.static('./dist')); +app.listen(7262, async() => { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + page.on('request', req => console.log(req.url())); + await page.goto('http://localhost:7262/'); + await new Promise((res,rej) => setTimeout(res, 1000)); + await page.click("#xport"); + await new Promise((res,rej) => setTimeout(res, 1000)); + await browser.close(); + process.exit(); +}); +'@ | Out-File -FilePath "test.js" -Encoding utf8 + +npm i --save puppeteer express@4 + +node -e "var pjson = JSON.parse(fs.readFileSync('./package.json')); console.log(pjson); delete pjson.main; fs.writeFileSync('package.json', JSON.stringify(pjson))" + +$versions = @("2.16.1", "1.12.3") +foreach ($n in $versions) { + npm i --save parcel@$n + npx -y parcel@$n build index.html + node test.js + npx -y xlsx-cli Presidents.xlsx | Select-Object -First 3 + Remove-Item -Path "Presidents.xlsx" -Force -ErrorAction SilentlyContinue +} + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/bundler/requirejs.ps1 b/tests/bundler/requirejs.ps1 new file mode 100644 index 0000000..1e79a8b --- /dev/null +++ b/tests/bundler/requirejs.ps1 @@ -0,0 +1,170 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/frontend/bundler/requirejs +# requires global puppeteer and express + +# npm i -g puppeteer express@4 + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-requirejs" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +Invoke-WebRequest -Uri "https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js" -OutFile "xlsx.full.min.js" +npm init -y +npm i puppeteer express + +@' +require(["xlsx"], function(XLSX) { + document.getElementById("xport").addEventListener("click", function() { + /* fetch JSON data and parse */ + var url = "https://docs.sheetjs.com/executive.json"; + fetch(url).then(function(res) { return res.json(); }).then(function(raw_data) { + + /* filter for the Presidents */ + var prez = raw_data.filter(function(row) { return row.terms.some(function(term) { return term.type === "prez"; }); }); + + /* sort by first presidential term */ + prez.forEach(function(row) { + row.start = row.terms.find(function(term) { + return term.type === "prez"; + }).start; + }); + prez.sort(function(l,r) { return l.start.localeCompare(r.start); }); + + /* flatten objects */ + var rows = prez.map(function(row) { return { + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday + }; }); + + /* generate worksheet and workbook */ + var worksheet = XLSX.utils.json_to_sheet(rows); + var workbook = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(workbook, worksheet, "Dates"); + + /* fix headers */ + XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + + /* calculate column width */ + var max_width = rows.reduce(function(w, r) { return Math.max(w, r.name.length); }, 10); + worksheet["!cols"] = [ { wch: max_width } ]; + + /* create an XLSX file and try to save to Presidents.xlsx */ + XLSX.writeFileXLSX(workbook, "Presidents.xlsx"); + console.log(XLSX.utils.sheet_to_csv(worksheet)); + }); + }); +}); +'@ | Out-File -FilePath "SheetJSRequire.js" -Encoding utf8 + +@' +({ + baseUrl: ".", + name: "SheetJSRequire", + paths: { + xlsx: "./xlsx.full.min" + }, + out: "SheetJSRequire.min.js" +}); +'@ | Out-File -FilePath "build.js" -Encoding utf8 + +@' +const puppeteer = require('puppeteer'); +const express = require('express'); +const app = express(); +app.use(express.static('./')); +app.listen(7262, async() => { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + await page.goto('http://localhost:7262/', {waitUntil: 'domcontentloaded'}); + + /* wait for requirejs to request xlsx.full.min.js */ + await page.waitForRequest(request => request.url().indexOf('xlsx.full.min.js') !== -1); + await new Promise((res,rej) => setTimeout(res, 1000)); + + await page.click("#xport"); + await new Promise((res,rej) => setTimeout(res, 2000)); + await browser.close(); + process.exit(); +}); +'@ | Out-File -FilePath "test1.js" -Encoding utf8 + +@' +const puppeteer = require('puppeteer'); +const express = require('express'); +const app = express(); +app.use(express.static('./')); +app.listen(7262, async() => { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + await page.goto('http://localhost:7262/optimized.html'); + await page.click("#xport"); + await new Promise((res,rej) => setTimeout(res, 1000)); + await browser.close(); + process.exit(); +}); +'@ | Out-File -FilePath "test2.js" -Encoding utf8 + +$versions = @("2.3.7", "2.1.22") + +foreach ($n in $versions) { + Write-Host "$n Standalone" + + @" +<!DOCTYPE html> +<html lang="en"> + <head></head> + <body> + <h1>SheetJS Presidents Demo</h1> + <button id="xport">Click here to export</button> + <script src="http://requirejs.org/docs/release/$n/comments/require.js"></script> + <script> +/* Wire up RequireJS */ +require.config({ + baseUrl: ".", + name: "SheetJSRequire", + paths: { + xlsx: "xlsx.full.min" + } +}); + </script> + <script src="SheetJSRequire.js"></script> + </body> +</html> +"@ | Out-File -FilePath "index.html" -Encoding utf8 + + node test1.js + + Write-Host "$n Optimizer" + + Remove-Item -Path "SheetJSRequire.min.js" -Force -ErrorAction Ignore + #npx -p requirejs@$n r.js -o build.js + # NOTE: `npx` issues in Windows necessitates this workaround + npm install --save requirejs@$n + node .\node_modules\requirejs\bin\r.js -o build.js + + @" +<!DOCTYPE html> +<html lang="en"> + <head></head> + <body> + <h1>SheetJS Presidents Demo</h1> + <button id="xport">Click here to export</button> + <script src="http://requirejs.org/docs/release/$n/comments/require.js"></script> + <script src="SheetJSRequire.min.js"></script> + </body> +</html> +"@ | Out-File -FilePath "optimized.html" -Encoding utf8 + + node test2.js +} + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/bundler/rollup.ps1 b/tests/bundler/rollup.ps1 new file mode 100644 index 0000000..b994a3c --- /dev/null +++ b/tests/bundler/rollup.ps1 @@ -0,0 +1,127 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/frontend/bundler/rollup + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-rollup" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +npm init -y + +npm i --save https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz + +@' +import { utils, version, writeFileXLSX } from 'xlsx'; + +document.getElementById("xport").addEventListener("click", async() => { +/* fetch JSON data and parse */ +const url = "https://docs.sheetjs.com/executive.json"; +const raw_data = await (await fetch(url)).json(); + +/* filter for the Presidents */ +const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); + +/* sort by first presidential term */ +prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start); +prez.sort((l,r) => l.start.localeCompare(r.start)); + +/* flatten objects */ +const rows = prez.map(row => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday +})); + +/* generate worksheet and workbook */ +const worksheet = utils.json_to_sheet(rows); +const workbook = utils.book_new(); +utils.book_append_sheet(workbook, worksheet, "Dates"); + +/* fix headers */ +utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + +/* calculate column width */ +const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); +worksheet["!cols"] = [ { wch: max_width } ]; + +/* create an XLSX file and try to save to Presidents.xlsx */ +writeFileXLSX(workbook, "Presidents.xlsx"); +}); +'@ | Out-File -FilePath "index.js" -Encoding utf8 + +@' +<!DOCTYPE html> +<html lang="en"> + <head></head> + <body> + <h1>SheetJS Presidents Demo</h1> + <button id="xport">Click here to export</button> + <script type="module" src="./bundle.js"></script> + </body> +</html> +'@ | Out-File -FilePath "index.html" -Encoding utf8 + +npm i --save puppeteer express@4 + +@' +const puppeteer = require('puppeteer'); +const express = require('express'); +const app = express(); +app.use(express.static('./')); +app.listen(7262, async() => { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + await page.goto('http://localhost:7262/'); + await page.click("#xport"); + await new Promise((res,rej) => setTimeout(res, 1000)); + await browser.close(); + process.exit(); +}); +'@ | Out-File -FilePath "test.js" -Encoding utf8 + +## RollupJS 4.x + +npm i --save rollup@4.x @rollup/plugin-node-resolve +npx -y rollup@4.x index.js --plugin @rollup/plugin-node-resolve --file bundle.js --format iife +node test.js +npx -y xlsx-cli Presidents.xlsx | Select-Object -First 3 +Remove-Item -Path "bundle.js" -Force +Remove-Item -Path "Presidents.xlsx" -Force + +## RollupJS 3.x + +npm i --save rollup@3.x @rollup/plugin-node-resolve +npx -y rollup@3.x index.js --plugin @rollup/plugin-node-resolve --file bundle.js --format iife +node test.js +npx -y xlsx-cli Presidents.xlsx | Select-Object -First 3 +Remove-Item -Path "bundle.js" -Force +Remove-Item -Path "Presidents.xlsx" -Force + +## RollupJS 2.x + +npm i --save rollup@2.x @rollup/plugin-node-resolve +npx -y rollup@2.x index.js --plugin @rollup/plugin-node-resolve --file bundle.js --format iife +node test.js +npx -y xlsx-cli Presidents.xlsx | Select-Object -First 3 +Remove-Item -Path "bundle.js" -Force +Remove-Item -Path "Presidents.xlsx" -Force + +## RollupJS 1.x + +npm i --save rollup@1.x rollup-plugin-node-resolve +npx -y rollup@1.x index.js --plugin rollup-plugin-node-resolve --file bundle.js --format iife +node test.js +npx -y xlsx-cli Presidents.xlsx | Select-Object -First 3 +Remove-Item -Path "bundle.js" -Force +Remove-Item -Path "Presidents.xlsx" -Force + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/bundler/rspack.ps1 b/tests/bundler/rspack.ps1 new file mode 100644 index 0000000..2283b91 --- /dev/null +++ b/tests/bundler/rspack.ps1 @@ -0,0 +1,103 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/frontend/bundler/rspack + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-rspack" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +npm init -y + +$packageJson = Get-Content package.json -Raw -Encoding UTF8 | ConvertFrom-Json +$packageJson.PSObject.Properties.Remove("type") +$packageJson | ConvertTo-Json -Depth 20 | Set-Content package.json -Encoding ASCII + +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz @rspack/core @rspack/cli + +New-Item -ItemType Directory -Path "src" | Out-Null + +@' +import { utils, writeFileXLSX } from 'xlsx'; + +document.getElementById("xport").addEventListener("click", async() => { +/* fetch JSON data and parse */ +const url = "https://docs.sheetjs.com/executive.json"; +const raw_data = await (await fetch(url)).json(); + +/* filter for the Presidents */ +const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); + +/* sort by first presidential term */ +prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start); +prez.sort((l,r) => l.start.localeCompare(r.start)); + +/* flatten objects */ +const rows = prez.map(row => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday +})); + +/* generate worksheet and workbook */ +const worksheet = utils.json_to_sheet(rows); +const workbook = utils.book_new(); +utils.book_append_sheet(workbook, worksheet, "Dates"); + +/* fix headers */ +utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + +/* calculate column width */ +const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); +worksheet["!cols"] = [ { wch: max_width } ]; + +/* create an XLSX file and try to save to Presidents.xlsx */ +writeFileXLSX(workbook, "Presidents.xlsx"); +}); +'@ | Out-File -FilePath "src\index.js" -Encoding utf8 + +npx -p @rspack/cli rspack build + +@' +<!DOCTYPE html> +<html lang="en"> + <head></head> + <body> + <h1>SheetJS Presidents Demo</h1> + <button id="xport">Click here to export</button> + <script src="dist/main.js"></script> + </body> +</html> +'@ | Out-File -FilePath "index.html" -Encoding utf8 + +npm i --save puppeteer express + +@' +const puppeteer = require('puppeteer'); +const express = require('express'); +const app = express(); +app.use(express.static('./')); +app.listen(7262, async() => { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + page.on('request', req => console.log(req.url())); + await page.goto('http://localhost:7262/'); + await page.click("#xport"); + await new Promise((res,rej) => setTimeout(res, 1000)); + await browser.close(); + process.exit(); +}); +'@ | Out-File -FilePath "test.js" -Encoding utf8 + +node test.js +npx -y xlsx-cli Presidents.xlsx | Select-Object -First 3 + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/bundler/rspack.sh b/tests/bundler/rspack.sh index 59f7301..9469a4f 100755 --- a/tests/bundler/rspack.sh +++ b/tests/bundler/rspack.sh @@ -92,4 +92,3 @@ EOF node test.js npx -y xlsx-cli Presidents.xlsx | head -n 3 - diff --git a/tests/bundler/snowpack.ps1 b/tests/bundler/snowpack.ps1 new file mode 100644 index 0000000..7b95071 --- /dev/null +++ b/tests/bundler/snowpack.ps1 @@ -0,0 +1,5 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/frontend/bundler/ + +Write-Error "Snowpack does not work in Windows!" +Exit 1 \ No newline at end of file diff --git a/tests/bundler/swcpack.ps1 b/tests/bundler/swcpack.ps1 new file mode 100644 index 0000000..ed10fbb --- /dev/null +++ b/tests/bundler/swcpack.ps1 @@ -0,0 +1,109 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/frontend/bundler/swcpack + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-spack" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +npm init -y + +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz regenerator-runtime @swc/cli @swc/core +npm ls | Select-String "core" + +@' +import { utils, version, writeFileXLSX } from 'xlsx'; + +document.getElementById("xport").addEventListener("click", async() => { +/* fetch JSON data and parse */ +const url = "https://docs.sheetjs.com/executive.json"; +const raw_data = await (await fetch(url)).json(); + +/* filter for the Presidents */ +const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); + +/* sort by first presidential term */ +prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start); +prez.sort((l,r) => l.start.localeCompare(r.start)); + +/* flatten objects */ +const rows = prez.map(row => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday +})); + +/* generate worksheet and workbook */ +const worksheet = utils.json_to_sheet(rows); +const workbook = utils.book_new(); +utils.book_append_sheet(workbook, worksheet, "Dates"); + +/* fix headers */ +utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + +/* calculate column width */ +const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); +worksheet["!cols"] = [ { wch: max_width } ]; + +/* create an XLSX file and try to save to Presidents.xlsx */ +writeFileXLSX(workbook, "Presidents.xlsx"); +}); +'@ | Out-File -FilePath "index.js" -Encoding utf8 + +@' +module.exports = ({ + entry: { + 'web': __dirname + '/index.js', + }, + output: { + path: __dirname + '/lib' + }, + module: {}, +}); +'@ | Out-File -FilePath "spack.config.js" -Encoding utf8 + +npx spack + +@' +<!DOCTYPE html> +<html lang="en"> + <head></head> + <body> + <h1>SheetJS Presidents Demo</h1> + <button id="xport">Click here to export</button> + <script src="./lib/web.js"></script> + </body> +</html> +'@ | Out-File -FilePath "index.html" -Encoding utf8 + +npm i --save puppeteer express@4 + +@' +const puppeteer = require('puppeteer'); +const express = require('express'); +const app = express(); +app.use(express.static('./')); +app.listen(7262, async() => { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + await page.goto('http://localhost:7262/'); + await page.click("#xport"); + await new Promise((res,rej) => setTimeout(res, 1000)); + await browser.close(); + process.exit(); +}); +'@ | Out-File -FilePath "test.js" -Encoding utf8 + +node test.js +npx -y xlsx-cli Presidents.xlsx | Select-Object -First 3 + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/bundler/systemjs.ps1 b/tests/bundler/systemjs.ps1 new file mode 100644 index 0000000..e31fb4d --- /dev/null +++ b/tests/bundler/systemjs.ps1 @@ -0,0 +1,69 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/frontend/bundler/systemjs + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-systemjs" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +npm init -y + +## NodeJS Demo + +npm i --save https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/systemjs/SheetJSystem.js" -OutFile "SheetJSystem.js" + +$versions = @("6.x", "0.21.6", "0.20.19", "0.19.47") +foreach ($v in $versions) { + Write-Host "SystemJS NodeJS version $v" + + npm i --save "systemjs@$v" + node SheetJSystem.js + npx -y xlsx-cli Presidents.xlsx | Select-Object -First 3 + Remove-Item -Path "Presidents.xlsx" -Force +} + +## Browser Demo + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/pres.xlsx" -OutFile "pres.xlsx" + +npm i --save puppeteer + +@' +const path = require('path'); +const puppeteer = require('puppeteer'); +(async() => { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + await page.goto('https://docs.sheetjs.com/systemjs/systemjs'); + await new Promise((res,rej) => setTimeout(res, 3000)); // required in windows tests + const xlf = await page.$('#xlf'); + await xlf.uploadFile(path.resolve('./pres.xlsx')); + await page.evaluate(() => { + const xlf = document.querySelector('#xlf'); + const evt = new Event('change', { bubbles: true }); + xlf.dispatchEvent(evt); + }); + await new Promise((res,rej) => setTimeout(res, 1000)); + const text = await page.$eval('#out', el => el.innerText); + console.log(text); + await browser.close(); + process.exit(); +})(); +'@ | Out-File -FilePath "test.js" -Encoding utf8 + +Write-Host "SystemJS Browser Demo" +node test.js + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/bundler/systemjs.sh b/tests/bundler/systemjs.sh index f8f5999..1ceb223 100755 --- a/tests/bundler/systemjs.sh +++ b/tests/bundler/systemjs.sh @@ -59,5 +59,6 @@ const puppeteer = require('puppeteer'); })(); EOF +echo "SystemJS Browser Demo" node test.js diff --git a/tests/bundler/vite.ps1 b/tests/bundler/vite.ps1 new file mode 100644 index 0000000..da859fe --- /dev/null +++ b/tests/bundler/vite.ps1 @@ -0,0 +1,115 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/frontend/bundler/vitejs + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-vite-tests" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +for ($n = 3; $n -le 7; $n++) { + Write-Host "Processing Vite version $n" + + $projectDir = Join-Path -Path $tempDir -ChildPath "sheetjs-vite$n" + npm create -y "vite@$n" sheetjs-vite$n -- --template vue-ts --no-rolldown --no-interactive + Set-Location -Path $projectDir + + npm i + npm i --save puppeteer express@4 + npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz + npm ls | Select-String "vite" + + ## See https://github.com/vuejs/language-tools/issues/4484#issuecomment-2182469459 + if ($n -eq 4) { npm i "vue-tsc@2" } + + New-Item -ItemType Directory -Path "data" -Force | Out-Null + Invoke-WebRequest -Uri "https://docs.sheetjs.com/pres.xlsx" -OutFile "data\pres.xlsx" + + @' +<script setup lang="ts"> +import { version, utils, writeFileXLSX } from 'xlsx'; + +interface President { + terms: { "type": "prez" | "viceprez"; }[]; + name: { first: string; last: string; } + bio: { birthday: string; } +} + +async function xport() { +/* fetch JSON data and parse */ +const url = "https://docs.sheetjs.com/executive.json"; +const raw_data: President[] = await (await fetch(url)).json(); + +/* filter for the Presidents */ +const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); + +/* sort by first presidential term */ +prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start); +prez.sort((l,r) => l.start.localeCompare(r.start)); + +/* flatten objects */ +const rows = prez.map(row => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday +})); + +/* generate worksheet and workbook */ +const worksheet = utils.json_to_sheet(rows); +const workbook = utils.book_new(); +utils.book_append_sheet(workbook, worksheet, "Dates"); + +/* fix headers */ +utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + +/* calculate column width */ +const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); +worksheet["!cols"] = [ { wch: max_width } ]; + +/* create an XLSX file and try to save to Presidents.xlsx */ +console.log(utils.sheet_to_csv(worksheet)); +writeFileXLSX(workbook, "Presidents.xlsx"); +} + +</script> + +<template> + <button type="button" @click="xport">Export with SheetJS version {{ version }}</button> +</template> +'@ | Out-File -FilePath "src\components\HelloWorld.vue" -Encoding utf8 + + npx vite build + + @' +const puppeteer = require('puppeteer'); +const express = require('express'); +const app = express(); +app.use(express.static('./dist/')); +app.listen(7262, async() => { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + page.on('request', req => console.log(req.url())); + await page.goto('http://localhost:7262/'); + await page.click("button"); + await new Promise((res,rej) => setTimeout(res, 2000)); + await browser.close(); + process.exit(); +}); +'@ | Out-File -FilePath "test.cjs" -Encoding utf8 + + node test.cjs + npx -y xlsx-cli Presidents.xlsx | Select-Object -First 3 + Remove-Item -Path "Presidents.xlsx" -Force + + Set-Location -Path $tempDir +} + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/bundler/webpack.ps1 b/tests/bundler/webpack.ps1 new file mode 100644 index 0000000..4f625d1 --- /dev/null +++ b/tests/bundler/webpack.ps1 @@ -0,0 +1,150 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/frontend/bundler/webpack + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-webpack" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +npm init -y + +npm i --save https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz + +@' +import { utils, version, writeFileXLSX } from 'xlsx/dist/xlsx.full.min.js'; + +document.getElementById("xport").addEventListener("click", function() { + /* fetch JSON data and parse */ + var url = "https://docs.sheetjs.com/executive.json"; + fetch(url).then(function(res) { return res.json(); }).then(function(raw_data) { + + /* filter for the Presidents */ + var prez = raw_data.filter(function(row) { return row.terms.some(function(term) { return term.type === "prez"; }); }); + + /* sort by first presidential term */ + prez.forEach(function(row) { + row.start = row.terms.find(function(term) { + return term.type === "prez"; + }).start; + }); + prez.sort(function(l,r) { return l.start.localeCompare(r.start); }); + + /* flatten objects */ + var rows = prez.map(function(row) { return { + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday + }; }); + + /* generate worksheet and workbook */ + var worksheet = utils.json_to_sheet(rows); + var workbook = utils.book_new(); + utils.book_append_sheet(workbook, worksheet, "Dates"); + + /* fix headers */ + utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + + /* calculate column width */ + var max_width = rows.reduce(function(w, r) { return Math.max(w, r.name.length); }, 10); + worksheet["!cols"] = [ { wch: max_width } ]; + + /* create an XLSX file and try to save to Presidents.xlsx */ + writeFileXLSX(workbook, "Presidents.xlsx"); + }); +}); +'@ | Out-File -FilePath "index.js" -Encoding utf8 + +@' +module.exports = { + /* entry point index.js */ + entry: './index.js', + + /* write to index.min.js */ + output: { path:__dirname, filename: './index.min.js' } +} +'@ | Out-File -FilePath "webpack.config.js" -Encoding utf8 + +@' +<!DOCTYPE html> +<html lang="en"> + <head></head> + <body> + <h1>SheetJS Presidents Demo</h1> + <button id="xport">Click here to export</button> + <script src="./index.min.js"></script> + </body> +</html> +'@ | Out-File -FilePath "index.html" -Encoding utf8 + +npm i --save puppeteer express@4 + +@' +const puppeteer = require('puppeteer'); +const express = require('express'); +const app = express(); +app.use(express.static('./')); +app.listen(7262, async() => { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + await page.goto('http://localhost:7262/'); + await page.click("#xport"); + await new Promise((res,rej) => setTimeout(res, 1000)); + await browser.close(); + process.exit(); +}); +'@ | Out-File -FilePath "test.js" -Encoding utf8 + +$packageJson = Get-Content package.json -Raw -Encoding UTF8 | ConvertFrom-Json +$packageJson.PSObject.Properties.Remove("type") +$packageJson | ConvertTo-Json -Depth 20 | Set-Content package.json -Encoding ASCII + +## Webpack 2.x + +npx -y webpack@2.x -p +node test.js +npx -y xlsx-cli Presidents.xlsx | Select-Object -First 3 +Remove-Item -Path "index.min.js" -Force +Remove-Item -Path "Presidents.xlsx" -Force + +## Webpack 3.x + +npx -y webpack@3.x -p +node test.js +npx -y xlsx-cli Presidents.xlsx | Select-Object -First 3 +Remove-Item -Path "index.min.js" -Force +Remove-Item -Path "Presidents.xlsx" -Force + +## Webpack 4.x and 5.x do not need to import the standalone build + +$indexContent = Get-Content "index.js" -Raw +$indexContent = $indexContent -replace '/dist/xlsx.full.min.js', '' +$indexContent | Out-File -FilePath "index.js" -Encoding utf8 + +## Webpack 4.x + +npm i --save webpack@4.x webpack-cli@4.x +npx -y webpack --mode=production +node test.js +npx -y xlsx-cli Presidents.xlsx | Select-Object -First 3 +Remove-Item -Path "index.min.js" -Force +Remove-Item -Path "Presidents.xlsx" -Force + +## Webpack 5.x + +npm i --save webpack@5.x webpack-cli@5.x +npx -y webpack --mode=production +node test.js +npx -y xlsx-cli Presidents.xlsx | Select-Object -First 3 +Remove-Item -Path "index.min.js" -Force +Remove-Item -Path "Presidents.xlsx" -Force + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/bundler/wmr.ps1 b/tests/bundler/wmr.ps1 new file mode 100644 index 0000000..b2b072c --- /dev/null +++ b/tests/bundler/wmr.ps1 @@ -0,0 +1,96 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/frontend/bundler/ + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-wmr" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +npm init -y + +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz + +@' +import { utils, version, writeFileXLSX } from 'xlsx'; + +document.getElementById("xport").addEventListener("click", async() => { +/* fetch JSON data and parse */ +const url = "https://docs.sheetjs.com/executive.json"; +const raw_data = await (await fetch(url)).json(); + +/* filter for the Presidents */ +const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); + +/* sort by first presidential term */ +prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start); +prez.sort((l,r) => l.start.localeCompare(r.start)); + +/* flatten objects */ +const rows = prez.map(row => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday +})); + +/* generate worksheet and workbook */ +const worksheet = utils.json_to_sheet(rows); +const workbook = utils.book_new(); +utils.book_append_sheet(workbook, worksheet, "Dates"); + +/* fix headers */ +utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + +/* calculate column width */ +const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); +worksheet["!cols"] = [ { wch: max_width } ]; + +/* create an XLSX file and try to save to Presidents.xlsx */ +writeFileXLSX(workbook, "Presidents.xlsx"); +}); +'@ | Out-File -FilePath "index.js" -Encoding utf8 + +@' +<!DOCTYPE html> +<html lang="en"> + <head></head> + <body> + <h1>SheetJS Presidents Demo</h1> + <button id="xport">Click here to export</button> + <script type="module" src="./index.js"></script> + </body> +</html> +'@ | Out-File -FilePath "index.html" -Encoding utf8 + +npx -y wmr@3.8.0 build + +npm i --save puppeteer express@4 + +@' +const puppeteer = require('puppeteer'); +const express = require('express'); +const app = express(); +app.use(express.static('./dist')); +app.listen(7262, async() => { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + await page.goto('http://localhost:7262/'); + await page.click("#xport"); + await new Promise((res,rej) => setTimeout(res, 1000)); + await browser.close(); + process.exit(); +}); +'@ | Out-File -FilePath "test.js" -Encoding utf8 + +node test.js +npx -y xlsx-cli Presidents.xlsx | Select-Object -First 3 + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/cli/bunsea.ps1 b/tests/cli/bunsea.ps1 new file mode 100644 index 0000000..723f45b --- /dev/null +++ b/tests/cli/bunsea.ps1 @@ -0,0 +1,39 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/cli/bunsea + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-bunsea" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +bun --version + +curl -o pres.numbers https://docs.sheetjs.com/pres.numbers + +@' +const XLSX = require("xlsx"); + +/* process.argv[2] is the first argument to the script */ +const filename = process.argv[2]; + +/* read file */ +const wb = XLSX.readFile(filename); + +/* generate CSV of first sheet */ +const ws = wb.Sheets[wb.SheetNames[0]]; +const csv = XLSX.utils.sheet_to_csv(ws); + +/* print to terminal */ +console.log(csv); +'@ | Out-File -FilePath "sheet2csv.ts" -Encoding utf8 + +bun install https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz + +bun run sheet2csv.ts pres.numbers + +bun build ./sheet2csv.ts --compile --outfile sheet2csv +./sheet2csv pres.numbers + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/cli/denosea.ps1 b/tests/cli/denosea.ps1 new file mode 100644 index 0000000..9ea704a --- /dev/null +++ b/tests/cli/denosea.ps1 @@ -0,0 +1,21 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/cli/denosea + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-cli-deno" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +deno --version + +curl -o pres.numbers https://docs.sheetjs.com/pres.numbers + +deno run -r --allow-read --allow-import https://docs.sheetjs.com/cli/sheet2csv.ts pres.numbers + +deno compile -r --allow-read --allow-import https://docs.sheetjs.com/cli/sheet2csv.ts + +./sheet2csv pres.numbers + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/cli/nexe.ps1 b/tests/cli/nexe.ps1 new file mode 100644 index 0000000..db9cb2c --- /dev/null +++ b/tests/cli/nexe.ps1 @@ -0,0 +1,26 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/cli/nexe + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-nexe" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/pres.numbers" -OutFile "pres.numbers" +Invoke-WebRequest -Uri "https://docs.sheetjs.com/cli/xlsx-cli.js" -OutFile "xlsx-cli.js" + +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz exit-on-epipe commander@2 + +$ARCH = $env:PROCESSOR_ARCHITECTURE + +switch ($ARCH) { + "AMD64" { npx -y nexe -t 14.15.3 xlsx-cli.js } + "ARM64" { npx -y nexe xlsx-cli.js --build --python=$(Get-Command python3).Source } + default { Write-Error "unsupported architecture: $ARCH"; exit 1 } +} + +.\xlsx-cli pres.numbers + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/cli/nexe.sh b/tests/cli/nexe.sh index e1e2491..5ed6b11 100755 --- a/tests/cli/nexe.sh +++ b/tests/cli/nexe.sh @@ -6,7 +6,6 @@ mkdir sheetjs-nexe cd sheetjs-nexe curl -o pres.numbers https://docs.sheetjs.com/pres.numbers - curl -o xlsx-cli.js https://docs.sheetjs.com/cli/xlsx-cli.js npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz exit-on-epipe commander@2 @@ -26,5 +25,4 @@ case "$ARCH" in *) echo "unsupported architecture: $ARCH"; exit 1 ;; esac -# Run the generated binary ./xlsx-cli pres.numbers diff --git a/tests/cli/nodesea.ps1 b/tests/cli/nodesea.ps1 new file mode 100644 index 0000000..df1e340 --- /dev/null +++ b/tests/cli/nodesea.ps1 @@ -0,0 +1,115 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/cli/nodesea + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-sea" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +# NOTE: This effectuates "Native Tools Command Prompt" + +$vsVersions = @("2022\Community", "2022\Professional", "2022\Enterprise", "2019\Community") + +foreach ($vsVersion in $vsVersions) { + $vcbasePath = "${env:ProgramFiles}\Microsoft Visual Studio\$vsVersion" + $vcvarsPath = "${env:ProgramFiles}\Microsoft Visual Studio\$vsVersion\VC\Auxiliary\Build\vcvars64.bat" + if (Test-Path -Path $vcvarsPath) { break } +} + +$tempEnvFile = [System.IO.Path]::GetTempFileName() + +Push-Location "$vcbasePath" +cmd.exe /c "`"$vcvarsPath`" && set > `"$tempEnvFile`"" +Pop-Location + +Get-Content "$tempEnvFile" | ForEach-Object { if ($_ -match '^([^=]+)=(.*)$') { + $name = $matches[1] + $value = $matches[2] + + if ($name -ne 'PATH') { + Set-Item -Path "Env:$name" -Value $value + } else { + $env:PATH = "$value;$env:PATH" + } +} } + +Remove-Item "$tempEnvFile" -Force -ErrorAction SilentlyContinue + +node --version + +npm init -y + +@' +// 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); +'@ | Out-File -FilePath "sheet2csv.js" -Encoding utf8 + +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz + +### Script Test + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/pres.numbers" -OutFile "pres.numbers" + +node sheet2csv.js pres.numbers + +### SEA Bundle + +@' +{ + "main": "sheet2csv.js", + "output": "sheet2csv.blob" +} +'@ | Out-File -FilePath "sheet2csv.json" -Encoding utf8 + +node --experimental-sea-config sheet2csv.json + +# Local Copy +$nodePath = (Get-Command node).Source +Copy-Item $nodePath "sheet2csv.exe" + +# Remove the code signature +# (windows) +signtool remove /s .\sheet2csv.exe + +# Inject the SEA bundle +## NOTE: npx -y postject seemed to fail in windows :( +npm i -g postject +postject --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 sheet2csv.exe NODE_SEA_BLOB sheet2csv.blob + +# Resign the binary +$cert = New-SelfSignedCertificate -Type CodeSigning -DnsName "www.onlyspans.net" -CertStoreLocation Cert:\CurrentUser\My +$pass = ConvertTo-SecureString -String "hunter2" -Force -AsPlainText +Export-PfxCertificate -Cert "cert:\CurrentUser\My\$($cert.Thumbprint)" -FilePath "mycert.pfx" -Password $pass + +## NOTE: if self-signed cert is not trusted, verify will show an error +$cert | Export-Certificate -FilePath "mycert.cer" +Import-Certificate -FilePath "mycert.cer" -CertStoreLocation Cert:\CurrentUser\Root | Out-Null + +signtool sign /v /f mycert.pfx /p hunter2 /fd SHA256 sheet2csv.exe + +### Standalone Test + +.\sheet2csv.exe pres.numbers + +# Validate the signature + +signtool verify /v /pa sheet2csv.exe + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force diff --git a/tests/cli/nodesea.sh b/tests/cli/nodesea.sh index 588e4e6..f1c0d06 100755 --- a/tests/cli/nodesea.sh +++ b/tests/cli/nodesea.sh @@ -48,18 +48,26 @@ EOF node --experimental-sea-config sheet2csv.json +# Local Copy cp `which node` sheet2csv -## NOTE: codesign required for macOS +# Remove the code signature +# (macos) command -v codesign has_cs=$? if [[ "$has_cs" == "0" ]]; then codesign --remove-signature ./sheet2csv; fi +# Inject the SEA bundle npx -y postject --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 --macho-segment-name NODE_SEA sheet2csv NODE_SEA_BLOB sheet2csv.blob +# Resign the binary if [[ "$has_cs" == "0" ]]; then codesign -s - ./sheet2csv; fi +### Standalone Test + ./sheet2csv pres.numbers +# Validate the signature + if [[ "$has_cs" == "0" ]]; then codesign -dv ./sheet2csv; fi diff --git a/tests/cli/pkg.ps1 b/tests/cli/pkg.ps1 new file mode 100644 index 0000000..cb7d14c --- /dev/null +++ b/tests/cli/pkg.ps1 @@ -0,0 +1,23 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/cli/pkg + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-pkg" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/pres.numbers" -OutFile "pres.numbers" +Invoke-WebRequest -Uri "https://docs.sheetjs.com/cli/xlsx-cli.js" -OutFile "xlsx-cli.js" + +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz exit-on-epipe commander@2 + +$OS = "win" +$ARCH = "x64" + +npx -y pkg -t "node18-win-$ARCH,node18-linux-$ARCH,node18-macos-$ARCH" xlsx-cli.js + +.\xlsx-cli-win.exe pres.numbers + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/cli/pkg.sh b/tests/cli/pkg.sh index 8d0f93e..0a7e362 100755 --- a/tests/cli/pkg.sh +++ b/tests/cli/pkg.sh @@ -6,7 +6,6 @@ mkdir sheetjs-pkg cd sheetjs-pkg curl -o pres.numbers https://docs.sheetjs.com/pres.numbers - curl -o xlsx-cli.js https://docs.sheetjs.com/cli/xlsx-cli.js npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz exit-on-epipe commander@2 @@ -26,8 +25,6 @@ case "$ARCH" in *) echo "unsupported arch: $ARCH"; exit 1 ;; esac -# Build for the current platform npx -y pkg -t "node18-win-${ARCH},node18-linux-${ARCH},node18-macos-${ARCH}" xlsx-cli.js -# Run the appropriate binary based on OS ./xlsx-cli-${OS} pres.numbers diff --git a/tests/cli/txiki.ps1 b/tests/cli/txiki.ps1 new file mode 100644 index 0000000..fcd0b9f --- /dev/null +++ b/tests/cli/txiki.ps1 @@ -0,0 +1,56 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/cli/txiki + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-txiki" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/pres.numbers" -OutFile "pres.numbers" + +@' +const XLSX = require("./xlsx.full.min"); + +/* tjs.args[1] is the first argument to the script */ +const filename = tjs.args[1]; + +/* read and parse file */ +const data = await tjs.readFile(filename); +const wb = XLSX.read(data); + +/* generate CSV of first sheet */ +const ws = wb.Sheets[wb.SheetNames[0]]; +const csv = XLSX.utils.sheet_to_csv(ws); + +/* print to terminal */ +console.log(csv); +'@ | Out-File -FilePath "sheet2csv.js" -Encoding utf8 + +Invoke-WebRequest -Uri "https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js" -OutFile "xlsx.full.min.js" + +$txikiUrl = "https://github.com/saghul/txiki.js/releases/download/v24.12.0/txiki-windows-x86_64.zip" +$txikiZip = "txiki-windows-x86_64.zip" + +Invoke-WebRequest -Uri $txikiUrl -OutFile $txikiZip + +# Extract the zip file +Expand-Archive -Path $txikiZip -DestinationPath "." + +# Move contents from subdirectory to current directory +$txikiDir = Get-ChildItem -Directory -Filter "txiki-windows-x86_64*" | Select-Object -First 1 +if ($txikiDir) { + Get-ChildItem -Path $txikiDir.FullName -File | Move-Item -Destination "." + Remove-Item -Path $txikiDir.FullName -Recurse -Force +} + +# Bundle the script +npx -y esbuild sheet2csv.js --bundle --outfile=bundle.js --platform=neutral + +# Compile and run +.\tjs compile bundle.js sheet2csv +.\sheet2csv pres.numbers + +# Cleanup +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/data/alasql-bun.ps1 b/tests/data/alasql-bun.ps1 new file mode 100644 index 0000000..8dff511 --- /dev/null +++ b/tests/data/alasql-bun.ps1 @@ -0,0 +1,45 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/data/alasql/#nodejs-example + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-alasql" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +@' +{ + "overrides": { + "xlsx": "https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz" + } +} +'@ | Out-File -FilePath "package.json" -Encoding utf8 + +bun i --save alasql@3.1.0 https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/pres.numbers" -OutFile "pres.numbers" + +@' +const { promise: alasql } = require("alasql"); + +(async() => { + /* read data from spreadsheet to JS */ + const data = await alasql(` + SELECT \`Name\`, \`Index\` + FROM XLSX("pres.numbers", {autoExt:false}) + WHERE \`Index\` < 45 + `); + console.log(data); + + /* write data from JS to spreadsheet */ + data.push({ Name: "SheetJS Dev", Index: 47 }); + await alasql(`SELECT * INTO XLSX("SheetJSAlaSQL1.xlsx") FROM ?`, [data]); +})(); +'@ | Out-File -FilePath "SheetJSAlaSQL.js" -Encoding utf8 + +bun run SheetJSAlaSQL.js + +bunx xlsx-cli SheetJSAlaSQL1.xlsx + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/data/alasql-node.ps1 b/tests/data/alasql-node.ps1 new file mode 100644 index 0000000..5ece5e4 --- /dev/null +++ b/tests/data/alasql-node.ps1 @@ -0,0 +1,45 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/data/alasql/#nodejs-example + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-alasql" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +@' +{ + "overrides": { + "xlsx": "https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz" + } +} +'@ | Out-File -FilePath "package.json" -Encoding utf8 + +npm i --save alasql@3.1.0 https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/pres.numbers" -OutFile "pres.numbers" + +@' +const { promise: alasql } = require("alasql"); + +(async() => { + /* read data from spreadsheet to JS */ + const data = await alasql(` + SELECT \`Name\`, \`Index\` + FROM XLSX("pres.numbers", {autoExt:false}) + WHERE \`Index\` < 45 + `); + console.log(data); + + /* write data from JS to spreadsheet */ + data.push({ Name: "SheetJS Dev", Index: 47 }); + await alasql(`SELECT * INTO XLSX("SheetJSAlaSQL1.xlsx") FROM ?`, [data]); +})(); +'@ | Out-File -FilePath "SheetJSAlaSQL.js" -Encoding utf8 + +node SheetJSAlaSQL.js + +npx xlsx-cli SheetJSAlaSQL1.xlsx + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/data/knexjs.ps1 b/tests/data/knexjs.ps1 new file mode 100644 index 0000000..9a2f1a1 --- /dev/null +++ b/tests/data/knexjs.ps1 @@ -0,0 +1,52 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/data/knex + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-knexjs" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +# Download sqlite CLI +Invoke-WebRequest -Uri "https://www.sqlite.org/2026/sqlite-tools-win-x64-3510200.zip" -OutFile "sqlite.zip" +Expand-Archive sqlite.zip +Move-Item */sqlite3.exe . + +npm init -y +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/knex/SheetJSKnexTest.js" -OutFile "SheetJSKnexTest.js" +Invoke-WebRequest -Uri "https://docs.sheetjs.com/pres.numbers" -OutFile "pres.numbers" + +Copy-Item -Path "SheetJSKnexTest.js" -Destination "SheetJSKnexTestOrig.js" + +# Workaround for KnexJS 0.21.20 + +Get-Content -Path "SheetJSKnexTestOrig.js" | ForEach-Object { $_ -replace 'better-sqlite3', 'sqlite' } | Out-File -FilePath "SheetJSKnexTest.js" -Encoding utf8 + +$oldVersions = @("0.21.20") +foreach ($n in $oldVersions) { + npm i --save knex@$n sqlite3 + npm ls | Select-String "knex" + + node SheetJSKnexTest.js + npx xlsx-cli SheetJSKnex.xlsx + .\sqlite3.exe SheetJSKnex.db 'select * from Test_Table' +} + +# Newer KnexJS versions + +Move-Item -Path "SheetJSKnexTestOrig.js" -Destination "SheetJSKnexTest.js" -Force + +$newVersions = @("2.4", "2.5", "3.1") +foreach ($n in $newVersions) { + npm i --save knex@$n better-sqlite3 + npm ls | Select-String "knex" + + node SheetJSKnexTest.js + npx xlsx-cli SheetJSKnex.xlsx + .\sqlite3.exe SheetJSKnex.db 'select * from Test_Table' +} + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/data/pouchdb.ps1 b/tests/data/pouchdb.ps1 new file mode 100644 index 0000000..9291a49 --- /dev/null +++ b/tests/data/pouchdb.ps1 @@ -0,0 +1,110 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/data/pouchdb + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-pouch" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/pouchdb/master.zip" -OutFile "master.zip" + +Expand-Archive -Path "master.zip" -DestinationPath "." +Set-Location -Path "getting-started-todo-master" + +# awk 'NR>1{print p} {p = $0}' js/app.js > export_code.js +$prev = $null +Get-Content js/app.js | ForEach-Object { + if ($prev -ne $null) { $_out += "`n" + $prev } + $prev = $_ +} +$_out | Set-Content export_code.js + +@' + document.getElementById("xport").addEventListener("click", function() { + console.log("clicked"); + db.allDocs({include_docs: true, descending: true}, function(err, doc) { + const aoo = doc.rows.map(r => { + const { _id, _rev, ...rest } = r.doc; + return rest; + }); + const ws = XLSX.utils.json_to_sheet(aoo); + const wb = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); + XLSX.writeFile(wb, "SheetJSPouch.xlsx"); + }); + }); +})(); +'@ | Out-File -FilePath "export_code.js" -Append -Encoding utf8 +Copy-Item -Path "export_code.js" -Destination "js\app.js" -Force + +$indexContent = Get-Content -Path "index.html" -Raw +$modifiedIndex = $indexContent -replace '<body>', '<body><script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script><button id="xport">Export!</button>' +$modifiedIndex | Out-File -FilePath "index.html" -Encoding utf8 + +npm init -y +npm i --save puppeteer express@4 + +@' +const puppeteer = require('puppeteer'); +const express = require('express'); +const app = express(); +app.use(express.static('./')); +app.listen(7262, async() => { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + page.on('request', req => console.log(req.url())); + await page.goto('http://localhost:7262/'); + await new Promise((res,rej) => setTimeout(res, 3000)); + + await page.focus('#new-todo'); + await page.keyboard.type('JS'); + await page.keyboard.press('Enter'); + await new Promise((res,rej) => setTimeout(res, 1000)); + + await page.focus('#new-todo'); + await page.keyboard.type('Sheet'); + await page.keyboard.press('Enter'); + await new Promise((res,rej) => setTimeout(res, 1000)); + + const toggles = await page.$$('.toggle'); + await toggles[0].click(); + await new Promise((res,rej) => setTimeout(res, 1000)); + + // Click export button + await page.click('#xport'); + await new Promise((res,rej) => setTimeout(res, 3000)); + + await browser.close(); + process.exit(); +}); +'@ | Out-File -FilePath "test.js" -Encoding utf8 + +$versions = @("9.0.0", "8.0.1", "7.3.1", "6.4.3", "5.4.5", "4.0.3", "3.6.0") + +foreach ($version in $versions) { + Write-Host "PouchDB $version" + + Copy-Item -Path "index.html" -Destination "index.html.bak" -Force + + $currentIndex = Get-Content -Path "index.html" -Raw + $modifiedIndex = $currentIndex -replace 'pouchdb/3.2.0/pouchdb.min.js', "npm/pouchdb@${version}/dist/pouchdb.min.js" + $modifiedIndex | Out-File -FilePath "index.html" -Encoding utf8 + + node test.js + npx xlsx-cli SheetJSPouch.xlsx | Select-Object -First 3 + Remove-Item -Path "SheetJSPouch.xlsx" -Force + + Copy-Item -Path "index.html.bak" -Destination "index.html" -Force +} + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/dom/cheerio.ps1 b/tests/dom/cheerio.ps1 new file mode 100644 index 0000000..a211e0b --- /dev/null +++ b/tests/dom/cheerio.ps1 @@ -0,0 +1,26 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/net/dom#cheeriojs + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-cheeriojs" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/dom/SheetJSCheerio.js" -OutFile "SheetJSCheerio.js" -MaximumRedirection 20 +# NOTE: IWR does not correctly handle the redirect from SheetJSTable.html +Invoke-WebRequest -Uri "https://docs.sheetjs.com/dom/SheetJSTable" -OutFile "SheetJSTable.html" -MaximumRedirection 20 + +$versions = @("1.2.0") +foreach ($version in $versions) { + if (Test-Path -Path "SheetJSCheerio.xlsx") { Remove-Item -Path "SheetJSCheerio.xlsx" -Force } + npm i --save cheerio@$version + npm ls cheerio + node SheetJSCheerio.js + npx -y xlsx-cli SheetJSCheerio.xlsx | Select-Object -First 3 +} + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/dom/cheerio.sh b/tests/dom/cheerio.sh index e80cae5..7f8e8d2 100755 --- a/tests/dom/cheerio.sh +++ b/tests/dom/cheerio.sh @@ -11,7 +11,7 @@ npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz curl -LO https://docs.sheetjs.com/dom/SheetJSCheerio.js curl -LO https://docs.sheetjs.com/dom/SheetJSTable.html -for n in 1.1.2; do +for n in 1.2.0; do rm -f SheetJSCheerio.xlsx npm i --save cheerio@$n npm ls | grep cheerio diff --git a/tests/email/pst.ps1 b/tests/email/pst.ps1 new file mode 100644 index 0000000..d98aad7 --- /dev/null +++ b/tests/email/pst.ps1 @@ -0,0 +1,22 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/net/email/pst + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-pst" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +npm init -y + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/pst/SheetJSPST.js" -OutFile "SheetJSPST.js" +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz pst-extractor@1.11.0 + +node --version +node SheetJSPST.js + +bun --version +bun SheetJSPST.js + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/engines/v8-rust.ps1 b/tests/engines/v8-rust.ps1 new file mode 100644 index 0000000..846c4e7 --- /dev/null +++ b/tests/engines/v8-rust.ps1 @@ -0,0 +1,26 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/engines/v8 + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-rustyv8" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +cargo new sheetjs-rustyv8 +Set-Location -Path "sheetjs-rustyv8" +cargo run + +cargo add v8 +cargo run + +Invoke-WebRequest -Uri "https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js" -OutFile "xlsx.full.min.js" +Invoke-WebRequest -Uri "https://docs.sheetjs.com/pres.numbers" -OutFile "pres.numbers" + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/v8/main.rs" -OutFile "src\main.rs" +cargo run --release pres.numbers + +npx -y xlsx-cli sheetjsw.xlsb + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/engines/v8-rust.sh b/tests/engines/v8-rust.sh index fa8fd3e..392c5e5 100755 --- a/tests/engines/v8-rust.sh +++ b/tests/engines/v8-rust.sh @@ -18,4 +18,3 @@ curl -L -o src/main.rs https://docs.sheetjs.com/v8/main.rs cargo run --release pres.numbers; echo $? npx -y xlsx-cli sheetjsw.xlsb - diff --git a/tests/installation/bun.ps1 b/tests/installation/bun.ps1 new file mode 100644 index 0000000..0a986d1 --- /dev/null +++ b/tests/installation/bun.ps1 @@ -0,0 +1,66 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/getting-started/installation/bun + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-bun-dle" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +bun init -y + +bun install https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz +if ($LASTEXITCODE -ne 0) { bun install xlsx@https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz } + +@' +import * as XLSX from 'xlsx'; +import * as fs from 'fs'; +XLSX.set_fs(fs); + +/* fetch JSON data and parse */ +const url = "https://docs.sheetjs.com/executive.json"; +const raw_data = await (await fetch(url)).json(); + +/* filter for the Presidents */ +const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); + +/* sort by first presidential term */ +prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start); +prez.sort((l,r) => l.start.localeCompare(r.start)); + +/* flatten objects */ +const rows = prez.map(row => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday +})); + +/* generate worksheet and workbook */ +const worksheet = XLSX.utils.json_to_sheet(rows); +const workbook = XLSX.utils.book_new(); +XLSX.utils.book_append_sheet(workbook, worksheet, "Dates"); + +/* fix headers */ +XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + +/* calculate column width */ +const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); +worksheet["!cols"] = [ { wch: max_width } ]; + +/* create an XLSX file and try to save to Presidents.xlsx */ +XLSX.writeFile(workbook, "Presidents.xlsx"); +'@ | Out-File -FilePath "SheetJSBun.js" -Encoding utf8 + +bun build --target=bun SheetJSBun.js --outfile=app.js + +Remove-Item -Path "package.json" -Force +Remove-Item -Path "bun.lockb" -Force -ErrorAction SilentlyContinue +Remove-Item -Path "bun.lock" -Force -ErrorAction SilentlyContinue +Remove-Item -Path "SheetJSBun.js" -Force +Remove-Item -Path "node_modules" -Recurse -Force -ErrorAction SilentlyContinue + +bun app.js + +bunx xlsx-cli Presidents.xlsx | Select-Object -First 10 + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/installation/bun.sh b/tests/installation/bun.sh index 661d3d4..ed23bfc 100755 --- a/tests/installation/bun.sh +++ b/tests/installation/bun.sh @@ -5,7 +5,8 @@ cd /tmp rm -rf sheetjs-bun-dle mkdir sheetjs-bun-dle cd sheetjs-bun-dle -echo "{}" > package.json + +bun init -y bun install https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz || bun install xlsx@https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz diff --git a/tests/math/tfjs-node.ps1 b/tests/math/tfjs-node.ps1 new file mode 100644 index 0000000..54b502b --- /dev/null +++ b/tests/math/tfjs-node.ps1 @@ -0,0 +1,33 @@ +#!/usr/bin/env powershell +# https://docs.sheetjs.com/docs/demos/math/tensorflow#nodejs-demo + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-tfjs-csv" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +npm init -y + +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz @tensorflow/tfjs @tensorflow/tfjs-node + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/tfjs/SheetJSTF.js" -OutFile "SheetJSTF.js" + +# this version uses `nvm` to cycle through node versions +$nvmCommandAvailable = Get-Command "nvm" -ErrorAction SilentlyContinue +if(! ($nvmCommandAvailable)) { + node --version + node SheetJSTF.js +} else { + +$versions = @(20, 22, 24) +foreach ($n in $versions) { + nvm install $n + nvm use $n + node --version + node SheetJSTF.js +} +} + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/server/express-worker.ps1 b/tests/server/express-worker.ps1 new file mode 100644 index 0000000..d7d4b6f --- /dev/null +++ b/tests/server/express-worker.ps1 @@ -0,0 +1,96 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/net/server#worker-threads + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-worker" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +'{ "type": "module" }' | Out-File -FilePath "package.json" -Encoding ASCII + +@' +/* load the worker_threads module */ +import { parentPort } from 'node:worker_threads'; + +/* load the SheetJS module and hook to FS */ +import { set_fs, readFile, write } from 'xlsx'; +import * as fs from 'fs'; +set_fs(fs); + +/* the server will send a message with the `path` field */ +parentPort.on('message', (task) => { + // read file + const wb = readFile(task.path, { dense: true }); + // send back XLSX + parentPort.postMessage(write(wb, { type: "buffer", bookType: "xlsx" })); + // remove file + fs.unlink(task.path, ()=>{}); +}); +'@ | Out-File -FilePath "worker.js" -Encoding ASCII + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/server/worker_pool.js" -OutFile "worker_pool.js" +Invoke-WebRequest -Uri "https://docs.sheetjs.com/pres.numbers" -OutFile "pres.numbers" + +@' +/* load dependencies */ +import os from 'node:os'; +import process from 'node:process' +import express from 'express'; +import formidable from 'formidable'; + +/* load worker pool */ +import WorkerPool from './worker_pool.js'; + +const pool = new WorkerPool(os.cpus().length); +process.on("beforeExit", () => { pool.close(); }) + +/* create server */ +const app = express(); +app.post('/', (req, res, next) => { + // parse body + const form = formidable({}); + form.parse(req, (err, fields, files) => { + // look for "upload" field + if(err) return next(err); + if(!files["upload"]) return next(new Error("missing `upload` file")); + + // send a message to the worker with the path to the uploaded file + pool.runTask({ path: files["upload"].filepath }, (err, result) => { + if(err) return next(err); + // send the file back as an attachment + res.attachment("SheetJSPool.xlsx"); + res.status(200).end(result); + }); + }); +}); + +// start server +app.listen(7262, () => { console.log(`Example app listening on port 7262`); }); +'@ | Out-File -FilePath "main.mjs" -Encoding ASCII + +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz formidable@2.1.2 + +$expressVersions = @("4.21.2", "5.1.0") +foreach ($express in $expressVersions) { + npm i --save express@$express + npm ls | Select-String "express" + # Test with different node versions (if available) + $nodeVersions = @(20, 22, 24) + foreach ($n in $nodeVersions) { + nvm use $n + node --version + + $proc = Start-Process -NoNewWindow -FilePath "node" -ArgumentList "main.mjs" -PassThru + Start-Sleep -Seconds 2 + pwsh -NonInteractive -Command 'Invoke-WebRequest -Uri "http://localhost:7262/" -Method Post -Form @{ upload = Get-Item "pres.numbers" } -OutFile "SheetJSPool.xlsx"' + + npx -y xlsx-cli SheetJSPool.xlsx | Select-Object -First 10 + Remove-Item -Path "SheetJSPool.xlsx" -Force + + $proc | Stop-Process + } +} + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/static/eleventy.ps1 b/tests/static/eleventy.ps1 new file mode 100644 index 0000000..1f9422f --- /dev/null +++ b/tests/static/eleventy.ps1 @@ -0,0 +1,33 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/static/eleventy +# This script builds the Static Site. It does not test HMR! + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-11ty" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +npm init -y + +New-Item -ItemType Directory -Path "_data" | Out-Null +Invoke-WebRequest -Uri "https://docs.sheetjs.com/pres.xlsx" -OutFile "_data/pres.xlsx" +Invoke-WebRequest -Uri "https://docs.sheetjs.com/eleventy/_eleventy.js" -OutFile ".eleventy.js" +Invoke-WebRequest -Uri "https://docs.sheetjs.com/eleventy/index.njk" -OutFile "index.njk" + +$versions = @("2.0.1", "3.1.2", "4.0.0-alpha.6") +foreach ($n in $versions) { + npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz @11ty/eleventy@$n + npx @11ty/eleventy@$n + + $htmlContent = Get-Content -Path "_site/index.html" -Raw + $clintonCount = ($htmlContent | Select-String -Pattern "Clinton" -AllMatches).Matches.Count + $besseljCount = ($htmlContent | Select-String -Pattern "BESSELJ" -AllMatches).Matches.Count + $jsCount = ($htmlContent | Select-String -Pattern '\.js' -AllMatches).Matches.Count + + Write-Output "Clinton $clintonCount BESSELJ $besseljCount JS $jsCount" + # Expected output: Clinton 1 BESSELJ 0 JS 0 +} + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/static/eleventy.sh b/tests/static/eleventy.sh index 7acbe25..d79c790 100755 --- a/tests/static/eleventy.sh +++ b/tests/static/eleventy.sh @@ -13,7 +13,7 @@ curl -Lo _data/pres.xlsx https://docs.sheetjs.com/pres.xlsx curl -L -o .eleventy.js https://docs.sheetjs.com/eleventy/_eleventy.js curl -LO https://docs.sheetjs.com/eleventy/index.njk -for n in 2.0.1 3.1.2; do +for n in 2.0.1 3.1.2 4.0.0-alpha.6; do npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz @11ty/eleventy@$n npx @11ty/eleventy@$n diff --git a/tests/static/esbuild.ps1 b/tests/static/esbuild.ps1 new file mode 100644 index 0000000..f593f7a --- /dev/null +++ b/tests/static/esbuild.ps1 @@ -0,0 +1,84 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/demos/static/esbuild + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-esb" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +npm init -y + +npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz +npm i --save puppeteer express + +@' +<!DOCTYPE html> +<html> + <head> + <title>SheetJS + ESBuild + + + + + +'@ | Out-File -FilePath "index.html" -Encoding utf8 + +@' +import data from './pres.numbers' +const elt = document.createElement('div'); +elt.innerHTML = "" + + data.map((row) => ` + + + `).join("") + +"
NameIndex
${row.Name}${row.Index}
"; +document.body.appendChild(elt); +'@ | Out-File -FilePath "app.js" -Encoding utf8 + +Invoke-WebRequest -Uri "https://docs.sheetjs.com/esbuild/build.mjs" -OutFile "build.mjs" +Invoke-WebRequest -Uri "https://docs.sheetjs.com/pres.numbers" -OutFile "pres.numbers" + +@' +const puppeteer = require('puppeteer'); +const express = require('express'); +const app = express(); +app.use(express.static('./')); +app.listen(7262, async() => { + await new Promise((res,rej) => setTimeout(res, 1000)); + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + page.on("console", msg => console.log("PAGE LOG:", msg.text())); + await page.setViewport({width: 1920, height: 1080}); + const client = await page.target().createCDPSession(); + await client.send('Browser.setDownloadBehavior', { + behavior: 'allow', + downloadPath: require("path").resolve('./') + }); + page.on('request', req => console.log(req.url())); + await page.goto('http://localhost:7262/'); + await new Promise((res,rej) => setTimeout(res, 1000)); + const innerText = await page.evaluate(() => document.body.innerText); + console.log(innerText); + await browser.close(); + process.exit(); +}); +'@ | Out-File -FilePath "test.js" -Encoding utf8 + +$versions = @("0.9.1", "0.9", "0.10", "0.11", "0.12", "0.13", "0.14", "0.15", "0.16", "0.17", "0.18", "0.19", "0.20", "0.21", "0.22", "0.23", "0.24", "0.25", "0.26", "0.27") + +foreach ($n in $versions) { + npm rm --save esbuild + npm i --save esbuild@$n + npm ls | Select-String "esbuild" + if (Test-Path -Path "out.js") { Remove-Item -Path "out.js" -Force } + node build.mjs + $clintonCount = (Select-String -Path "out.js" -Pattern "Clinton" | Measure-Object).Count + $besseljCount = (Select-String -Path "out.js" -Pattern "BESSELJ" | Measure-Object).Count + Write-Host "Clinton $clintonCount BESSELJ $besseljCount" + node test.js +} + + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/static/esbuild.sh b/tests/static/esbuild.sh index 940cc9c..5f4fd2a 100755 --- a/tests/static/esbuild.sh +++ b/tests/static/esbuild.sh @@ -63,7 +63,7 @@ app.listen(7262, async() => { EOF -for n in 0.9.1 0.{9..25}; do +for n in 0.9.1 0.{9..27}; do npm rm --save esbuild npm i --save esbuild@$n npm ls | grep esbuild diff --git a/tests/tutorials/export/bun.ps1 b/tests/tutorials/export/bun.ps1 new file mode 100644 index 0000000..ee440a8 --- /dev/null +++ b/tests/tutorials/export/bun.ps1 @@ -0,0 +1,55 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/getting-started/installation/bun + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-bun" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +bun init -y +bun i --save https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz + +@' +const XLSX = require("xlsx"); + +(async() => { + /* fetch JSON data and parse */ + const url = "https://docs.sheetjs.com/executive.json"; + const raw_data = await (await fetch(url)).json(); + + /* filter for the Presidents */ + const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); + + /* sort by first presidential term */ + prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start); + prez.sort((l,r) => l.start.localeCompare(r.start)); + + /* flatten objects */ + const rows = prez.map(row => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday + })); + + /* generate worksheet and workbook */ + const worksheet = XLSX.utils.json_to_sheet(rows); + const workbook = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(workbook, worksheet, "Dates"); + + /* fix headers */ + XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + + /* calculate column width */ + const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); + worksheet["!cols"] = [ { wch: max_width } ]; + + /* create an XLSX file and try to save to Presidents.xlsx */ + XLSX.writeFile(workbook, "Presidents.xlsx", { compression: true }); +})(); +'@ | Out-File -FilePath "SheetJSNodeJS.js" -Encoding utf8 + +bun SheetJSNodeJS.js +npx xlsx-cli Presidents.xlsx | Select-Object -First 10 + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/tutorials/export/deno.ps1 b/tests/tutorials/export/deno.ps1 new file mode 100644 index 0000000..f7f4293 --- /dev/null +++ b/tests/tutorials/export/deno.ps1 @@ -0,0 +1,51 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/getting-started/installation/deno + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-deno" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +@' +// @deno-types="https://cdn.sheetjs.com/xlsx-0.20.3/package/types/index.d.ts" +import * as XLSX from 'https://cdn.sheetjs.com/xlsx-0.20.3/package/xlsx.mjs'; + +/* fetch JSON data and parse */ +const url = "https://docs.sheetjs.com/executive.json"; +const raw_data = await (await fetch(url)).json(); + +/* filter for the Presidents */ +const prez = raw_data.filter((row: any) => row.terms.some((term: any) => term.type === "prez")); + +/* sort by first presidential term */ +prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start); +prez.sort((l,r) => l.start.localeCompare(r.start)); + +/* flatten objects */ +const rows = prez.map((row: any) => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday +})); + +/* generate worksheet and workbook */ +const worksheet = XLSX.utils.json_to_sheet(rows); +const workbook = XLSX.utils.book_new(); +XLSX.utils.book_append_sheet(workbook, worksheet, "Dates"); + +/* fix headers */ +XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + +/* calculate column width */ +const max_width = rows.reduce((w: number, r: any) => Math.max(w, r.name.length), 10); +worksheet["!cols"] = [ { wch: max_width } ]; + +/* create an XLSX file and try to save to Presidents.xlsx */ +XLSX.writeFile(workbook, "Presidents.xlsx", { compression: true }); +'@ | Out-File -FilePath "SheetJSDeno.ts" -Encoding utf8 + +deno run -A SheetJSDeno.ts +npx xlsx-cli Presidents.xlsx | Select-Object -First 10 + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file diff --git a/tests/tutorials/export/node.ps1 b/tests/tutorials/export/node.ps1 new file mode 100644 index 0000000..756db77 --- /dev/null +++ b/tests/tutorials/export/node.ps1 @@ -0,0 +1,55 @@ +#!/usr/bin/env pwsh +# https://docs.sheetjs.com/docs/getting-started/installation/node + +$oldDir = Get-Location +$tempDir = Join-Path -Path $env:TEMP -ChildPath "sheetjs-node" +if (Test-Path -Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force } +New-Item -ItemType Directory -Path $tempDir | Out-Null +Set-Location -Path $tempDir + +npm init -y +npm i --save https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz + +@' +const XLSX = require("xlsx"); + +(async() => { + /* fetch JSON data and parse */ + const url = "https://docs.sheetjs.com/executive.json"; + const raw_data = await (await fetch(url)).json(); + + /* filter for the Presidents */ + const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez")); + + /* sort by first presidential term */ + prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start); + prez.sort((l,r) => l.start.localeCompare(r.start)); + + /* flatten objects */ + const rows = prez.map(row => ({ + name: row.name.first + " " + row.name.last, + birthday: row.bio.birthday + })); + + /* generate worksheet and workbook */ + const worksheet = XLSX.utils.json_to_sheet(rows); + const workbook = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(workbook, worksheet, "Dates"); + + /* fix headers */ + XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" }); + + /* calculate column width */ + const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10); + worksheet["!cols"] = [ { wch: max_width } ]; + + /* create an XLSX file and try to save to Presidents.xlsx */ + XLSX.writeFile(workbook, "Presidents.xlsx", { compression: true }); +})(); +'@ | Out-File -FilePath "SheetJSNodeJS.js" -Encoding utf8 + +node SheetJSNodeJS.js +npx xlsx-cli Presidents.xlsx | Select-Object -First 10 + +Set-Location $oldDir +Remove-Item -Path $tempDir -Recurse -Force \ No newline at end of file