Use Neon for Node.js
This commit is contained in:
parent
ec8c4e338a
commit
ad05741df0
|
@ -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
|
||||
|
|
|
@ -68,7 +68,7 @@ Check out the [docs](https://docs.rs/minify-html) for API and usage examples.
|
|||
<summary><img width="24" src="https://wilsonl.in/minify-html/icon/nodejs.png"> <strong>Node.js</strong></summary>
|
||||
|
||||
- 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("<p> Hello, world! </p>", cfg);
|
||||
const minified = minifyHtml.minify("<p> Hello, world! </p>", { 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`.
|
||||
|
||||
</details>
|
||||
|
||||
|
|
2
format
2
format
|
@ -15,7 +15,7 @@ for dir in \
|
|||
fuzz \
|
||||
fuzz/process \
|
||||
java \
|
||||
nodejs/native \
|
||||
nodejs \
|
||||
python \
|
||||
ruby \
|
||||
rust/main \
|
||||
|
|
|
@ -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"]
|
|
@ -1,6 +1,6 @@
|
|||
/build/
|
||||
/Cargo.lock
|
||||
/index.node
|
||||
/native/Cargo.lock
|
||||
/native/target
|
||||
/package-lock.json
|
||||
/target/
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
|
|
|
@ -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 <npm@wilsonl.in>"]
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
minify-html = "0.8.1"
|
||||
|
||||
[dependencies.neon]
|
||||
version = "0.10"
|
||||
default-features = false
|
||||
features = ["napi-1"]
|
187
nodejs/binding.c
187
nodejs/binding.c
|
@ -1,187 +0,0 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define NAPI_VERSION 1
|
||||
#include <node_api.h>
|
||||
|
||||
typedef struct Cfg Cfg;
|
||||
|
||||
#include <minify_html_ffi.h>
|
||||
|
||||
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)
|
|
@ -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",
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
|
@ -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",
|
||||
}
|
||||
);
|
|
@ -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);
|
|
@ -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;
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
[package]
|
||||
publish = false
|
||||
name = "minify-html-ffi"
|
||||
version = "0.8.1"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
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" }
|
|
@ -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));
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
use neon::prelude::*;
|
||||
use neon::types::buffer::TypedArray;
|
||||
|
||||
fn minify(mut cx: FunctionContext) -> JsResult<JsBuffer> {
|
||||
let src = cx.argument::<JsBuffer>(0)?;
|
||||
let opt = cx.argument::<JsObject>(1)?;
|
||||
let cfg = minify_html::Cfg {
|
||||
do_not_minify_doctype: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "do_not_minify_doctype")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
ensure_spec_compliant_unquoted_attribute_values: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "ensure_spec_compliant_unquoted_attribute_values")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
keep_closing_tags: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "keep_closing_tags")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
keep_html_and_head_opening_tags: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "keep_html_and_head_opening_tags")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
keep_spaces_between_attributes: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "keep_spaces_between_attributes")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
keep_comments: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "keep_comments")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
minify_css: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "minify_css")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
minify_js: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "minify_js")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
remove_bangs: opt
|
||||
.get_opt::<JsBoolean, _, _>(&mut cx, "remove_bangs")?
|
||||
.map(|v| v.value(&mut cx))
|
||||
.unwrap_or(false),
|
||||
remove_processing_instructions: opt
|
||||
.get_opt::<JsBoolean, _, _>(&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(())
|
||||
}
|
Loading…
Reference in New Issue