From ad05741df03fb87537dc058f34528fbea06e72aa Mon Sep 17 00:00:00 2001 From: Wilson Lin Date: Tue, 21 Jun 2022 23:03:35 +1000 Subject: [PATCH] Use Neon for Node.js --- .github/workflows/nodejs.yml | 8 +- README.md | 7 +- format | 2 +- nodejs/.cargo/config | 4 - nodejs/.gitignore | 6 +- nodejs/Cargo.toml | 18 ++++ nodejs/binding.c | 187 ----------------------------------- nodejs/binding.gyp | 43 -------- nodejs/buildnative.js | 15 --- nodejs/compress.js | 7 -- nodejs/index.d.ts | 23 ++--- nodejs/native/Cargo.toml | 18 ---- nodejs/native/build.rs | 13 --- nodejs/native/src/lib.rs | 69 ------------- nodejs/package.json | 19 ++-- nodejs/postinstall.js | 19 ++-- nodejs/src/lib.rs | 57 +++++++++++ version | 3 +- 18 files changed, 113 insertions(+), 405 deletions(-) delete mode 100644 nodejs/.cargo/config create mode 100644 nodejs/Cargo.toml delete mode 100644 nodejs/binding.c delete mode 100644 nodejs/binding.gyp delete mode 100644 nodejs/buildnative.js delete mode 100644 nodejs/compress.js delete mode 100644 nodejs/native/Cargo.toml delete mode 100644 nodejs/native/build.rs delete mode 100644 nodejs/native/src/lib.rs create mode 100644 nodejs/src/lib.rs diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index e593bc1..0dec6f9 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -54,18 +54,17 @@ jobs: shell: bash run: | npm install - npm run build - node compress.js + npm run build-release echo ::set-output name=BINARY_NAME::"$(node -e 'console.log([process.platform, process.arch].join("__"))')" - name: Upload to B2 uses: wilsonzlin/b2-upload-action@v1.0.0 with: bucket: ${{ secrets.CICD_CLI_B2_BUCKET_NAME }} - uploadKey: minify-html/bin/nodejs/${{ steps.version.outputs.VERSION }}/${{ matrix.feature }}/${{ steps.module.outputs.BINARY_NAME }}.node.gz + uploadKey: minify-html/bin/nodejs/${{ steps.version.outputs.VERSION }}/${{ steps.module.outputs.BINARY_NAME }}.node keyId: ${{ secrets.CICD_CLI_B2_KEY_ID }} applicationKey: ${{ secrets.CICD_CLI_B2_APPLICATION_KEY }} - file: ./nodejs/index.node.gz + file: ./nodejs/index.node package: runs-on: ubuntu-18.04 @@ -87,6 +86,7 @@ jobs: package-lock=false //registry.npmjs.org/:_authToken=${{ secrets.NPM_AUTH_TOKEN }} EOF + # npm refuses to work with symlinks. cp ../README.md . if [[ "${{ steps.version.outputs.VERSION }}" != "0.0.0" ]]; then npm publish --access public diff --git a/README.md b/README.md index 7c32147..852afe8 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ Check out the [docs](https://docs.rs/minify-html) for API and usage examples. Node.js - Package: [@minify-html/node](https://www.npmjs.com/package/@minify-html/node) -- Binding: [N-API](https://nodejs.org/api/n-api.html) +- Binding: [Neon](https://github.com/neon-bindings/neon) - Platforms: Linux (ARM64 and x64), macOS (ARM64 and x64), Windows (x64); Node.js 8.6.0 and higher ### Get @@ -93,11 +93,10 @@ TypeScript definitions are available. import * as minifyHtml from "@minify-html/node"; // Or `const minifyHtml = require("@minify-html/node")` if not using TS/ESM. -const cfg = minifyHtml.createConfiguration({ keep_spaces_between_attributes: true, keep_comments: true }); -const minified = minifyHtml.minify("

Hello, world!

", cfg); +const minified = minifyHtml.minify("

Hello, world!

", { keep_spaces_between_attributes: true, keep_comments: true }); ``` -All [`Cfg` fields](https://docs.rs/minify-html/latest/minify_html/struct.Cfg.html) are available as snake_case properties on the object provided to `createConfiguration`; if any are not set, they default to `false`. +All [`Cfg` fields](https://docs.rs/minify-html/latest/minify_html/struct.Cfg.html) are available as snake_case properties on the object provided as the second argument; if any are not set, they default to `false`. diff --git a/format b/format index eb60258..ba980de 100755 --- a/format +++ b/format @@ -15,7 +15,7 @@ for dir in \ fuzz \ fuzz/process \ java \ - nodejs/native \ + nodejs \ python \ ruby \ rust/main \ diff --git a/nodejs/.cargo/config b/nodejs/.cargo/config deleted file mode 100644 index dcd4c4a..0000000 --- a/nodejs/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[target.x86_64-pc-windows-msvc] -rustflags = ["--print=native-static-libs"] -[target.i686-pc-windows-msvc] -rustflags = ["--print=native-static-libs"] diff --git a/nodejs/.gitignore b/nodejs/.gitignore index 03c3b23..ae4d859 100644 --- a/nodejs/.gitignore +++ b/nodejs/.gitignore @@ -1,6 +1,6 @@ -/build/ +/Cargo.lock /index.node -/native/Cargo.lock -/native/target /package-lock.json +/target/ node_modules/ +npm-debug.log* diff --git a/nodejs/Cargo.toml b/nodejs/Cargo.toml new file mode 100644 index 0000000..af0ade8 --- /dev/null +++ b/nodejs/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "minify-html-node" +publish = false +version = "0.8.1" +description = "Node.js bindings for minify-html" +authors = ["Wilson Lin "] +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +minify-html = "0.8.1" + +[dependencies.neon] +version = "0.10" +default-features = false +features = ["napi-1"] diff --git a/nodejs/binding.c b/nodejs/binding.c deleted file mode 100644 index e6aebc4..0000000 --- a/nodejs/binding.c +++ /dev/null @@ -1,187 +0,0 @@ -#include -#include -#include -#include - -#define NAPI_VERSION 1 -#include - -typedef struct Cfg Cfg; - -#include - -static inline void* assert_malloc(size_t bytes) { - void* ptr = malloc(bytes); - if (ptr == NULL) { - fprintf(stderr, "[Node.js minify-html] Internal assertion error: failed to allocate memory\n"); - exit(67); - } - return ptr; -} - -static inline void assert_ok(napi_status status) { - if (status != napi_ok) { - fprintf(stderr, "[Node.js minify-html] Internal assertion error: N-API status not OK\n"); - exit(67); - } -} - -static inline napi_value get_undefined(napi_env env) { - napi_value undefined; - assert_ok(napi_get_undefined(env, &undefined)); - return undefined; -} - -typedef napi_status (*napi_is_pred)(napi_env env, napi_value value, bool* result); - -static inline bool napi_is(napi_env env, napi_value value, napi_is_pred pred) { - bool res; - assert_ok(pred(env, value, &res)); - return res; -} - -void js_cfg_finalizer(napi_env env, void* finalize_data, void* _finalize_hint) { - ffi_drop_cfg((Cfg const*) finalize_data); -} - -void js_output_buf_finalizer(napi_env env, void* _finalize_data, void* finalize_hint) { - ffi_output* metadata = (ffi_output*) finalize_hint; - ffi_drop_output(metadata); -} - -napi_value node_method_create_configuration(napi_env env, napi_callback_info info) { - napi_value undefined = get_undefined(env); - - size_t argc = 1; - napi_value argv[1]; - napi_value _this; - void* _data; - - // Get the arguments. - if (napi_get_cb_info(env, info, &argc, argv, &_this, &_data) != napi_ok) { - assert_ok(napi_throw_error(env, NULL, "Failed to get callback info")); - return undefined; - } - napi_value obj_arg = argv[0]; - -#define GET_CFG_PROP(prop) \ - bool prop = false; \ - napi_value prop##_value; \ - if (napi_get_named_property(env, obj_arg, #prop, &prop##_value) == napi_ok) { \ - /* It's OK if this fails. */ napi_get_value_bool(env, prop##_value, &prop); \ - } - - GET_CFG_PROP(do_not_minify_doctype); - GET_CFG_PROP(ensure_spec_compliant_unquoted_attribute_values); - GET_CFG_PROP(keep_closing_tags); - GET_CFG_PROP(keep_comments); - GET_CFG_PROP(keep_html_and_head_opening_tags); - GET_CFG_PROP(keep_spaces_between_attributes); - GET_CFG_PROP(minify_css); - GET_CFG_PROP(minify_js); - GET_CFG_PROP(remove_bangs); - GET_CFG_PROP(remove_processing_instructions); - - Cfg const* cfg = ffi_create_cfg( - do_not_minify_doctype, - ensure_spec_compliant_unquoted_attribute_values, - keep_closing_tags, - keep_comments, - keep_html_and_head_opening_tags, - keep_spaces_between_attributes, - minify_css, - minify_js, - remove_bangs, - remove_processing_instructions - ); - - napi_value js_cfg; - if (napi_create_external(env, (void*) cfg, js_cfg_finalizer, NULL, &js_cfg) != napi_ok) { - assert_ok(napi_throw_error(env, NULL, "Failed to create return value")); - return undefined; - } - return js_cfg; -} - -napi_value node_method_minify(napi_env env, napi_callback_info info) { - napi_value undefined = get_undefined(env); - napi_value min_buf_rv = undefined; - - void* src_data_copy = NULL; - - size_t argc = 2; - napi_value argv[2]; - napi_value _this; - void* _data; - - // Get the arguments. - if (napi_get_cb_info(env, info, &argc, argv, &_this, &_data) != napi_ok) { - assert_ok(napi_throw_error(env, NULL, "Failed to get callback info")); - goto rollback; - } - napi_value src_arg = argv[0]; - napi_value js_cfg_arg = argv[1]; - - void* src_data; - size_t src_data_len; - if (napi_is(env, src_arg, napi_is_buffer)) { - // Get pointer to bytes in buffer. - if (napi_get_buffer_info(env, src_arg, &src_data, &src_data_len) != napi_ok || src_data == NULL) { - assert_ok(napi_throw_type_error(env, NULL, "Failed to read source buffer")); - goto rollback; - } - } else { - // Assume string. - if (napi_get_value_string_utf8(env, src_arg, NULL, 0, &src_data_len) != napi_ok) { - assert_ok(napi_throw_type_error(env, NULL, "Failed to read source string")); - goto rollback; - } - src_data_copy = assert_malloc(src_data_len + 1); - size_t bytes_copied; - if (napi_get_value_string_utf8(env, src_arg, src_data_copy, src_data_len + 1, &bytes_copied) != napi_ok - || bytes_copied != src_data_len) { - assert_ok(napi_throw_error(env, NULL, "Failed to copy source string")); - goto rollback; - } - src_data = src_data_copy; - } - - // Get Cfg. - void* cfg_raw; - if (napi_get_value_external(env, js_cfg_arg, &cfg_raw) != napi_ok) { - assert_ok(napi_throw_type_error(env, NULL, "Failed to get configuration")); - goto rollback; - } - Cfg const* cfg = (Cfg const*) cfg_raw; - - // Run minifier. - ffi_output const* output = ffi_minify(src_data, src_data_len, cfg); - - // Create minified buffer with copied memory. - if (napi_create_external_buffer(env, output->len, output->data, js_output_buf_finalizer, (void*) output, &min_buf_rv) != napi_ok) { - assert_ok(napi_throw_error(env, NULL, "Failed to create minified buffer")); - goto rollback; - } - - goto cleanup; - -rollback: - -cleanup: - free(src_data_copy); - return min_buf_rv; -} - -static inline void define_method(napi_env env, napi_value exports, char const* name, napi_callback cb) { - napi_value js_fn; - assert_ok(napi_create_function(env, name, NAPI_AUTO_LENGTH, cb, NULL, &js_fn)); - assert_ok(napi_set_named_property(env, exports, name, js_fn)); -} - -napi_value node_module_init(napi_env env, napi_value exports) { - define_method(env, exports, "createConfiguration", node_method_create_configuration); - define_method(env, exports, "minify", node_method_minify); - return exports; -} - -NAPI_MODULE(NODE_GYP_MODULE_NAME, node_module_init) diff --git a/nodejs/binding.gyp b/nodejs/binding.gyp deleted file mode 100644 index 299096a..0000000 --- a/nodejs/binding.gyp +++ /dev/null @@ -1,43 +0,0 @@ -{ - "targets": [ - { - "target_name": "index", - "sources": [ - "binding.c" - ], - "include_dirs": [ - "native/target/release/", - ], - "actions": [ - { - "action_name": "build minify-html-ffi static library", - "inputs": ["native/src/lib.rs"], - "outputs": [ - "native/target/release/libminify_html_ffi.a", - "native/target/release/minify_html_ffi.h", - "native/target/release/minify_html_ffi.lib", - ], - "action": ["node", "./buildnative.js"], - } - ], - "conditions": [ - ["OS=='mac'", { - "libraries": [ - "Security.framework", - ], - }], - ["OS!='win'", { - "libraries": [ - "../native/target/release/libminify_html_ffi.a", - ], - }], - ["OS=='win'", { - "libraries": [ - "kernel32.lib", "ws2_32.lib", "bcrypt.lib", "advapi32.lib", "userenv.lib", "kernel32.lib", "msvcrt.lib", - "../native/target/release/minify_html_ffi.lib", - ], - }], - ], - }, - ], -} diff --git a/nodejs/buildnative.js b/nodejs/buildnative.js deleted file mode 100644 index 14de45e..0000000 --- a/nodejs/buildnative.js +++ /dev/null @@ -1,15 +0,0 @@ -const cp = require("child_process"); -const path = require("path"); - -cp.spawnSync( - "cargo", - [ - "build", - "--manifest-path", - path.join(__dirname, "native", "Cargo.toml"), - "--release", - ], - { - stdio: "inherit", - } -); diff --git a/nodejs/compress.js b/nodejs/compress.js deleted file mode 100644 index f4bec7d..0000000 --- a/nodejs/compress.js +++ /dev/null @@ -1,7 +0,0 @@ -const { readFileSync, writeFileSync } = require("fs"); -const { join } = require("path"); -const { gzipSync } = require("zlib"); - -const src = readFileSync(join(__dirname, "index.node")); -const out = gzipSync(src); -writeFileSync(join(__dirname, "index.node.gz"), out); diff --git a/nodejs/index.d.ts b/nodejs/index.d.ts index fc5c93a..cd615fe 100644 --- a/nodejs/index.d.ts +++ b/nodejs/index.d.ts @@ -1,13 +1,11 @@ -export type Cfg = { __doNotUseCfgDirectly: string & { __itIsANapiExternalValue: never } }; - /** - * Creates configuration that can be passed to minification functions to change the minification approach. - * The value returned is an [external](https://nodejs.org/api/n-api.html#n_api_napi_create_external) value with typeof `object` and prototype `null`; it does not have any properties, and should only be used as arguments to minify functions. + * Minifies a string containing HTML code. * - * @param options - Configurable minifier settings to use when this configuration is passed to a minify function - * @returns An opaque value that can be passed to minify functions + * @param src - Source HTML code + * @param cfg - Configurable minifier settings to use + * @returns Minified HTML code */ -export function createConfiguration (options: { +export function minify (src: Buffer, cfg: { /** Do not minify DOCTYPEs. Minified DOCTYPEs may not be spec compliant. */ do_not_minify_doctype?: boolean, /** Ensure all unquoted attribute values in the output do not contain any characters prohibited by the WHATWG specification. */ @@ -32,13 +30,4 @@ export function createConfiguration (options: { remove_bangs?: boolean; /** Remove all processing_instructions. */ remove_processing_instructions?: boolean; -}): Cfg; - -/** - * Minifies a string containing HTML code. - * - * @param src - Source HTML code - * @param cfg - Configuration created by {@link createConfiguration} - * @returns Minified HTML code - */ -export function minify (src: string | Buffer, cfg: Cfg): Buffer; +}): Buffer; diff --git a/nodejs/native/Cargo.toml b/nodejs/native/Cargo.toml deleted file mode 100644 index 72162a7..0000000 --- a/nodejs/native/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -publish = false -name = "minify-html-ffi" -version = "0.8.1" -authors = ["Wilson Lin "] -license = "MIT" -edition = "2018" - -[lib] -name = "minify_html_ffi" -crate-type = ["staticlib"] - -[build-dependencies] -cbindgen = "0.14" - -[dependencies] -libc = "0.2" -minify-html = { path = "../../rust/main" } diff --git a/nodejs/native/build.rs b/nodejs/native/build.rs deleted file mode 100644 index 4c76180..0000000 --- a/nodejs/native/build.rs +++ /dev/null @@ -1,13 +0,0 @@ -use std::env; - -fn main() { - let crate_dir = env!("CARGO_MANIFEST_DIR"); - let profile = env::var("PROFILE").unwrap(); - - cbindgen::Builder::new() - .with_language(cbindgen::Language::C) - .with_crate(crate_dir) - .generate() - .expect("generate C bindings") - .write_to_file(format!("target/{}/minify_html_ffi.h", profile)); -} diff --git a/nodejs/native/src/lib.rs b/nodejs/native/src/lib.rs deleted file mode 100644 index 89c556b..0000000 --- a/nodejs/native/src/lib.rs +++ /dev/null @@ -1,69 +0,0 @@ -use minify_html::{minify, Cfg}; -use std::{mem, slice}; - -#[no_mangle] -pub extern "C" fn ffi_create_cfg( - do_not_minify_doctype: bool, - ensure_spec_compliant_unquoted_attribute_values: bool, - keep_closing_tags: bool, - keep_comments: bool, - keep_html_and_head_opening_tags: bool, - keep_spaces_between_attributes: bool, - minify_css: bool, - minify_js: bool, - remove_bangs: bool, - remove_processing_instructions: bool, -) -> *const Cfg { - Box::into_raw(Box::new(Cfg { - do_not_minify_doctype, - ensure_spec_compliant_unquoted_attribute_values, - keep_closing_tags, - keep_comments, - keep_html_and_head_opening_tags, - keep_spaces_between_attributes, - minify_css, - minify_js, - remove_bangs, - remove_processing_instructions, - })) -} - -#[no_mangle] -pub extern "C" fn ffi_drop_cfg(cfg: *const Cfg) -> () { - unsafe { - Box::from_raw(cfg as *mut Cfg); - }; -} - -#[repr(C)] -pub struct ffi_output { - data: *mut u8, - len: usize, - cap: usize, -} - -#[no_mangle] -pub extern "C" fn ffi_drop_output(ptr: *const ffi_output) -> () { - unsafe { - let out = Box::from_raw(ptr as *mut ffi_output); - Vec::from_raw_parts(out.data, out.len, out.cap); - }; -} - -#[no_mangle] -// TODO Return result memory (let Node.js manage GC) instead of overwriting source. -pub extern "C" fn ffi_minify( - code: *const u8, - code_len: usize, - cfg: *const Cfg, -) -> *const ffi_output { - let code_slice = unsafe { slice::from_raw_parts(code, code_len) }; - let mut out_code = minify(code_slice, unsafe { &*cfg }); - let res = Box::into_raw(Box::new(ffi_output { - data: out_code.as_mut_ptr(), - len: out_code.len(), - cap: out_code.capacity(), - })); - mem::forget(out_code); - res -} diff --git a/nodejs/package.json b/nodejs/package.json index cf85f29..7503d0b 100644 --- a/nodejs/package.json +++ b/nodejs/package.json @@ -4,18 +4,15 @@ "bin": { "minify-html": "./cli.js" }, - "version": "0.8.1", "main": "index.js", + "files": ["src/**", "Cargo.toml", "cli.js", "index.d.ts", "index.js", "README.md", "postinstall.js"], + "version": "0.8.1", "types": "index.d.ts", - "files": [ - "cli.js", - "postinstall.js", - "index.d.ts", - "index.js" - ], "scripts": { - "build": "node-gyp build && shx mv build/Release/index.node index.node", - "clean": "cd native && cargo clean && cd .. && node-gyp clean && node-gyp configure && shx rm -f index.node", + "build": "npm_package_name=minify-html-node cargo-cp-artifact -nc index.node -- cargo build --message-format=json-render-diagnostics", + "build-debug": "npm run build --", + "build-release": "npm run build -- --release", + "clean": "shx rm -rf target index.node", "postinstall": "node postinstall.js" }, "repository": { @@ -37,8 +34,8 @@ "homepage": "https://github.com/wilsonzlin/minify-html#readme", "devDependencies": { "@types/node": "^14.6.0", - "node-gyp": "^7.0.0", - "shx": "^0.3.2" + "cargo-cp-artifact": "^0.1", + "shx": "^0.3.4" }, "keywords": [ "compress", diff --git a/nodejs/postinstall.js b/nodejs/postinstall.js index 4f87dec..b83fb22 100644 --- a/nodejs/postinstall.js +++ b/nodejs/postinstall.js @@ -1,8 +1,8 @@ const fs = require("fs"); const https = require("https"); const path = require("path"); -const zlib = require("zlib"); const pkg = require("./package.json"); +const cp = require("child_process"); const MAX_DOWNLOAD_ATTEMPTS = 4; @@ -36,12 +36,10 @@ const downloadNativeBinary = async () => { let binary; try { binary = await fetch( - `https://wilsonl.in/minify-html/bin/nodejs/${pkg.version}/${ - pkg.name.split("/")[1] - }/${binaryName}.node.gz` + `https://wilsonl.in/minify-html/bin/nodejs/${pkg.version}/${binaryName}.node` ); } catch (e) { - if (e instanceof StatusError && attempt < MAX_DOWNLOAD_ATTEMPTS) { + if (e instanceof StatusError && e.status !== 404 && attempt < MAX_DOWNLOAD_ATTEMPTS) { await wait(Math.random() * 2500 + 500); continue; } @@ -60,8 +58,15 @@ if ( downloadNativeBinary().then( () => console.log(`Downloaded ${pkg.name}`), (err) => { - console.error(`Failed to download ${pkg.name}: ${err}`); - process.exit(1); + console.error(`Failed to download ${pkg.name}, will build from source: ${err}`); + const out = cp.spawnSync("npm", ["run", "build-release"], { + cwd: __dirname, + stdio: ["ignore", "inherit", "inherit"], + }); + process.exitCode = out.exitCode; + if (out.error) { + throw out.error; + } } ); } diff --git a/nodejs/src/lib.rs b/nodejs/src/lib.rs new file mode 100644 index 0000000..c330ca5 --- /dev/null +++ b/nodejs/src/lib.rs @@ -0,0 +1,57 @@ +use neon::prelude::*; +use neon::types::buffer::TypedArray; + +fn minify(mut cx: FunctionContext) -> JsResult { + let src = cx.argument::(0)?; + let opt = cx.argument::(1)?; + let cfg = minify_html::Cfg { + do_not_minify_doctype: opt + .get_opt::(&mut cx, "do_not_minify_doctype")? + .map(|v| v.value(&mut cx)) + .unwrap_or(false), + ensure_spec_compliant_unquoted_attribute_values: opt + .get_opt::(&mut cx, "ensure_spec_compliant_unquoted_attribute_values")? + .map(|v| v.value(&mut cx)) + .unwrap_or(false), + keep_closing_tags: opt + .get_opt::(&mut cx, "keep_closing_tags")? + .map(|v| v.value(&mut cx)) + .unwrap_or(false), + keep_html_and_head_opening_tags: opt + .get_opt::(&mut cx, "keep_html_and_head_opening_tags")? + .map(|v| v.value(&mut cx)) + .unwrap_or(false), + keep_spaces_between_attributes: opt + .get_opt::(&mut cx, "keep_spaces_between_attributes")? + .map(|v| v.value(&mut cx)) + .unwrap_or(false), + keep_comments: opt + .get_opt::(&mut cx, "keep_comments")? + .map(|v| v.value(&mut cx)) + .unwrap_or(false), + minify_css: opt + .get_opt::(&mut cx, "minify_css")? + .map(|v| v.value(&mut cx)) + .unwrap_or(false), + minify_js: opt + .get_opt::(&mut cx, "minify_js")? + .map(|v| v.value(&mut cx)) + .unwrap_or(false), + remove_bangs: opt + .get_opt::(&mut cx, "remove_bangs")? + .map(|v| v.value(&mut cx)) + .unwrap_or(false), + remove_processing_instructions: opt + .get_opt::(&mut cx, "remove_processing_instructions")? + .map(|v| v.value(&mut cx)) + .unwrap_or(false), + }; + let out = minify_html::minify(src.as_slice(&mut cx), &cfg); + Ok(JsBuffer::external(&mut cx, out)) +} + +#[neon::main] +fn main(mut cx: ModuleContext) -> NeonResult<()> { + cx.export_function("minify", minify)?; + Ok(()) +} diff --git a/version b/version index aebf9f9..dbd1959 100755 --- a/version +++ b/version @@ -101,10 +101,9 @@ for (const f of [ `${RUST_MAIN_DIR}/Cargo.toml`, `${RUST_ONEPASS_DIR}/Cargo.toml`, "cli/Cargo.toml", - "nodejs/native/Cargo.toml", + "nodejs/Cargo.toml", "java/Cargo.toml", "python/Cargo.toml", - "python/Cargo.js.toml", "ruby/Cargo.toml", ]) { replaceInFile(