Compare commits

...

412 Commits

Author SHA1 Message Date
K.J. Valencik
f3a96aaa7d
Merge pull request #676 from neon-bindings/dependabot/npm_and_yarn/test/electron/electron-11.1.0
Some checks failed
Lints / lint (14.x, nightly) (push) Has been cancelled
Test on Linux / build (12.x, beta) (push) Has been cancelled
Test on Linux / build (12.x, nightly) (push) Has been cancelled
Test on Linux / build (12.x, stable) (push) Has been cancelled
Test on Linux / build (14.x, beta) (push) Has been cancelled
Test on Linux / build (14.x, nightly) (push) Has been cancelled
Test on Linux / build (14.x, stable) (push) Has been cancelled
Test on Linux / build (16.x, beta) (push) Has been cancelled
Test on Linux / build (16.x, nightly) (push) Has been cancelled
Test on Linux / build (16.x, stable) (push) Has been cancelled
Test on MacOS / build (12.x, beta) (push) Has been cancelled
Test on MacOS / build (12.x, nightly) (push) Has been cancelled
Test on MacOS / build (12.x, stable) (push) Has been cancelled
Test on MacOS / build (14.x, beta) (push) Has been cancelled
Test on MacOS / build (14.x, nightly) (push) Has been cancelled
Test on MacOS / build (14.x, stable) (push) Has been cancelled
Test on MacOS / build (16.x, beta) (push) Has been cancelled
Test on MacOS / build (16.x, nightly) (push) Has been cancelled
Test on MacOS / build (16.x, stable) (push) Has been cancelled
Test on Windows / build (12.x, beta) (push) Has been cancelled
Test on Windows / build (12.x, nightly) (push) Has been cancelled
Test on Windows / build (12.x, stable) (push) Has been cancelled
Test on Windows / build (14.x, beta) (push) Has been cancelled
Test on Windows / build (14.x, nightly) (push) Has been cancelled
Test on Windows / build (14.x, stable) (push) Has been cancelled
Test on Windows / build (16.x, beta) (push) Has been cancelled
Test on Windows / build (16.x, nightly) (push) Has been cancelled
Test on Windows / build (16.x, stable) (push) Has been cancelled
build(deps-dev): bump electron from 11.0.4 to 11.1.0 in /test/electron
2021-05-18 11:09:28 -04:00
K.J. Valencik
e0c25bfd75
Merge pull request #726 from neon-bindings/dependabot/npm_and_yarn/test/cli/lodash-4.17.21
Bump lodash from 4.17.19 to 4.17.21 in /test/cli
2021-05-18 11:09:16 -04:00
K.J. Valencik
c81d98f195
Merge pull request #731 from neon-bindings/dependabot/npm_and_yarn/test/electron/lodash-4.17.21
Bump lodash from 4.17.20 to 4.17.21 in /test/electron
2021-05-18 11:08:59 -04:00
K.J. Valencik
d401a32b78
Merge pull request #730 from neon-bindings/dependabot/npm_and_yarn/test/electron/ua-parser-js-0.7.28
Bump ua-parser-js from 0.7.22 to 0.7.28 in /test/electron
2021-05-18 11:08:56 -04:00
K.J. Valencik
d69768f567
Merge pull request #725 from neon-bindings/dependabot/npm_and_yarn/cli/lodash-4.17.21
Bump lodash from 4.17.19 to 4.17.21 in /cli
2021-05-18 11:08:49 -04:00
K.J. Valencik
2f93620146
Merge pull request #724 from neon-bindings/dependabot/npm_and_yarn/test/cli/handlebars-4.7.7
Bump handlebars from 4.5.3 to 4.7.7 in /test/cli
2021-05-18 11:08:44 -04:00
K.J. Valencik
8814886b41
Merge pull request #723 from neon-bindings/dependabot/npm_and_yarn/cli/handlebars-4.7.7
Bump handlebars from 4.7.6 to 4.7.7 in /cli
2021-05-18 11:08:37 -04:00
K.J. Valencik
e2cc8cc81d
Merge pull request #737 from neon-bindings/kv/v0.8.2
v0.8.2
2021-05-18 10:59:15 -04:00
K.J. Valencik
5c308aec22
v0.8.2 2021-05-18 10:48:44 -04:00
K.J. Valencik
d9eac77765
Update migration guide to include removing build.rs 2021-05-18 10:33:04 -04:00
K.J. Valencik
73bde85776
Merge pull request #736 from neon-bindings/types-apidocs
Top-level API docs for `neon::types`
2021-05-18 10:30:59 -04:00
David Herman
8758b7f416 API docs for the neon::types module top level. 2021-05-17 18:47:46 -07:00
Dave Herman
73390414ee
Merge pull request #735 from neon-bindings/types-diagram
Types diagram for docs
2021-05-17 07:47:51 -07:00
David Herman
fc5a214389 Types diagram, for use in the docs 2021-05-16 14:49:41 -07:00
Dave Herman
c5c277e98b
Merge pull request #733 from neon-bindings/event-api-docs
Top level API docs for `neon::event`
2021-05-15 12:37:43 -07:00
K.J. Valencik
264a6a4ce0 chore(cli): Suggest using create-neon instead
Resolves https://github.com/neon-bindings/neon/issues/696
2021-05-15 09:54:39 -07:00
David Herman
0df7033978 Use error message from PSD error on failure. 2021-05-14 17:39:35 -07:00
David Herman
3f6804c79f cargo fmt 2021-05-14 17:38:20 -07:00
David Herman
1e8d6261a4 Upgrade to Rust 2018 Edition 2021-05-14 11:25:31 -07:00
David Herman
56834b5afc Add initial section title, and some rewording of opening sentence 2021-05-14 02:11:32 -07:00
David Herman
b64f9203ab Delete trailing spaces 2021-05-14 02:06:21 -07:00
David Herman
5b20370bee Top level API docs for neon::event 2021-05-13 20:41:29 -07:00
dependabot[bot]
acd5ba6e2a
Bump lodash from 4.17.20 to 4.17.21 in /test/electron
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-10 14:21:09 +00:00
dependabot[bot]
d473ead705
Bump ua-parser-js from 0.7.22 to 0.7.28 in /test/electron
Bumps [ua-parser-js](https://github.com/faisalman/ua-parser-js) from 0.7.22 to 0.7.28.
- [Release notes](https://github.com/faisalman/ua-parser-js/releases)
- [Commits](https://github.com/faisalman/ua-parser-js/compare/0.7.22...0.7.28)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-08 04:39:35 +00:00
dependabot[bot]
01fbf284a4
Bump lodash from 4.17.19 to 4.17.21 in /test/cli
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.19 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.19...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-06 18:46:00 +00:00
dependabot[bot]
ec3e057ec6
Bump lodash from 4.17.19 to 4.17.21 in /cli
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.19 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.19...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-06 18:45:47 +00:00
dependabot[bot]
5fe99a8941
Bump handlebars from 4.5.3 to 4.7.7 in /test/cli
Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.5.3 to 4.7.7.
- [Release notes](https://github.com/wycats/handlebars.js/releases)
- [Changelog](https://github.com/handlebars-lang/handlebars.js/blob/master/release-notes.md)
- [Commits](https://github.com/wycats/handlebars.js/compare/v4.5.3...v4.7.7)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-06 16:43:52 +00:00
dependabot[bot]
0ab3b6ee2e
Bump handlebars from 4.7.6 to 4.7.7 in /cli
Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.7.6 to 4.7.7.
- [Release notes](https://github.com/wycats/handlebars.js/releases)
- [Changelog](https://github.com/handlebars-lang/handlebars.js/blob/master/release-notes.md)
- [Commits](https://github.com/wycats/handlebars.js/compare/v4.7.6...v4.7.7)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-06 16:43:40 +00:00
K.J. Valencik
2f2bfca92a
Merge pull request #722 from neon-bindings/kv/suggest-napi
chore(cli): Suggest using `create-neon` instead
2021-05-05 12:04:42 -04:00
K.J. Valencik
378dcc8e8a
chore(cli): Suggest using create-neon instead
Resolves https://github.com/neon-bindings/neon/issues/696
2021-05-05 10:42:53 -04:00
K.J. Valencik
165dffdf4a
Merge pull request #721 from neon-bindings/nom-init-snippet
docs nit: fix CLI example in main `neon` module
2021-05-05 10:24:56 -04:00
Dave Herman
77f2ac06de
Fix CLI example in top level API docs
`neon init neon` -> `npm init neon` in main lib API docs
2021-05-01 09:31:46 -07:00
K.J. Valencik
14bc6072ec
Merge pull request #720 from neon-bindings/kv/v0.8.1
v0.8.1
2021-04-30 13:22:19 -04:00
K.J. Valencik
a20636e548
v0.8.1 2021-04-30 13:05:02 -04:00
K.J. Valencik
0e259239d3
Merge pull request #719 from neon-bindings/kv/doc-tests
chore(neon): Run all of the doc tests and run tests in debug mode
2021-04-30 12:56:58 -04:00
K.J. Valencik
fbd09f0bff
chore(neon): Drop support for Node 10 which is end of life 2021-04-30 12:43:07 -04:00
K.J. Valencik
d7ac291d97
chore(neon): Run all of the doc tests and run tests in debug mode 2021-04-28 15:41:08 -04:00
K.J. Valencik
1e9bedb2d7
Merge pull request #713 from neon-bindings/result-apidocs
Top-level module API docs for `neon::result`
2021-04-28 15:03:51 -04:00
David Herman
859d531fe8 Remove unnecessary ignores. 2021-04-28 09:12:08 -07:00
David Herman
671add6f37 Fix broken code in doc examples. 2021-04-28 09:08:36 -07:00
David Herman
0ab1a9d52f Better links to context docs from result docs. 2021-04-27 17:02:53 -07:00
David Herman
d3a296928f Much more complete documentation on contexts. 2021-04-27 16:53:55 -07:00
K.J. Valencik
ad209e30da
Merge pull request #717 from antonok-edm/readme-node-16-support
Update README to mention Node 16 support
2021-04-27 14:21:57 -04:00
Anton Lazarev
f4cd384ed5
update README to mention Node 16 support 2021-04-27 11:12:24 -07:00
K.J. Valencik
be85d188fc
Merge pull request #715 from ogoffart/fix_build_node_16
Fix build with node 16
2021-04-27 10:46:54 -04:00
Olivier Goffart
830836167e Github worflow: replace Node 15 by node 16
Update the Github CI workflows to reflect the current supported Node
versions by removing Node 15 and adding Node 16
2021-04-27 15:39:47 +02:00
Olivier Goffart
50cb290278 Fix build with Node 16
The overload of node::AtExit that takes only two arguments was removed in
dfc288e7fd (diff-4acdf5a5c11188763423b746a9a43917c90546f3b48b9aa6f6eeb60e157ae2a7)
2021-04-27 14:45:57 +02:00
Olivier Goffart
3189ee00c6 Show the compilation error in the console and abort the build
... in case of failure

instead of having an error later when the .so cannot be found.
2021-04-27 14:45:37 +02:00
David Herman
e302ab9e31 Mention idiomatic use of question mark operator. 2021-04-07 10:52:45 -07:00
David Herman
17a0ea921c Top-level module API docs for neon::result. 2021-04-07 10:46:05 -07:00
Dave Herman
b8c8c2a1ae
Merge pull request #707 from neon-bindings/dependabot/npm_and_yarn/cli/y18n-4.0.1
Bump y18n from 4.0.0 to 4.0.1 in /cli
2021-04-07 09:12:58 -07:00
Dave Herman
3a16627093
Merge pull request #710 from neon-bindings/handle-apidocs
Top-level API docs for `neon::handle`
2021-04-07 09:06:46 -07:00
David Herman
5078b1714f Semantic links to stdlib. 2021-04-07 09:05:10 -07:00
Dave Herman
dd3ada4944
Merge pull request #711 from neon-bindings/amilajack-patch-1
update NAPI impl status in readme
2021-04-07 08:35:03 -07:00
Amila Welihinda
c2667bde11 update n-api status in readme 2021-04-06 18:31:13 -07:00
David Herman
54c35c52b5 Align wording for all module top-level entries. 2021-04-06 17:57:53 -07:00
David Herman
01fe92123c Update Deref wording to be closer to the JsBox wording. 2021-04-06 17:17:04 -07:00
David Herman
ed3bb5392e Add section on the implementation of Deref. 2021-04-06 15:44:30 -07:00
David Herman
687fd06042 Top-level API docs for neon::handle. 2021-04-06 13:34:26 -07:00
Dave Herman
534c49575a
Merge pull request #708 from neon-bindings/context-api-docs
Module API docs: neon::context
2021-04-05 11:15:27 -07:00
David Herman
50827bee3d Add examples. 2021-04-05 10:51:12 -07:00
David Herman
0e270d1c7c Top level module API docs for the neon::context module. 2021-04-02 09:22:17 -07:00
dependabot[bot]
b7c26755c1
Bump y18n from 4.0.0 to 4.0.1 in /cli
Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.1.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-01 06:09:09 +00:00
Dave Herman
03c7e9e425
Merge pull request #705 from neon-bindings/api-docs
API docs: Neon root, module summaries, neon::borrow
2021-03-29 16:01:38 -07:00
David Herman
e860829dac Address feedback from @kjvalencik's review 2021-03-26 22:37:23 -07:00
Dave Herman
f4ec6eaa29
Apply suggestions from code review
Co-authored-by: K.J. Valencik <kjvalencik@gmail.com>
2021-03-26 19:16:02 -07:00
David Herman
96ff123914 Ignore code blocks in tests. 2021-03-26 18:52:01 -07:00
David Herman
3792dfd5c6 API docs for:
- main Neon root doc
- all module summaries
- `neon::borrow` module
2021-03-23 20:39:16 -07:00
K.J. Valencik
d5bfee3dac
Merge pull request #704 from neon-bindings/kv/v0.8.0
v0.8.0
2021-03-23 12:54:10 -04:00
K.J. Valencik
e6e92cf431
v0.8.0 2021-03-22 10:07:52 -04:00
K.J. Valencik
bf32f66e95
Merge pull request #700 from neon-bindings/kv/drop-queue
Global drop queue for Root
2021-03-22 09:22:15 -04:00
K.J. Valencik
4c224560b6
review(neon): Address review feedback for the global drop queue 2021-03-19 13:47:53 -04:00
K.J. Valencik
194945ebc6
Lint fix 2021-03-16 15:54:35 -04:00
K.J. Valencik
3ab690e8f8
feat(neon): Add a drop queue for safely dropping Root without leaking on N-API 6+ 2021-03-16 15:54:32 -04:00
K.J. Valencik
b10a779daa
Merge pull request #692 from patr0nus/main
Add binding to napi_run_script
2021-03-15 16:35:17 -04:00
patr0nus
ccbc5916fe cargo fmt 2021-03-15 20:43:13 +08:00
patr0nus
64ee1659c2 Merge remote-tracking branch 'upstream/main' into main
# Conflicts:
#	crates/neon-runtime/src/napi/bindings/functions.rs
#	src/lib.rs
2021-03-14 23:52:32 +08:00
K.J. Valencik
b730df7fa5
Merge pull request #698 from neon-bindings/kv/rustfmt
Lint CI enforcement and cargo fmt
2021-03-14 09:06:31 -04:00
Wang, Chi
bd795eabae
Update mod.rs 2021-03-14 13:14:23 +08:00
K.J. Valencik
111d2ac73c
Simplify clippy lint workflows with the -Zpackage-features RFC
Also adds, `cargo clippy-legacy` and `cargo clippy-napi` aliases
2021-03-13 18:17:23 -05:00
patr0nus
397c734839 Move the run_script binding to neon::reflect::eval 2021-03-13 21:58:26 +08:00
patr0nus
2918268580 Merge remote-tracking branch 'upstream/main' into main
# Conflicts:
#	crates/neon-runtime/src/napi/bindings/functions.rs
2021-03-13 21:42:03 +08:00
David Herman
bd69a89cda Bump create-neon patch version. 2021-03-12 16:48:15 -08:00
Dave Herman
5d1d659f1a
Merge pull request #697 from neon-bindings/create-neon-readme
create-neon README
2021-03-12 15:17:37 -08:00
K.J. Valencik
56b3715d7b
cargo fmt all the things! 2021-03-12 18:05:44 -05:00
K.J. Valencik
fdb2a48a44
Clippy and cargo fmt check in CI 2021-03-12 18:05:26 -05:00
K.J. Valencik
188c8d1852
Lint fixes 2021-03-12 18:05:15 -05:00
K.J. Valencik
c0d72cba94
Merge pull request #609 from neon-bindings/kv/cleanup
Clean-up: Lots of lint fixes
2021-03-12 17:30:22 -05:00
K.J. Valencik
0f7572ab00
Fix clippy lints in tests 2021-03-12 17:10:48 -05:00
David Herman
98a8435062 Explain the build process a bit more. 2021-03-12 13:57:11 -08:00
K.J. Valencik
553650ada6
Fix all clippy lints except for clippy::missing_safety_doc
A couple of lints are ignored because they would be breaking changes to the API
2021-03-12 16:53:36 -05:00
K.J. Valencik
f467acf8ff
fix(neon-build): Fix incorrect panic mesasge 2021-03-12 16:53:05 -05:00
K.J. Valencik
f35724bdfe
Remove unnecessary extern "C" 2021-03-12 16:53:04 -05:00
K.J. Valencik
3486ff34fe
Merge pull request #667 from neon-bindings/kv/external-buffer
feat(neon): Add `Buffer::external` for creating a `Buffer` backed by Rust data
2021-03-12 15:15:12 -05:00
K.J. Valencik
b0ff15ef97
feat(neon): Add Buffer::external and ArrayBuffer::external for creating buffers backed by Rust data 2021-03-11 14:42:11 -05:00
David Herman
446b60cdec Project README and more content for the generated README. 2021-03-10 22:28:24 -08:00
David Herman
3e76b0196d Bump create-neon to 0.1.1 so we can publish. 2021-03-10 09:54:41 -08:00
Dave Herman
691a66f809
Merge pull request #690 from neon-bindings/create-neon
create-neon
2021-03-10 09:18:35 -08:00
David Herman
6165246692 Shell to npm using shell: true instead of tacking on the extension for Windows. 2021-03-10 08:50:19 -08:00
patr0nus
272fe0d209 Test run_string_as_script with invalid syntax 2021-03-10 23:11:03 +08:00
David Herman
e9a82cb9c2 Relax test timeout from 2s to 5s, since GH Actions test runners are fairly slow and there aren't very many tests anyway. 2021-03-09 23:41:55 -08:00
David Herman
af4a264f77 Tweaking diagnostic output... 2021-03-09 23:14:48 -08:00
David Herman
208346f37b Call npm.cmd on Windows 2021-03-09 21:13:06 -08:00
David Herman
993d106e30 More CI debugging: print stderr on failure 2021-03-09 21:03:45 -08:00
David Herman
20727befc1 Debugging CI: print output on failure of child process 2021-03-09 20:35:08 -08:00
David Herman
8400efa8ae Add rimraf shim since { recursive: true } isn't supported in all our supported Node versions. 2021-03-09 13:01:26 -08:00
David Herman
6b21eb10cb Longer retry delay for rmdir? 2021-03-09 10:38:12 -08:00
David Herman
9d975415da Add 3 retries to rmdir after each test. 2021-03-09 10:30:45 -08:00
David Herman
7b136788fc Remove fs/promises since some supported Node versions don't support it. 2021-03-09 10:21:04 -08:00
David Herman
7c3c97b2f7 Ensure we run npm install before running the tests, for CI. 2021-03-09 09:48:36 -08:00
David Herman
ddcbcbc657 Add create-neon tests to CI. 2021-03-09 09:40:15 -08:00
David Herman
e8803c6b36 - Move test helpers into dev/ directory
- Delete test output directory after every test
- Add test output directories to gitignore
- Add npm-debug.log to gitignore template
2021-03-08 21:51:23 -08:00
David Herman
7840161021 Initial test suite. 2021-03-07 23:11:25 -08:00
patr0nus
2e7a34a071 Add binding to napi_run_script 2021-03-07 19:25:30 +08:00
David Herman
d79f9eebb1 Simplify the datatypes for the template expansion. 2021-03-06 10:46:48 -08:00
David Herman
70fe6e4504 Avoids asking the "main" or "test" package.json entries by creating the package.json up front with default values. 2021-03-06 10:27:49 -08:00
David Herman
f7ee6b6d95 Updates the generated package.json with Neon-specific default configuration. 2021-03-05 13:39:33 -08:00
David Herman
73bbe423ff Add shebang 2021-03-05 10:01:21 -08:00
David Herman
d7f1c7f3fd - remove dead import
- eliminate `+` hack
2021-03-05 09:56:34 -08:00
David Herman
01c0526a3b Just call npm directly since npm init create-neon doesn't pass the environment variables through to npx. 2021-03-05 09:52:42 -08:00
David Herman
96f3f8672a Abstract out die helper. 2021-03-04 23:15:20 -08:00
David Herman
fe9e5882ec Address @kjvalencik's review, plus some general cleanup and refactoring:
- Abstracted handlebars template logic into a Template class
- Abstracted the template context type into a Metadata module with some type definitions
- Better error messages
- Infer the N-API version from the current process
- Drop the Neon patch version number from the generated manifest
- Use JSON.stringify for quoting text
2021-03-04 23:07:33 -08:00
David Herman
5cffd02772 First working version, with a simple manual test. Next up we need automated tests. 2021-03-04 13:45:32 -08:00
David Herman
e548f23b74 Add shelling to npm init and reading from package.json. 2021-03-03 11:37:34 -08:00
David Herman
e40c6125b6 WIP 2021-02-28 23:28:38 -08:00
Dave Herman
6e2557c4aa
Merge pull request #685 from neon-bindings/migration-experiment
N-API migration guide
2021-02-26 14:23:14 -08:00
David Herman
1a2c1a59bc - Add link to migration guide to readme
- Uncommit accidentally-committed changes to the code
2021-02-26 13:50:57 -08:00
dependabot[bot]
1a4cecf9b0
build(deps-dev): bump electron from 11.0.4 to 11.1.0 in /test/electron
Bumps [electron](https://github.com/electron/electron) from 11.0.4 to 11.1.0.
- [Release notes](https://github.com/electron/electron/releases)
- [Changelog](https://github.com/electron/electron/blob/master/docs/breaking-changes.md)
- [Commits](https://github.com/electron/electron/compare/v11.0.4...v11.1.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-24 20:14:16 +00:00
K.J. Valencik
ff0593b823
Merge pull request #687 from neon-bindings/kv/cargo-cp-artifact
Switch N-API tests to `cargo-cp-artifact` from `neon-build`
2021-02-24 15:12:54 -05:00
K.J. Valencik
19e2c4a452
Switch N-API tests to cargo-cp-artifact from neon-build 2021-02-24 12:01:40 -05:00
David Herman
375dc4a396 Some more explanation around the task API and contention with libuv thread pool. 2021-02-19 11:01:23 -08:00
David Herman
25a4dd3619 Flesh out the JsBox example with Finalize and a pure JS class wrapper (per @kjvalencik suggestions). 2021-02-19 10:55:45 -08:00
David Herman
7cb91d9314 More hate for declare_types! :) 2021-02-19 10:45:58 -08:00
David Herman
af6506ae8e Explain different N-API version feature flags. 2021-02-18 12:04:27 -08:00
David Herman
077f9e5afb Add intro 2021-02-16 18:17:44 -08:00
David Herman
7cae7c774e Add feature flag info for "event-queue-api" flag. 2021-02-15 08:27:16 -08:00
David Herman
4fda49d283 Wrote up a complete migration guide with all of the incompatible changes between the legacy backend and N-API backend. 2021-02-14 23:22:38 -08:00
K.J. Valencik
eabe09026c
Merge pull request #681 from jrose-signal/empty-buffers
Fix as_slice and as_mut_slice for empty Buffers and ArrayBuffers
2021-02-10 15:37:27 -05:00
Jordan Rose
c6768569ee Fix as_slice and as_mut_slice for empty Buffers and ArrayBuffers
These buffers may have NULL as their address, which
slice::from_raw_parts does not allow.
2021-02-10 11:29:03 -08:00
K.J. Valencik
d775895e21
Merge pull request #680 from jrose-signal/Optional-Finalize
Make Option<T: Finalize> implement Finalize
2021-02-09 19:20:10 -05:00
Jordan Rose
10b84c773e Make Option<T: Finalize> implement Finalize 2021-02-09 15:13:21 -08:00
K.J. Valencik
8af9d22508
Merge pull request #679 from neon-bindings/kv/v0.7.1
v0.7.1 RC
2021-02-04 16:46:21 -05:00
K.J. Valencik
22b3196442
Release v0.7.1 2021-02-04 16:18:15 -05:00
K.J. Valencik
0a35c58e96
Merge pull request #677 from neon-bindings/kv/no-panic-shutdown
fix(neon): Do not panic when dropping a Root if the VM has shutdown
2021-02-02 10:45:53 -05:00
K.J. Valencik
ea15e232b9
fix(ci): Fix linux builds to work on Ubuntu 20.04 2021-01-29 15:25:14 -05:00
K.J. Valencik
ace68bdd55
fix(neon): Do not panic when dropping a Root if the VM has shutdown 2021-01-29 14:29:57 -05:00
Amila Welihinda
d566f83de4
Merge pull request #669 from neon-bindings/fix/is-date-napi-5
fix: gate is_date api behind napi-5 feature flag
2021-01-13 17:46:39 -08:00
Amila Welihinda
1e3be80740 fix: gate is_date api behind napi-5 feature flag 2021-01-13 17:42:09 -08:00
K.J. Valencik
6e0b62750a
Merge pull request #668 from ab-cgh/correct-cast-types
Don't assume pointer type in runtime casts
2021-01-13 18:09:03 -05:00
ABGH, C
c59f20b123 Don't assume pointer type in runtime casts 2021-01-13 16:23:41 -06:00
Amila Welihinda
7a76945fea
Merge pull request #639 from neon-bindings/feat/date-api
feat: impl Date API
2021-01-13 10:40:32 -08:00
Dave Herman
5adcdba556
Merge pull request #666 from neon-bindings/same-handle
N-API: deprecate PartialEq and add strict_equals method
2021-01-13 10:07:45 -08:00
David Herman
5c908229ac Make it a compile-time error to use PartialEq / Eq on Handles in the new runtime. 2021-01-13 09:10:56 -08:00
Amila Welihinda
22a7ea90a5 docs: more rust doc additions 2021-01-12 11:08:43 -08:00
Amila Welihinda
6a375cb6af chore: more refactors to reflect comments 2021-01-12 10:14:51 -08:00
Amila Welihinda
1cce66bbd9 feat: add safety doc comments to neon runtime date api 2021-01-11 11:23:00 -08:00
David Herman
cd460af96b Deprecates PartialEq for the N-API backend and adds a strict_equals method for handles. 2021-01-09 17:47:34 -08:00
Amila Welihinda
7a5ae29f75 fix: refator date logic to separate file 2021-01-09 15:49:51 -08:00
Amila Welihinda
0426692743 feat: impl new_lossy 2021-01-09 15:49:49 -08:00
Amila Welihinda
7105a63ad6 test: add additional date api test cases 2021-01-09 15:48:00 -08:00
Amila Welihinda
3799bfc8db test: add additional date api test cases 2021-01-09 15:48:00 -08:00
Amila Welihinda
ea1011f8f3 test: add out of range date test case 2021-01-09 15:48:00 -08:00
Amila Welihinda
d8d4032e6b feat: implement JsDate::try_new API 2021-01-09 15:48:00 -08:00
Amila Welihinda
e46340bd55 fix: address more cr comments 2021-01-09 15:48:00 -08:00
Amila Welihinda
9774b95145 fix: cr comemnt fixes 2021-01-09 15:48:00 -08:00
Amila Welihinda
49fd8b308f feat: impl Date API (closes #70) 2021-01-09 15:48:00 -08:00
Dave Herman
a68d5fc8bb
Merge pull request #664 from neon-bindings/jsbuffer-uninitialized
JsBuffer::uninitialized() for N-API backend
2021-01-07 11:48:35 -08:00
K.J. Valencik
c0937e36c9
Update lock files 2021-01-07 14:34:28 -05:00
K.J. Valencik
aae89f36d0
Merge pull request #661 from Himself65/patch-1
Update documentation URL
2021-01-07 08:10:15 -05:00
Himself65
df9f5cbba9 Update documentation URL
Co-authored-by: K.J. Valencik <kjvalencik@gmail.com>
2021-01-07 14:42:38 +08:00
David Herman
75457c97e3 Implements JsBuffer::uninitialized() for N-API backend. This checks off one of the last remaining tasks for #444. 2021-01-06 16:07:57 -08:00
K.J. Valencik
f64543a2bd
Merge pull request #663 from neon-bindings/kv/remove-deprecated
Remove and feature flag features that are being removed in N-API
2021-01-06 12:48:31 -05:00
K.J. Valencik
0734bf4a07
Remove classes from N-API 2021-01-06 12:29:57 -05:00
K.J. Valencik
6cf59213fe
Remove APIs that will not be implemented in N-API 2021-01-06 12:09:38 -05:00
K.J. Valencik
94bb1cd933
Merge pull request #660 from neon-bindings/kv/0.7.0-rc
v0.7.0 Release Candidate
2021-01-05 11:54:04 -05:00
K.J. Valencik
999a4bb7ea
v0.7.0 2021-01-05 10:07:17 -05:00
K.J. Valencik
4730ab7166
Threadsafe Handles (#622)
feat: Implements Threadsafe Handles as specified by https://github.com/neon-bindings/rfcs/pull/32

Requires the `event-queue-api` feature flag until the RFC is accepted.
2021-01-05 09:56:46 -05:00
K.J. Valencik
f98dec2679
feat(neon-runtime): Add selectable N-API versions (#649)
feat(neon-runtime): Add selectable N-API versions

* Clear error message around minimum N-API version
* Only load the host process as a library once
2021-01-04 09:06:46 -05:00
K.J. Valencik
39a6c4fbdc
Merge pull request #651 from neon-bindings/dependabot/npm_and_yarn/test/electron/ini-1.3.7
build(deps): bump ini from 1.3.5 to 1.3.7 in /test/electron
2020-12-11 16:06:55 -05:00
dependabot[bot]
0013378993
build(deps): bump ini from 1.3.5 to 1.3.7 in /test/electron
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.7.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.7)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-11 20:41:37 +00:00
Renée Kooi
77408d3063
Upgrade cfg-if (#650) 2020-12-10 08:22:58 +01:00
K.J. Valencik
f45f71dbdd
Merge pull request #648 from neon-bindings/kv/rc-0.6.0
Version 0.6.0
2020-12-09 15:23:36 -05:00
K.J. Valencik
c50b6bf6b4
v0.6.0 2020-12-09 14:14:37 -05:00
K.J. Valencik
b44a3a59e8
Merge pull request #631 from neon-bindings/kv/try-catch
feat(neon): Update `try-catch` to match the RFC; return a `T: Sized` instead of `T: Value`
2020-12-09 14:03:38 -05:00
K.J. Valencik
eb4356209d
review(neon): Add test to try_catch 2020-12-09 13:12:18 -05:00
K.J. Valencik
a68f115edb
review(neon-sys): Fix comments on try_catch 2020-12-09 13:12:18 -05:00
K.J. Valencik
0b51e17183
review(neon): Sized is implied and can be elided in try_catch 2020-12-09 13:12:18 -05:00
K.J. Valencik
bd74a239cf
feat(neon): Update try-catch to match the RFC 2020-12-09 13:12:17 -05:00
K.J. Valencik
c1bdfd1bdf
Merge pull request #647 from neon-bindings/kv/build-refactor
`neon-build` refactor to make use of dynamic loading
2020-12-09 13:11:33 -05:00
K.J. Valencik
02975d0fdc
review(neon-build): Change name of neon_build::Builder::new() to neon_build::Setup::options() 2020-12-09 12:05:01 -05:00
K.J. Valencik
1be0a598f7
chore(electron): Convert electron package-lock.json to version 1 2020-12-08 10:46:56 -05:00
K.J. Valencik
f21eecdb2c
feat(neon-build): Add builder for customizing index.node location 2020-12-07 14:45:21 -05:00
K.J. Valencik
ea6e96bde4
test(electron): Update electron test to n-api 2020-12-04 14:30:21 -05:00
K.J. Valencik
b3a38869ca
Remove the win delay load hook 2020-12-04 14:20:49 -05:00
K.J. Valencik
096104084b
test(napi): Flatten structure 2020-12-04 14:20:40 -05:00
K.J. Valencik
585bd33f1c
feature(neon-build): Output index.node without neon-cli 2020-12-04 13:08:19 -05:00
K.J. Valencik
f4871dbc10
chore(neon-build): Re-organize to prepare for changes in N-API build logic
* Update to 2018 edition
* Re-structure to platform module structure
* Remove `cfg-if`
* Make `ureq` unconditionally required
* Document `neon-build`
2020-12-04 13:08:18 -05:00
K.J. Valencik
5f6481a532
Merge pull request #646 from neon-bindings/kv/dynamic-loading
Dynamic Loading
2020-12-04 09:16:49 -05:00
K.J. Valencik
ccd508dd48
doc(neon-runtime): Add documentation from dynamic loading review comments 2020-12-02 13:51:19 -05:00
K.J. Valencik
1c0a5406f0
hack(test/napi): Remove neon-build to test dynamic loading
This will be reverted with the neon-build refactor.
2020-12-01 15:34:24 -05:00
K.J. Valencik
0900dd2a50
feature(neon-runtime): Dynamic module loading 2020-12-01 15:34:21 -05:00
K.J. Valencik
7422e60f66
chore(neon-runtime): Rename nodejs-sys feature to napi 2020-11-29 22:20:46 -05:00
K.J. Valencik
84c2f518da
chore(neon-runtime): Update to 2018 edition 2020-11-29 19:18:56 -05:00
K.J. Valencik
28ae751606
Fix neon-macros description 2020-11-24 12:31:26 -05:00
K.J. Valencik
cffe3cfc23
Merge pull request #643 from neon-bindings/kv/v0.5.3
v0.5.3
2020-11-24 12:22:45 -05:00
K.J. Valencik
ca6103d0fc
v0.5.3 2020-11-24 09:25:35 -05:00
K.J. Valencik
f04c41761e
Merge pull request #636 from neon-bindings/kv/proc-macro
feat(neon-macros): Add `neon::main` proc attr macro
2020-11-24 08:35:56 -05:00
Renée Kooi
efeff8f7ae
finish up scopes for n-api (#637) 2020-11-24 12:15:09 +01:00
Renée Kooi
68f136ec28
Node.js 15 support (legacy) (#623) 2020-11-24 11:46:32 +01:00
K.J. Valencik
37d237a9ec
feat(neon-macros): Add neon::main proc attr macro 2020-11-23 10:48:35 -05:00
Amila Welihinda
8aec5b0074
Merge pull request #640 from neon-bindings/kv/ci
Fix linux CI
2020-11-22 11:03:28 -08:00
K.J. Valencik
5c3253d22f
Fix linux CI 2020-11-21 17:37:48 -05:00
K.J. Valencik
6a3848bbd7
Merge pull request #635 from neon-bindings/kv/0.5.2.rc
v0.5.2 RC
2020-11-16 12:24:15 -05:00
K.J. Valencik
83a54f2702
0.5.2 2020-11-16 11:30:39 -05:00
K.J. Valencik
15d881b1cc
Merge pull request #610 from sbillig/argv-smallvec
Use smallvec for CallContext arguments (napi)
2020-11-16 09:27:47 -05:00
sean billig
cf4b54e9a9 Merge branch 'main' into argv-smallvec 2020-11-15 11:24:08 -08:00
Dave Herman
e91a284c82
Merge pull request #633 from neon-bindings/kv/args
feat: Allow additional arguments to be passed to `cargo build`
2020-11-13 10:20:04 -08:00
Nathaniel Daniel
8142074f07
Add redirect support for downloading node.lib (#620)
Co-authored-by: Renée Kooi <renee@kooi.me>
2020-11-13 15:48:06 +01:00
K.J. Valencik
35f5a42002
Merge pull request #634 from neon-bindings/upgrade-actions
ci: upgrade install-llvm-action to v1.1.0
2020-11-13 09:42:53 -05:00
Renée Kooi
c312a0a0d7
ci: upgrade install-llvm-action to v1.1.0
Fixes the issue that causes all the warnings in check runs, like here:
https://github.com/neon-bindings/neon/actions/runs/361710689
2020-11-13 15:17:57 +01:00
K.J. Valencik
c1eaaf0d77
feat: Allow additional arguments to be passed to cargo build
`neon build -- --features my-feature` will pass everything after `--` to cargo
2020-11-12 12:47:00 -05:00
K.J. Valencik
11cd59dc69
Merge pull request #619 from neon-bindings/kv/0.5.1.rc
v0.5.1
2020-10-28 10:00:53 -04:00
K.J. Valencik
99260dc449
v0.5.1 2020-10-27 19:13:39 -04:00
K.J. Valencik
1f217f56cb
Merge pull request #579 from neon-bindings/kv/jsbox
Implementation of JsBox
2020-10-27 18:43:32 -04:00
K.J. Valencik
a89ea8ca40
JsBox review updates 2020-10-27 11:34:37 -04:00
K.J. Valencik
4a1bfa1a15
(feat): JsBox 2020-10-27 11:34:37 -04:00
K.J. Valencik
7a1eff0ebe
Merge pull request #618 from neon-bindings/kv/fix-ci
Fix CI after changing master branch name to main
2020-10-27 11:34:18 -04:00
K.J. Valencik
3ae3decff5
Fix CI after changing master branch name to main 2020-10-27 11:14:14 -04:00
K.J. Valencik
878a47bab9
Merge pull request #607 from sbillig/call-smallvec
Reduce JsFunction::call overhead (via smallvec)
2020-10-19 09:22:51 -04:00
K.J. Valencik
22a03bf5f5
Merge branch 'main' into call-smallvec 2020-10-19 09:11:57 -04:00
K.J. Valencik
cc8daf27bc
Merge pull request #617 from staltz/nodejs-mobile
Support nodejs-mobile on Android and iOS
2020-10-19 09:08:06 -04:00
Andre Staltz
ada4803f46
support nodejs-mobile on iOS 2020-10-18 21:43:34 +03:00
Andre Staltz
c0b2a85334
support nodejs-mobile on Android 2020-10-15 13:38:07 +03:00
K.J. Valencik
7b095648a0
Merge pull request #615 from neon-bindings/0.5.0
v0.5.0
2020-10-12 10:18:21 -04:00
K.J. Valencik
40a8aebdc3
v0.5.0 2020-10-12 10:03:13 -04:00
Renée Kooi
299a206506
update rfcs main branch references 2020-10-08 15:47:17 +02:00
Renée Kooi
0afefdd5fb
update branch name 2020-10-08 15:39:00 +02:00
K.J. Valencik
32f3276ded
Merge pull request #606 from sbillig/downcasterror-crash
Fix crash in DowncastError Display impl, remove String member
2020-10-06 13:37:25 -04:00
sean billig
e5b8154255 add tests for DowncastError Display impl 2020-10-05 20:17:57 -07:00
sean billig
17a186d0eb Use smallvec for CallContext arguments 2020-09-28 10:41:35 -07:00
sean billig
f6a71f2ed6 Use smallvec in JsFunction::construct too 2020-09-26 20:54:13 -07:00
sean billig
bd36672e54 Reduce JsFunction::call overhead (via smallvec) 2020-09-26 20:08:02 -07:00
sean billig
e285029e24 Fix crash in DowncastError Display impl, remove String member 2020-09-26 13:16:48 -07:00
K.J. Valencik
a1770816bc
Merge pull request #602 from neon-bindings/kv/0.4.2.rc
v0.4.2 release
2020-09-23 14:42:47 -04:00
K.J. Valencik
da1dacfe24
v0.4.2 release 2020-09-23 12:54:25 -04:00
Renée Kooi
c143cc64a5
n-api: use napi_get_all_property_names (#601) 2020-09-22 15:55:47 +02:00
K.J. Valencik
637d53504d
Merge pull request #600 from neon-bindings/kv/eventhandler-hotfix
fixed incorrect unsafe closure usage in event handler
2020-09-22 07:08:22 -04:00
K.J. Valencik
af7d84582f
fixed incorrect unsafe closure usage in event handler 2020-09-21 15:00:15 -04:00
K.J. Valencik
6c445cdbd1
Merge pull request #552 from neon-bindings/kv/eventhandler-soundness
EventHandler memory leak and race condition
2020-09-21 13:55:47 -04:00
Amila Welihinda
336b65b031
Merge pull request #599 from neon-bindings/remove-docs-workflow
Remove docs gh workflow
2020-09-19 10:28:36 -07:00
Amila Welihinda
f7c65e9e28
Delete docs.yml 2020-09-19 09:39:19 -07:00
K.J. Valencik
68e17d9ad9
Merge pull request #598 from neon-bindings/kv/v0.4.1.rc
Release v0.4.1
2020-09-18 17:24:20 -04:00
K.J. Valencik
28acc76375
Release v0.4.1 2020-09-18 16:42:40 -04:00
K.J. Valencik
828d28596a
Remove link to deprecated API docs. Use docs.rs instead. 2020-09-18 16:42:39 -04:00
K.J. Valencik
dc81562076
Enable EventHandler and try_catch in docs.rs 2020-09-18 16:42:39 -04:00
K.J. Valencik
a5f045755f
Merge pull request #588 from goto-bus-stop/delay-load-hook
Port win_delay_load_hook
2020-09-18 08:44:30 -04:00
K.J. Valencik
abdff5dfaa
Merge pull request #583 from goto-bus-stop/windows-node.lib
Download and link `node.lib` on Windows
2020-09-18 08:37:06 -04:00
dependabot[bot]
d69d80c626
build(deps): bump handlebars from 4.4.5 to 4.5.3 in /test/cli (#595)
Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.4.5 to 4.5.3.
- [Release notes](https://github.com/wycats/handlebars.js/releases)
- [Changelog](https://github.com/handlebars-lang/handlebars.js/blob/master/release-notes.md)
- [Commits](https://github.com/wycats/handlebars.js/compare/v4.4.5...v4.5.3)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-09-05 10:22:24 +02:00
Renée Kooi
3b12f9c50b
contributing: fix link to Slack (#593) 2020-09-04 19:17:08 +02:00
Renée Kooi
614b6730a3
build: only add win_delay_load_hook for the N-API runtime 2020-09-04 16:11:04 +02:00
dependabot[bot]
882fd14a4c
Bump handlebars from 4.3.0 to 4.4.5 in /test/cli (#594)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-09-04 09:10:02 +02:00
Renée Kooi
5ffa2d2821
accept electron.exe in delay-load-hook 2020-08-28 18:25:24 +02:00
Renée Kooi
0fc614ff84
initial win_delay_load_hook port 2020-08-28 16:50:58 +02:00
Renée Kooi
8d1f0029d1
tweak the Path::new() hack comment 2020-08-28 15:59:02 +02:00
Renée Kooi
b8259eb9d4
use npm_config_target if set 2020-08-28 15:57:08 +02:00
Renée Kooi
412b6577a4
pass through raw output from failing node -v call 2020-08-28 15:56:49 +02:00
Renée Kooi
e7837852f0
ci: the action looks like it could be faster 2020-08-13 21:35:26 +02:00
Renée Kooi
558c3d1f14
ci: try installing llvm on windows? 2020-08-13 21:13:52 +02:00
Renée Kooi
151137363c
build: only download node.lib if we dont have one yet 2020-08-13 20:51:44 +02:00
Renée Kooi
e80c8c1933
use @kjvalencik's non-{{ suggestion 2020-08-11 17:41:28 +02:00
Renée Kooi
468d425ac8
support NEON_NODE_LIB env var 2020-08-11 17:34:47 +02:00
Renée Kooi
3e9865139e
support 32 bit 2020-08-11 17:19:44 +02:00
Dave Herman
65681d2769
Merge pull request #585 from neon-bindings/is-construct
Implement FunctionContext::kind() for N-API
2020-08-10 07:57:12 -07:00
David Herman
f0f8e6b1f8 Address feedback in review:
- Use `Local` instead of `napi_value`, for consistency
- Comment that `target` is guaranteed to be initialized but may be NULL
2020-08-09 13:46:55 -07:00
David Herman
b17c2fbd6c Implement FunctionContext::kind() for N-API 2020-08-08 15:25:08 -07:00
Dave Herman
6456bcd725
Merge pull request #575 from goto-bus-stop/tag-checks
napi tidbits: implement remaining tag checks
2020-08-07 21:27:52 -07:00
Renée Kooi
2574b2dbda
Use node.js to download node.lib 2020-08-07 15:01:35 +02:00
Renée Kooi
2c8fd5ed12
napi: get it to compile on windows 2020-08-07 14:50:27 +02:00
K.J. Valencik
59e48eab9a
Merge pull request #582 from felixonmars/patch-1
Correct a typo in test/dynamic/lib/classes.js
2020-08-05 16:53:15 -04:00
Felix Yan
3383d61bba
Correct a typo in test/dynamic/lib/classes.js 2020-08-06 03:26:52 +08:00
Dave Herman
bc0f181d53
Merge pull request #580 from neon-bindings/kv/actions-linux-fix
Linux build failures do not fail the build
2020-08-04 15:33:00 -07:00
K.J. Valencik
ff4b67b853
Linux build failures do not fail the build because of a bug in the xvfb-action. Use a script instead. 2020-08-04 17:38:02 -04:00
Dave Herman
cd8f80ad97
Merge pull request #578 from neon-bindings/avoid-duplicate-ci
Disable duplicate CI jobs for internal PRs
2020-08-03 12:33:09 -07:00
David Herman
04b3bdb322 Address issues caught by @kjvalencik in review:
- remove dead conditional in docs workflow
- more precise language in the linux/macos/windows comments
2020-08-03 10:54:21 -07:00
Dave Herman
87a8d6493a
Merge pull request #555 from amilajack/chore/bump-deps
chore: cli infra updates
2020-08-02 16:20:09 -07:00
Amila Welihinda
049c93e781 bump ts-typed-json 2020-08-02 15:52:26 -07:00
Amila Welihinda
cb826b7cb6 fix: drop ts-dict, remove any types, bump deps 2020-08-02 15:52:26 -07:00
Amila Welihinda
df1a598299 migrate to esmodule interop 2020-08-02 15:52:26 -07:00
Amila Welihinda
8b0bf9ce30 drop unused deps 2020-08-02 15:52:26 -07:00
Amila Welihinda
3c1de72890 bump all deps 2020-08-02 15:52:26 -07:00
Amila Welihinda
69c75cecf3 drop ts-dict for Record 2020-08-02 15:52:26 -07:00
Amila Welihinda
4dcd9ead0a remove rsvp 2020-08-02 15:52:26 -07:00
David Herman
9293903e9f Aha! From the docs:
> For a `pull_request` event, only branches and tags on the base are evaluated.
2020-08-02 07:42:44 -07:00
David Herman
9661293f4d ugh wrong indentation. still stabbing randomly at this 2020-08-02 07:41:10 -07:00
David Herman
59693f845c la la I am making things up 2020-08-02 07:40:05 -07:00
David Herman
6fdfd366c7 no really, how do you yaml 2020-08-02 07:36:00 -07:00
David Herman
d2bc5f504c how do you yaml 2020-08-02 07:35:08 -07:00
David Herman
5f53d9caf6 Use a branch filter instead of a condition, to avoid polluting the UI. 2020-08-02 07:34:01 -07:00
Dave Herman
0aec7dba72
Merge pull request #577 from neon-bindings/actions-badges
README badges
2020-08-02 07:25:31 -07:00
David Herman
603b55b30b Disable the tests for pull_request events created by our own internal PRs, since they already get triggered for the push to the branch, resulting in duplicate CI jobs. See:
https://github.community/t/duplicate-checks-on-push-and-pull-request-simultaneous-event/18012/5
2020-08-01 23:25:33 -07:00
David Herman
6a5bb0e4c1 Move CI badges to the end, so people can see the Cargo and npm badges first. 2020-08-01 19:22:54 -07:00
David Herman
46e365c67e Fix Windows Actions badge URL path. 2020-08-01 19:21:45 -07:00
David Herman
e315310cca Fix the Actions badge URL path. 2020-08-01 19:20:32 -07:00
David Herman
31aa1cfaf0 Replace Travis and Appveyor badges with Actions badges. 2020-08-01 19:15:46 -07:00
Dave Herman
471d66c38f
Merge pull request #576 from neon-bindings/increase-test-timeouts
Increase test timeouts to 5s
2020-08-01 19:05:22 -07:00
David Herman
391abad782 Increase mocha tests' timeout to 5s, to decrease the number of nondeterministic test failures in GitHub Actions. 2020-08-01 18:14:35 -07:00
K.J. Valencik
f70f4b825b
Merge pull request #531 from lhr0909/master
Switch to GitHub Actions
2020-08-01 14:09:23 -04:00
Simon Liang
f91b12baf5
Update .github/workflows/linux.yml
Co-authored-by: K.J. Valencik <kjvalencik@gmail.com>
2020-08-01 10:39:56 +08:00
Simon Liang
354fe43e4a
Update .github/workflows/docs.yml
Co-authored-by: K.J. Valencik <kjvalencik@gmail.com>
2020-08-01 10:39:48 +08:00
Renée Kooi
c5527f0d27
fixup! napi: implement remaining tag checks 2020-07-31 14:13:50 +02:00
Renée Kooi
43e2030140
napi: implement remaining tag checks 2020-07-31 13:25:54 +02:00
Dave Herman
29fa5d4b4c
Merge pull request #573 from goto-bus-stop/napi-coercions
napi tidbits: finish up type coercion APIs
2020-07-26 12:18:18 -07:00
Renée Kooi
160b28c9d1
Merge branch 'master' into napi-coercions 2020-07-26 20:02:16 +02:00
Dave Herman
9a247e11fe
Merge pull request #558 from goto-bus-stop/port-tests-to-napi
napi tidbits: port numbers and strings test from nan
2020-07-26 10:24:17 -07:00
Dave Herman
0bddba6102
Merge pull request #559 from goto-bus-stop/finish-napi-array
napi tidbits: finish `neon_runtime::napi::array`
2020-07-26 10:22:37 -07:00
Renée Kooi
0894971b17
napi: mark to_object as unused 2020-07-25 10:39:14 +02:00
Renée Kooi
32f69bcb15
napi: add test for to_string coercion 2020-07-25 10:36:35 +02:00
Renée Kooi
c8a777e20b
napi: assert result in all tag checks 2020-07-24 19:36:22 +02:00
Renée Kooi
343c05f1fa
napi: implement neon_runtime::napi::convert::to_object 2020-07-24 19:33:42 +02:00
Renée Kooi
2fd4e654b8
napi: implement is_array check 2020-07-24 19:24:12 +02:00
Renée Kooi
44c8d01550
napi: implement neon_runtime::napi::array::new 2020-07-24 19:10:29 +02:00
Renée Kooi
5a63267ee8
napi: port array tests from nan 2020-07-24 19:09:04 +02:00
Renée Kooi
3888b0f3da
napi: port numbers and strings test from nan 2020-07-24 19:06:41 +02:00
Dave Herman
f305e92feb
Merge pull request #545 from goto-bus-stop/array-buffer
n-api: ArrayBuffers and Buffers
2020-07-24 09:37:11 -07:00
Renée Kooi
a39442ad91
Elide lifetime on .lock() 2020-07-24 11:40:18 +02:00
Dave Herman
c86998ed43
Merge pull request #549 from neon-bindings/dependabot/npm_and_yarn/cli/lodash-4.17.19
Bump lodash from 4.17.15 to 4.17.19 in /cli
2020-07-18 17:23:19 -07:00
dependabot[bot]
1c6de72064
Bump lodash from 4.17.15 to 4.17.19 in /cli
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-18 20:38:57 +00:00
Dave Herman
6f9ffa9b5f
Merge pull request #554 from neon-bindings/dependabot/npm_and_yarn/test/napi/lodash-4.17.19
Bump lodash from 4.17.15 to 4.17.19 in /test/napi
2020-07-18 13:38:56 -07:00
Dave Herman
9eb3ca6bd3
Merge pull request #553 from neon-bindings/dependabot/npm_and_yarn/test/electron/lodash-4.17.19
Bump lodash from 4.17.15 to 4.17.19 in /test/electron
2020-07-18 13:38:41 -07:00
Dave Herman
cd39666dc3
Merge pull request #550 from neon-bindings/dependabot/npm_and_yarn/test/cli/lodash-4.17.19
Bump lodash from 4.17.15 to 4.17.19 in /test/cli
2020-07-18 13:38:09 -07:00
Simon Liang
3067a25dd4 added workflow trigger on pull_request, removed travis and appveyor 2020-07-18 22:10:32 +08:00
Simon Liang
5e0a4e1919 added macos test 2020-07-18 21:49:57 +08:00
Simon Liang
7f0a04c7c7 dropping nodejs 8.x and adding nodejs 14.x 2020-07-18 21:25:26 +08:00
Simon Liang
b5f84f4895 update electron version to fix the node-gyp issue in windows 2020-07-18 21:25:26 +08:00
Simon Liang
a9f9d640ea updating node-gyp version to get around the electron download error 2020-07-18 21:25:26 +08:00
Simon Liang
0491055f77 trying to use msvs 2019 and see if it passes 2020-07-18 21:25:26 +08:00
Simon Liang
539465703d trying out windows build 2020-07-18 21:25:26 +08:00
Simon Liang
068ba22531 added docs workflow 2020-07-18 21:25:26 +08:00
Simon Liang
c64a39a05d added electron test 2020-07-18 21:25:26 +08:00
Simon Liang
2ef84d29a9 fixed the build trigger 2020-07-18 21:25:26 +08:00
Simon Liang
0b5a5ea29f test github action 2020-07-18 21:25:26 +08:00
dependabot[bot]
01bb2c78d9
Bump lodash from 4.17.15 to 4.17.19 in /test/napi
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-18 10:51:37 +00:00
dependabot[bot]
e681947af6
Bump lodash from 4.17.15 to 4.17.19 in /test/electron
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-18 06:44:38 +00:00
dependabot[bot]
69299bb154
Bump lodash from 4.17.15 to 4.17.19 in /test/cli
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-18 04:36:01 +00:00
Dave Herman
6891109f1c
Merge pull request #537 from amilajack/fix/updated-windows-cli-fix
fix: `neon new` not exiting on windows
2020-07-17 21:34:10 -07:00
K.J. Valencik
9ba0fe3180
Workaround for EventHandler drop race 2020-07-17 15:22:01 -04:00
K.J. Valencik
3aacc3a617
Fix EventHandler leak on delete 2020-07-17 15:21:55 -04:00
Amila Welihinda
c9158d70d8 fix(cli): use rimraf prevent TOUTOC 2020-07-17 11:48:35 -07:00
Renée Kooi
9e1a4c4b22
Merge branch 'master' into array-buffer 2020-07-17 17:48:59 +02:00
Dave Herman
7e1ca41633
Merge pull request #543 from neon-bindings/try-catch-internal
try_catch
2020-07-14 17:19:11 -07:00
David Herman
a03b27b095 Return a generic T: Value in the Ok case, rather than JsValue. 2020-07-14 14:46:26 -07:00
David Herman
35a8858e5c Remove unnecessary UnwindSafe requirement for N-API version of public try_catch API. 2020-07-14 13:31:06 -07:00
David Herman
ef349bb8b8 Remove unnecessary UnwindSafe restriction for N-API backend. 2020-07-14 13:28:16 -07:00
David Herman
93e564d013 Merge branch 'master' into try-catch-internal 2020-07-14 10:51:10 -07:00
David Herman
b4bdf87d0b Panic on spurious Err(Throw) instead of silently coercing to undefined 2020-07-14 10:23:25 -07:00
Renée Kooi
c3eb47dfdc
Merge branch 'master' into array-buffer 2020-07-14 11:09:52 +02:00
Dave Herman
bd2479cd4b
Merge pull request #542 from neon-bindings/errors-napi
Migrated error type to napi error
2020-07-13 09:54:56 -07:00
Anshul Goyal
a3503ee824
Migrated error type to napi error 2020-07-13 09:52:18 -04:00
Dave Herman
48e7a40398
Merge pull request #544 from goto-bus-stop/cleanup
n-api: some warning cleanup
2020-07-12 07:40:14 -07:00
Dave Herman
d8c6775838
Merge pull request #534 from neon-bindings/kv/n-api-arg-cache
Fix #530: Cache function arguments in N-API
2020-07-12 07:38:21 -07:00
David Herman
fa4812e439 Implement N-API backend as well. 2020-07-11 09:03:52 -07:00
Amila Welihinda
63c059f53a fix: use rimraf for removing dir 2020-07-11 08:45:41 -07:00
David Herman
f899e21c0a Fix N-API build. 2020-07-10 18:05:34 -07:00
David Herman
bc185ac13e Put public try_catch API behind a feature flag, and enable the flag for the dynamic tests. 2020-07-10 17:55:05 -07:00
David Herman
9c1f0ce2bc - Clean up internal signatures to use a control-flow enum
- Implement panic propagation
- Add tests for panic and regular return value
2020-07-10 16:32:50 -07:00
Renée Kooi
1c4381017d
n-api: create_buffer has an out param, use it 2020-07-10 15:52:34 +02:00
K.J. Valencik
861b1ed458
Fix issue #530: Cache function arguments in N-API 2020-07-10 08:25:20 -04:00
Renée Kooi
a8d9208673
n-api: cast the bytes pointer 2020-07-10 13:45:20 +02:00
Renée Kooi
1319098e99
n-api: implement JsBuffer::new 2020-07-10 13:34:01 +02:00
Renée Kooi
cb2ed3da80
legacy: add a test for creating Buffers on the Rust side 2020-07-10 13:07:46 +02:00
Renée Kooi
4aa564d590
n-api: remove outdated comments 2020-07-10 13:03:09 +02:00
Renée Kooi
e8a53f44e9
n-api: some warning cleanup 2020-07-10 12:59:28 +02:00
Renée Kooi
cda549d06c
n-api: support borrowing of node.js Buffer data 2020-07-10 12:55:49 +02:00
Renée Kooi
ac9215e146
n-api: support basic borrowing of ArrayBuffer data 2020-07-10 12:49:51 +02:00
David Herman
2626dd12a1 Add test for nested instances of try_catch active on the stack. 2020-07-09 14:27:15 -07:00
David Herman
3afc01d7d6 Add a comment explaining the "unlikely case" in Neon_TryCatch_With. 2020-07-09 14:03:39 -07:00
David Herman
03b4308217 Add a comment explaining the boxing. 2020-07-09 14:02:21 -07:00
David Herman
9b196a0a56 Use MaybeUninit instead of raw pointers. 2020-07-09 13:41:00 -07:00
David Herman
b65531b38b Basic functionality of try_catch implemented, with a simple test. Still left to do:
- hide the public API (and tests) behind a feature flag
- add tests for nested `TryCatch` instances on the stack
- add panic handler and tests to ensure panics get caught by try_catch
2020-07-07 14:44:42 -07:00
Amila Welihinda
ad8f98b5a8 fix: change methods to sync 2020-07-03 17:56:19 -07:00
Amila Welihinda
557fc3c5ad fix: update node requirements in readme 2020-07-03 14:01:33 -07:00
Amila Welihinda
0e55bb7468 fix: update node versions in appveyor 2020-07-03 13:58:16 -07:00
Amila Welihinda
6c1bc68508 fix: add node 14 to ci node versions 2020-07-03 13:05:07 -07:00
Amila Welihinda
f3294d1b2e fix: do not unlink if file does not exist 2020-07-03 13:04:24 -07:00
Amila Welihinda
463e0d8dc2 fix: upgrade to typescript@3.9.6 2020-07-03 11:38:58 -07:00
Usagi Ito
17b905b5f6 Fix #406
- Fix `neon new` could not be comple in Windows
- Update packages
2020-06-28 11:33:48 -07:00
Renée Kooi
457068a561
Implement is_arraybuffer tag check 2020-06-26 12:06:28 +02:00
Renée Kooi
abd322ed8d
Implement creating new array buffers 2020-06-26 12:06:16 +02:00
Dave Herman
35c8b60a18
Merge pull request #507 from goto-bus-stop/functions
Function calls
2020-06-20 13:52:52 -07:00
Renée Kooi
0a40f6abb0
reference TODO issue 2020-06-19 19:01:29 +02:00
Renée Kooi
7213332d72
do a capitalisation 2020-06-16 22:40:07 +02:00
Renée Kooi
e31c16cf5b
try to explain why we unwrap the external 2020-06-16 22:39:09 +02:00
Renée Kooi
528124767c
Remove unnecessary argc value from neon_runtime::call::data(). 2020-06-16 22:22:15 +02:00
Renée Kooi
a488204d10
kick ci 2020-06-09 14:53:49 +02:00
Renée Kooi
d25fe613a0
Add a lifetime parameter to CallbackInfo 2020-05-24 22:34:27 +02:00
Renée Kooi
d9e33245ab
Remove possibly-incorrect handling of Rust panics in callback 2020-05-24 22:34:27 +02:00
Renée Kooi
3b4de37674
Check that get_own_property_names does not return Symbols 2020-05-24 22:34:27 +02:00
Renée Kooi
b7e52e134e
Add test for get_own_property_names. 2020-05-24 22:34:27 +02:00
Renée Kooi
07384320cd
Remove outdated comments. 2020-05-24 22:34:26 +02:00
Renée Kooi
f4adc5b613
Enable other passing this tests. 2020-05-24 22:34:26 +02:00
Renée Kooi
10495c4ac2
Implement runtime::fun::this(). 2020-05-24 22:34:26 +02:00
Renée Kooi
1835acf0dd
Implement is_object tag check. 2020-05-24 22:34:26 +02:00
Renée Kooi
440e5f9149
Implement runtime::fun::construct. 2020-05-24 22:34:26 +02:00
Renée Kooi
546f2ce76d
Implement runtime::fun::call. 2020-05-24 22:34:26 +02:00
Renée Kooi
8d00d716c0
Start porting object test to n-api runtime. 2020-05-24 22:34:26 +02:00
Renée Kooi
dfebfc61b2
Start porting function tests from nan to n-api runtime. 2020-05-24 22:34:26 +02:00
Renée Kooi
a0ec71b633
napi: implement return value
napi expects you to return a `napi_value` from your functions, instead
of using `SetReturn` like in nan. I ended up having to duplicate these
`invoke` implementations after all!
2020-05-24 22:34:26 +02:00
Renée Kooi
f61b739aff
napi: Implement receiving call arguments on the Rust side. 2020-05-24 22:34:25 +02:00
Renée Kooi
98462ae56d
Start work on exporting n-api functions 2020-05-24 22:34:25 +02:00
Renée Kooi
cfc894015b
Unwrap v8::External pointer in C++
napi automatically wraps and unwraps the `data` pointer on functions
created through `napi_create_function`, so we don't need to use the
`napi_create_external` API in neon-runtime. Instead we can work with the
raw pointers. This aligns the C++ and n-api APIs so that the `neon`
crate can just assume associated data for a function is always a raw
pointer.
2020-05-24 22:34:25 +02:00
Renée Kooi
6d5c32a8ea
Make CallbackInfo wrap a pointer. 2020-05-24 22:34:25 +02:00
Renée Kooi
1ac73a640b
Add env parameter to invoke() API 2020-05-24 22:34:22 +02:00
199 changed files with 15175 additions and 5214 deletions

6
.cargo/config.toml Normal file
View File

@ -0,0 +1,6 @@
[alias]
# Neon defines mutually exclusive feature flags which prevents using `cargo clippy --all-features`
# The following aliases simplify linting the entire workspace
clippy-legacy = "clippy --all-targets --no-default-features -p neon -p neon-runtime -p neon-build -p neon-macros -p tests -p static_tests --features event-handler-api,proc-macros,try-catch-api,legacy-runtime -- -A clippy::missing_safety_doc"
clippy-napi = "clippy --all-targets --no-default-features -p neon -p neon-runtime -p neon-build -p neon-macros -p electron-tests -p napi-tests --features proc-macros,try-catch-api,napi-experimental -- -A clippy::missing_safety_doc"
neon-test = "test --no-default-features --features napi-experimental"

39
.github/workflows/lint.yml vendored Normal file
View File

@ -0,0 +1,39 @@
name: Lints
on:
push:
# Prevent duplicate runs of this workflow on our own internal PRs.
branches:
- main
pull_request:
branches:
- main
jobs:
lint:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
rust-toolchain: [nightly]
steps:
- uses: actions/checkout@v2
- name: Use Rust ${{ matrix.rust-toolchain }}
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust-toolchain }}
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: install build-essential
run: sudo apt-get install -y build-essential
- name: Formatting
run: cargo fmt --all -- --check
- name: Clippy (N-API)
run: cargo clippy-napi
- name: Clippy (Legacy)
run: cargo clippy-legacy

38
.github/workflows/linux.yml vendored Normal file
View File

@ -0,0 +1,38 @@
name: Test on Linux
on:
push:
# Prevent duplicate runs of this workflow on our own internal PRs.
branches:
- main
pull_request:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x, 14.x, 16.x]
rust-toolchain: [stable, beta, nightly]
steps:
- uses: actions/checkout@v2
- name: Use Rust ${{ matrix.rust-toolchain }}
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust-toolchain }}
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: install build-essential
run: sudo apt-get install -y build-essential
- name: run cargo test
run: xvfb-run --auto-servernum cargo neon-test -- --nocapture
- name: run CLI test
working-directory: ./create-neon
run: npm test

40
.github/workflows/macos.yml vendored Normal file
View File

@ -0,0 +1,40 @@
name: Test on MacOS
on:
push:
# Prevent duplicate runs of this workflow on our own internal PRs.
branches:
- main
pull_request:
branches:
- main
jobs:
build:
runs-on: macos-latest
strategy:
matrix:
node-version: [12.x, 14.x, 16.x]
rust-toolchain: [stable, beta, nightly]
steps:
- uses: actions/checkout@v2
- name: Use Rust ${{ matrix.rust-toolchain }}
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust-toolchain }}
target: x86_64-apple-darwin
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
# - name: update node-gyp to latest
# # https://github.com/nodejs/node-gyp/issues/1933#issuecomment-586915535
# run: npm install -g node-gyp@latest
- name: run cargo test
run: cargo neon-test
- name: run CLI test
working-directory: ./create-neon
run: npm test

51
.github/workflows/windows.yml vendored Normal file
View File

@ -0,0 +1,51 @@
name: Test on Windows
on:
push:
# Prevent duplicate runs of this workflow on our own internal PRs.
branches:
- main
pull_request:
branches:
- main
jobs:
build:
runs-on: windows-latest
strategy:
matrix:
node-version: [12.x, 14.x, 16.x]
rust-toolchain: [stable, beta, nightly]
steps:
- uses: actions/checkout@v2
- name: Use Rust ${{ matrix.rust-toolchain }}
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust-toolchain }}
target: x86_64-pc-windows-msvc
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Use npm v6
if: ${{ matrix.node-version == '16.x' }}
run: npm install -g npm@6
- name: Install libclang
uses: KyleMayes/install-llvm-action@01144dc97b1e2693196c3056414a44f15180648b
with:
version: "10"
directory: ${{ runner.temp }}/llvm
# - name: update node-gyp to latest
# # https://github.com/nodejs/node-gyp/issues/1933#issuecomment-586915535
# run: npm install -g node-gyp@latest
- run: npm config set msvs_version 2019
- name: run cargo test
run: cargo neon-test
env:
LIBCLANG_PATH: ${{ runner.temp }}/llvm/bin
- name: run CLI test
working-directory: ./create-neon
run: npm test

3
.gitignore vendored
View File

@ -7,6 +7,9 @@ Cargo.lock
**/index.node
**/artifacts.json
cli/lib
create-neon/dist
create-neon/create-neon-test-project
create-neon/create-neon-manual-test-project
test/cli/lib
npm-debug.log
rls*.log

View File

@ -1,62 +0,0 @@
language: rust
dist: trusty
rust:
- stable
- beta
- nightly
matrix:
exclude:
- env: TRAVIS_NODE_VERSION="8"
rust: beta
- env: TRAVIS_NODE_VERSION="8"
rust: nightly
env:
matrix:
- TRAVIS_NODE_VERSION="12"
- TRAVIS_NODE_VERSION="10"
- TRAVIS_NODE_VERSION="8"
global:
- secure: mO6uooJGRkDISBZbTq0zvjOfjQ6BeclkxVZN3XWaXrZ/4KjPi7/fRzkm9c8brPe7LWnD4bQ9Bhp7/I6+SVRlvw+uGXNhBiiIyl95jp9s9mOEN+8V7TyShIHEYjbVJf/EGiv5Rz7ni9cNG6iBHcxy5ehycodPtVdAn/VKw31Og/JNWFTu6OzaDZL6gsFIk7VEnHUHgGtl4/iPPdPgAN18oxWbf0CjaknFxXaQiwJXuevd+fuZU16HygBn2Kmj7gqbAKyG8T6wJ1LAQpTkIduXAcgW/PJnj+Stzu48GRVoWoqMQ9Ksk2oSX70fxksC3U3SH4tIQW1+68fXZz4Y0I6b7LkwxovRxkcE4rgoU15xxJuMjxXlQ/csupwhpnBdHhh+Fmjsr0n5KFFLCI7m04ZqAn7+xx9g2NhyuPmO7/ETW24XV9fRy7IywcqR8UgLmftI36r0nV5iO500t4o13DJ0hBTIUgX6KVenbr7v68WO+M/XSRU81RPGjQKsAFM60EpCtn36uCLAZbKyxQi1kYk6UFJLfb/bfrvSS6dzUQ7fEcNRekLMn8Fo4CKAmYCJ70tvhyx/EN0HrIpCfIYedMTLYf11ZQ/bKWcHE4GzU77cRgNwBYLsY6tFjchFukyK14F6jWgpqF81g0yzG0pRJRxZqrtwEI63Db/eLidGctmcEyQ=
before_install:
- source $HOME/.nvm/nvm.sh
- nvm install ${TRAVIS_NODE_VERSION}
- nvm use ${TRAVIS_NODE_VERSION}
- node -v
- npm -v
# Required for electron tests
before_script:
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
- sleep 3 # give xvfb some time to start
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
script:
- cargo test --release -- --nocapture
jobs:
include:
- stage: docs
before_install: skip
before_script:
- export PATH=$HOME/.local/bin:$PATH
- pip install ghp-import --user $(whoami)
script: |
if [[ $TRAVIS_BRANCH=master && $TRAVIS_PULL_REQUEST=false && $TRAVIS_COMMIT_MESSAGE =~ %travis:docs ]]; then
echo "Generating API docs..." &&
cargo doc &&
echo "<meta http-equiv=refresh content=0;url=neon/index.html>" > target/doc/index.html &&
echo "Deploying API docs..." &&
ghp-import -n target/doc &&
git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
fi

View File

@ -5,23 +5,32 @@ Neon owes its existence to the contributions of these fine people.
* [Reza Akhavan](https://github.com/jedireza)
* [Nerijus Arlauskas](https://github.com/Nercury)
* [Igor Artamonov](https://github.com/splix)
* [Peter Atashian](https://github.com/retep998)
* [David Baker](https://github.com/dbkr)
* [Sean Billig](https://github.com/sbillig)
* [Tim Blair](https://github.com/tblair)
* [Max Brunsfeld](https://github.com/maxbrunsfeld)
* [Dale Bustad](https://github.com/divmain)
* [Eduard-Mihai Burtescu](https://github.com/eddyb)
* [Gabriel Castro](https://github.com/GabrielCastro)
* [Lin Clark](https://github.com/linclark)
* [Nathaniel Daniel](https://github.com/adumbidiot)
* [Joey Ezechiëls](https://github.com/jjpe)
* [Cory Forsyth](https://github.com/bantic)
* [Olivier Goffart](https://github.com/ogoffart)
* [Dave Herman](https://github.com/dherman)
* [Himself65](https://github.com/Himself65)
* [Maciej Hirsz](https://github.com/maciejhirsz)
* [Amal Hussein](https://github.com/nomadtechie)
* [Usagi Ito](https://github.com/usagi)
* [Jeroen (jrd-rocks)](https://github.com/jrd-rocks)
* [Keegan (mhsjlw)](https://github.com/mhsjlw)
* [Florian Keller](https://github.com/ffflorian)
* [Aleksey Kladov](https://github.com/matklad)
* [Adam Kloboucnik](https://github.com/akloboucnik)
* [Renée Kooi](https://github.com/goto-bus-stop)
* [Anton Lazarev](https://github.com/antonok-edm)
* [Simon Liang](https://github.com/lhr0909)
* [Terence Lee](https://github.com/hone)
* [Milan Loveless](https://github.com/MilanLoveless)
* [Darin Morrison](https://github.com/freebroccolo)
@ -31,9 +40,11 @@ Neon owes its existence to the contributions of these fine people.
* [Robbie Pitts](https://github.com/robbiepitts)
* [Thiago Pontes](https://github.com/thiagopnts)
* [Sean Prashad](https://github.com/SeanPrashad)
* [Jordan Rose](https://github.com/jrose-signal)
* [Antonio Scandurra](https://github.com/as-cii)
* [Edward Shaw](https://github.com/EdShaw)
* [Nathan Sobo](https://github.com/nathansobo)
* [André Staltz](https://github.com/staltz)
* [Ingvar Stepanyan](https://github.com/RReverser)
* [stoically](https://github.com/stoically)
* [Andrew Stucki](https://github.com/andrewstucki)
@ -41,8 +52,11 @@ Neon owes its existence to the contributions of these fine people.
* [A2ZH (theJian)](https://github.com/theJian)
* [Corbin Uselton](https://github.com/corbinu)
* [K.J. Valencik](https://github.com/kjvalencik)
* [Velithris](https://github.com/Zireael-N)
* [Roberto Vidal](https://github.com/jrvidal)
* [Georg Vienna](https://github.com/geovie)
* [Daijiro Wachi](https://github.com/watilde)
* [Chi Wang](https://github.com/patr0nus)
* [wangcong](https://github.com/king6cong)
* [Amila Welihinda](https://github.com/amilajack)
* [Felix Yan](https://github.com/felixonmars)

View File

@ -18,7 +18,7 @@ we encourage you to [submit an RFC](https://github.com/neon-bindings/rfcs)!
The [RFC process](https://github.com/neon-bindings/rfcs#the-process) has a little more overhead than
filing an issue, but it's for the goal of allowing the Neon community to have a chance to vet
design ideas and reach consensus. And even at that, we've deliberately kept the [RFC template](https://github.com/neon-bindings/rfcs/blob/master/0000-template.md)
design ideas and reach consensus. And even at that, we've deliberately kept the [RFC template](https://github.com/neon-bindings/rfcs/blob/main/0000-template.md)
simple and open-ended.
### Good first bugs
@ -41,4 +41,4 @@ Unless you explicitly state otherwise, any contribution intentionally submitted
## Communication
* Slack: http://neon-community.slack.com -- get an invite from [the Slackin app](http://neon-community-slackin.herokuapp.com)
* Slack: <https://rust-bindings.slack.com> -- get an invite from [the Slackin app](https://rust-bindings-slackin.herokuapp.com)

View File

@ -1,28 +1,32 @@
[package]
name = "neon"
version = "0.4.0"
version = "0.8.2"
authors = ["Dave Herman <david.herman@gmail.com>"]
description = "A safe abstraction layer for Node.js."
readme = "README.md"
documentation = "https://api.neon-bindings.com/neon/index.html"
homepage = "https://www.neon-bindings.com"
repository = "https://github.com/neon-bindings/neon"
license = "MIT/Apache-2.0"
exclude = ["neon.jpg"]
exclude = ["neon.jpg", "doc/**/*"]
build = "build.rs"
edition = "2018"
[build-dependencies]
neon-build = { version = "=0.4.0", path = "crates/neon-build" }
neon-build = { version = "=0.8.2", path = "crates/neon-build" }
[dev-dependencies]
lazy_static = "1.4.0"
rustversion = "0.1.4"
semver = "0.9"
psd = "0.1.9" # used for a doc example
failure = "0.1.5" # used for a doc example
[dependencies]
cslice = "0.2"
semver = "0.9.0"
neon-runtime = { version = "=0.4.0", path = "crates/neon-runtime" }
smallvec = "1.4.2"
neon-runtime = { version = "=0.8.2", path = "crates/neon-runtime" }
neon-macros = { version = "=0.8.2", path = "crates/neon-macros", optional = true }
[features]
default = ["legacy-runtime"]
@ -41,23 +45,47 @@ default-panic-hook = []
# enabled by default.
legacy-runtime = ["neon-runtime/neon-sys", "neon-build/neon-sys"]
# Feature flag to enable the experimental N-API runtime. For now, this feature
# is disabled by default.
napi-runtime = ["neon-runtime/nodejs-sys"]
# Default N-API version. Prefer to select a minimum required version.
napi-runtime = ["napi-6"]
# Feature flag to disable external dependencies on docs build
# Select the N-API version
# Feature flags to enable the experimental N-API runtime. For now, this feature
# is disabled by default.
# The Node N-API documentation specifies N-API and Node version requirements
# https://nodejs.org/api/n-api.html
napi-1 = ["proc-macros", "neon-macros/napi", "neon-runtime/napi"]
napi-2 = ["napi-1", "neon-runtime/napi-2"]
napi-3 = ["napi-2", "neon-runtime/napi-3"]
napi-4 = ["napi-3", "neon-runtime/napi-4"]
napi-5 = ["napi-4", "neon-runtime/napi-5"]
napi-6 = ["napi-5", "neon-runtime/napi-6"]
napi-latest = ["napi-6"]
napi-experimental = ["napi-6", "neon-runtime/napi-experimental"]
# Feature flag to disable external dependencies on docs build
docs-only = ["neon-runtime/docs-only"]
# Feature flag to enable the try_catch API of RFC 29.
try-catch-api = []
# Feature flag to enable the `EventQueue` API of RFC 33.
# https://github.com/neon-bindings/rfcs/pull/32
event-queue-api = []
# Feature flag to include procedural macros
proc-macros = ["neon-macros"]
[package.metadata.docs.rs]
features = ["docs-only"]
features = ["docs-only", "event-handler-api", "proc-macros", "try-catch-api"]
[workspace]
members = [
"crates/neon-build",
"crates/neon-macros",
"crates/neon-runtime",
"crates/neon-sys",
"test/static",
"test/electron/native",
"test/electron",
"test/dynamic/native",
"test/napi/native"
"test/napi"
]

View File

@ -1,14 +1,320 @@
# [WIP] N-API Migration Guide
# N-API Migration Guide
## Context
## What is this about?
Since v10, Node.js supports an improved API for building native modules, known as [N-API](https://nodejs.org/api/n-api.html). N-API offers a clearer, more complete, and more stable API layer for writing Node.js plugins than previous Node versions did.
The Neon community has been [hard at work](https://github.com/neon-bindings/neon/issues/444) porting the library to a new backend based on N-API.
### Why N-API?
Some key benefits of the new backend include:
- Compiled Neon modules will work in all versions of Node _without needing to be recompiled_, guaranteed!
- You can precompile Neon-based libraries to be completely transparent to downstream consumers.
- The build process is streamlined, making Neon apps more reliable and easier to debug.
- The stability guarantees of N-API allow us to avoid risk of incompatible changes to future releases of Neon.
### What does this mean for me?
Porting Neon to N-API has been mostly transparent, but it has required a few backwards-incompatible changes. This guide provides instructions on how to migrate existing apps to the new N-API backend.
Fortunately, the guaranteed stability of N-API means that once Neon users do this migration, we have increased confidence in the stability of Neon. We expect this to be the **last major breaking change before reaching Neon 1.0.**
If you have any trouble porting, **please reach out to us** with a Neon issue or on the community Slack! We want to help everyone upgrade as smoothly and seamlessly as possible.
## Getting started
### Supported Node versions
The N-API backend of Neon requires a minimum Node version of 10.0.
### Enabling the N-API backend
To enable the N-API backend, you need to:
1. Remove `build.rs` from the project directory and `build = "build.rs"` from the `Cargo.toml`. The N-API backend does not require a Cargo build script.
2. Disable the default features (for now, the default features select the legacy backend) by setting `default-features = false`; and
3. Enable the appropriate feature flag in your `Cargo.toml` to select the N-API version you need support for (each N-API version N uses the feature flag `"napi-N"`, for example `"napi-4"` for N-API version 4).
As a rule, you should choose the **oldest version of N-API that has the APIs you need.** (We will be adding N-API version requirements to the Neon API docs to make this clearer in the future.) You can consult the [official N-API feature matrix](https://nodejs.org/api/n-api.html#n_api_node_api_version_matrix) to see which N-API versions come with various versions of Node.
```toml
[dependencies.neon]
version = "0.8.2"
default-features = false
features = ["napi-4"]
```
## Minor API changes
### Context
Many methods that previously did not require context (e.g., `JsString::size`) now require a context. In many cases, this means adding an additional argument or using a convenience method on the `Context` trait.
### Impacted methods
#### Affected methods
##### Handle
* `Handle`
- `is_a`
- `downcast`
`Handle::downcast` also requires a second type argument for the context type. This can usually be inferred, so you can typically use `_`.
**Before:**
```rust
value.downcast::<JsNumber>()
```
**After:**
```rust
value.downcast::<JsNumber, _>(&mut cx)
```
##### Primitive types
* `JsBoolean`
- `value`
* `JsNull`
- `new`
* `JsString`
- `size`
- `value`
* `JsNumber`
- `value`
* `JsUndefined`
- `new`
##### Object APIs
* `PropertyKey`
- `get_from`
- `set_from`
### Handle equality
Handles no longer implement `Eq` or `PartialEq`, which had underspecified behavior. Use `Value::strict_equals` instead to invoke the behavior of JavaScript's `===` operator.
## Major API changes
The N-API backend introduces two categories of significant change:
1. Embedding Rust data, which is no longer done through the awkward and complex `declare_types!` (i.e. classes) macro, but through a simpler primitive: the `JsBox` API.
2. Concurrency, which is offered through the Event Queue API instead of the Task API or Event Handlers, both of which are deprecated and removed in the N-API backend.
### Embedding Rust data
The `declare_types!` macro is deprecated and replaced by the `JsBox` type.
_Rationale:_ The `declare_types!` macro provides a syntax for defining classes, but requires substantial boilerplate and is unergonomic for simple cases and tends to interact poorly with IDEs. It's also not flexible enough to express the full range of JavaScript classes syntax and semantics. With the `JsBox` type, it's easy to embed Rust data in JavaScript objects, which can then be nested inside of more feature-rich classes defined in pure JavaScript (or TypeScript).
**Before:**
```rust
struct User {
first_name: String,
last_name: String,
}
impl User {
fn full_name(&self) -> String {
format!("{} {}", self.first_name, self.last_name)
}
}
declare_types! {
class JsUser for User {
init(mut cx) {
let first_name = cx.argument::<JsString>(0)?;
let last_name = cx.argument::<JsString>(1)?;
Ok(User { first_name, last_name })
}
method full_name(mut cx) {
let this = cx.this();
let guard = cx.lock();
let user = this.borrow(&guard);
let full_name = user.full_name();
Ok(cx.string(full_name).upcast())
}
}
}
```
**After:**
On the Rust side, the wrapped type must implement the `Finalize` trait, but this comes with a default implementation so it can be implemented with an empty `impl` block:
```rust
struct User {
first_name: String,
last_name: String,
}
impl Finalize for User { }
```
The type can then be exposed to JavaScript with simple functions that wrap `User` in a `JsBox`:
```rust
fn create_user(mut cx: FunctionContext) -> JsResult<JsBox<User>> {
let first_name = cx.argument::<JsString>(0)?.value(&mut cx);
let last_name = cx.argument::<JsString>(1)?.value(&mut cx);
Ok(cx.boxed(User { first_name, last_name }))
}
fn user_full_name(mut cx: FunctionContext) -> JsResult<JsString> {
let user = cx.argument::<JsBox<User>>(0)?;
let full_name = user.full_name();
Ok(cx.string(full_name))
}
```
Finally, you can provide an idiomatic JavaScript interface to the type by wrapping the boxed type in a class:
```js
class User {
constructor(firstName, lastName) {
this.boxed = addon.createUser(firstName, lastName);
}
fullName() {
return addon.userFullName(this.boxed);
}
}
```
### Concurrency
The supported mechanism for concurrency is the Event Queue API (`neon::event::EventQueue`). This feature has not yet stabilized, so to use this API, you'll also need to enable the `"event-queue-api"` feature flag as well:
```toml
[dependencies.neon]
version = "0.8.1"
default-features = false
features = ["napi-4", "event-queue-api"]
```
#### Deprecated: Task API
The Task API (`neon::task`) is deprecated, and should in most cases be translated to using the Event Queue API.
_Rationale:_ The Task API was built on top of the low-level libuv thread pool, which manages the concurrency of the Node.js system internals and should rarely be exposed to user-level programs. For most use cases, Neon users took advantage of this API as the only way to implement background, asynchronous computations. The Event Queue API is a more general-purpose, convenient, and safe way of achieving that purpose.
That said, **if you believe you need access to the libuv thread pool, please [file an issue in the Neon repository](https://github.com/neon-bindings/neon/issues) with a description of your use case to let us know about it.** We don't believe this is commonly needed, but we don't want to leave you stuck!
**Before:**
With the `Task` API it was possible to define background computations off the main JavaScript thread, but these could only be run within the libuv thread pool--which runs all the system logic for the internals of Node.js. This gave Neon programmers a real power but forced them to contend with Node.js system tasks.
```rust
impl Task for MyTask {
type Output = i32;
type Error = String;
type JsEvent = JsNumber;
fn perform(&self) -> Result<Self::Output, Self::Error> {
// compute the result...
}
fn complete(self, mut cx: TaskContext, result: Result<Self::Output, Self::Error>) -> JsResult<Self::JsEvent> {
match result {
Ok(n) => {
Ok(cx.number(n))
}
Err(s) => {
cx.throw_error(s)
}
}
}
}
pub fn start_task(mut cx: FunctionContext) -> JsResult<JsUndefined> {
let callback = cx.argument::<JsFunction>(0)?;
MyTask.schedule(callback);
Ok(cx.undefined())
}
```
**After:**
With the N-API backend, Neon programmers can use their own native threads and avoid competing with the Node.js system internals. This also brings some convenience since it doesn't require defining any custom trait implementations.
```rust
pub fn start_task(mut cx: FunctionContext) -> JsResult<JsUndefined> {
let callback = cx.argument::<JsFunction>(0)?.root(&mut cx);
let queue = cx.queue();
std::thread::spawn(move || {
let result = // compute the result...
queue.send(move |mut cx| {
let callback = callback.into_inner(&mut cx);
let this = cx.undefined();
let args = match result {
Ok(n) => vec![
cx.null().upcast::<JsValue>(),
cx.number(result).upcast()
],
Err(msg) => vec![
cx.error(msg).upcast()
]
};
callback.call(&mut cx, this, args)?;
Ok(())
});
});
Ok(cx.undefined())
}
```
#### Deprecated: Event Handler API
The Event Handler API (`neon::event::EventHandler`) is deprecated and should be replaced by the Event Queue API.
_Rationale_: The Event Handler API had multiple issues with safety, memory leaks, and ergonomics ([1](https://github.com/neon-bindings/neon/issues/551), [2](https://github.com/neon-bindings/rfcs/issues/31)).
**Before:**
```rust
pub fn start_task(mut cx: FunctionContext) -> JsResult<JsUndefined> {
let callback = cx.argument::<JsFunction>(0)?;
let handler = EventHandler::new(callback);
thread::spawn(move || {
let result = // compute the result...
handler.schedule(move |cx| {
vec![cx.number(result).upcast()]
});
});
Ok(cx.undefined())
}
```
**After:**
```rust
pub fn start_task(mut cx: FunctionContext) -> JsResult<JsUndefined> {
let callback = cx.argument::<JsFunction>(0)?.root(&mut cx);
let queue = cx.queue();
std::thread::spawn(move || {
let result = // compute the result...
queue.send(move |mut cx| {
let callback = callback.into_inner(&mut cx);
let this = cx.undefined();
let args = vec![
cx.null().upcast::<JsValue>(),
cx.number(result).upcast()
];
callback.call(&mut cx, this, args)?;
Ok(())
});
});
Ok(cx.undefined())
}
```

View File

@ -1,9 +1,10 @@
<img src="neon.png" alt="neon" width="100%" />
[![Travis Build Status](https://travis-ci.org/neon-bindings/neon.svg?branch=master)](https://travis-ci.org/neon-bindings/neon)
[![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/github/neon-bindings/neon?branch=master&svg=true)](https://ci.appveyor.com/project/dherman/neon/branch/master)
[![](http://meritbadge.herokuapp.com/neon)](https://crates.io/crates/neon)
[![Cargo](http://meritbadge.herokuapp.com/neon)](https://crates.io/crates/neon)
[![npm](https://img.shields.io/npm/v/neon-cli.svg)](https://www.npmjs.com/package/neon-cli)
[![Linux Build Status](https://github.com/neon-bindings/neon/workflows/Test%20on%20Linux/badge.svg)](https://github.com/neon-bindings/neon/actions?query=workflow%3A%22Test+on+Linux%22)
[![macOS Build Status](https://github.com/neon-bindings/neon/workflows/Test%20on%20MacOS/badge.svg)](https://github.com/neon-bindings/neon/actions?query=workflow%3A%22Test+on+MacOS%22)
[![Windows Build Status](https://github.com/neon-bindings/neon/workflows/Test%20on%20Windows/badge.svg)](https://github.com/neon-bindings/neon/actions?query=workflow%3A%22Test+on+Windows%22)
Rust bindings for writing safe and fast native Node.js modules.
@ -12,15 +13,22 @@ Rust bindings for writing safe and fast native Node.js modules.
Once you have the [platform dependencies](https://neon-bindings.com/docs/getting-started#install-node-build-tools/) installed, getting started is as simple as:
```
$ npm install -g neon-cli
$ neon new my-project
$ npm init neon my-project
```
Then see the [Hello World guide](https://neon-bindings.com/docs/hello-world/) for writing your first Hello World in Neon!
_**Note:** This will create a new project with the `napi-backend` and some documentation may not be up to date._
# Docs
See our [Neon fundamentals docs](https://neon-bindings.com/docs/primitives) and our [API docs](https://neon-bindings.com/api/neon/).
See our [Neon fundamentals docs](https://neon-bindings.com/docs/intro) and our [API docs](https://docs.rs/neon/latest/neon).
# N-API Migration Guide
We've ported Neon to a new backend based on [N-API](https://nodejs.org/api/n-api.html), which will be the basis for Neon 1.0.
**Read the new [migration guide](https://github.com/neon-bindings/neon/blob/main/MIGRATION_GUIDE.md)** to learn how to port your Neon projects to N-API!
# Platform Support
@ -32,11 +40,11 @@ See our [Neon fundamentals docs](https://neon-bindings.com/docs/primitives) and
### Node.js
| Node 8 | Node 10 | Node 12 |
| ------ | ------- | ------- |
| ✓ | ✓ | ✓ |
| Node 12 | Node 14 | Node 16 |
| ------- | ------- | ------- |
| ✓ | ✓ | ✓ |
Support for [LTS versions of Node](https://github.com/nodejs/LTS#lts-schedule) and current are expected. If you're using a different version of Node and believe it should be supported, let us know.
Support for [LTS versions of Node](https://github.com/nodejs/LTS#release-schedule) and current are expected. If you're using a different version of Node and believe it should be supported, let us know.
### Rust

View File

@ -1,8 +1,165 @@
# Version 0.8.2
* More docs improvements
* Added a deprecation warning to `neon new` (https://github.com/neon-bindings/neon/pull/722)
# Version 0.8.1
* Fix `legacy-backend` for Node 16 (https://github.com/neon-bindings/neon/pull/715)
* Various docs improvements
# Version 0.8.0
## Fixes
* `as_slice` and `as_mut_slice` properly handle a `null` pointer from an empty buffer (https://github.com/neon-bindings/neon/pull/681)
* Global drop queue added to avoid panics on N-API 6+ when dropping a `Root` (https://github.com/neon-bindings/neon/pull/700)
## Features
* Added `neon::reflect::eval` (https://github.com/neon-bindings/neon/pull/692)
* Added `create-neon` for creating an N-API project (https://github.com/neon-bindings/neon/pull/690)
* Added details to the `README.md` generated by `create-neon` (https://github.com/neon-bindings/neon/pull/697)
## Improvements
* Switched N-API tests to `cargo-cp-artifact` (https://github.com/neon-bindings/neon/pull/687)
* Added `impl<T: Finalize> Finalize for Option<T>` (https://github.com/neon-bindings/neon/pull/680)
* Added a N-API migration guide (https://github.com/neon-bindings/neon/pull/685)
## Housekeeping
* Lint fixes (https://github.com/neon-bindings/neon/pull/609)
* Lint CI enforcement and `cargo fmt` (https://github.com/neon-bindings/neon/pull/698)
# Version 0.7.1
### Features
* Added `JsDate` to N-API backend (https://github.com/neon-bindings/neon/pull/639)
* Implement `JsBuffer::unitialized` for N-API backend (https://github.com/neon-bindings/neon/pull/664)
### Fixes
* Do not panic if a `Root` is leaked after the event loop has stopped (https://github.com/neon-bindings/neon/pull/677)
* Stubs for features that will not be implemented in the N-API backend are removed (https://github.com/neon-bindings/neon/pull/663)
* Fix doc URL link (https://github.com/neon-bindings/neon/pull/663)
# Version 0.7.0
## N-API
### Version Selection
Neon supports a large number of different Node versions which may have different N-API requirements. Neon now supports selecting the minimum required N-API version required by a module. For example, for N-API Version 4:
```toml
neon = { version = "0.7", default-features = false, features = ["napi-4"] }
```
If the Neon module is loaded in an older version of Node that does not support that N-API version, a `panic` message will inform the user.
### Threadsafe Functions
A prerelease version of `EventQueue` for calling into the main JavaScript thread from Rust threads can be enabled with the `event-queue-api` feature flag. The API is considered unstable and may change in the future until the [RFC](https://github.com/neon-bindings/rfcs/pull/32) is merged.
# Version 0.6.0
The `cx.try_catch(..)` API has been updated to return `T: Sized` instead of `T: Value` (https://github.com/neon-bindings/neon/pull/631). This API is strictly more powerful and allows users to return both JavaScript and Rust values from `try_catch` closures.
## N-API
* N-API symbols are now loaded dynamically (https://github.com/neon-bindings/neon/pull/646)
* Build process for N-API is greatly simplified by leveraging dynamic loading (https://github.com/neon-bindings/neon/pull/647)
# Version 0.5.3
## Bug Fixes
Upgrade `node-gyp` (https://github.com/neon-bindings/neon/pull/623)
* Fix Windows Node 15
* Fix Apple M1
## Features
Added `neon::main` macro as a replacement for `register_module!` (https://github.com/neon-bindings/neon/pull/636)
## Known Issues
Builds occassionally fail with Windows, Node 15 and npm 7 (https://github.com/neon-bindings/neon/issues/642)
# Version 0.5.2
## CLI
Added support for [additional arguments](https://github.com/neon-bindings/neon/pull/633) passed to `cargo build`. Resolves https://github.com/neon-bindings/neon/issues/471.
```sh
neon build --release -- --features awesome
```
## N-API
* Improved [arguments performance](https://github.com/neon-bindings/neon/pull/610)
* Add [redirect and `NPM_CONFIG_DISTURL`](https://github.com/neon-bindings/neon/pull/620) support
# Version 0.5.1
## Performance
* `smallvec` is used for collecting arguments and yields a small performance gain when calling `JsFunction`
## Broader Support
Thanks to @staltz, neon now builds for both iOS and Android with [nodejs-mobile](https://github.com/JaneaSystems/nodejs-mobile).
# Version 0.5.0
_Re-publish_
Versions `0.4.1` and `0.4.2` included a breaking change in `neon-runtime`. At the time, this was considered acceptable because `neon-runtime` is considered an internal crate and not part of the public API. However, it was discovered, after publishing, that `neon-serde`, a commonly used crate in the `neon` ecosystem, contained a direct dependency on `neon-runtime`. In order to best support users, versions `0.4.1` and `0.4.2` were "yanked" and re-published as `0.5.0`.
Additionally, the team is working with the authors of `neon-serde` to remove the dependency on `neon-runtime` to prevent future issues.
## Bug Fixes
* Fix stack overflow in `DowncastError` `Display` impl (https://github.com/neon-bindings/neon/pull/606)
# Version 0.4.2
_Unpublished / Yanked_
## Bug Fixes
* Fix memory leak and race condition in `EventHandler`
# Version 0.4.1
_Unpublished / Yanked_
## Features
### Try Catch
Added the `cx.try_catch` API of [RFC 29](https://github.com/neon-bindings/rfcs/pull/29). This feature is behind the `try-catch-api` feature flag.
## Bug Fixes
* Pass `async_context` to `node::MakeCallback` (https://github.com/neon-bindings/neon/pull/498)
* Cache bust neon if node version changes (https://github.com/neon-bindings/neon/pull/388)
* Fix debug builds in windows (https://github.com/neon-bindings/neon/pull/400)
* Fix cross compiling architectures (https://github.com/neon-bindings/neon/pull/491)
* Fix neon new hanging on Windows (https://github.com/neon-bindings/neon/pull/537)
## CI Improvements
The Neon Project now uses Github Actions thanks to @lhr0909! As part of this change, CI now runs on all of our supported platforms (macOS, Windows, linux) and Node versions.
# Version ✨0.4✨ 🎉
## `EventHandler` API
The [`EventHandler` API](https://github.com/neon-bindings/rfcs/blob/master/text/0025-event-handler.md) is a new feature for scheduling work on the javascript main thread from other threads. Big thanks to @geovie for the RFC and implementation.
The [`EventHandler` API](https://github.com/neon-bindings/rfcs/blob/main/text/0025-event-handler.md) is a new feature for scheduling work on the javascript main thread from other threads. Big thanks to @geovie for the RFC and implementation.
This feature is currently _unstable_ and gated by a `event-handler-api` feature flag.
@ -47,7 +204,7 @@ Since `neon-build` has been included in the project template since `0.1` this ch
## N-API
Neon 0.3.2 lays the groundwork for the next major revision. Development of Neon against an ABI stable Node API (N-API) will occur on master.
Neon 0.3.2 lays the groundwork for the next major revision. Development of Neon against an ABI stable Node API (N-API) will occur on main.
* Added `legacy-runtime` and `n-api` feature flags for toggling neon runtime
* Moved the legacy runtime to `nodejs-sys` crate
@ -81,16 +238,16 @@ Neon 0.3.2 lays the groundwork for the next major revision. Development of Neon
See the [Neon 0.2 Migration Guide](https://github.com/neon-bindings/neon/wiki/Neon-0.2-Migration-Guide) for documentation on migrating your projects from the Neon 0.1.x series to Neon 0.2, and please [let us know](https://github.com/neon-bindings/neon#get-involved) if you need help!
* Release automation (#318)
* New `ArrayBuffer` views API -- see [RFC 5](https://github.com/neon-bindings/rfcs/blob/master/text/0005-array-buffer-views.md) (#306)
* VM 2.0 -- see [RFC 14](https://github.com/neon-bindings/rfcs/blob/master/text/0014-vm-2.0.md) (#306)
* New `JsString` constructor -- see [RFC 21](https://github.com/neon-bindings/rfcs/blob/master/text/0021-string-constructor.md) (#322)
* Eliminated `JsInteger`, `JsVariant`, `callee()` -- see [RFC 22](https://github.com/neon-bindings/rfcs/blob/master/text/0022-zero-dot-two.md) (#323)
* Renamed `Key` to `PropertyKey` and its method names -- see [RFC 22](https://github.com/neon-bindings/rfcs/blob/master/text/0022-zero-dot-two.md) (#323)
* Module reorganization -- see [RFC 20](https://github.com/neon-bindings/rfcs/blob/master/text/0020-module-reorg.md) (#324)
* New `JsError` API -- see [RFC 23](https://github.com/neon-bindings/rfcs/blob/master/text/0023-error-subtyping.md) (#325)
* Eliminated `ToJsString` API -- see [RFC 22](https://github.com/neon-bindings/rfcs/blob/master/text/0022-zero-dot-two.md) (#326)
* Eliminated `NEON_NODE_ABI` env var -- see [RFC 22](https://github.com/neon-bindings/rfcs/blob/master/text/0022-zero-dot-two.md) (#327)
* Default to release builds -- see [RFC 22](https://github.com/neon-bindings/rfcs/blob/master/text/0022-zero-dot-two.md) (#328)
* New `ArrayBuffer` views API -- see [RFC 5](https://github.com/neon-bindings/rfcs/blob/main/text/0005-array-buffer-views.md) (#306)
* VM 2.0 -- see [RFC 14](https://github.com/neon-bindings/rfcs/blob/main/text/0014-vm-2.0.md) (#306)
* New `JsString` constructor -- see [RFC 21](https://github.com/neon-bindings/rfcs/blob/main/text/0021-string-constructor.md) (#322)
* Eliminated `JsInteger`, `JsVariant`, `callee()` -- see [RFC 22](https://github.com/neon-bindings/rfcs/blob/main/text/0022-zero-dot-two.md) (#323)
* Renamed `Key` to `PropertyKey` and its method names -- see [RFC 22](https://github.com/neon-bindings/rfcs/blob/main/text/0022-zero-dot-two.md) (#323)
* Module reorganization -- see [RFC 20](https://github.com/neon-bindings/rfcs/blob/main/text/0020-module-reorg.md) (#324)
* New `JsError` API -- see [RFC 23](https://github.com/neon-bindings/rfcs/blob/main/text/0023-error-subtyping.md) (#325)
* Eliminated `ToJsString` API -- see [RFC 22](https://github.com/neon-bindings/rfcs/blob/main/text/0022-zero-dot-two.md) (#326)
* Eliminated `NEON_NODE_ABI` env var -- see [RFC 22](https://github.com/neon-bindings/rfcs/blob/main/text/0022-zero-dot-two.md) (#327)
* Default to release builds -- see [RFC 22](https://github.com/neon-bindings/rfcs/blob/main/text/0022-zero-dot-two.md) (#328)
* Made `Buffer` construction safe by default (#329, #331)
* Made `Throw` not implement `std::error::Error` to avoid accidental suppression, thanks to [@kjvalencik](https://github.com/kjvalencik) (#334)
* Fixed a bug causing unnecessary rebuilds, thanks to [@kjvalencik](https://github.com/kjvalencik) (#343)

View File

@ -1,49 +0,0 @@
os: unstable
image: Visual Studio 2015
environment:
RUST_BACKTRACE: 1
matrix:
- PLATFORM: x64
NODEJS_VERSION: "8"
RUST_TOOLCHAIN: stable-x86_64-pc-windows-msvc
- PLATFORM: x64
NODEJS_VERSION: "10"
RUST_TOOLCHAIN: stable-x86_64-pc-windows-msvc
- PLATFORM: x64
NODEJS_VERSION: "10"
RUST_TOOLCHAIN: beta-x86_64-pc-windows-msvc
- PLATFORM: x64
NODEJS_VERSION: "10"
RUST_TOOLCHAIN: nightly-x86_64-pc-windows-msvc
- PLATFORM: x64
NODEJS_VERSION: "12"
RUST_TOOLCHAIN: stable-x86_64-pc-windows-msvc
- PLATFORM: x64
NODEJS_VERSION: "12"
RUST_TOOLCHAIN: beta-x86_64-pc-windows-msvc
- PLATFORM: x64
NODEJS_VERSION: "12"
RUST_TOOLCHAIN: nightly-x86_64-pc-windows-msvc
install:
- ps: Install-Product node $env:NODEJS_VERSION $env:PLATFORM
# Workaround until https://github.com/nodejs/node-gyp/issues/1933 is fixed.
- npm install -g npm@6.11.3
- npm config set msvs_version 2015
- node -e "console.log(process.argv[0], process.arch, process.versions)"
- curl -sSf -o rustup-init.exe https://win.rustup.rs
- rustup-init.exe -y --default-toolchain %RUST_TOOLCHAIN%
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
- rustup show
- rustc -V
- cargo -V
build: false
test_script:
- cargo test --release
cache:
- target
- C:\Users\appveyor\.cargo\registry

View File

@ -1,5 +1,6 @@
#!/usr/bin/env node
require('make-promises-safe');
var CLI = require('../lib/cli.js').default;
var cli = new CLI(process.argv, process.cwd());
cli.exec()

2090
cli/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "neon-cli",
"version": "0.4.0",
"version": "0.8.2",
"description": "Build and load native Rust/Neon modules.",
"author": "Dave Herman <david.herman@gmail.com>",
"repository": {
@ -10,48 +10,34 @@
"main": "lib/index.js",
"types": "lib/index.d.ts",
"bin": {
"neon": "./bin/cli.js"
"neon": "bin/cli.js"
},
"license": "SEE LICENSE IN LICENSE-*",
"dependencies": {
"chalk": "~2.1.0",
"command-line-args": "^4.0.2",
"command-line-commands": "^2.0.0",
"command-line-usage": "^4.0.0",
"chalk": "^4.1.0",
"command-line-args": "^5.1.1",
"command-line-commands": "^3.0.1",
"command-line-usage": "^6.1.0",
"git-config": "0.0.7",
"handlebars": "^4.1.0",
"inquirer": "^3.0.6",
"mkdirp": "^0.5.1",
"quickly-copy-file": "^1.0.0",
"rimraf": "^2.6.1",
"rsvp": "^4.6.1",
"semver": "^5.1.0",
"toml": "^2.3.0",
"ts-typed-json": "^0.2.2",
"validate-npm-package-license": "^3.0.1",
"handlebars": "^4.7.6",
"inquirer": "^7.3.3",
"make-promises-safe": "^5.1.0",
"rimraf": "^3.0.2",
"semver": "^7.3.2",
"toml": "^3.0.0",
"ts-typed-json": "^0.3.2",
"validate-npm-package-license": "^3.0.4",
"validate-npm-package-name": "^3.0.0"
},
"devDependencies": {
"@types/chai": "^4.1.3",
"@types/chalk": "^0.4.31",
"@types/es6-promise": "0.0.33",
"@types/inquirer": "0.0.35",
"@types/mkdirp": "^0.5.1",
"@types/mocha": "^5.2.0",
"@types/nexpect": "^0.4.29",
"@types/node": "^8.10.39",
"@types/rimraf": "^2.0.2",
"@types/rsvp": "^3.3.1",
"@types/semver": "^5.3.31",
"@types/tmp": "0.0.33",
"chai": "^4.1.2",
"mocha": "^5.2.0",
"nexpect": "^0.5.0",
"tmp": "0.0.33",
"ts-dict": "^0.1.1",
"ts-node": "^3.0.2",
"ts-unknown": "^0.2.0",
"typescript": "^2.2.2"
"@types/chalk": "^2.2.0",
"@types/inquirer": "^7.3.0",
"@types/mocha": "^8.0.1",
"@types/node": "10.17.26",
"@types/rimraf": "^3.0.0",
"@types/semver": "^7.3.1",
"mocha": "^8.1.0",
"typescript": "^3.9.7"
},
"scripts": {
"transpile": "tsc",

View File

@ -1,6 +1,5 @@
import BuildSettings from './build-settings';
import { writeFileSync } from 'fs';
import Dict from 'ts-dict';
import * as JSON from 'ts-typed-json';
/**
@ -16,10 +15,10 @@ export default class Artifacts {
/**
* A table tracking the state of any build artifacts in the `target`
* directory.
*
*
* On Windows, this table has the type:
*
* ```
*
* ```json
* {
* "i686-pc-windows-msvc\\debug"?: BuildSettings,
* "i686-pc-windows-msvc\\release"?: BuildSettings,
@ -27,20 +26,20 @@ export default class Artifacts {
* "x86_64-pc-windows-msvc\\release"?: BuildSettings
* }
* ```
*
*
* On Linux and macOS, this table has the type:
*
* ```
*
* ```json
* {
* "debug"?: BuildSettings,
* "release"?: BuildSettings
* }
* ```
*/
private targets: Dict<BuildSettings>;
private targets: Record<string, BuildSettings>;
constructor(active: string | null = null,
targets: Dict<BuildSettings> = {})
targets: Record<string, BuildSettings> = {})
{
this.active = active;
this.targets = targets;
@ -55,18 +54,13 @@ export default class Artifacts {
}
static fromJSON(json: JSON.Value): Artifacts {
if (!JSON.isObject(json)) {
throw new TypeError("expected object, found " + (json === null ? "null" : typeof json));
}
let active = json.active;
json = JSON.asObject(json, "json");
const active = json.active;
if (typeof active !== 'string' && active !== null) {
throw new TypeError("json.active is not a string or null");
}
let jsonTargets = json.targets;
if (!JSON.isObject(jsonTargets)) {
throw new TypeError("json.targets is not an object");
}
let targets: Dict<BuildSettings> = {};
const jsonTargets = JSON.asObject(json.targets, "json.targets");
let targets: Record<string, BuildSettings> = {};
for (let key of Object.keys(jsonTargets)) {
targets[key] = BuildSettings.fromJSON(jsonTargets[key]);
}
@ -74,7 +68,7 @@ export default class Artifacts {
}
toJSON(): JSON.Object {
let targets: JSON.Object = {};
let targets = {};
for (let target of Object.keys(this.targets)) {
targets[target] = this.targets[target].toJSON();
}

View File

@ -1,9 +1,9 @@
import { promisify } from 'util';
import * as child from 'child_process';
import child from 'child_process';
export function spawn(command: string, args?: string[], options?: child.SpawnOptions): Promise<number> {
return new Promise((resolve, reject) => {
let ps = child.spawn(command, args || [], options);
let ps = child.spawn(command, args || [], options!);
ps.on('error', reject);
ps.on('close', resolve);
});

View File

@ -1,34 +0,0 @@
import * as fs from 'fs';
import quicklyCopyFile = require('quickly-copy-file');
import RSVP = require('rsvp');
import rimraf = require('rimraf');
import mkdirp = require('mkdirp');
export let stat: (path: string) => Promise<fs.Stats>
= RSVP.denodeify(fs.stat, false);
let rf: (path: string, options?: { encoding: string; flag?: string; }) => Promise<string | Buffer>
= RSVP.denodeify(fs.readFile, false);
export function readFile(path: string, options: { encoding: string; flag?: string; }): Promise<string>;
export function readFile(path: string): Promise<Buffer>;
export function readFile(path: string, options?: { encoding: string; flag?: string; }): Promise<string | Buffer> {
return rf(path, options);
}
export type WriteOptions = {
encoding?: string,
mode?: number,
flag?: string
};
export let writeFile: (path: string, contents: string, options: WriteOptions) => Promise<void>
= RSVP.denodeify(fs.writeFile, false);
export let copy = quicklyCopyFile;
export let remove: (path: string) => Promise<void>
= RSVP.denodeify(rimraf, false);
export let mkdirs: (path: string) => Promise<void>
= RSVP.denodeify(mkdirp, false);

View File

@ -1,7 +0,0 @@
import RSVP = require('rsvp');
import gitconfig = require('git-config');
let gc: () => Promise<gitconfig.Dict>
= RSVP.denodeify(gitconfig, false);
export default gc;

4
cli/src/async/rimraf.ts Normal file
View File

@ -0,0 +1,4 @@
import _rimraf from 'rimraf';
import { promisify } from 'util';
export const rimraf = promisify(_rimraf);

View File

@ -1,8 +1,7 @@
import * as rust from './rust';
import Dict from 'ts-dict';
import * as JSON from 'ts-typed-json';
function isStringDict(x: JSON.Object): x is Dict<string | null> {
function isStringDict(x: JSON.Object): x is Record<string, string | null> {
for (let key of Object.keys(x)) {
if (x[key] !== null && typeof x[key] !== 'string') {
return false;
@ -14,9 +13,9 @@ function isStringDict(x: JSON.Object): x is Dict<string | null> {
export default class BuildSettings {
private rustc: string;
private nodeVersion: string | null;
private env: Dict<string | null>;
private env: Record<string, string | null>;
constructor(rustc: string, nodeVersion: string | null, env: Dict<string | null>) {
constructor(rustc: string, nodeVersion: string | null, env: Record<string, string | null>) {
this.rustc = rustc;
this.nodeVersion = nodeVersion;
this.env = env;
@ -58,14 +57,16 @@ export default class BuildSettings {
npm_config_disturl: process.env.npm_config_disturl || null,
npm_config_runtime: process.env.npm_config_runtime || null,
npm_config_build_from_source: process.env.npm_config_build_from_source || null,
npm_config_devdir: process.env.npm_config_devdir || null
npm_config_devdir: process.env.npm_config_devdir || null,
npm_config_node_engine: process.env.npm_config_node_engine || null,
npm_config_nodedir: process.env.npm_config_nodedir || null,
npm_config_node_gyp: process.env.npm_config_node_gyp || null,
npm_config_platform: process.env.npm_config_platform || null
});
}
static fromJSON(value: JSON.Value): BuildSettings {
if (!JSON.isObject(value)) {
throw new TypeError("value must be an object");
}
value = JSON.asObject(value, "value")
let { rustc, env, nodeVersion } = value;
if (typeof rustc !== 'string') {
throw new TypeError("value.rustc must be a string");

View File

@ -1,4 +1,4 @@
import * as path from 'path';
import path from 'path';
import neon_new from './ops/neon_new';
import neon_build from './ops/neon_build';
import neon_clean from './ops/neon_clean';
@ -8,9 +8,7 @@ import cliArgs = require('command-line-args');
import cliUsage = require('command-line-usage');
import log from './log';
import { setup as setupLogging } from './log';
import Dict from 'ts-dict';
import * as JSON from 'ts-typed-json';
import unknown from 'ts-unknown';
import { Toolchain } from './rust';
let metadata = JSON.loadSync(path.resolve(__dirname, '..', 'package.json'));
@ -31,6 +29,23 @@ function logIf(multiple: boolean, action: string, cwd: string, module: string) {
}
}
function parseArgv(argv: string[]): { cli: string[], extra: string[] } {
let splitAt = argv.indexOf('--');
// No additional arguments provided
if (splitAt < 0) {
return {
cli: argv,
extra: [],
};
}
return {
cli: argv.slice(0, splitAt),
extra: argv.slice(splitAt + 1)
};
}
function parseModules(cwd: string, names: string[], paths: boolean) {
let modules = names.length
? names.map(m => paths ? path.resolve(cwd, m)
@ -43,7 +58,7 @@ function parseModules(cwd: string, names: string[], paths: boolean) {
};
}
type Action = (this: CLI, options: Dict<unknown>, usage: string) => void;
type Action = (this: CLI, options: Record<string, unknown>, usage: string) => void;
type Command = {
args: cliArgs.OptionDefinition[],
@ -51,7 +66,7 @@ type Command = {
action: Action
};
type Spec = Dict<Command>;
type Spec = Record<string, Command>;
const spec: Spec = {
@ -63,7 +78,7 @@ const spec: Spec = {
content: "Neon is a tool for building native Node.js modules with Rust."
}, {
header: "Synopsis",
content: "$ neon [options] <command>"
content: "$ neon [options] <command> -- [cargo options]"
}, {
header: "Command List",
content: [{ name: "new", summary: "Create a new Neon project." },
@ -161,7 +176,7 @@ const spec: Spec = {
}, {
header: "Synopsis",
content: ["$ neon build [options]",
"$ neon build [options] [underline]{module} ..."]
"$ neon build [options] {underline module} ..."]
}, {
header: "Options",
optionList: [{
@ -182,6 +197,7 @@ const spec: Spec = {
return;
}
let extra = options.extra as string[];
let { modules, multiple } = parseModules(this.cwd,
(options.modules || []) as string[],
!!options.path);
@ -189,7 +205,7 @@ const spec: Spec = {
for (let module of modules) {
logIf(multiple, "building", this.cwd, module);
await neon_build(module, this.toolchain, !!options.release);
await neon_build(module, this.toolchain, !!options.release, extra);
}
}
},
@ -204,7 +220,7 @@ const spec: Spec = {
}, {
header: "Synopsis",
content: ["$ neon clean [options]",
"$ neon clean [options] [underline]{module} ..."]
"$ neon clean [options] {underline module} ..."]
}, {
header: "Options",
optionList: [{
@ -247,7 +263,7 @@ const spec: Spec = {
return;
}
console.log(JSON.asObject(metadata).version);
console.log((JSON.asObject(metadata)).version);
}
}
@ -291,13 +307,14 @@ export default class CLI {
}
process.exit(1);
return;
}
try {
let { command, argv } = parsed;
let { cli, extra } = parseArgv(argv);
let options = { extra, ...cliArgs(spec[command].args, { argv: cli }) };
await spec[command].action.call(this,
cliArgs(spec[command].args, { argv }),
options,
cliUsage(spec[command].usage));
} catch (e) {
console.error(style.error(e.message));

View File

@ -1,9 +1,9 @@
import * as TOML from 'toml';
import * as path from 'path';
import { readFileSync } from 'fs';
import { remove, copy } from './async/fs';
import TOML from 'toml';
import path from 'path';
import { readFileSync, promises as fs } from 'fs';
import Artifacts from './artifacts';
import Project from './project';
import { rimraf } from './async/rimraf';
export type CrateOptions = {
subdirectory?: string,
@ -14,7 +14,7 @@ export type CrateOptions = {
export default class Crate {
/** The Neon project containing this crate. */
readonly project: Project;
/** The subpath of this crate relative to the Neon project root. */
/** The subpath of this crate relative to the Neon project root. */
readonly subdirectory: string;
/** The subpath of the `.node` addon relative to this crate root. */
readonly nodefile: string;
@ -43,12 +43,12 @@ export default class Crate {
}
async finish(dylib: string) {
await remove(this.addon);
await copy(dylib, this.addon);
await rimraf(this.addon);
await fs.copyFile(dylib, this.addon);
}
async removeAddon() {
await remove(this.addon);
await rimraf(this.addon);
}
resetArtifacts() {
@ -61,10 +61,17 @@ export default class Crate {
}
function loadLibName(file: string): string {
let metadata = TOML.parse(readFileSync(file, 'utf8'));
type Metadata = {
lib?: {
name?: string
}
}
if (!metadata || typeof metadata !== 'object' || !metadata.lib.name) {
function loadLibName(file: string): string {
let metadata = TOML.parse<Metadata>(readFileSync(file, 'utf8'));
if (!metadata) throw new Error(`Failed to parse TOML file "${file}"`)
if (!metadata || typeof metadata !== 'object' || !metadata?.lib?.name) {
throw new Error("Cargo.toml does not contain a [lib] section with a 'name' field");
}

View File

@ -1,5 +1,4 @@
declare module 'command-line-usage' {
import Dict from 'ts-dict';
namespace internal {
export type Sections = Section | Section[];
@ -8,7 +7,7 @@ declare module 'command-line-usage' {
export type ContentSection = {
header: string,
content: string | string[] | Dict<any>[],
content: string | string[] | Record<string, any>[],
raw?: boolean
};
@ -43,8 +42,6 @@ declare module 'command-line-commands' {
}
declare module 'command-line-args' {
import Dict from 'ts-dict';
import unknown from 'ts-unknown';
namespace internal {
export type CommandLineArgsOptions = {
@ -67,7 +64,7 @@ declare module 'command-line-args' {
function internal(optionDefinitions: internal.OptionDefinition[],
options?: internal.CommandLineArgsOptions)
: Dict<unknown>;
: Record<string, unknown>;
export = internal;
}

View File

@ -1,10 +1,12 @@
declare module 'git-config' {
function internal(callback: internal.GitConfigCallback): void;
namespace internal {
export type Dict = { [key: string]: any };
export type MaybeError = Error | null;
export type GitConfigCallback = (err: MaybeError, config?: Dict) => void;
export type Config = {
user: {
name?: string,
email?: string
},
github: {
user?: string
}
export = internal;
}
export function sync(gitFile?: string): Config;
}

View File

@ -1,4 +0,0 @@
declare module 'quickly-copy-file' {
function internal(from: string, to: string): Promise<void>;
export = internal;
}

View File

@ -1,3 +1,3 @@
declare module 'toml' {
export function parse(source: string): any;
}
export function parse<T extends object>(source: string): Partial<T> | undefined | null;
}

View File

@ -3,7 +3,8 @@ import * as rust from '../rust';
export default async function neon_build(root: string,
toolchain: rust.Toolchain = 'default',
release: boolean) {
release: boolean,
args: string[]) {
let project = await Project.create(root);
await project.build(toolchain, release);
await project.build(toolchain, release, args);
}

View File

@ -1,13 +1,15 @@
import { readFile, writeFile, mkdirs, stat } from '../async/fs';
import { mkdirSync, writeFileSync, promises as fsPromises } from 'fs';
import { prompt } from 'inquirer';
import gitconfig from '../async/git-config';
import * as path from 'path';
import * as handlebars from 'handlebars';
import * as semver from 'semver';
import path from 'path';
import handlebars from 'handlebars';
import semver from 'semver';
import * as style from '../style';
import validateLicense = require('validate-npm-package-license');
import validateName = require('validate-npm-package-name');
import * as JSON from 'ts-typed-json';
import gitconfig from 'git-config';
const { readFile, stat } = fsPromises;
const ROOT_DIR = path.resolve(__dirname, '..', '..');
const TEMPLATES_DIR = path.resolve(ROOT_DIR, 'templates');
@ -30,13 +32,18 @@ const LIBRS_TEMPLATE = compile('lib.rs.hbs');
const README_TEMPLATE = compile('README.md.hbs');
const BUILDRS_TEMPLATE = compile('build.rs.hbs');
type Author = {
name?: string,
email?: string
};
async function guessAuthor() {
let author = {
let author: Author = {
name: process.env.USER || process.env.USERNAME,
email: undefined
};
try {
let config = await gitconfig();
let config = gitconfig.sync();
if (config.user.name) {
author.name = config.user.name;
}
@ -73,7 +80,30 @@ async function parseNeonVersion(flag: string | null) : Promise<NeonVersion> {
return { type: path.isAbsolute(flag) ? "absolute" : "relative", value: flag };
}
interface Answers {
name: {
npm: {
full: string;
scope: string | null;
local: string;
};
cargo: {
external: string;
internal: string;
};
};
description: string;
git: string;
author: string;
node: string;
}
export default async function wizard(pwd: string, name: string, neon: string | null, features: string | null, noDefaultFeatures: boolean) {
let warning = "WARN: `neon new` is deprecated. To create a new project use `npm init neon my-project`.";
let banner = "".padStart(warning.length + 4, "#");
console.warn(`${banner}\n# ${warning} #\n${banner}\n`);
let its = validateName(name);
if (!its.validForNewPackages) {
let errors = (its.errors || []).concat(its.warnings || []);
@ -92,7 +122,7 @@ export default async function wizard(pwd: string, name: string, neon: string | n
let root = path.resolve(pwd, local);
let guess = await guessAuthor();
let answers = await prompt([
let answers: Answers = await prompt([
{
type: 'input',
name: 'version',
@ -193,16 +223,16 @@ export default async function wizard(pwd: string, name: string, neon: string | n
let native_ = path.resolve(root, 'native');
let src = path.resolve(native_, 'src');
await mkdirs(lib);
await mkdirs(src);
mkdirSync(lib, { recursive: true });
mkdirSync(src, { recursive: true });
await writeFile(path.resolve(root, '.gitignore'), (await GITIGNORE_TEMPLATE)(ctx), { flag: 'wx' });
await writeFile(path.resolve(root, 'package.json'), (await NPM_TEMPLATE)(ctx), { flag: 'wx' });
await writeFile(path.resolve(native_, 'Cargo.toml'), (await CARGO_TEMPLATE)(ctx), { flag: 'wx' });
await writeFile(path.resolve(root, 'README.md'), (await README_TEMPLATE)(ctx), { flag: 'wx' });
await writeFile(path.resolve(root, answers.node), (await INDEXJS_TEMPLATE)(ctx), { flag: 'wx' });
await writeFile(path.resolve(src, 'lib.rs'), (await LIBRS_TEMPLATE)(ctx), { flag: 'wx' });
await writeFile(path.resolve(native_, 'build.rs'), (await BUILDRS_TEMPLATE)(ctx), { flag: 'wx' });
writeFileSync(path.resolve(root, '.gitignore'), (await GITIGNORE_TEMPLATE)(ctx), { flag: 'wx' });
writeFileSync(path.resolve(root, 'package.json'), (await NPM_TEMPLATE)(ctx), { flag: 'wx' });
writeFileSync(path.resolve(native_, 'Cargo.toml'), (await CARGO_TEMPLATE)(ctx), { flag: 'wx' });
writeFileSync(path.resolve(root, 'README.md'), (await README_TEMPLATE)(ctx), { flag: 'wx' });
writeFileSync(path.resolve(root, answers.node), (await INDEXJS_TEMPLATE)(ctx), { flag: 'wx' });
writeFileSync(path.resolve(src, 'lib.rs'), (await LIBRS_TEMPLATE)(ctx), { flag: 'wx' });
writeFileSync(path.resolve(native_, 'build.rs'), (await BUILDRS_TEMPLATE)(ctx), { flag: 'wx' });
let relativeRoot = path.relative(pwd, root);
let relativeNode = path.relative(pwd, path.resolve(root, answers.node));

View File

@ -1,4 +1,4 @@
import * as path from 'path';
import path from 'path';
import Crate from './crate';
import Target from './target';
import BuildSettings from './build-settings';
@ -38,7 +38,7 @@ export default class Project {
});
}
async build(toolchain: rust.Toolchain, release: boolean) {
async build(toolchain: rust.Toolchain, release: boolean, args: string[]) {
let target = new Target(this.crate, { release: release });
let settings = BuildSettings.current(toolchain);
@ -50,7 +50,7 @@ export default class Project {
// 2. Build the dylib.
log("running cargo");
await target.build(toolchain, settings);
await target.build(toolchain, settings, args);
// 3. Copy the dylib as the main addon file.
log("generating " + path.join(this.crate.subdirectory, this.crate.nodefile));

View File

@ -1,5 +1,5 @@
import * as async from './async/child_process';
import * as child_process from 'child_process';
import * as childProcess from 'child_process';
export type Toolchain = 'default' | 'stable' | 'nightly' | 'beta';
@ -10,15 +10,15 @@ function toolchainPrefix(toolchain: Toolchain = 'default') {
export function spawnSync(tool: string,
args: string[],
toolchain: Toolchain = 'default',
options?: child_process.SpawnOptions)
options?: childProcess.SpawnOptions)
{
return child_process.spawnSync(tool, toolchainPrefix(toolchain).concat(args), options);
return childProcess.spawnSync(tool, toolchainPrefix(toolchain).concat(args), options);
}
export function spawn(tool: string,
args: string[],
toolchain: Toolchain = 'default',
options?: child_process.SpawnOptions)
options?: childProcess.SpawnOptions)
{
return async.spawn(tool, toolchainPrefix(toolchain).concat(args), options);
}

View File

@ -1,4 +1,4 @@
import * as chalk from 'chalk';
import chalk from 'chalk';
export let project = chalk.cyan.bold;
export let command = chalk.green.bold;

View File

@ -1,11 +1,10 @@
import { remove } from './async/fs';
import * as rust from './rust';
import * as path from 'path';
import Dict from 'ts-dict';
import path from 'path';
import Crate from './crate';
import BuildSettings from './build-settings';
import { rimraf } from './async/rimraf';
const LIB_PREFIX: Dict<string> = {
const LIB_PREFIX: Record<string, string> = {
'darwin': "lib",
'freebsd': "lib",
'linux': "lib",
@ -13,7 +12,7 @@ const LIB_PREFIX: Dict<string> = {
'win32': ""
};
const LIB_SUFFIX: Dict<string> = {
const LIB_SUFFIX: Record<string, string> = {
'darwin': ".dylib",
'freebsd': ".so",
'linux': ".so",
@ -62,7 +61,8 @@ export default class Target {
async clean() {
// Remove the directory associated with this target.
await remove(path.resolve(this.crate.root, 'target', this.subdirectory));
const absolutePathSubdir = path.resolve(this.crate.root, 'target', this.subdirectory);
await rimraf(absolutePathSubdir);
// If this target was the active target, remove the addon.
if (this.crate.artifacts.haveActivated(this.subdirectory)) {
@ -75,12 +75,13 @@ export default class Target {
}
async build(toolchain: rust.Toolchain,
settings: BuildSettings)
settings: BuildSettings,
additionalArgs: string[])
{
let releaseFlags = this.release ? ["--release"] : [];
let targetFlags = this.triple ? ["--target=" + this.triple] : [];
let args = ['build'].concat(releaseFlags, targetFlags);
let args = ['build'].concat(releaseFlags, targetFlags, additionalArgs);
try {
let result = await rust.spawn("cargo", args, toolchain, {

View File

@ -1,9 +1,10 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es6",
"lib": [
"es5", "es2015.core"
"es6",
"es7"
],
"allowJs": false,
@ -12,6 +13,7 @@
"declaration": true,
"esModuleInterop": true,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"strictNullChecks": true,

View File

@ -1,15 +1,12 @@
[package]
name = "neon-build"
version = "0.4.0"
version = "0.8.2"
authors = ["Dave Herman <david.herman@gmail.com>"]
description = "Build logic required for Neon projects."
repository = "https://github.com/neon-bindings/neon"
license = "MIT/Apache-2.0"
edition = "2018"
build = "build.rs"
[dependencies]
neon-sys = { version = "=0.4.0", path = "../neon-sys", optional = true }
cfg-if = "0.1.9"
[build-dependencies]
cfg-if = "0.1.9"
neon-sys = { version = "=0.8.2", path = "../neon-sys", optional = true }

View File

@ -1,28 +1,22 @@
extern crate cfg_if;
#[cfg(all(windows, feature = "neon-sys"))]
fn main() {
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use cfg_if::cfg_if;
cfg_if! {
if #[cfg(all(windows, feature = "neon-sys"))] {
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;
// Extract linker metadata from neon-sys and save it in a text file.
// The neon-build lib.rs will textually include them into constants.
fn save(var: &str, filename: &str) {
let path = Path::new(&env::var("OUT_DIR").unwrap()).join(filename);
let mut buffer = File::create(path).unwrap();
write!(buffer, "{}", env::var(var).unwrap()).unwrap();
}
fn main() {
save("DEP_NEON_NODE_ROOT_DIR", "node_root_dir");
save("DEP_NEON_NODE_ARCH", "node_arch");
save("DEP_NEON_NODE_LIB_FILE", "node_lib_file");
}
} else {
fn main() { }
// Extract linker metadata from neon-sys and save it in a text file.
// The neon-build lib.rs will textually include them into constants.
fn save(var: &str, filename: &str) {
let path = Path::new(&env::var("OUT_DIR").unwrap()).join(filename);
let mut buffer = File::create(path).unwrap();
write!(buffer, "{}", env::var(var).unwrap()).unwrap();
}
save("DEP_NEON_NODE_ROOT_DIR", "node_root_dir");
save("DEP_NEON_NODE_ARCH", "node_arch");
save("DEP_NEON_NODE_LIB_FILE", "node_lib_file");
}
#[cfg(any(not(windows), not(feature = "neon-sys")))]
fn main() {}

View File

@ -0,0 +1 @@
pub(crate) fn setup() {}

View File

@ -0,0 +1,4 @@
pub(crate) fn setup() {
println!("cargo:rustc-cdylib-link-arg=-undefined");
println!("cargo:rustc-cdylib-link-arg=dynamic_lookup");
}

View File

@ -0,0 +1,14 @@
#[cfg(all(not(windows), not(target_os = "macos")))]
mod linux;
#[cfg(all(not(windows), not(target_os = "macos")))]
pub(crate) use linux::*;
#[cfg(target_os = "macos")]
mod macos;
#[cfg(target_os = "macos")]
pub(crate) use macos::*;
#[cfg(windows)]
mod windows;
#[cfg(windows)]
pub(crate) use windows::*;

View File

@ -0,0 +1,36 @@
use std::env::var;
use std::path::Path;
const NODE_ROOT_DIR: &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_root_dir"));
const NODE_ARCH: &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_arch"));
const NODE_LIB_FILE: &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_lib_file"));
/// Set up the build environment by setting Cargo configuration variables.
pub(crate) fn setup() {
let debug = var("DEBUG").ok().map_or(false, |s| s == "true");
let configuration = if debug { "Debug" } else { "Release" };
let node_lib_file_path = Path::new(NODE_LIB_FILE);
let mut node_lib_path = Path::new(NODE_ROOT_DIR).to_path_buf();
node_lib_path.push(NODE_ARCH);
println!(
"cargo:rustc-link-search={}\\{}",
NODE_ROOT_DIR, configuration
);
println!(
"cargo:rustc-link-search=native={}",
&node_lib_path.display()
);
println!(
"cargo:rustc-link-lib={}",
&node_lib_file_path.file_stem().unwrap().to_str().unwrap()
);
// Link `win_delay_load_hook.obj` for windows electron
let node_runtime_env = "npm_config_runtime";
println!("cargo:rerun-if-env-changed={}", node_runtime_env);
if var(node_runtime_env).map(|s| s == "electron") == Ok(true) {
println!("cargo:rustc-cdylib-link-arg=win_delay_load_hook.obj");
println!("cargo:rustc-cdylib-link-arg=delayimp.lib");
println!("cargo:rustc-cdylib-link-arg=/DELAYLOAD:node.exe");
}
}

View File

@ -1,43 +1,32 @@
extern crate cfg_if;
#[cfg(feature = "neon-sys")]
mod legacy;
#[cfg(not(feature = "neon-sys"))]
mod napi;
use cfg_if::cfg_if;
#[cfg(not(feature = "neon-sys"))]
pub use napi::Setup;
cfg_if! {
if #[cfg(all(windows, feature = "neon-sys"))] {
use std::env::var;
use std::path::Path;
const NODE_ROOT_DIR: &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_root_dir"));
const NODE_ARCH: &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_arch"));
const NODE_LIB_FILE: &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_lib_file"));
/// Set up the build environment by setting Cargo configuration variables.
pub fn setup() {
let debug = var("DEBUG").ok().map_or(false, |s| s == "true");
let configuration = if debug { "Debug" } else { "Release" };
let node_lib_file_path = Path::new(NODE_LIB_FILE);
let mut node_lib_path = Path::new(NODE_ROOT_DIR).to_path_buf();
node_lib_path.push(NODE_ARCH);
println!("cargo:rustc-link-search={}\\{}", NODE_ROOT_DIR, configuration);
println!("cargo:rustc-link-search=native={}", &node_lib_path.display());
println!("cargo:rustc-link-lib={}", &node_lib_file_path.file_stem().unwrap().to_str().unwrap());
// Link `win_delay_load_hook.obj` for windows electron
let node_runtime_env = "npm_config_runtime";
println!("cargo:rerun-if-env-changed={}", node_runtime_env);
if var(node_runtime_env).map(|s| s == "electron") == Ok(true) {
println!("cargo:rustc-cdylib-link-arg=win_delay_load_hook.obj");
println!("cargo:rustc-cdylib-link-arg=delayimp.lib");
println!("cargo:rustc-cdylib-link-arg=/DELAYLOAD:node.exe");
}
}
} else if #[cfg(target_os = "macos")] {
/// Set up the build environment by setting Cargo configuration variables.
pub fn setup() {
println!("cargo:rustc-cdylib-link-arg=-undefined");
println!("cargo:rustc-cdylib-link-arg=dynamic_lookup");
}
} else {
pub fn setup() { }
}
/// Custom build scripts for [Neon][neon] modules.
/// Must be called from `main.rs` in a Cargo [build script][build-script].
///
/// ```toml
/// [package]
/// build = "build.rs"
/// ```
///
/// ```rust
/// // build.rs
/// # #[allow(clippy::needless_doctest_main)]
/// fn main() {
/// neon_build::setup();
/// }
/// ```
///
/// [neon]: https://docs.rs/neon
/// [build-script]: https://doc.rust-lang.org/cargo/reference/build-scripts.html
pub fn setup() {
#[cfg(feature = "neon-sys")]
legacy::setup();
#[cfg(not(feature = "neon-sys"))]
napi::setup();
}

View File

@ -0,0 +1,171 @@
use std::path::{Path, PathBuf};
fn manifest_dir() -> PathBuf {
std::env::var_os("CARGO_MANIFEST_DIR")
.map(PathBuf::from)
.expect("Expected CARGO_MANIFEST_DIR environment variable")
}
fn out_dir() -> PathBuf {
std::env::var_os("OUT_DIR")
.map(PathBuf::from)
.expect("Expected OUT_DIR environment variable")
}
fn is_env(env_var: &str, value: &str) -> bool {
std::env::var_os(env_var)
.map(|v| v == value)
.unwrap_or(false)
}
fn setup_unix(output_file: PathBuf) {
println!("cargo:rustc-cdylib-link-arg=-o");
println!("cargo:rustc-cdylib-link-arg={}", output_file.display());
}
fn setup_windows(output_file: PathBuf) {
let pdb_file = output_file
.file_name()
.map(|file| out_dir().join(Path::new(file).with_extension("pdb")))
.expect("Expected a neon output file name");
println!("cargo:rustc-cdylib-link-arg=/OUT:{}", output_file.display());
println!("cargo:rustc-cdylib-link-arg=/PDB:{}", pdb_file.display());
}
/// `Setup` acts as a builder for initializing a Neon build script
///
/// A default setup builder is provided as [`neon_build::setup()`](crate::setup()).
///
/// # Example
///
/// Output the neon module at `lib/native.node`
///
/// ```
/// # #[allow(clippy::needless_doctest_main)]
/// fn main() {
/// neon_build::Setup::options()
/// .output_dir("lib")
/// .output_dir("native.node")
/// .setup();
/// }
#[derive(Debug, Default)]
pub struct Setup {
output_dir: Option<PathBuf>,
output_file: Option<PathBuf>,
}
impl Setup {
/// Create a new builder for Setup options
pub fn options() -> Self {
Default::default()
}
/// Sets the output directory for the native library.
/// Defaults to the cargo manifest directory. If not absolute, paths will
/// be relative to the cargo manifest directory.
pub fn output_dir(&mut self, output_dir: impl AsRef<Path>) -> &mut Self {
self.output_dir = Some(output_dir.as_ref().to_path_buf());
self
}
/// Sets the name of the native library. Defaults to `index.node`. If not
/// absolute, paths will be relative to the [`Setup::output_dir`].
///
/// **Note**: Node.js requires that native libraries have the `.node`
/// extension to be loaded by `require`.
pub fn output_file(&mut self, output_file: impl AsRef<Path>) -> &mut Self {
self.output_file = Some(output_file.as_ref().to_path_buf());
self
}
/// Setup the Cargo build process for Neon. Should be called once from
/// `fn main` in a cargo build script.
pub fn setup(&self) {
let output_file = self.absolute_output_file();
let is_windows = is_env("CARGO_CFG_TARGET_OS", "windows");
let is_gnu = is_env("CARGO_CFG_TARGET_ENV", "gnu");
if is_windows && !is_gnu {
setup_windows(output_file);
} else {
setup_unix(output_file);
}
}
fn absolute_output_file(&self) -> PathBuf {
let output_file = self
.output_file
.clone()
.unwrap_or_else(|| PathBuf::from("index.node"));
// Don't prepend `output_dir` if `output_file` is absolute
if output_file.is_absolute() {
return output_file;
}
let output_dir = if let Some(output_dir) = self.output_dir.clone() {
// If `output_dir` is absolute, use it, otherwise
// append it to `manifest_dir()`
if output_dir.is_absolute() {
output_dir
} else {
manifest_dir().join(output_dir)
}
} else {
// Default to `manifest_dir()`
manifest_dir()
};
output_dir.join(output_file)
}
}
pub(crate) fn setup() {
Setup::options().setup()
}
#[test]
fn test_absolute_output_file_defaults() {
let expected = manifest_dir().join("index.node");
let actual = Setup::options().absolute_output_file();
assert_eq!(actual, expected);
}
#[test]
fn test_absolute_output_file_absolute_file() {
let expected = PathBuf::from("/tmp/hello.node");
let actual = Setup::options()
.output_dir("/tmp/ignore/me")
.output_file("/tmp/hello.node")
.absolute_output_file();
assert_eq!(actual, expected);
}
#[test]
fn test_absolute_output_file_absolute_dir() {
let expected = PathBuf::from("/tmp/index.node");
let actual = Setup::options().output_dir("/tmp").absolute_output_file();
assert_eq!(actual, expected);
}
#[test]
fn test_absolute_output_file_relative_dir() {
let expected = manifest_dir().join("lib").join("index.node");
let actual = Setup::options().output_dir("lib").absolute_output_file();
assert_eq!(actual, expected);
}
#[test]
fn test_absolute_output_file_relative_file() {
let expected = manifest_dir().join("lib.node");
let actual = Setup::options()
.output_file("lib.node")
.absolute_output_file();
assert_eq!(actual, expected);
}

View File

@ -0,0 +1,18 @@
[package]
name = "neon-macros"
version = "0.8.2"
authors = ["Dave Herman <david.herman@gmail.com>"]
description = "Procedural macros supporting Neon"
repository = "https://github.com/neon-bindings/neon"
license = "MIT/Apache-2.0"
edition = "2018"
[lib]
proc-macro = true
[features]
napi = []
[dependencies]
quote = "1"
syn = { version = "1", features = ["full"] }

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,19 @@
Copyright (c) 2015 David Herman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,81 @@
pub(crate) fn main(
_attr: proc_macro::TokenStream,
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
let input = syn::parse_macro_input!(item as syn::ItemFn);
let attrs = &input.attrs;
let vis = &input.vis;
let sig = &input.sig;
let block = &input.block;
let name = &sig.ident;
quote::quote!(
#(#attrs) *
#vis #sig {
// Mark this function as a global constructor (like C++).
#[allow(improper_ctypes)]
#[cfg_attr(target_os = "linux", link_section = ".ctors")]
#[cfg_attr(target_os = "android", link_section = ".ctors")]
#[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
#[cfg_attr(target_os = "ios", link_section = "__DATA,__mod_init_func")]
#[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
#[used]
static __LOAD_NEON_MODULE: extern "C" fn() = {
extern "C" fn __load_neon_module() {
// Put everything else in the ctor fn so the user fn can't see it.
#[repr(C)]
struct __NodeModule {
version: i32,
flags: u32,
dso_handle: *mut u8,
filename: *const u8,
register_func: Option<extern "C" fn(
::neon::handle::Handle<::neon::types::JsObject>, *mut u8, *mut u8)>,
context_register_func: Option<extern "C" fn(
::neon::handle::Handle<::neon::types::JsObject>, *mut u8, *mut u8, *mut u8)>,
modname: *const u8,
priv_data: *mut u8,
link: *mut __NodeModule
}
// Mark as used during tests to suppress warnings
#[cfg_attr(test, used)]
static mut __NODE_MODULE: __NodeModule = __NodeModule {
version: 0,
flags: 0,
dso_handle: 0 as *mut _,
filename: b"neon_source.rs\0" as *const u8,
register_func: Some(__register_neon_module),
context_register_func: None,
modname: b"neon_module\0" as *const u8,
priv_data: 0 as *mut _,
link: 0 as *mut _
};
extern "C" fn __register_neon_module(
m: ::neon::handle::Handle<::neon::types::JsObject>, _: *mut u8, _: *mut u8) {
::neon::macro_internal::initialize_module(m, #name);
}
extern "C" {
fn node_module_register(module: *mut __NodeModule);
}
// During tests, node is not available. Skip module registration.
#[cfg(not(test))]
unsafe {
// Set the ABI version based on the NODE_MODULE_VERSION constant provided by the current node headers.
__NODE_MODULE.version = ::neon::macro_internal::runtime::module::get_version();
node_module_register(&mut __NODE_MODULE);
}
}
__load_neon_module
};
#block
}
)
.into()
}

View File

@ -0,0 +1,44 @@
//! Procedural macros supporting [Neon](https://docs.rs/neon/latest/neon/)
#[cfg(feature = "napi")]
mod napi;
#[cfg(feature = "napi")]
use napi as macros;
#[cfg(not(feature = "napi"))]
mod legacy;
#[cfg(not(feature = "napi"))]
use legacy as macros;
// Proc macro definitions must be in the root of the crate
// Implementations are in the backend dependent module
#[proc_macro_attribute]
/// Marks a function as the main entry point for initialization in
/// a Neon module.
///
/// This attribute should only be used _once_ in a module and will
/// be called each time the module is initialized in a context.
///
/// ```ignore
/// #[neon::main]
/// fn main(mut cx: ModuleContext) -> NeonResult<()> {
/// let version = cx.string("1.0.0");
///
/// cx.export_value("version", version)?;
///
/// Ok(())
/// }
/// ```
///
/// If multiple functions are marked with `#[neon::main]`, there may be a compile error:
///
/// ```sh
/// error: symbol `napi_register_module_v1` is already defined
/// ```
pub fn main(
attr: proc_macro::TokenStream,
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
macros::main(attr, item)
}

View File

@ -0,0 +1,34 @@
pub(crate) fn main(
_attr: proc_macro::TokenStream,
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
let input = syn::parse_macro_input!(item as syn::ItemFn);
let attrs = &input.attrs;
let vis = &input.vis;
let sig = &input.sig;
let block = &input.block;
let name = &sig.ident;
quote::quote!(
#(#attrs) *
#vis #sig {
#[no_mangle]
unsafe extern "C" fn napi_register_module_v1(
env: ::neon::macro_internal::runtime::raw::Env,
m: ::neon::macro_internal::runtime::raw::Local,
) -> ::neon::macro_internal::runtime::raw::Local {
::neon::macro_internal::initialize_module(
env,
::std::mem::transmute(m),
#name,
);
m
}
#block
}
)
.into()
}

View File

@ -1,18 +1,30 @@
[package]
name = "neon-runtime"
version = "0.4.0"
version = "0.8.2"
authors = ["Dave Herman <david.herman@gmail.com>"]
description = "Bindings to the Node.js native addon API, used by the Neon implementation."
repository = "https://github.com/neon-bindings/neon"
license = "MIT/Apache-2.0"
edition = "2018"
[dependencies]
cfg-if = "0.1.9"
neon-sys = { version = "=0.4.0", path = "../neon-sys", optional = true }
nodejs-sys = { version = "0.2.0", optional = true }
cfg-if = "1.0.0"
libloading = { version = "0.6.5", optional = true }
neon-sys = { version = "=0.8.2", path = "../neon-sys", optional = true }
smallvec = "1.4.2"
[dev-dependencies]
nodejs-sys = "0.7.0" # Not strictly needed; just here for easy manual copying
[features]
default = []
napi = ["libloading"]
napi-2 = ["napi"]
napi-3 = ["napi-2"]
napi-4 = ["napi-3"]
napi-5 = ["napi-4"]
napi-6 = ["napi-5"]
napi-experimental = ["napi-6"]
docs-only = ["neon-sys/docs-only"]
[package.metadata.docs.rs]

View File

@ -1,25 +1,23 @@
extern crate cfg_if;
#[cfg(all(not(feature = "neon-sys"), not(feature = "nodejs-sys")))]
compile_error!("The Neon runtime must have at least one of the `neon-sys` or `nodejs-sys` backends enabled.");
#[cfg(all(not(feature = "neon-sys"), not(feature = "napi")))]
compile_error!(
"The Neon runtime must have at least one of the `neon-sys` or `napi` backends enabled."
);
use cfg_if::cfg_if;
cfg_if! {
if #[cfg(feature = "nodejs-sys")] {
pub extern crate nodejs_sys;
if #[cfg(feature = "napi")] {
pub mod napi;
}
}
cfg_if! {
if #[cfg(feature = "neon-sys")] {
extern crate neon_sys;
pub mod nan;
// The legacy variant is the default API as long as it's present.
pub use nan::*;
} else if #[cfg(feature = "nodejs-sys")] {
pub use crate::nan::*;
} else if #[cfg(feature = "napi")] {
// The N-API variant is only the default API if the legacy variant is disabled.
pub use napi::*;
pub use crate::napi::*;
}
}

View File

@ -18,7 +18,7 @@ pub use neon_sys::Neon_Call_IsConstruct as is_construct;
/// the function is bound to.
pub use neon_sys::Neon_Call_This as this;
/// Mutates the `out` argument provided to refer to the `v8::Local` handle value of the
/// Mutates the `out` argument provided to refer to the pointer value of the
/// `v8::FunctionCallbackInfo` `Data`.
pub use neon_sys::Neon_Call_Data as data;

View File

@ -1,16 +1,28 @@
//! Facilities for creating and throwing JS errors.
use crate::raw::{Isolate, Local};
/// Throws an `Error` object in the current context.
pub use neon_sys::Neon_Error_Throw as throw;
pub unsafe fn throw(_: Isolate, val: Local) {
neon_sys::Neon_Error_Throw(val)
}
/// Mutates the `out` argument provided to refer to a newly created `Error` object.
pub use neon_sys::Neon_Error_NewError as new_error;
pub unsafe fn new_error(_: Isolate, out: &mut Local, msg: Local) {
neon_sys::Neon_Error_NewError(out, msg)
}
/// Mutates the `out` argument provided to refer to a newly created `TypeError` object.
pub use neon_sys::Neon_Error_NewTypeError as new_type_error;
pub unsafe fn new_type_error(_: Isolate, out: &mut Local, msg: Local) {
neon_sys::Neon_Error_NewTypeError(out, msg)
}
/// Mutates the `out` argument provided to refer to a newly created `RangeError` object.
pub use neon_sys::Neon_Error_NewRangeError as new_range_error;
pub unsafe fn new_range_error(_: Isolate, out: &mut Local, msg: Local) {
neon_sys::Neon_Error_NewRangeError(out, msg)
}
/// Throws an `Error` object in the current context.
pub use neon_sys::Neon_Error_ThrowErrorFromUtf8 as throw_error_from_utf8;
pub unsafe fn throw_error_from_utf8(_: Isolate, msg: *const u8, len: i32) {
neon_sys::Neon_Error_ThrowErrorFromUtf8(msg, len)
}

View File

@ -1,18 +1,19 @@
pub mod raw;
pub mod call;
pub mod scope;
pub mod object;
pub mod array;
pub mod string;
pub mod primitive;
pub mod error;
pub mod arraybuffer;
pub mod buffer;
pub mod tag;
pub mod module;
pub mod mem;
pub mod fun;
pub mod convert;
pub mod call;
pub mod class;
pub mod task;
pub mod convert;
pub mod error;
pub mod fun;
pub mod handler;
pub mod mem;
pub mod module;
pub mod object;
pub mod primitive;
pub mod raw;
pub mod scope;
pub mod string;
pub mod tag;
pub mod task;
pub mod try_catch;

View File

@ -1,3 +1,5 @@
//! Fundamental definitions for mapping to the V8 memory space.
pub use neon_sys::{Local, FunctionCallbackInfo, Isolate, HandleScope, EscapableHandleScope, InheritedHandleScope};
pub use neon_sys::{
EscapableHandleScope, FunctionCallbackInfo, HandleScope, InheritedHandleScope, Isolate, Local,
};

View File

@ -1,15 +1,23 @@
//! Facilities for working with `v8::HandleScope`s and `v8::EscapableHandleScope`s.
use raw::{HandleScope, EscapableHandleScope, InheritedHandleScope, Isolate};
use crate::raw::{EscapableHandleScope, HandleScope, InheritedHandleScope, Isolate};
pub trait Root {
/// # Safety
/// Allocates an uninitialized scope. See `enter` and `exit`.
unsafe fn allocate() -> Self;
unsafe fn enter(&mut self, Isolate);
unsafe fn exit(&mut self, Isolate);
/// # Safety
/// Must be called exactly once after creating a `Root` and before usage
unsafe fn enter(&mut self, _: Isolate);
/// # Safety
/// Must be called exactly once, if and only if `enter` succeeds
unsafe fn exit(&mut self, _: Isolate);
}
impl Root for HandleScope {
unsafe fn allocate() -> Self { HandleScope::new() }
unsafe fn allocate() -> Self {
HandleScope::new()
}
unsafe fn enter(&mut self, isolate: Isolate) {
enter(self, isolate)
}
@ -19,7 +27,9 @@ impl Root for HandleScope {
}
impl Root for EscapableHandleScope {
unsafe fn allocate() -> Self { EscapableHandleScope::new() }
unsafe fn allocate() -> Self {
EscapableHandleScope::new()
}
unsafe fn enter(&mut self, isolate: Isolate) {
enter_escapable(self, isolate)
}
@ -29,9 +39,11 @@ impl Root for EscapableHandleScope {
}
impl Root for InheritedHandleScope {
unsafe fn allocate() -> Self { InheritedHandleScope }
unsafe fn enter(&mut self, _: Isolate) { }
unsafe fn exit(&mut self, _: Isolate) { }
unsafe fn allocate() -> Self {
InheritedHandleScope
}
unsafe fn enter(&mut self, _: Isolate) {}
unsafe fn exit(&mut self, _: Isolate) {}
}
/// Mutates the `out` argument provided to refer to the newly escaped `v8::Local` value.

View File

@ -0,0 +1,4 @@
/// Wraps a computation with an RAII-allocated Nan::TryCatch.
pub use neon_sys::Neon_TryCatch_With as with;
pub use neon_sys::TryCatchControl;

View File

@ -1,18 +1,26 @@
//! Facilities for working with Array `napi_value`s.
use raw::{Local, Env};
use crate::raw::{Env, Local};
use nodejs_sys as napi;
use crate::napi::bindings as napi;
pub unsafe extern "C" fn new(_out: &mut Local, _env: Env, _length: u32) { unimplemented!() }
pub unsafe fn new(out: &mut Local, env: Env, length: u32) {
assert_eq!(
napi::create_array_with_length(env, length as usize, out as *mut _),
napi::Status::Ok,
);
}
/// Gets the length of a `napi_value` containing a JavaScript Array.
///
/// # Panics
/// This function panics if `array` is not an Array, or if a previous n-api call caused a pending
/// exception.
pub unsafe extern "C" fn len(env: Env, array: Local) -> u32 {
pub unsafe fn len(env: Env, array: Local) -> u32 {
let mut len = 0;
assert_eq!(napi::napi_get_array_length(env, array, &mut len as *mut _), napi::napi_status::napi_ok);
assert_eq!(
napi::get_array_length(env, array, &mut len as *mut _),
napi::Status::Ok
);
len
}

View File

@ -1,6 +1,50 @@
use raw::Local;
use crate::raw::{Env, Local};
use std::mem::MaybeUninit;
use std::os::raw::c_void;
use std::ptr::null_mut;
pub unsafe extern "C" fn new(_out: &mut Local, _isolate: *mut c_void, _size: u32) -> bool { unimplemented!() }
use crate::napi::bindings as napi;
pub unsafe extern "C" fn data<'a, 'b>(_base_out: &'a mut *mut c_void, _obj: Local) -> usize { unimplemented!() }
pub unsafe fn new(out: &mut Local, env: Env, size: u32) -> bool {
let status = napi::create_arraybuffer(env, size as usize, null_mut(), out as *mut _);
status == napi::Status::Ok
}
pub unsafe fn data(env: Env, base_out: &mut *mut c_void, obj: Local) -> usize {
let mut size = 0;
assert_eq!(
napi::get_arraybuffer_info(env, obj, base_out as *mut _, &mut size as *mut _),
napi::Status::Ok,
);
size
}
pub unsafe fn new_external<T>(env: Env, data: T) -> Local
where
T: AsMut<[u8]> + Send,
{
// Safety: Boxing could move the data; must box before grabbing a raw pointer
let mut data = Box::new(data);
let buf = data.as_mut().as_mut();
let length = buf.len();
let mut result = MaybeUninit::uninit();
assert_eq!(
napi::create_external_arraybuffer(
env,
buf.as_mut_ptr() as *mut _,
length,
Some(drop_external::<T>),
Box::into_raw(data) as *mut _,
result.as_mut_ptr(),
),
napi::Status::Ok,
);
result.assume_init()
}
unsafe extern "C" fn drop_external<T>(_env: Env, _data: *mut c_void, hint: *mut c_void) {
Box::<T>::from_raw(hint as *mut _);
}

View File

@ -0,0 +1,327 @@
#![allow(clippy::too_many_arguments)]
mod napi1 {
use super::super::types::*;
use std::os::raw::{c_char, c_void};
generate!(
extern "C" {
fn get_undefined(env: Env, result: *mut Value) -> Status;
fn get_null(env: Env, result: *mut Value) -> Status;
fn get_global(env: Env, result: *mut Value) -> Status;
fn get_boolean(env: Env, value: bool, result: *mut Value) -> Status;
fn create_double(env: Env, value: f64, result: *mut Value) -> Status;
fn create_object(env: Env, result: *mut Value) -> Status;
fn get_value_bool(env: Env, value: Value, result: *mut bool) -> Status;
fn get_value_double(env: Env, value: Value, result: *mut f64) -> Status;
fn create_array_with_length(env: Env, length: usize, result: *mut Value) -> Status;
fn get_array_length(env: Env, value: Value, result: *mut u32) -> Status;
fn get_new_target(env: Env, cbinfo: CallbackInfo, result: *mut Value) -> Status;
fn coerce_to_object(env: Env, value: Value, result: *mut Value) -> Status;
fn coerce_to_string(env: Env, value: Value, result: *mut Value) -> Status;
fn throw(env: Env, error: Value) -> Status;
fn create_error(env: Env, code: Value, msg: Value, result: *mut Value) -> Status;
fn get_and_clear_last_exception(env: Env, result: *mut Value) -> Status;
fn is_exception_pending(env: Env, result: *mut bool) -> Status;
fn get_value_external(env: Env, value: Value, result: *mut *mut c_void) -> Status;
fn typeof_value(env: Env, value: Value, result: *mut ValueType) -> Status;
fn close_escapable_handle_scope(env: Env, scope: EscapableHandleScope) -> Status;
fn open_escapable_handle_scope(env: Env, result: *mut EscapableHandleScope) -> Status;
fn open_handle_scope(env: Env, result: *mut HandleScope) -> Status;
fn close_handle_scope(env: Env, scope: HandleScope) -> Status;
fn is_arraybuffer(env: Env, value: Value, result: *mut bool) -> Status;
fn is_buffer(env: Env, value: Value, result: *mut bool) -> Status;
fn is_error(env: Env, value: Value, result: *mut bool) -> Status;
fn is_array(env: Env, value: Value, result: *mut bool) -> Status;
fn get_value_string_utf8(
env: Env,
value: Value,
buf: *mut c_char,
bufsize: usize,
result: *mut usize,
) -> Status;
fn create_type_error(env: Env, code: Value, msg: Value, result: *mut Value) -> Status;
fn create_range_error(env: Env, code: Value, msg: Value, result: *mut Value) -> Status;
fn create_string_utf8(
env: Env,
str: *const c_char,
length: usize,
result: *mut Value,
) -> Status;
fn create_arraybuffer(
env: Env,
byte_length: usize,
data: *mut *mut c_void,
result: *mut Value,
) -> Status;
fn get_arraybuffer_info(
env: Env,
arraybuffer: Value,
data: *mut *mut c_void,
byte_length: *mut usize,
) -> Status;
fn create_buffer(
env: Env,
length: usize,
data: *mut *mut c_void,
result: *mut Value,
) -> Status;
fn get_buffer_info(
env: Env,
value: Value,
data: *mut *mut c_void,
length: *mut usize,
) -> Status;
fn get_cb_info(
env: Env,
cbinfo: CallbackInfo,
argc: *mut usize,
argv: *mut Value,
this_arg: *mut Value,
data: *mut *mut c_void,
) -> Status;
fn create_external(
env: Env,
data: *mut c_void,
finalize_cb: Finalize,
finalize_hint: *mut c_void,
result: *mut Value,
) -> Status;
fn new_instance(
env: Env,
constructor: Value,
argc: usize,
argv: *const Value,
result: *mut Value,
) -> Status;
fn call_function(
env: Env,
recv: Value,
func: Value,
argc: usize,
argv: *const Value,
result: *mut Value,
) -> Status;
fn create_function(
env: Env,
utf8name: *const c_char,
length: usize,
cb: Callback,
data: *mut c_void,
result: *mut Value,
) -> Status;
fn set_property(env: Env, object: Value, key: Value, value: Value) -> Status;
fn get_property(env: Env, object: Value, key: Value, result: *mut Value) -> Status;
fn set_element(env: Env, object: Value, index: u32, value: Value) -> Status;
fn get_element(env: Env, object: Value, index: u32, result: *mut Value) -> Status;
fn escape_handle(
env: Env,
scope: EscapableHandleScope,
escapee: Value,
result: *mut Value,
) -> Status;
fn create_reference(
env: Env,
value: Value,
initial_ref_count: u32,
result: *mut Ref,
) -> Status;
fn reference_ref(env: Env, reference: Ref, result: *mut u32) -> Status;
fn reference_unref(env: Env, reference: Ref, result: *mut u32) -> Status;
fn get_reference_value(env: Env, reference: Ref, result: *mut Value) -> Status;
fn strict_equals(env: Env, lhs: Value, rhs: Value, result: *mut bool) -> Status;
fn create_external_arraybuffer(
env: Env,
data: *mut c_void,
length: usize,
finalize_cb: Finalize,
finalize_hint: *mut c_void,
result: *mut Value,
) -> Status;
fn create_external_buffer(
env: Env,
length: usize,
data: *mut c_void,
finalize_cb: Finalize,
finalize_hint: *mut c_void,
result: *mut Value,
) -> Status;
fn run_script(env: Env, script: Value, result: *mut Value) -> Status;
}
);
}
#[cfg(feature = "napi-4")]
mod napi4 {
use super::super::types::*;
use std::os::raw::c_void;
generate!(
extern "C" {
fn create_threadsafe_function(
env: Env,
func: Value,
async_resource: Value,
async_resource_name: Value,
max_queue_size: usize,
initial_thread_count: usize,
thread_finalize_data: *mut c_void,
thread_finalize_cb: Finalize,
context: *mut c_void,
call_js_cb: ThreadsafeFunctionCallJs,
result: *mut ThreadsafeFunction,
) -> Status;
fn call_threadsafe_function(
func: ThreadsafeFunction,
data: *mut c_void,
is_blocking: ThreadsafeFunctionCallMode,
) -> Status;
fn release_threadsafe_function(
func: ThreadsafeFunction,
mode: ThreadsafeFunctionReleaseMode,
) -> Status;
fn ref_threadsafe_function(env: Env, func: ThreadsafeFunction) -> Status;
fn unref_threadsafe_function(env: Env, func: ThreadsafeFunction) -> Status;
}
);
}
#[cfg(feature = "napi-5")]
mod napi5 {
use super::super::types::*;
generate!(
extern "C" {
fn create_date(env: Env, value: f64, result: *mut Value) -> Status;
fn get_date_value(env: Env, value: Value, result: *mut f64) -> Status;
fn is_date(env: Env, value: Value, result: *mut bool) -> Status;
}
);
}
#[cfg(feature = "napi-6")]
mod napi6 {
use super::super::types::*;
use std::os::raw::c_void;
generate!(
extern "C" {
fn get_all_property_names(
env: Env,
object: Value,
key_mode: KeyCollectionMode,
key_filter: KeyFilter,
key_conversion: KeyConversion,
result: *mut Value,
) -> Status;
fn set_instance_data(
env: Env,
data: *mut c_void,
finalize_cb: Finalize,
finalize_hint: *mut c_void,
) -> Status;
fn get_instance_data(env: Env, data: *mut *mut c_void) -> Status;
}
);
}
pub(crate) use napi1::*;
#[cfg(feature = "napi-4")]
pub(crate) use napi4::*;
#[cfg(feature = "napi-5")]
pub(crate) use napi5::*;
#[cfg(feature = "napi-6")]
pub(crate) use napi6::*;
use super::{Env, Status};
// This symbol is loaded separately because it is a prerequisite
unsafe fn get_version(host: &libloading::Library, env: Env) -> Result<u32, libloading::Error> {
let get_version = host.get::<fn(Env, *mut u32) -> Status>(b"napi_get_version")?;
let mut version = 0;
assert_eq!(get_version(env, &mut version as *mut _), Status::Ok,);
Ok(version)
}
pub(crate) unsafe fn load(env: Env) -> Result<(), libloading::Error> {
#[cfg(not(windows))]
let host = libloading::os::unix::Library::this().into();
#[cfg(windows)]
let host = libloading::os::windows::Library::this()?.into();
// This never fail since `get_version` is in N-API Version 1 and the module will fail
// with `Error: Module did not self-register` if N-API does not exist.
let version = get_version(&host, env).expect("Failed to find N-API version");
napi1::load(&host, version, 1)?;
#[cfg(feature = "napi-4")]
napi4::load(&host, version, 4)?;
#[cfg(feature = "napi-5")]
napi5::load(&host, version, 5)?;
#[cfg(feature = "napi-6")]
napi6::load(&host, version, 6)?;
Ok(())
}

View File

@ -0,0 +1,185 @@
//! # FFI bindings to N-API symbols
//!
//! These types are manually copied from bindings generated from `bindgen`. To
//! update, use the following approach:
//!
//! * Run `cargo test --manifest-path=crates/neon-runtime/Cargo.toml --features napi`
//! at least once to install `nodejs-sys`
//! * Open the generated bindings at `target/release/build/nodejs-sys-*/out/bindings.rs`
//! * Copy the types needed into `types.rs` and `functions.rs`
//! * Modify to match Rust naming conventions:
//! - Remove `napi_` prefixes
//! - Use `PascalCase` for types
//! - Rename types that match a reserved word
/// Constructs the name of a N-API symbol as a string from a function identifier
/// E.g., `get_undefined` becomes `"napi_get_undefined"`
macro_rules! napi_name {
// Explicitly replace identifiers that have been renamed from the N-API
// symbol because they would match a reserved word.
(typeof_value) => {
"napi_typeof"
};
// Default case: Stringify the identifier and prefix with `napi_`
($name:ident) => {
concat!("napi_", stringify!($name))
};
}
/// Generate dynamic bindings to N-API symbols from definitions in an
/// block `extern "C"`.
///
/// * A single global mutable struct holds references to the N-API functions
/// * The global `Napi` struct is initialized with stubs that panic if called
/// * A `load` function is generated that loads the N-API symbols from the
/// host process and replaces the global struct with real implementations
/// * `load` should be called exactly once before using any N-API functions
/// * Wrapper functions are generated to delegate to fields in the `Napi` struct
///
/// Sample input:
///
/// ```
/// extern "C" {
/// fn get_undefined(env: Env, result: *mut Value) -> Status;
/// /* Additional functions may be included */
/// }
/// ```
///
/// Generated output:
///
/// ```
/// // Each field is a pointer to a N-API function
/// pub(crate) struct Napi {
/// get_undefined: unsafe extern "C" fn(env: Env, result: *mut Value) -> Status,
/// /* ... repeat for each N-API function */
/// }
///
/// // Defines a panic function that is called if symbols have not been loaded
/// #[inline(never)]
/// fn panic_load<T>() -> T {
/// panic!("Must load N-API bindings")
/// }
///
/// // Mutable global instance of the Napi struct
/// // Initialized with stubs of N-API methods that panic
/// static mut NAPI: Napi = {
/// // Stubs are defined in a block to prevent naming conflicts with wrappers
/// unsafe extern "C" fn get_undefined(_: Env, _: *mut Value) -> Status {
/// panic_load()
/// }
/// /* ... repeat for each N-API function */
///
/// Napi {
/// get_undefined,
/// /* ... repeat for each N-API function */
/// }
/// };
///
/// // Load N-API symbols from the host process
/// // # Safety: Must only be called once
/// pub(crate) unsafe fn load(
/// host: &libloading::Library,
/// actual_napi_version: u32,
/// expected_napi_version: u32,
/// ) -> Result<(), libloading::Error> {
/// assert!(
/// actual_napi_version >= expected_napi_version,
/// "Minimum required N-API version {}, found {}.",
/// expected_napi_version,
/// actual_napi_version,
/// );
///
/// NAPI = Napi {
/// // Load each N-API symbol
/// get_undefined: *host.get("napi_get_undefined".as_bytes())?,
/// /* ... repeat for each N-API function */
/// };
///
/// Ok(())
/// }
///
/// // Each N-API function has wrapper for easy calling. These calls are optimized
/// // to a single pointer dereference.
/// #[inline]
/// pub(crate) unsafe fn get_undefined(env: Env, result: *mut Value) -> Status {
/// (NAPI.get_undefined)(env, result)
/// }
/// ```
macro_rules! generate {
(extern "C" {
$(fn $name:ident($($param:ident: $ptype:ty$(,)?)*) -> $rtype:ty;)+
}) => {
pub(crate) struct Napi {
$(
$name: unsafe extern "C" fn(
$($param: $ptype,)*
) -> $rtype,
)*
}
#[inline(never)]
fn panic_load<T>() -> T {
panic!("Must load N-API bindings")
}
static mut NAPI: Napi = {
$(
unsafe extern "C" fn $name($(_: $ptype,)*) -> $rtype {
panic_load()
}
)*
Napi {
$(
$name,
)*
}
};
pub(crate) unsafe fn load(
host: &libloading::Library,
actual_napi_version: u32,
expected_napi_version: u32,
) -> Result<(), libloading::Error> {
assert!(
actual_napi_version >= expected_napi_version,
"Minimum required N-API version {}, found {}.",
expected_napi_version,
actual_napi_version,
);
NAPI = Napi {
$(
$name: *host.get(napi_name!($name).as_bytes())?,
)*
};
Ok(())
}
$(
#[inline]
pub(crate) unsafe fn $name($($param: $ptype,)*) -> $rtype {
(NAPI.$name)($($param,)*)
}
)*
};
}
use std::sync::Once;
pub(crate) use functions::*;
pub(crate) use types::*;
mod functions;
mod types;
static SETUP: Once = Once::new();
/// Loads N-API symbols from host process.
/// Must be called at least once before using any functions in `neon-runtime` or
/// they will panic.
/// Safety: `env` must be a valid `napi_env` for the current thread
pub unsafe fn setup(env: Env) {
SETUP.call_once(|| load(env).expect("Failed to load N-API symbols"));
}

View File

@ -0,0 +1,188 @@
use std::ffi::c_void;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Env__ {
_unused: [u8; 0],
}
pub type Env = *mut Env__;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Value__ {
_unused: [u8; 0],
}
pub type Value = *mut Value__;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct CallbackInfo__ {
_unused: [u8; 0],
}
pub type CallbackInfo = *mut CallbackInfo__;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EscapableHandleScope__ {
_unused: [u8; 0],
}
pub type EscapableHandleScope = *mut EscapableHandleScope__;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct HandleScope__ {
_unused: [u8; 0],
}
pub type HandleScope = *mut HandleScope__;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Ref__ {
_unused: [u8; 0],
}
pub type Ref = *mut Ref__;
#[cfg(feature = "napi-4")]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ThreadsafeFunction__ {
_unused: [u8; 0],
}
#[cfg(feature = "napi-4")]
pub type ThreadsafeFunction = *mut ThreadsafeFunction__;
pub(crate) type Callback = Option<unsafe extern "C" fn(env: Env, info: CallbackInfo) -> Value>;
pub(crate) type Finalize =
Option<unsafe extern "C" fn(env: Env, finalize_data: *mut c_void, finalize_hint: *mut c_void)>;
#[cfg(feature = "napi-4")]
pub type ThreadsafeFunctionCallJs = Option<
unsafe extern "C" fn(env: Env, js_callback: Value, context: *mut c_void, data: *mut c_void),
>;
#[allow(dead_code)]
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Status {
Ok = 0,
InvalidArg = 1,
ObjectExpected = 2,
StringExpected = 3,
NameExpected = 4,
FunctionExpected = 5,
NumberExpected = 6,
BooleanExpected = 7,
ArrayExpected = 8,
GenericFailure = 9,
PendingException = 10,
Cancelled = 11,
EscapeCalledTwice = 12,
HandleScopeMismatch = 13,
CallbackScopeMismatch = 14,
QueueFull = 15,
Closing = 16,
BigintExpected = 17,
DateExpected = 18,
ArraybufferExpected = 19,
DetachableArraybufferExpected = 20,
WouldDeadlock = 21,
}
#[allow(dead_code)]
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub(crate) enum ValueType {
Undefined = 0,
Null = 1,
Boolean = 2,
Number = 3,
String = 4,
Symbol = 5,
Object = 6,
Function = 7,
External = 8,
BigInt = 9,
}
#[allow(dead_code)]
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum KeyCollectionMode {
IncludePrototypes = 0,
OwnOnly = 1,
}
#[allow(dead_code)]
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum KeyConversion {
KeepNumbers = 0,
NumbersToStrings = 1,
}
#[cfg(feature = "napi-4")]
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum ThreadsafeFunctionCallMode {
NonBlocking = 0,
Blocking = 1,
}
#[cfg(feature = "napi-4")]
#[allow(dead_code)]
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum ThreadsafeFunctionReleaseMode {
Release = 0,
Abort = 1,
}
#[repr(transparent)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub(crate) struct KeyFilter(pub ::std::os::raw::c_uint);
#[allow(dead_code)]
impl KeyFilter {
pub(crate) const ALL_PROPERTIES: KeyFilter = KeyFilter(0);
pub(crate) const WRITABLE: KeyFilter = KeyFilter(1);
pub(crate) const CONFIGURABLE: KeyFilter = KeyFilter(4);
pub(crate) const SKIP_STRINGS: KeyFilter = KeyFilter(8);
pub(crate) const SKIP_SYMBOLS: KeyFilter = KeyFilter(16);
}
impl std::ops::BitOr<KeyFilter> for KeyFilter {
type Output = Self;
#[inline]
fn bitor(self, other: Self) -> Self {
KeyFilter(self.0 | other.0)
}
}
impl std::ops::BitOrAssign for KeyFilter {
#[inline]
fn bitor_assign(&mut self, rhs: KeyFilter) {
self.0 |= rhs.0;
}
}
impl std::ops::BitAnd<KeyFilter> for KeyFilter {
type Output = Self;
#[inline]
fn bitand(self, other: Self) -> Self {
KeyFilter(self.0 & other.0)
}
}
impl std::ops::BitAndAssign for KeyFilter {
#[inline]
fn bitand_assign(&mut self, rhs: KeyFilter) {
self.0 &= rhs.0;
}
}

View File

@ -1,8 +1,63 @@
use raw::Local;
use crate::raw::{Env, Local};
use std::mem::MaybeUninit;
use std::os::raw::c_void;
use std::ptr::null_mut;
pub unsafe extern "C" fn new(_out: &mut Local, _size: u32) -> bool { unimplemented!() }
use crate::napi::bindings as napi;
pub unsafe extern "C" fn uninitialized(_out: &mut Local, _size: u32) -> bool { unimplemented!() }
pub unsafe fn new(env: Env, out: &mut Local, size: u32) -> bool {
let mut bytes = null_mut();
let status = napi::create_buffer(env, size as usize, &mut bytes as *mut _, out as *mut _);
if status == napi::Status::Ok {
// zero-initialize it. If performance is critical, JsBuffer::uninitialized can be used
// instead.
std::ptr::write_bytes(bytes, 0, size as usize);
true
} else {
false
}
}
pub unsafe extern "C" fn data<'a, 'b>(_base_out: &'a mut *mut c_void, _obj: Local) -> usize { unimplemented!() }
pub unsafe fn uninitialized(env: Env, out: &mut Local, size: u32) -> bool {
let mut bytes = null_mut();
let status = napi::create_buffer(env, size as usize, &mut bytes as *mut _, out as *mut _);
status == napi::Status::Ok
}
pub unsafe fn new_external<T>(env: Env, data: T) -> Local
where
T: AsMut<[u8]> + Send,
{
// Safety: Boxing could move the data; must box before grabbing a raw pointer
let mut data = Box::new(data);
let buf = data.as_mut().as_mut();
let length = buf.len();
let mut result = MaybeUninit::uninit();
assert_eq!(
napi::create_external_buffer(
env,
length,
buf.as_mut_ptr() as *mut _,
Some(drop_external::<T>),
Box::into_raw(data) as *mut _,
result.as_mut_ptr(),
),
napi::Status::Ok,
);
result.assume_init()
}
pub unsafe fn data(env: Env, base_out: &mut *mut c_void, obj: Local) -> usize {
let mut size = 0;
assert_eq!(
napi::get_buffer_info(env, obj, base_out as *mut _, &mut size as *mut _),
napi::Status::Ok,
);
size
}
unsafe extern "C" fn drop_external<T>(_env: Env, _data: *mut c_void, hint: *mut c_void) {
Box::<T>::from_raw(hint as *mut _);
}

View File

@ -1,35 +1,93 @@
use std::mem::MaybeUninit;
use std::os::raw::c_void;
use std::ptr::null_mut;
use raw::{FunctionCallbackInfo, Env, Local};
use smallvec::{smallvec, SmallVec};
use crate::napi::bindings as napi;
use crate::raw::{Env, FunctionCallbackInfo, Local};
#[repr(C)]
pub struct CCallback {
pub static_callback: *mut c_void,
pub dynamic_callback: *mut c_void
pub dynamic_callback: *mut c_void,
}
impl Default for CCallback {
fn default() -> Self {
CCallback {
static_callback: null_mut(),
dynamic_callback: null_mut()
dynamic_callback: null_mut(),
}
}
}
pub unsafe extern "C" fn set_return(_info: &FunctionCallbackInfo, _value: Local) { unimplemented!() }
pub unsafe fn is_construct(env: Env, info: FunctionCallbackInfo) -> bool {
let mut target: MaybeUninit<Local> = MaybeUninit::zeroed();
pub unsafe extern "C" fn get_isolate(_info: &FunctionCallbackInfo) -> Env { unimplemented!() }
let status = napi::get_new_target(env, info, target.as_mut_ptr());
// FIXME: Remove. This will never be implemented
pub unsafe extern "C" fn current_isolate() -> Env { panic!("current_isolate won't be implemented in n-api") }
assert_eq!(status, napi::Status::Ok);
pub unsafe extern "C" fn is_construct(_info: &FunctionCallbackInfo) -> bool { unimplemented!() }
// get_new_target is guaranteed to assign to target, so it's initialized.
let target: Local = target.assume_init();
pub unsafe extern "C" fn this(_info: &FunctionCallbackInfo, _out: &mut Local) { unimplemented!() }
// By the get_new_target contract, target will either be NULL if the current
// function was called without `new`, or a valid napi_value handle if the current
// function was called with `new`.
!target.is_null()
}
pub unsafe extern "C" fn data(_info: &FunctionCallbackInfo, _out: &mut Local) { unimplemented!() }
pub unsafe fn this(env: Env, info: FunctionCallbackInfo, out: &mut Local) {
let status = napi::get_cb_info(env, info, null_mut(), null_mut(), out as *mut _, null_mut());
assert_eq!(status, napi::Status::Ok);
}
pub unsafe extern "C" fn len(_info: &FunctionCallbackInfo) -> i32 { unimplemented!() }
/// Mutates the `out` argument provided to refer to the associated data value of the
/// `napi_callback_info`.
pub unsafe fn data(env: Env, info: FunctionCallbackInfo, out: &mut *mut c_void) {
let mut data = null_mut();
let status = napi::get_cb_info(
env,
info,
null_mut(),
null_mut(),
null_mut(),
&mut data as *mut _,
);
if status == napi::Status::Ok {
*out = data;
}
}
pub unsafe extern "C" fn get(_info: &FunctionCallbackInfo, _i: i32, _out: &mut Local) { unimplemented!() }
/// Gets the number of arguments passed to the function.
pub unsafe fn len(env: Env, info: FunctionCallbackInfo) -> i32 {
let mut argc = 0usize;
let status = napi::get_cb_info(
env,
info,
&mut argc as *mut _,
null_mut(),
null_mut(),
null_mut(),
);
assert_eq!(status, napi::Status::Ok);
argc as i32
}
/// Returns the function arguments as a `SmallVec<[Local; 8]>`
pub unsafe fn argv(env: Env, info: FunctionCallbackInfo) -> SmallVec<[Local; 8]> {
let len = len(env, info);
let mut args = smallvec![null_mut(); len as usize];
let mut num_args = args.len();
let status = napi::get_cb_info(
env,
info,
&mut num_args as *mut _,
args.as_mut_ptr(),
null_mut(),
null_mut(),
);
assert_eq!(status, napi::Status::Ok);
args
}

View File

@ -1,39 +0,0 @@
use std::os::raw::c_void;
use call::CCallback;
use raw::{Env, Local};
pub unsafe extern "C" fn get_class_map(_isolate: Env) -> *mut c_void { unimplemented!() }
pub unsafe extern "C" fn set_class_map(_isolate: Env, _map: *mut c_void, _free_map: *mut c_void) { unimplemented!() }
pub unsafe extern "C" fn create_base(_isolate: Env,
_allocate: CCallback,
_construct: CCallback,
_call: CCallback,
_drop: extern "C" fn(*mut c_void)) -> *mut c_void { unimplemented!() }
pub unsafe extern "C" fn get_name<'a>(_base_out: &'a mut *mut u8, _isolate: Env, _metadata: *const c_void) -> usize { unimplemented!() }
pub unsafe extern "C" fn set_name(_isolate: Env, _metadata: *mut c_void, _name: *const u8, _byte_length: u32) -> bool { unimplemented!() }
pub unsafe extern "C" fn throw_call_error(_isolate: Env, _metadata: *mut c_void) { unimplemented!() }
pub unsafe extern "C" fn throw_this_error(_isolate: Env, _metadata: *mut c_void) { unimplemented!() }
pub unsafe extern "C" fn add_method(_isolate: Env, _metadata: *mut c_void, _name: *const u8, _byte_length: u32, _method: Local) -> bool { unimplemented!() }
pub unsafe extern "C" fn metadata_to_constructor(_out: &mut Local, _isolate: Env, _metadata: *mut c_void) -> bool { unimplemented!() }
// FIXME: get rid of all the "kernel" nomenclature
pub unsafe extern "C" fn get_allocate_kernel(_obj: Local) -> *mut c_void { unimplemented!() }
pub unsafe extern "C" fn get_construct_kernel(_obj: Local) -> *mut c_void { unimplemented!() }
pub unsafe extern "C" fn get_call_kernel(_obj: Local) -> *mut c_void { unimplemented!() }
pub unsafe extern "C" fn constructor(_out: &mut Local, _ft: Local) -> bool { unimplemented!() }
pub unsafe extern "C" fn has_instance(_metadata: *mut c_void, _v: Local) -> bool { unimplemented!() }
pub unsafe extern "C" fn get_instance_internals(_obj: Local) -> *mut c_void { unimplemented!() }

View File

@ -1,11 +1,15 @@
use nodejs_sys as napi;
use crate::napi::bindings as napi;
use crate::raw::{Env, Local};
use raw::{Env, Local};
/// This API is currently unused, see https://github.com/neon-bindings/neon/issues/572
pub unsafe fn to_object(out: &mut Local, env: Env, value: Local) -> bool {
let status = napi::coerce_to_object(env, value, out as *mut _);
pub unsafe extern "C" fn to_object(_out: &mut Local, _value: &Local) -> bool { unimplemented!() }
pub unsafe extern "C" fn to_string(out: &mut Local, env: Env, value: Local) -> bool {
let status = napi::napi_coerce_to_string(env, value, out as *mut _);
status == napi::napi_status::napi_ok
status == napi::Status::Ok
}
pub unsafe fn to_string(out: &mut Local, env: Env, value: Local) -> bool {
let status = napi::coerce_to_string(env, value, out as *mut _);
status == napi::Status::Ok
}

View File

@ -0,0 +1,28 @@
use crate::napi::bindings as napi;
use crate::raw::{Env, Local};
use std::mem::MaybeUninit;
/// Create a new date object
///
/// # Safety
///
/// `env` is a raw pointer. Please ensure it points to a napi_env that is valid for the current context.
pub unsafe fn new_date(env: Env, value: f64) -> Local {
let mut local = MaybeUninit::zeroed();
let status = napi::create_date(env, value, local.as_mut_ptr());
assert_eq!(status, napi::Status::Ok);
local.assume_init()
}
/// Get the value of a date object
///
/// # Safety
///
/// `env` is a raw pointer. Please ensure it points to a napi_env that is valid for the current context.
/// `Local` must be an NAPI value associated with the given `Env`
pub unsafe fn value(env: Env, p: Local) -> f64 {
let mut value = 0.0;
let status = napi::get_date_value(env, p, &mut value as *mut _);
assert_eq!(status, napi::Status::Ok);
value
}

View File

@ -1,11 +1,90 @@
use raw::Local;
use std::mem::MaybeUninit;
use std::ptr;
pub unsafe extern "C" fn throw(_val: Local) { unimplemented!() }
use crate::napi::bindings as napi;
use crate::raw::{Env, Local};
pub unsafe extern "C" fn new_error(_out: &mut Local, _msg: Local) { unimplemented!() }
pub unsafe fn is_throwing(env: Env) -> bool {
let mut b: MaybeUninit<bool> = MaybeUninit::zeroed();
pub unsafe extern "C" fn new_type_error(_out: &mut Local, _msg: Local) { unimplemented!() }
let status = napi::is_exception_pending(env, b.as_mut_ptr());
pub unsafe extern "C" fn new_range_error(_out: &mut Local, _msg: Local) { unimplemented!() }
assert_eq!(status, napi::Status::Ok);
pub unsafe extern "C" fn throw_error_from_utf8(_msg: *const u8, _len: i32) { unimplemented!() }
b.assume_init()
}
pub unsafe fn catch_error(env: Env, error: *mut Local) -> bool {
if !is_throwing(env) {
return false;
}
let status = napi::get_and_clear_last_exception(env, error);
assert_eq!(status, napi::Status::Ok);
true
}
pub unsafe fn clear_exception(env: Env) {
let mut result = MaybeUninit::uninit();
let status = napi::is_exception_pending(env, result.as_mut_ptr());
assert_eq!(status, napi::Status::Ok);
if !result.assume_init() {
return;
}
let mut result = MaybeUninit::uninit();
let status = napi::get_and_clear_last_exception(env, result.as_mut_ptr());
assert_eq!(status, napi::Status::Ok);
}
pub unsafe fn throw(env: Env, val: Local) {
let status = napi::throw(env, val);
assert_eq!(status, napi::Status::Ok);
}
pub unsafe fn new_error(env: Env, out: &mut Local, msg: Local) {
let mut result = MaybeUninit::uninit();
let status = napi::create_error(env, ptr::null_mut(), msg, result.as_mut_ptr());
assert_eq!(status, napi::Status::Ok);
*out = result.assume_init();
}
pub unsafe fn new_type_error(env: Env, out: &mut Local, msg: Local) {
let mut result = MaybeUninit::uninit();
let status = napi::create_type_error(env, ptr::null_mut(), msg, result.as_mut_ptr());
assert_eq!(status, napi::Status::Ok);
*out = result.assume_init();
}
pub unsafe fn new_range_error(env: Env, out: &mut Local, msg: Local) {
let mut result = MaybeUninit::uninit();
let status = napi::create_range_error(env, ptr::null_mut(), msg, result.as_mut_ptr());
assert_eq!(status, napi::Status::Ok);
*out = result.assume_init();
}
pub unsafe fn throw_error_from_utf8(env: Env, msg: *const u8, len: i32) {
let mut out = MaybeUninit::uninit();
let status = napi::create_string_utf8(env, msg as *const _, len as usize, out.as_mut_ptr());
assert_eq!(status, napi::Status::Ok);
let mut err = MaybeUninit::uninit();
let status = napi::create_error(env, ptr::null_mut(), out.assume_init(), err.as_mut_ptr());
assert_eq!(status, napi::Status::Ok);
throw(env, err.assume_init());
}

View File

@ -0,0 +1,72 @@
use std::mem::MaybeUninit;
use crate::napi::bindings as napi;
use crate::raw::{Env, Local};
/// `finalize_external` is invoked immediately before a `napi_external` is garbage collected
extern "C" fn finalize_external<T: Send + 'static>(
env: Env,
// Raw pointer to a `Box<T>` stored by a `napi_external`
data: *mut std::ffi::c_void,
// Pointer to a Rust `fn` stored in the `hint` parameter of a `napi_external` called
// with the contents of `data` immediately before the value is garbage collected.
hint: *mut std::ffi::c_void,
) {
unsafe {
let data = Box::<T>::from_raw(data as *mut _);
let finalizer: fn(Env, T) = std::mem::transmute(hint as *const ());
finalizer(env, *data);
}
}
/// Returns a pointer to data stored in a `napi_external`
/// Safety: `deref` must only be called with `napi_external` created by that
/// module. Calling `deref` with an external created by another native module,
/// even another neon module, is undefined behavior.
/// https://github.com/neon-bindings/neon/issues/591
pub unsafe fn deref<T: Send + 'static>(env: Env, local: Local) -> Option<*const T> {
let mut result = MaybeUninit::uninit();
let status = napi::typeof_value(env, local, result.as_mut_ptr());
assert_eq!(status, napi::Status::Ok);
let result = result.assume_init();
// Note: This only validates it is an external, not that it was created by
// this module. In this future, this can be improved with type tagging:
// https://nodejs.org/api/n-api.html#n_api_napi_type_tag
// https://github.com/neon-bindings/neon/issues/591
if result != napi::ValueType::External {
return None;
}
let mut result = MaybeUninit::uninit();
let status = napi::get_value_external(env, local, result.as_mut_ptr());
assert_eq!(status, napi::Status::Ok);
Some(result.assume_init() as *const _)
}
/// Creates a `napi_external` from a Rust type
pub unsafe fn create<T: Send + 'static>(env: Env, v: T, finalizer: fn(Env, T)) -> Local {
let v = Box::new(v);
let mut result = MaybeUninit::uninit();
let status = napi::create_external(
env,
Box::into_raw(v) as *mut _,
Some(finalize_external::<T>),
// Casting to `*const ()` is required to ensure the correct layout
// https://rust-lang.github.io/unsafe-code-guidelines/layout/function-pointers.html
finalizer as *const () as *mut _,
result.as_mut_ptr(),
);
// `napi_create_external` will only fail if the VM is in a throwing state
// or shutting down.
assert_eq!(status, napi::Status::Ok);
result.assume_init()
}

View File

@ -1,13 +1,59 @@
//! Facilities for working with JS functions.
use std::os::raw::c_void;
use call::CCallback;
use raw::{Env, Local};
use std::ptr::null;
pub unsafe extern "C" fn new(_out: &mut Local, _env: Env, _callback: CCallback) -> bool { unimplemented!() }
use crate::call::CCallback;
use crate::napi::bindings as napi;
use crate::raw::{Env, Local};
pub unsafe extern "C" fn new_template(_out: &mut Local, _env: Env, _callback: CCallback) -> bool { unimplemented!() }
/// Mutates the `out` argument provided to refer to a newly created `v8::Function`. Returns
/// `false` if the value couldn't be created.
pub unsafe fn new(out: &mut Local, env: Env, callback: CCallback) -> bool {
let status = napi::create_function(
env,
null(),
0,
Some(std::mem::transmute(callback.static_callback)),
callback.dynamic_callback,
out as *mut Local,
);
pub unsafe extern "C" fn get_dynamic_callback(_obj: Local) -> *mut c_void { unimplemented!() }
status == napi::Status::Ok
}
pub unsafe extern "C" fn call(_out: &mut Local, _env: Env, _fun: Local, _this: Local, _argc: i32, _argv: *mut c_void) -> bool { unimplemented!() }
pub unsafe fn get_dynamic_callback(_env: Env, data: *mut c_void) -> *mut c_void {
data
}
pub unsafe extern "C" fn construct(_out: &mut Local, _env: Env, _fun: Local, _argc: i32, _argv: *mut c_void) -> bool { unimplemented!() }
pub unsafe fn call(
out: &mut Local,
env: Env,
fun: Local,
this: Local,
argc: i32,
argv: *mut c_void,
) -> bool {
let status = napi::call_function(
env,
this,
fun,
argc as usize,
argv as *const _,
out as *mut _,
);
status == napi::Status::Ok
}
pub unsafe fn construct(
out: &mut Local,
env: Env,
fun: Local,
argc: i32,
argv: *mut c_void,
) -> bool {
let status = napi::new_instance(env, fun, argc as usize, argv as *const _, out as *mut _);
status == napi::Status::Ok
}

View File

@ -1,7 +0,0 @@
use raw::Local;
use std::os::raw::c_void;
pub unsafe extern "C" fn new(_isolate: *mut c_void, _this: Local, _callback: Local) -> *mut c_void { unimplemented!() }
pub unsafe extern "C" fn schedule(_thread_safe_cb: *mut c_void, _rust_callback: *mut c_void,
_complete: unsafe extern fn(Local, Local, *mut c_void)) { unimplemented!() }
pub unsafe extern "C" fn delete(_thread_safe_cb: *mut c_void) { unimplemented!() }

View File

@ -0,0 +1,49 @@
//! # Environment life cycle APIs
//!
//! These APIs map to the life cycle of a specific "Agent" or self-contained
//! environment. If a Neon module is loaded multiple times (Web Workers, worker
//! threads), these API will be handle data associated with a specific instance.
//!
//! See the [N-API Lifecycle][npai-docs] documentation for more details.
//!
//! [napi-docs]: https://nodejs.org/api/n-api.html#n_api_environment_life_cycle_apis
use std::mem::MaybeUninit;
use std::os::raw::c_void;
use std::ptr;
use crate::napi::bindings as napi;
use crate::raw::Env;
/// # Safety
/// `env` must point to a valid `napi_env` for this thread
pub unsafe fn set_instance_data<T: Send + 'static>(env: Env, data: T) -> *mut T {
let data = Box::into_raw(Box::new(data));
assert_eq!(
napi::set_instance_data(env, data.cast(), Some(drop_box::<T>), ptr::null_mut(),),
napi::Status::Ok,
);
data
}
/// # Safety
/// * `T` must be the same type used in `set_instance_data`
/// * Caller must ensure reference does not outlive `Env`
/// * Return value may be `null`
/// * `env` must point to a valid `napi_env` for this thread
pub unsafe fn get_instance_data<T: Send + 'static>(env: Env) -> *mut T {
let mut data = MaybeUninit::uninit();
assert_eq!(
napi::get_instance_data(env, data.as_mut_ptr(),),
napi::Status::Ok,
);
data.assume_init().cast()
}
unsafe extern "C" fn drop_box<T>(_env: Env, data: *mut c_void, _hint: *mut c_void) {
Box::<T>::from_raw(data.cast());
}

View File

@ -1,3 +1,11 @@
use raw::Local;
use crate::napi::bindings as napi;
use crate::raw::{Env, Local};
pub unsafe extern "C" fn same_handle(_h1: Local, _h2: Local) -> bool { unimplemented!() }
pub unsafe fn strict_equals(env: Env, lhs: Local, rhs: Local) -> bool {
let mut result = false;
assert_eq!(
napi::strict_equals(env, lhs, rhs, &mut result as *mut _),
napi::Status::Ok
);
result
}

View File

@ -2,16 +2,24 @@ pub mod array;
pub mod arraybuffer;
pub mod buffer;
pub mod call;
pub mod class;
pub mod convert;
#[cfg(feature = "napi-5")]
pub mod date;
pub mod error;
pub mod external;
pub mod fun;
#[cfg(feature = "napi-6")]
pub mod lifecycle;
pub mod mem;
pub mod object;
pub mod primitive;
pub mod raw;
pub mod reference;
pub mod scope;
pub mod string;
pub mod tag;
pub mod task;
pub mod handler;
#[cfg(feature = "napi-4")]
pub mod tsfn;
mod bindings;
pub use bindings::*;

View File

@ -1,98 +1,41 @@
use std::mem::MaybeUninit;
use nodejs_sys as napi;
use array;
use convert;
use tag;
use raw::{Env, Local};
use crate::napi::bindings as napi;
use crate::raw::{Env, Local};
/// Mutates the `out` argument to refer to a `napi_value` containing a newly created JavaScript Object.
pub unsafe extern "C" fn new(out: &mut Local, env: Env) {
napi::napi_create_object(env, out as *mut _);
pub unsafe fn new(out: &mut Local, env: Env) {
napi::create_object(env, out as *mut _);
}
#[cfg(feature = "napi-6")]
/// Mutates the `out` argument to refer to a `napi_value` containing the own property names of the
/// `object` as a JavaScript Array.
pub unsafe extern "C" fn get_own_property_names(out: &mut Local, env: Env, object: Local) -> bool {
// Node.js 13+ have `napi_get_all_property_names`, which does the conversion right and allows
// us to ask for only own properties or prototype properties or anything we like.
// Unfortunately, earlier versions do not support that method, so we have to implement it
// manually.
//
// So we use a temporary array for the raw names:
let mut raw_names = MaybeUninit::uninit();
if napi::napi_get_property_names(env, object, raw_names.as_mut_ptr()) != napi::napi_status::napi_ok {
return false;
}
// And a "fixed" array for the actual return value:
let mut fixed_names = MaybeUninit::uninit();
if napi::napi_create_array(env, fixed_names.as_mut_ptr()) != napi::napi_status::napi_ok {
pub unsafe fn get_own_property_names(out: &mut Local, env: Env, object: Local) -> bool {
let mut property_names = MaybeUninit::uninit();
if napi::get_all_property_names(
env,
object,
napi::KeyCollectionMode::OwnOnly,
napi::KeyFilter::ALL_PROPERTIES | napi::KeyFilter::SKIP_SYMBOLS,
napi::KeyConversion::NumbersToStrings,
property_names.as_mut_ptr(),
) != napi::Status::Ok
{
return false;
}
let raw_names = raw_names.assume_init();
let fixed_names = fixed_names.assume_init();
*out = fixed_names;
let raw_len = array::len(env, raw_names);
let mut fixed_len = 0;
for index in 0..raw_len {
let mut property_name: Local = std::mem::zeroed();
// In general, getters may cause arbitrary JS code to be run, but this is a newly created
// Array from an official internal API so it doesn't do anything strange.
if !get_index(&mut property_name, env, raw_names, index) {
continue;
}
// Before https://github.com/nodejs/node/pull/27524, `napi_get_property_names` would return
// numbers for numeric indices instead of strings.
// Make sure we always return strings.
let property_name = if !tag::is_string(env, property_name) {
let mut stringified: Local = std::mem::zeroed();
// If we can't convert to a string, something went wrong.
if !convert::to_string(&mut stringified, env, property_name) {
return false;
}
stringified
} else {
property_name
};
let mut is_own_property = false;
// May return a non-OK status if `key` is not a string or a Symbol, but here it is always
// a string.
if napi::napi_has_own_property(env, object, property_name, &mut is_own_property as *mut _) != napi::napi_status::napi_ok {
return false;
}
if !is_own_property {
continue;
}
let mut dummy = false;
// If we can't convert assign to this array, something went wrong.
if !set_index(&mut dummy, env, fixed_names, fixed_len, property_name) {
return false;
}
fixed_len += 1;
}
*out = property_names.assume_init();
true
}
// Unused.
pub unsafe extern "C" fn get_isolate(_obj: Local) -> Env {
unimplemented!()
}
/// Mutate the `out` argument to refer to the value at `index` in the given `object`. Returns `false` if the value couldn't be retrieved.
pub unsafe extern "C" fn get_index(out: &mut Local, env: Env, object: Local, index: u32) -> bool {
let status = napi::napi_get_element(env, object, index, out as *mut _);
pub unsafe fn get_index(out: &mut Local, env: Env, object: Local, index: u32) -> bool {
let status = napi::get_element(env, object, index, out as *mut _);
status == napi::napi_status::napi_ok
status == napi::Status::Ok
}
/// Sets the key value of a `napi_value` at the `index` provided. Returns `true` if the set
@ -102,29 +45,33 @@ pub unsafe extern "C" fn get_index(out: &mut Local, env: Env, object: Local, ind
/// see [discussion].
///
/// [discussion]: https://github.com/neon-bindings/neon/pull/458#discussion_r344827965
pub unsafe extern "C" fn set_index(out: &mut bool, env: Env, object: Local, index: u32, val: Local) -> bool {
let status = napi::napi_set_element(env, object, index, val);
*out = status == napi::napi_status::napi_ok;
pub unsafe fn set_index(out: &mut bool, env: Env, object: Local, index: u32, val: Local) -> bool {
let status = napi::set_element(env, object, index, val);
*out = status == napi::Status::Ok;
*out
}
/// Mutate the `out` argument to refer to the value at a named `key` in the given `object`. Returns `false` if the value couldn't be retrieved.
pub unsafe extern "C" fn get_string(env: Env, out: &mut Local, object: Local, key: *const u8, len: i32) -> bool {
pub unsafe fn get_string(
env: Env,
out: &mut Local,
object: Local,
key: *const u8,
len: i32,
) -> bool {
let mut key_val = MaybeUninit::uninit();
// Not using `crate::string::new()` because it requires a _reference_ to a Local,
// while we only have uninitialized memory.
if napi::napi_create_string_utf8(env, key as *const i8, len as usize, key_val.as_mut_ptr())
!= napi::napi_status::napi_ok
if napi::create_string_utf8(env, key as *const _, len as usize, key_val.as_mut_ptr())
!= napi::Status::Ok
{
return false;
}
// Not using napi_get_named_property() because the `key` may not be null terminated.
if napi::napi_get_property(env, object, key_val.assume_init(), out as *mut _)
!= napi::napi_status::napi_ok
{
if napi::get_property(env, object, key_val.assume_init(), out as *mut _) != napi::Status::Ok {
return false;
}
@ -137,21 +84,26 @@ pub unsafe extern "C" fn get_string(env: Env, out: &mut Local, object: Local, ke
/// see [discussion].
///
/// [discussion]: https://github.com/neon-bindings/neon/pull/458#discussion_r344827965
pub unsafe extern "C" fn set_string(env: Env, out: &mut bool, object: Local, key: *const u8, len: i32, val: Local) -> bool {
pub unsafe fn set_string(
env: Env,
out: &mut bool,
object: Local,
key: *const u8,
len: i32,
val: Local,
) -> bool {
let mut key_val = MaybeUninit::uninit();
*out = true;
if napi::napi_create_string_utf8(env, key as *const i8, len as usize, key_val.as_mut_ptr())
!= napi::napi_status::napi_ok
if napi::create_string_utf8(env, key as *const _, len as usize, key_val.as_mut_ptr())
!= napi::Status::Ok
{
*out = false;
return false;
}
if napi::napi_set_property(env, object, key_val.assume_init(), val)
!= napi::napi_status::napi_ok
{
if napi::set_property(env, object, key_val.assume_init(), val) != napi::Status::Ok {
*out = false;
return false;
}
@ -161,21 +113,21 @@ pub unsafe extern "C" fn set_string(env: Env, out: &mut bool, object: Local, key
/// Mutates `out` to refer to the value of the property of `object` named by the `key` value.
/// Returns false if the value couldn't be retrieved.
pub unsafe extern "C" fn get(out: &mut Local, env: Env, object: Local, key: Local) -> bool {
let status = napi::napi_get_property(env, object, key, out as *mut _);
pub unsafe fn get(out: &mut Local, env: Env, object: Local, key: Local) -> bool {
let status = napi::get_property(env, object, key, out as *mut _);
status == napi::napi_status::napi_ok
status == napi::Status::Ok
}
/// Sets the property value of an `napi_value` object, named by another `napi_value` `key`. Returns `true` if the set succeeded.
/// Sets the property value of an `napi_value` object, named by another `value` `key`. Returns `true` if the set succeeded.
///
/// The `out` parameter and the return value contain the same information for historical reasons,
/// see [discussion].
///
/// [discussion]: https://github.com/neon-bindings/neon/pull/458#discussion_r344827965
pub unsafe extern "C" fn set(out: &mut bool, env: Env, object: Local, key: Local, val: Local) -> bool {
let status = napi::napi_set_property(env, object, key, val);
*out = status == napi::napi_status::napi_ok;
pub unsafe fn set(out: &mut bool, env: Env, object: Local, key: Local, val: Local) -> bool {
let status = napi::set_property(env, object, key, val);
*out = status == napi::Status::Ok;
*out
}

View File

@ -1,50 +1,45 @@
use raw::{Local, Env};
use nodejs_sys as napi;
use crate::napi::bindings as napi;
use crate::raw::{Env, Local};
/// Mutates the `out` argument provided to refer to the global `undefined` object.
pub unsafe extern "C" fn undefined(out: &mut Local, env: Env) {
napi::napi_get_undefined(env, out as *mut Local);
pub unsafe fn undefined(out: &mut Local, env: Env) {
napi::get_undefined(env, out as *mut Local);
}
/// Mutates the `out` argument provided to refer to the global `null` object.
pub unsafe extern "C" fn null(out: &mut Local, env: Env) {
napi::napi_get_null(env, out as *mut Local);
pub unsafe fn null(out: &mut Local, env: Env) {
napi::get_null(env, out as *mut Local);
}
/// Mutates the `out` argument provided to refer to one of the global `true` or `false` objects.
pub unsafe extern "C" fn boolean(out: &mut Local, env: Env, b: bool) {
napi::napi_get_boolean(env, b, out as *mut Local);
pub unsafe fn boolean(out: &mut Local, env: Env, b: bool) {
napi::get_boolean(env, b, out as *mut Local);
}
/// Get the boolean value out of a `Local` object. If the `Local` object does not contain a
/// boolean, this function panics.
pub unsafe extern "C" fn boolean_value(env: Env, p: Local) -> bool {
pub unsafe fn boolean_value(env: Env, p: Local) -> bool {
let mut value = false;
assert_eq!(napi::napi_get_value_bool(env, p, &mut value as *mut bool), napi::napi_status::napi_ok);
assert_eq!(
napi::get_value_bool(env, p, &mut value as *mut bool),
napi::Status::Ok
);
value
}
// DEPRECATE(0.2)
pub unsafe extern "C" fn integer(_out: &mut Local, _isolate: Env, _x: i32) { unimplemented!() }
pub unsafe extern "C" fn is_u32(_p: Local) -> bool { unimplemented!() }
pub unsafe extern "C" fn is_i32(_p: Local) -> bool { unimplemented!() }
// DEPRECATE(0.2)
pub unsafe extern "C" fn integer_value(_p: Local) -> i64 { unimplemented!() }
/// Mutates the `out` argument provided to refer to a newly created `Local` containing a
/// JavaScript number.
pub unsafe extern "C" fn number(out: &mut Local, env: Env, v: f64) {
napi::napi_create_double(env, v, out as *mut Local);
pub unsafe fn number(out: &mut Local, env: Env, v: f64) {
napi::create_double(env, v, out as *mut Local);
}
/// Gets the underlying value of an `Local` object containing a JavaScript number. Panics if
/// the given `Local` is not a number.
pub unsafe extern "C" fn number_value(env: Env, p: Local) -> f64 {
pub unsafe fn number_value(env: Env, p: Local) -> f64 {
let mut value = 0.0;
assert_eq!(napi::napi_get_value_double(env, p, &mut value as *mut f64), napi::napi_status::napi_ok);
return value;
assert_eq!(
napi::get_value_double(env, p, &mut value as *mut f64),
napi::Status::Ok
);
value
}

View File

@ -1,32 +1,51 @@
use std::os::raw::c_void;
use std::ptr;
use nodejs_sys as napi;
use crate::napi::bindings as napi;
pub type Local = napi::napi_value;
pub type Local = napi::Value;
pub type FunctionCallbackInfo = c_void;
pub type FunctionCallbackInfo = napi::CallbackInfo;
pub type Env = napi::napi_env;
pub type Env = napi::Env;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct HandleScope {
pub word: napi::napi_handle_scope
pub word: napi::HandleScope,
}
impl HandleScope {
pub fn new() -> Self { Self { word: ptr::null_mut() } }
pub fn new() -> Self {
Self {
word: ptr::null_mut(),
}
}
}
impl Default for HandleScope {
fn default() -> Self {
Self::new()
}
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct EscapableHandleScope {
pub word: napi::napi_escapable_handle_scope
pub word: napi::EscapableHandleScope,
}
impl EscapableHandleScope {
pub fn new() -> Self { Self { word: ptr::null_mut() } }
pub fn new() -> Self {
Self {
word: ptr::null_mut(),
}
}
}
impl Default for EscapableHandleScope {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone, Copy)]

View File

@ -0,0 +1,49 @@
use std::mem::MaybeUninit;
use crate::napi::bindings as napi;
use crate::raw::{Env, Local};
pub unsafe fn new(env: Env, value: Local) -> napi::Ref {
let mut result = MaybeUninit::uninit();
assert_eq!(
napi::create_reference(env, value, 1, result.as_mut_ptr()),
napi::Status::Ok,
);
result.assume_init()
}
pub unsafe fn reference(env: Env, value: napi::Ref) -> usize {
let mut result = MaybeUninit::uninit();
assert_eq!(
napi::reference_ref(env, value, result.as_mut_ptr()),
napi::Status::Ok,
);
result.assume_init() as usize
}
pub unsafe fn unreference(env: Env, value: napi::Ref) -> usize {
let mut result = MaybeUninit::uninit();
assert_eq!(
napi::reference_unref(env, value, result.as_mut_ptr()),
napi::Status::Ok,
);
result.assume_init() as usize
}
pub unsafe fn get(env: Env, value: napi::Ref) -> Local {
let mut result = MaybeUninit::uninit();
assert_eq!(
napi::get_reference_value(env, value, result.as_mut_ptr()),
napi::Status::Ok,
);
result.assume_init()
}

View File

@ -1,72 +1,71 @@
use std::os::raw::c_void;
use std::mem::MaybeUninit;
use nodejs_sys as napi;
use raw::{Env, HandleScope, EscapableHandleScope, InheritedHandleScope};
type Local = napi::napi_value;
use crate::napi::bindings as napi;
use crate::raw::{Env, EscapableHandleScope, HandleScope, InheritedHandleScope, Local};
// TODO: This leaves a lot of room for UB; we can have a cleaner
// implementation for N-API.
pub trait Root {
unsafe fn allocate() -> Self;
unsafe fn enter(&mut self, Env);
unsafe fn exit(&mut self, Env);
unsafe fn enter(&mut self, env: Env);
unsafe fn exit(&mut self, env: Env);
}
impl Root for HandleScope {
unsafe fn allocate() -> Self { HandleScope::new() }
unsafe fn allocate() -> Self {
HandleScope::new()
}
unsafe fn enter(&mut self, env: Env) {
let mut scope = MaybeUninit::uninit();
let status = napi::napi_open_handle_scope(env, scope.as_mut_ptr());
let status = napi::open_handle_scope(env, scope.as_mut_ptr());
assert_eq!(status, napi::napi_status::napi_ok);
assert_eq!(status, napi::Status::Ok);
self.word = scope.assume_init();
}
unsafe fn exit(&mut self, env: Env) {
let status = napi::napi_close_handle_scope(env, self.word);
let status = napi::close_handle_scope(env, self.word);
assert_eq!(status, napi::napi_status::napi_ok);
assert_eq!(status, napi::Status::Ok);
}
}
impl Root for EscapableHandleScope {
unsafe fn allocate() -> Self { EscapableHandleScope::new() }
unsafe fn allocate() -> Self {
EscapableHandleScope::new()
}
unsafe fn enter(&mut self, env: Env) {
let mut scope = MaybeUninit::uninit();
let status = napi::napi_open_escapable_handle_scope(env, scope.as_mut_ptr());
let status = napi::open_escapable_handle_scope(env, scope.as_mut_ptr());
assert_eq!(status, napi::napi_status::napi_ok);
assert_eq!(status, napi::Status::Ok);
self.word = scope.assume_init();
}
unsafe fn exit(&mut self, env: Env) {
let status = napi::napi_close_escapable_handle_scope(env, self.word);
let status = napi::close_escapable_handle_scope(env, self.word);
assert_eq!(status, napi::napi_status::napi_ok);
assert_eq!(status, napi::Status::Ok);
}
}
impl Root for InheritedHandleScope {
unsafe fn allocate() -> Self { InheritedHandleScope }
unsafe fn enter(&mut self, _: Env) { }
unsafe fn exit(&mut self, _: Env) { }
unsafe fn allocate() -> Self {
InheritedHandleScope
}
unsafe fn enter(&mut self, _: Env) {}
unsafe fn exit(&mut self, _: Env) {}
}
pub unsafe extern "C" fn escape(_out: &mut Local, _scope: *mut EscapableHandleScope, _value: Local) { unimplemented!() }
pub unsafe fn escape(env: Env, out: &mut Local, scope: *mut EscapableHandleScope, value: Local) {
let status = napi::escape_handle(env, (*scope).word, value, out as *mut _);
pub unsafe extern "C" fn chained(_out: *mut c_void, _closure: *mut c_void, _callback: extern fn(&mut c_void, *mut c_void, *mut c_void, *mut c_void), _parent_scope: *mut c_void) { unimplemented!() }
assert_eq!(status, napi::Status::Ok);
}
pub unsafe extern "C" fn nested(_out: *mut c_void, _closure: *mut c_void, _callback: extern fn(&mut c_void, *mut c_void, *mut c_void), _realm: *mut c_void) { unimplemented!() }
pub unsafe extern "C" fn size() -> usize { unimplemented!() }
pub unsafe extern "C" fn alignment() -> usize { unimplemented!() }
pub unsafe extern "C" fn escapable_size() -> usize { unimplemented!() }
pub unsafe extern "C" fn escapable_alignment() -> usize { unimplemented!() }
pub unsafe extern "C" fn get_global(_env: Env, _out: &mut Local) { unimplemented!() }
pub unsafe fn get_global(env: Env, out: &mut Local) {
assert_eq!(
crate::napi::bindings::get_global(env, out as *mut _),
napi::Status::Ok
);
}

View File

@ -1,47 +1,36 @@
use std::mem::MaybeUninit;
use std::ptr;
use nodejs_sys as napi;
use raw::{Env, Local};
use crate::napi::bindings as napi;
use crate::raw::{Env, Local};
pub unsafe fn new(out: &mut Local, env: Env, data: *const u8, len: i32) -> bool {
let status = napi::napi_create_string_utf8(
env,
data as *const i8,
len as usize,
out,
);
let status = napi::create_string_utf8(env, data as *const _, len as usize, out);
status == napi::napi_status::napi_ok
status == napi::Status::Ok
}
pub unsafe extern "C" fn utf8_len(env: Env, value: Local) -> isize {
pub unsafe fn utf8_len(env: Env, value: Local) -> isize {
let mut len = MaybeUninit::uninit();
let status = napi::napi_get_value_string_utf8(
env,
value,
ptr::null_mut(),
0,
len.as_mut_ptr(),
);
let status = napi::get_value_string_utf8(env, value, ptr::null_mut(), 0, len.as_mut_ptr());
assert_eq!(status, napi::napi_status::napi_ok);
assert_eq!(status, napi::Status::Ok);
len.assume_init() as isize
}
pub unsafe extern "C" fn data(env: Env, out: *mut u8, len: isize, value: Local) -> isize {
pub unsafe fn data(env: Env, out: *mut u8, len: isize, value: Local) -> isize {
let mut read = MaybeUninit::uninit();
let status = napi::napi_get_value_string_utf8(
env,
value,
out as *mut i8,
len as usize,
read.as_mut_ptr(),
);
let status =
napi::get_value_string_utf8(env, value, out as *mut _, len as usize, read.as_mut_ptr());
assert_eq!(status, napi::napi_status::napi_ok);
assert_eq!(status, napi::Status::Ok);
read.assume_init() as isize
}
pub unsafe fn run_script(out: &mut Local, env: Env, value: Local) -> bool {
let status = napi::run_script(env, value, out as *mut _);
status == napi::Status::Ok
}

View File

@ -1,44 +1,91 @@
use raw::{Env, Local};
use nodejs_sys as napi;
use crate::napi::bindings as napi;
use crate::raw::{Env, Local};
/// Return true if an `napi_value` `val` has the expected value type.
unsafe fn is_type(env: Env, val: Local, expect: napi::napi_valuetype) -> bool {
let mut actual = napi::napi_valuetype::napi_undefined;
if napi::napi_typeof(env, val, &mut actual as *mut _) == napi::napi_status::napi_ok {
actual == expect
} else {
false
}
unsafe fn is_type(env: Env, val: Local, expect: napi::ValueType) -> bool {
let mut actual = napi::ValueType::Undefined;
assert_eq!(
napi::typeof_value(env, val, &mut actual as *mut _),
napi::Status::Ok
);
actual == expect
}
pub unsafe extern "C" fn is_undefined(_env: Env, _val: Local) -> bool { unimplemented!() }
pub unsafe fn is_undefined(env: Env, val: Local) -> bool {
is_type(env, val, napi::ValueType::Undefined)
}
pub unsafe extern "C" fn is_null(_env: Env, _val: Local) -> bool { unimplemented!() }
pub unsafe fn is_null(env: Env, val: Local) -> bool {
is_type(env, val, napi::ValueType::Null)
}
/// Is `val` a JavaScript number?
pub unsafe extern "C" fn is_number(env: Env, val: Local) -> bool {
is_type(env, val, napi::napi_valuetype::napi_number)
pub unsafe fn is_number(env: Env, val: Local) -> bool {
is_type(env, val, napi::ValueType::Number)
}
/// Is `val` a JavaScript boolean?
pub unsafe extern "C" fn is_boolean(env: Env, val: Local) -> bool {
is_type(env, val, napi::napi_valuetype::napi_boolean)
pub unsafe fn is_boolean(env: Env, val: Local) -> bool {
is_type(env, val, napi::ValueType::Boolean)
}
/// Is `val` a JavaScript string?
pub unsafe extern "C" fn is_string(env: Env, val: Local) -> bool {
is_type(env, val, napi::napi_valuetype::napi_string)
pub unsafe fn is_string(env: Env, val: Local) -> bool {
is_type(env, val, napi::ValueType::String)
}
pub unsafe extern "C" fn is_object(_env: Env, _val: Local) -> bool { unimplemented!() }
pub unsafe fn is_object(env: Env, val: Local) -> bool {
is_type(env, val, napi::ValueType::Object)
}
pub unsafe extern "C" fn is_array(_env: Env, _val: Local) -> bool { unimplemented!() }
pub unsafe fn is_array(env: Env, val: Local) -> bool {
let mut result = false;
assert_eq!(
napi::is_array(env, val, &mut result as *mut _),
napi::Status::Ok
);
result
}
pub unsafe extern "C" fn is_function(_env: Env, _val: Local) -> bool { unimplemented!() }
pub unsafe fn is_function(env: Env, val: Local) -> bool {
is_type(env, val, napi::ValueType::Function)
}
pub unsafe extern "C" fn is_error(_env: Env, _val: Local) -> bool { unimplemented!() }
pub unsafe fn is_error(env: Env, val: Local) -> bool {
let mut result = false;
assert_eq!(
napi::is_error(env, val, &mut result as *mut _),
napi::Status::Ok
);
result
}
pub unsafe extern "C" fn is_buffer(_env: Env, _obj: Local) -> bool { unimplemented!() }
/// Is `val` a Node.js Buffer instance?
pub unsafe fn is_buffer(env: Env, val: Local) -> bool {
let mut result = false;
assert_eq!(
napi::is_buffer(env, val, &mut result as *mut _),
napi::Status::Ok
);
result
}
pub unsafe extern "C" fn is_arraybuffer(_env: Env, _obj: Local) -> bool { unimplemented!() }
/// Is `val` an ArrayBuffer instance?
pub unsafe fn is_arraybuffer(env: Env, val: Local) -> bool {
let mut result = false;
assert_eq!(
napi::is_arraybuffer(env, val, &mut result as *mut _),
napi::Status::Ok
);
result
}
#[cfg(feature = "napi-5")]
pub unsafe fn is_date(env: Env, val: Local) -> bool {
let mut result = false;
assert_eq!(
napi::is_date(env, val, &mut result as *mut _),
napi::Status::Ok
);
result
}

View File

@ -1,7 +0,0 @@
use raw::Local;
use std::os::raw::c_void;
pub unsafe extern "C" fn schedule(_task: *mut c_void,
_perform: unsafe extern fn(*mut c_void) -> *mut c_void,
_complete: unsafe extern fn(*mut c_void, *mut c_void, &mut Local),
_callback: Local) { unimplemented!() }

View File

@ -0,0 +1,177 @@
//! Idiomatic Rust wrappers for N-API threadsafe functions
use std::ffi::c_void;
use std::mem::MaybeUninit;
use crate::napi::bindings as napi;
use crate::raw::{Env, Local};
unsafe fn string(env: Env, s: impl AsRef<str>) -> Local {
let s = s.as_ref();
let mut result = MaybeUninit::uninit();
assert_eq!(
napi::create_string_utf8(
env,
s.as_bytes().as_ptr() as *const _,
s.len(),
result.as_mut_ptr(),
),
napi::Status::Ok,
);
result.assume_init()
}
#[derive(Debug)]
struct Tsfn(napi::ThreadsafeFunction);
unsafe impl Send for Tsfn {}
unsafe impl Sync for Tsfn {}
#[derive(Debug)]
/// Threadsafe Function encapsulate a Rust function pointer and N-API threadsafe
/// function for scheduling tasks to execute on a JavaScript thread.
pub struct ThreadsafeFunction<T> {
tsfn: Tsfn,
callback: fn(Option<Env>, T),
}
#[derive(Debug)]
struct Callback<T> {
callback: fn(Option<Env>, T),
data: T,
}
/// Error returned when scheduling a threadsafe function with some data
pub struct CallError<T> {
kind: napi::Status,
data: T,
}
impl<T> CallError<T> {
/// The specific error that occurred
pub fn kind(&self) -> napi::Status {
self.kind
}
/// Returns the data that was sent when scheduling to allow re-scheduling
pub fn into_inner(self) -> T {
self.data
}
}
impl<T: Send + 'static> ThreadsafeFunction<T> {
/// Creates a new unbounded N-API Threadsafe Function
/// Safety: `Env` must be valid for the current thread
pub unsafe fn new(env: Env, callback: fn(Option<Env>, T)) -> Self {
Self::with_capacity(env, 0, callback)
}
/// Creates a bounded N-API Threadsafe Function
/// Safety: `Env` must be valid for the current thread
pub unsafe fn with_capacity(
env: Env,
max_queue_size: usize,
callback: fn(Option<Env>, T),
) -> Self {
let mut result = MaybeUninit::uninit();
assert_eq!(
napi::create_threadsafe_function(
env,
std::ptr::null_mut(),
std::ptr::null_mut(),
string(env, "neon threadsafe function"),
max_queue_size,
// Always set the reference count to 1. Prefer using
// Rust `Arc` to maintain the struct.
1,
std::ptr::null_mut(),
None,
std::ptr::null_mut(),
Some(Self::callback),
result.as_mut_ptr(),
),
napi::Status::Ok,
);
Self {
tsfn: Tsfn(result.assume_init()),
callback,
}
}
/// Schedule a threadsafe function to be executed with some data
pub fn call(
&self,
data: T,
is_blocking: Option<napi::ThreadsafeFunctionCallMode>,
) -> Result<(), CallError<T>> {
let is_blocking = is_blocking.unwrap_or(napi::ThreadsafeFunctionCallMode::Blocking);
let callback = Box::into_raw(Box::new(Callback {
callback: self.callback,
data,
}));
let status =
unsafe { napi::call_threadsafe_function(self.tsfn.0, callback as *mut _, is_blocking) };
if status == napi::Status::Ok {
Ok(())
} else {
// If the call failed, the callback won't execute
let callback = unsafe { Box::from_raw(callback) };
Err(CallError {
kind: status,
data: callback.data,
})
}
}
/// References a threadsafe function to prevent exiting the event loop until it has been dropped. (Default)
/// Safety: `Env` must be valid for the current thread
pub unsafe fn reference(&mut self, env: Env) {
assert_eq!(
napi::ref_threadsafe_function(env, self.tsfn.0,),
napi::Status::Ok,
);
}
/// Unreferences a threadsafe function to allow exiting the event loop before it has been dropped.
/// Safety: `Env` must be valid for the current thread
pub unsafe fn unref(&mut self, env: Env) {
assert_eq!(
napi::unref_threadsafe_function(env, self.tsfn.0,),
napi::Status::Ok,
);
}
// Provides a C ABI wrapper for invoking the user supplied function pointer
unsafe extern "C" fn callback(
env: Env,
_js_callback: napi::Value,
_context: *mut c_void,
data: *mut c_void,
) {
let Callback { callback, data } = *Box::from_raw(data as *mut Callback<T>);
// Event loop has terminated
let env = if env.is_null() { None } else { Some(env) };
callback(env, data);
}
}
impl<T> Drop for ThreadsafeFunction<T> {
fn drop(&mut self) {
unsafe {
napi::release_threadsafe_function(
self.tsfn.0,
napi::ThreadsafeFunctionReleaseMode::Release,
);
};
}
}

View File

@ -1,6 +1,6 @@
[package]
name = "neon-sys"
version = "0.4.0"
version = "0.8.2"
authors = ["David Herman <david.herman@gmail.com>"]
description = "Exposes the low-level V8/NAN C/C++ APIs. Will be superseded by N-API."
edition = "2018"

View File

@ -12,11 +12,11 @@ mod build {
#[cfg(not(feature = "docs-only"))]
mod build {
use std::process::Command;
use regex::Regex;
use std::env;
use std::fs;
use std::path::Path;
use regex::Regex;
use std::process::Command;
pub fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
@ -94,7 +94,8 @@ mod build {
//
// gyp verb architecture ia32
fn parse_node_arch(node_gyp_output: &str) -> String {
let version_regex = Regex::new(r"gyp verb architecture (?P<arch>ia32|x64)").unwrap();
let version_regex =
Regex::new(r"gyp verb architecture (?P<arch>ia32|x64|arm|arm64)").unwrap();
let captures = version_regex.captures(&node_gyp_output).unwrap();
String::from(&captures["arch"])
}
@ -109,7 +110,10 @@ mod build {
.find(node_root_dir_flag_pattern)
.map(|i| i + node_root_dir_flag_pattern.len())
.expect("Couldn't find node_root_dir in node-gyp output.");
let node_root_dir_end_index = node_gyp_output[node_root_dir_start_index..].find("'").unwrap() + node_root_dir_start_index;
let node_root_dir_end_index = node_gyp_output[node_root_dir_start_index..]
.find('\'')
.unwrap()
+ node_root_dir_start_index;
&node_gyp_output[node_root_dir_start_index..node_root_dir_end_index]
}
@ -131,7 +135,10 @@ mod build {
.find(node_lib_file_flag_pattern)
.map(|i| i + node_lib_file_flag_pattern.len())
.expect("Couldn't find node_lib_file in node-gyp output.");
let node_lib_file_end_index = node_gyp_output[node_lib_file_start_index..].find("'").unwrap() + node_lib_file_start_index;
let node_lib_file_end_index = node_gyp_output[node_lib_file_start_index..]
.find('\'')
.unwrap()
+ node_lib_file_start_index;
&node_gyp_output[node_lib_file_start_index..node_lib_file_end_index]
}
@ -147,37 +154,70 @@ mod build {
}
// Ensure that all package.json dependencies and dev dependencies are installed.
npm(native_dir).args(&["install", "--silent"]).status().ok().expect("Failed to run \"npm install\" for neon-sys!");
npm(native_dir)
.args(&["install", "--silent"])
.status()
.expect("Failed to run \"npm install\" for neon-sys!");
// Run `node-gyp configure` in verbose mode to read node_root_dir on Windows.
let output = npm(native_dir)
.args(&["run", if debug() { "configure-debug" } else { "configure-release" }])
.args(&[
"run",
if debug() {
"configure-debug"
} else {
"configure-release"
},
])
.output()
.expect("Failed to run \"node-gyp configure\" for neon-sys!");
if !output.status.success() {
panic!(format!(
panic!(
"Failed to run \"node-gyp configure\" for neon-sys!\n Out: {}\n Err: {}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
));
);
}
if cfg!(windows) {
let node_gyp_output = String::from_utf8_lossy(&output.stderr);
println!("cargo:node_root_dir={}", parse_node_root_dir(&node_gyp_output));
println!("cargo:node_lib_file={}", parse_node_lib_file(&node_gyp_output));
println!(
"cargo:node_root_dir={}",
parse_node_root_dir(&node_gyp_output)
);
println!(
"cargo:node_lib_file={}",
parse_node_lib_file(&node_gyp_output)
);
}
// Run `node-gyp build`.
let build_output = npm(native_dir)
.args(&["run", if debug() { "build-debug" } else { "build-release" }])
.args(&[
"run",
if debug() {
"build-debug"
} else {
"build-release"
},
])
.output()
.ok()
.expect("Failed to run \"node-gyp build\" for neon-sys!");
if !build_output.status.success() {
panic!(
"Failed to run \"node-gyp build\" for neon-sys!\n Out: {}\n Err: {}",
String::from_utf8_lossy(&build_output.stdout),
String::from_utf8_lossy(&build_output.stderr)
);
}
let node_gyp_build_output = String::from_utf8_lossy(&build_output.stderr);
println!("cargo:node_arch={}", parse_node_arch(&node_gyp_build_output));
println!(
"cargo:node_arch={}",
parse_node_arch(&node_gyp_build_output)
);
}
// Link the built object file into a static library.
@ -193,15 +233,23 @@ mod build {
.join("src")
.join("neon.o")
} else {
native_dir
let neon_dir = native_dir
.join("build")
.join(configuration)
.join("obj")
.join("neon")
.join("neon.obj")
.join("neon");
let object_path = neon_dir.join("src").join("neon.obj");
if object_path.exists() {
object_path
} else {
neon_dir.join("neon.obj")
}
};
cc::Build::new().cpp(true).object(object_path).compile("libneon.a");
cc::Build::new()
.cpp(true)
.object(object_path)
.compile("libneon.a");
}
#[cfg(unix)]
@ -232,7 +280,7 @@ mod build {
fn debug() -> bool {
match env::var("DEBUG") {
Ok(s) => s == "true",
Err(_) => false
Err(_) => false,
}
}
}

View File

@ -8,14 +8,14 @@
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
},
"ajv": {
"version": "5.5.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
"integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"requires": {
"co": "^4.6.0",
"fast-deep-equal": "^1.0.0",
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.3.0"
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"ansi-regex": {
@ -29,18 +29,21 @@
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
},
"are-we-there-yet": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
"integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
"integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
"requires": {
"delegates": "^1.0.0",
"readable-stream": "^2.0.6"
}
},
"asn1": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
"integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
"requires": {
"safer-buffer": "~2.1.0"
}
},
"assert-plus": {
"version": "1.0.0",
@ -58,9 +61,9 @@
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
},
"aws4": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
"integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w=="
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
},
"balanced-match": {
"version": "1.0.0",
@ -68,10 +71,9 @@
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"bcrypt-pbkdf": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
"integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
"optional": true,
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
"requires": {
"tweetnacl": "^0.14.3"
}
@ -81,18 +83,10 @@
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz",
"integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE="
},
"block-stream": {
"version": "0.0.9",
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
"integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
"requires": {
"inherits": "~2.0.0"
}
},
"brace-expansion": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
"integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -103,10 +97,10 @@
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
"chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
},
"code-point-at": {
"version": "1.1.0",
@ -114,9 +108,9 @@
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
},
"combined-stream": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
"integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"requires": {
"delayed-stream": "~1.0.0"
}
@ -155,14 +149,19 @@
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
},
"ecc-jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
"integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
"optional": true,
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
"requires": {
"jsbn": "~0.1.0"
"jsbn": "~0.1.0",
"safer-buffer": "^2.1.0"
}
},
"env-paths": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz",
"integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA=="
},
"extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@ -174,14 +173,14 @@
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
},
"fast-deep-equal": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
"integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ="
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"fast-json-stable-stringify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
},
"forever-agent": {
"version": "0.6.1",
@ -189,31 +188,28 @@
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
},
"form-data": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
"integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "1.0.6",
"combined-stream": "^1.0.6",
"mime-types": "^2.1.12"
}
},
"fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"requires": {
"minipass": "^3.0.0"
}
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"fstream": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
"integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
"requires": {
"graceful-fs": "^4.1.2",
"inherits": "~2.0.0",
"mkdirp": ">=0.5 0",
"rimraf": "2"
}
},
"gauge": {
"version": "2.7.4",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
@ -238,9 +234,9 @@
}
},
"glob": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@ -251,9 +247,9 @@
}
},
"graceful-fs": {
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw=="
},
"har-schema": {
"version": "2.0.0",
@ -261,11 +257,11 @@
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
},
"har-validator": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
"integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
"integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
"requires": {
"ajv": "^5.1.0",
"ajv": "^6.12.3",
"har-schema": "^2.0.0"
}
},
@ -294,9 +290,9 @@
}
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"is-fullwidth-code-point": {
"version": "1.0.0",
@ -329,8 +325,7 @@
"jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
"optional": true
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
},
"json-schema": {
"version": "0.2.3",
@ -338,9 +333,9 @@
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
},
"json-schema-traverse": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
"integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
},
"json-stringify-safe": {
"version": "5.0.1",
@ -359,16 +354,16 @@
}
},
"mime-db": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
"integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="
"version": "1.44.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
"integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
},
"mime-types": {
"version": "2.1.18",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
"integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
"version": "2.1.27",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
"integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
"requires": {
"mime-db": "~1.33.0"
"mime-db": "1.44.0"
}
},
"minimatch": {
@ -379,18 +374,27 @@
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
"minipass": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
"integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
"requires": {
"yallist": "^4.0.0"
}
},
"minizlib": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"requires": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
}
},
"mkdirp": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"requires": {
"minimist": "0.0.8"
}
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
},
"nan": {
"version": "2.14.0",
@ -398,29 +402,26 @@
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg=="
},
"node-gyp": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz",
"integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=",
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz",
"integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==",
"requires": {
"fstream": "^1.0.0",
"glob": "^7.0.3",
"graceful-fs": "^4.1.2",
"minimatch": "^3.0.2",
"mkdirp": "^0.5.0",
"nopt": "2 || 3",
"npmlog": "0 || 1 || 2 || 3 || 4",
"osenv": "0",
"request": "2",
"rimraf": "2",
"semver": "~5.3.0",
"tar": "^2.0.0",
"which": "1"
"env-paths": "^2.2.0",
"glob": "^7.1.4",
"graceful-fs": "^4.2.3",
"nopt": "^5.0.0",
"npmlog": "^4.1.2",
"request": "^2.88.2",
"rimraf": "^3.0.2",
"semver": "^7.3.2",
"tar": "^6.0.2",
"which": "^2.0.2"
}
},
"nopt": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
"integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
"requires": {
"abbrev": "1"
}
@ -442,9 +443,9 @@
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
},
"oauth-sign": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
"integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
},
"object-assign": {
"version": "4.1.1",
@ -459,25 +460,6 @@
"wrappy": "1"
}
},
"os-homedir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
},
"os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
},
"osenv": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz",
"integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=",
"requires": {
"os-homedir": "^1.0.0",
"os-tmpdir": "^1.0.0"
}
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
@ -489,14 +471,19 @@
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"process-nextick-args": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
"psl": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
"integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
},
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
},
"qs": {
"version": "6.5.2",
@ -504,63 +491,68 @@
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
},
"readable-stream": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
"integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~1.0.6",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.0.3",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"request": {
"version": "2.87.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz",
"integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==",
"version": "2.88.2",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
"integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
"requires": {
"aws-sign2": "~0.7.0",
"aws4": "^1.6.0",
"aws4": "^1.8.0",
"caseless": "~0.12.0",
"combined-stream": "~1.0.5",
"extend": "~3.0.1",
"combined-stream": "~1.0.6",
"extend": "~3.0.2",
"forever-agent": "~0.6.1",
"form-data": "~2.3.1",
"har-validator": "~5.0.3",
"form-data": "~2.3.2",
"har-validator": "~5.1.3",
"http-signature": "~1.2.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.17",
"oauth-sign": "~0.8.2",
"mime-types": "~2.1.19",
"oauth-sign": "~0.9.0",
"performance-now": "^2.1.0",
"qs": "~6.5.1",
"safe-buffer": "^5.1.1",
"tough-cookie": "~2.3.3",
"qs": "~6.5.2",
"safe-buffer": "^5.1.2",
"tough-cookie": "~2.5.0",
"tunnel-agent": "^0.6.0",
"uuid": "^3.1.0"
"uuid": "^3.3.2"
}
},
"rimraf": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
"integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"requires": {
"glob": "^7.0.5"
"glob": "^7.1.3"
}
},
"safe-buffer": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"semver": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8="
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
},
"set-blocking": {
"version": "2.0.0",
@ -568,14 +560,14 @@
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
},
"signal-exit": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
},
"sshpk": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz",
"integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=",
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
"integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
"requires": {
"asn1": "~0.2.3",
"assert-plus": "^1.0.0",
@ -584,6 +576,7 @@
"ecc-jsbn": "~0.1.1",
"getpass": "^0.1.1",
"jsbn": "~0.1.0",
"safer-buffer": "^2.0.2",
"tweetnacl": "~0.14.0"
}
},
@ -598,9 +591,9 @@
}
},
"string_decoder": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.1.0"
}
@ -614,34 +607,25 @@
}
},
"tar": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
"integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz",
"integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==",
"requires": {
"block-stream": "*",
"fstream": "^1.0.12",
"inherits": "2"
},
"dependencies": {
"fstream": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
"integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
"requires": {
"graceful-fs": "^4.1.2",
"inherits": "~2.0.0",
"mkdirp": ">=0.5 0",
"rimraf": "2"
}
}
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
"minipass": "^3.0.0",
"minizlib": "^2.1.1",
"mkdirp": "^1.0.3",
"yallist": "^4.0.0"
}
},
"tough-cookie": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
"integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
"requires": {
"punycode": "^1.4.1"
"psl": "^1.1.28",
"punycode": "^2.1.1"
}
},
"tunnel-agent": {
@ -655,8 +639,15 @@
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
"optional": true
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
"uri-js": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
"integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
"requires": {
"punycode": "^2.1.0"
}
},
"util-deprecate": {
"version": "1.0.2",
@ -664,9 +655,9 @@
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"uuid": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
"integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA=="
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
},
"verror": {
"version": "1.10.0",
@ -679,25 +670,30 @@
}
},
"which": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
"integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"requires": {
"isexe": "^2.0.0"
}
},
"wide-align": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
"integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
"requires": {
"string-width": "^1.0.2"
"string-width": "^1.0.2 || 2"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
}
}

View File

@ -9,7 +9,7 @@
},
"dependencies": {
"bindings": "1.2.1",
"node-gyp": "^3.5.0",
"nan": "^2.14.0"
"nan": "^2.14.0",
"node-gyp": "^7.1.2"
}
}

View File

@ -26,25 +26,30 @@ extern "C" bool Neon_Call_IsConstruct(v8::FunctionCallbackInfo<v8::Value> *info)
return info->IsConstructCall();
}
extern "C" void Neon_Call_This(v8::FunctionCallbackInfo<v8::Value> *info, v8::Local<v8::Object> *out) {
extern "C" void Neon_Call_This(v8::Isolate *isolate, v8::FunctionCallbackInfo<v8::Value> *info, v8::Local<v8::Object> *out) {
*out = info->This();
}
extern "C" void Neon_Call_Data(v8::FunctionCallbackInfo<v8::Value> *info, v8::Local<v8::Value> *out) {
extern "C" void Neon_Call_Data(v8::Isolate *isolate, v8::FunctionCallbackInfo<v8::Value> *info, void **out) {
/*
printf("Call_Data: v8 info = %p\n", *(void **)info);
dump((void *)info, 3);
printf("Call_Data: v8 info implicit:\n");
dump_implicit((void *)info);
*/
*out = info->Data();
// Call data is stored wrapped in a v8::External by Neon_Fun_New et al, so we need to unwrap it before handing it back to Rust.
v8::Local<v8::Value> external = info->Data();
if (external->IsExternal()) {
*out = external.As<v8::External>()->Value();
}
}
extern "C" int32_t Neon_Call_Length(v8::FunctionCallbackInfo<v8::Value> *info) {
extern "C" int32_t Neon_Call_Length(v8::Isolate *isolate, v8::FunctionCallbackInfo<v8::Value> *info) {
return info->Length();
}
extern "C" void Neon_Call_Get(v8::FunctionCallbackInfo<v8::Value> *info, int32_t i, v8::Local<v8::Value> *out) {
extern "C" void Neon_Call_Get(v8::Isolate *isolate, v8::FunctionCallbackInfo<v8::Value> *info, int32_t i, v8::Local<v8::Value> *out) {
*out = (*info)[i];
}
@ -178,12 +183,12 @@ extern "C" bool Neon_Convert_ToString(v8::Local<v8::String> *out, v8::Isolate *i
return maybe.ToLocal(out);
}
extern "C" bool Neon_Convert_ToObject(v8::Local<v8::Object> *out, v8::Local<v8::Value> *value) {
Nan::MaybeLocal<v8::Object> maybe = Nan::To<v8::Object>(*value);
extern "C" bool Neon_Convert_ToObject(v8::Local<v8::Object> *out, v8::Isolate *isolate, v8::Local<v8::Value> value) {
Nan::MaybeLocal<v8::Object> maybe = Nan::To<v8::Object>(value);
return maybe.ToLocal(out);
}
extern "C" bool Neon_Buffer_New(v8::Local<v8::Object> *out, uint32_t size) {
extern "C" bool Neon_Buffer_New(v8::Isolate *isolate, v8::Local<v8::Object> *out, uint32_t size) {
Nan::MaybeLocal<v8::Object> maybe = Nan::NewBuffer(size);
if (!maybe.ToLocal(out)) {
return false;
@ -194,12 +199,12 @@ extern "C" bool Neon_Buffer_New(v8::Local<v8::Object> *out, uint32_t size) {
return true;
}
extern "C" bool Neon_Buffer_Uninitialized(v8::Local<v8::Object> *out, uint32_t size) {
extern "C" bool Neon_Buffer_Uninitialized(v8::Isolate *isolate, v8::Local<v8::Object> *out, uint32_t size) {
Nan::MaybeLocal<v8::Object> maybe = Nan::NewBuffer(size);
return maybe.ToLocal(out);
}
extern "C" size_t Neon_Buffer_Data(void **base_out, v8::Local<v8::Object> obj) {
extern "C" size_t Neon_Buffer_Data(v8::Isolate *isolate, void **base_out, v8::Local<v8::Object> obj) {
*base_out = node::Buffer::Data(obj);
return node::Buffer::Length(obj);
@ -214,7 +219,7 @@ extern "C" bool Neon_ArrayBuffer_New(v8::Local<v8::ArrayBuffer> *out, v8::Isolat
return true;
}
extern "C" size_t Neon_ArrayBuffer_Data(void **base_out, v8::Local<v8::ArrayBuffer> buffer) {
extern "C" size_t Neon_ArrayBuffer_Data(v8::Isolate *isolate, void **base_out, v8::Local<v8::ArrayBuffer> buffer) {
v8::ArrayBuffer::Contents contents = buffer->GetContents();
*base_out = contents.Data();
@ -226,7 +231,7 @@ extern "C" bool Neon_Tag_IsArrayBuffer(v8::Isolate *isolate, v8::Local<v8::Value
return value->IsArrayBuffer();
}
extern "C" void Neon_Scope_Escape(v8::Local<v8::Value> *out, Nan::EscapableHandleScope *scope, v8::Local<v8::Value> value) {
extern "C" void Neon_Scope_Escape(v8::Isolate *isolate, v8::Local<v8::Value> *out, Nan::EscapableHandleScope *scope, v8::Local<v8::Value> value) {
*out = scope->Escape(value);
}
@ -327,21 +332,21 @@ extern "C" void Neon_Class_SetClassMap(v8::Isolate *isolate, void *map, Neon_Dro
neon::ClassMapHolder *holder = new neon::ClassMapHolder(map, drop_map);
isolate->SetData(NEON_ISOLATE_SLOT, holder);
// ISSUE(#77): When workers land in node, this will need to be generalized to a per-worker version.
node::AtExit(cleanup_class_map, holder);
node::AtExit(node::GetCurrentEnvironment(isolate->GetCurrentContext()), cleanup_class_map, holder);
}
extern "C" void *Neon_Class_GetCallKernel(v8::Local<v8::External> wrapper) {
neon::ClassMetadata *metadata = static_cast<neon::ClassMetadata *>(wrapper->Value());
extern "C" void *Neon_Class_GetCallKernel(void *wrapper) {
neon::ClassMetadata *metadata = static_cast<neon::ClassMetadata *>(wrapper);
return metadata->GetCallKernel();
}
extern "C" void *Neon_Class_GetConstructKernel(v8::Local<v8::External> wrapper) {
neon::ClassMetadata *metadata = static_cast<neon::ClassMetadata *>(wrapper->Value());
extern "C" void *Neon_Class_GetConstructKernel(void *wrapper) {
neon::ClassMetadata *metadata = static_cast<neon::ClassMetadata *>(wrapper);
return metadata->GetConstructKernel();
}
extern "C" void *Neon_Class_GetAllocateKernel(v8::Local<v8::External> wrapper) {
neon::BaseClassMetadata *metadata = static_cast<neon::BaseClassMetadata *>(wrapper->Value());
extern "C" void *Neon_Class_GetAllocateKernel(void *wrapper) {
neon::BaseClassMetadata *metadata = static_cast<neon::BaseClassMetadata *>(wrapper);
return metadata->GetAllocateKernel();
}
@ -433,8 +438,8 @@ extern "C" bool Neon_Fun_New(v8::Local<v8::Function> *out, v8::Isolate *isolate,
return maybe_result.ToLocal(out);
}
extern "C" void *Neon_Fun_GetDynamicCallback(v8::Local<v8::External> data) {
return data->Value();
extern "C" void *Neon_Fun_GetDynamicCallback(v8::Isolate *isolate, void *data) {
return data;
}
extern "C" bool Neon_Fun_Call(v8::Local<v8::Value> *out, v8::Isolate *isolate, v8::Local<v8::Function> fun, v8::Local<v8::Value> self, int32_t argc, v8::Local<v8::Value> argv[]) {
@ -536,3 +541,26 @@ extern "C" void Neon_EventHandler_Delete(void * thread_safe_cb) {
neon::EventHandler *cb = static_cast<neon::EventHandler*>(thread_safe_cb);
cb->close();
}
extern "C" try_catch_control_t Neon_TryCatch_With(Neon_TryCatchGlue glue_fn, void *rust_thunk, void *cx, void *ok, v8::Local<v8::Value> *err, void **unwind_value) {
Nan::TryCatch try_catch;
try_catch_control_t ctrl = glue_fn(rust_thunk, cx, ok, unwind_value);
if (ctrl == CONTROL_PANICKED) {
return CONTROL_PANICKED;
}
if (!try_catch.HasCaught()) {
// It's possible, if unlikely, that a Neon user might return `Err(Throw)` even
// though the VM is not actually in a throwing state. In this case we return
// `CONTROL_UNEXPECTED_ERR` to signal that Rust should panic.
if (ctrl == CONTROL_THREW) {
return CONTROL_UNEXPECTED_ERR;
}
return CONTROL_RETURNED;
} else {
*err = try_catch.Exception();
return CONTROL_THREW;
}
}

View File

@ -5,22 +5,30 @@
#include <stdint.h>
#include <v8.h>
// corresponding Rust struct `CCallback` defined in fun.rs
// corresponding Rust struct `CCallback` defined in lib.rs
typedef struct {
void* static_callback;
void* dynamic_callback;
} callback_t;
// corresponding Rust enum `TryCatchControl` defined in lib.rs
typedef enum : uint8_t {
CONTROL_RETURNED = 0,
CONTROL_THREW = 1,
CONTROL_PANICKED = 2,
CONTROL_UNEXPECTED_ERR = 3
} try_catch_control_t;
extern "C" {
void Neon_Call_SetReturn(v8::FunctionCallbackInfo<v8::Value> *info, v8::Local<v8::Value> value);
void *Neon_Call_GetIsolate(v8::FunctionCallbackInfo<v8::Value> *info);
void *Neon_Call_CurrentIsolate();
bool Neon_Call_IsConstruct(v8::FunctionCallbackInfo<v8::Value> *info);
void Neon_Call_This(v8::FunctionCallbackInfo<v8::Value> *info, v8::Local<v8::Object> *out);
void Neon_Call_Data(v8::FunctionCallbackInfo<v8::Value> *info, v8::Local<v8::Value> *out);
int32_t Neon_Call_Length(v8::FunctionCallbackInfo<v8::Value> *info);
void Neon_Call_Get(v8::FunctionCallbackInfo<v8::Value> *info, int32_t i, v8::Local<v8::Value> *out);
void Neon_Call_This(v8::Isolate *isolate, v8::FunctionCallbackInfo<v8::Value> *info, v8::Local<v8::Object> *out);
void Neon_Call_Data(v8::Isolate *isolate, v8::FunctionCallbackInfo<v8::Value> *info, void **out);
int32_t Neon_Call_Length(v8::Isolate *isolate, v8::FunctionCallbackInfo<v8::Value> *info);
void Neon_Call_Get(v8::Isolate *isolate, v8::FunctionCallbackInfo<v8::Value> *info, int32_t i, v8::Local<v8::Value> *out);
void Neon_Primitive_Number(v8::Local<v8::Number> *out, v8::Isolate *isolate, double value);
void Neon_Primitive_Undefined(v8::Local<v8::Primitive> *out, v8::Isolate *isolate);
@ -47,20 +55,20 @@ extern "C" {
size_t Neon_String_Data(char *out, size_t len, v8::Local<v8::Value> str);
bool Neon_Convert_ToString(v8::Local<v8::String> *out, v8::Isolate *isolate, v8::Local<v8::Value> value);
bool Neon_Convert_ToObject(v8::Local<v8::Object> *out, v8::Local<v8::Value> *value);
bool Neon_Convert_ToObject(v8::Local<v8::Object> *out, v8::Isolate *isolate, v8::Local<v8::Value> value);
bool Neon_Buffer_New(v8::Local<v8::Object> *out, uint32_t size);
size_t Neon_Buffer_Data(void **base_out, v8::Local<v8::Object> obj);
bool Neon_Buffer_New(v8::Isolate *isolate, v8::Local<v8::Object> *out, uint32_t size);
size_t Neon_Buffer_Data(v8::Isolate *isolate, void **base_out, v8::Local<v8::Object> obj);
bool Neon_ArrayBuffer_New(v8::Local<v8::ArrayBuffer> *out, v8::Isolate *isolate, uint32_t size);
bool Neon_ArrayBuffer_Uninitialized(v8::Local<v8::ArrayBuffer> *out, v8::Isolate *isolate, uint32_t size);
size_t Neon_ArrayBuffer_Data(void **base_out, v8::Local<v8::ArrayBuffer> buffer);
size_t Neon_ArrayBuffer_Data(v8::Isolate *isolate, void **base_out, v8::Local<v8::ArrayBuffer> buffer);
typedef void(*Neon_ChainedScopeCallback)(void *, void *, void *, void *);
typedef void(*Neon_NestedScopeCallback)(void *, void *, void *);
typedef void(*Neon_RootScopeCallback)(void *, void *, void *);
void Neon_Scope_Escape(v8::Local<v8::Value> *out, Nan::EscapableHandleScope *scope, v8::Local<v8::Value> value);
void Neon_Scope_Escape(v8::Isolate *isolate, v8::Local<v8::Value> *out, Nan::EscapableHandleScope *scope, v8::Local<v8::Value> value);
void Neon_Scope_Nested(void *out, void *closure, Neon_NestedScopeCallback callback, void *realm);
void Neon_Scope_Chained(void *out, void *closure, Neon_ChainedScopeCallback callback, void *parent_scope);
void Neon_Scope_Enter(v8::HandleScope *scope, v8::Isolate *isolate);
@ -75,7 +83,7 @@ extern "C" {
bool Neon_Fun_New(v8::Local<v8::Function> *out, v8::Isolate *isolate, callback_t callback);
bool Neon_Fun_Template_New(v8::Local<v8::FunctionTemplate> *out, v8::Isolate *isolate, callback_t callback);
void *Neon_Fun_GetDynamicCallback(v8::Local<v8::External> obj);
void *Neon_Fun_GetDynamicCallback(v8::Isolate *isolate, void *obj);
bool Neon_Fun_Call(v8::Local<v8::Value> *out, v8::Isolate *isolate, v8::Local<v8::Function> fun, v8::Local<v8::Value> self, int32_t argc, v8::Local<v8::Value> argv[]);
bool Neon_Fun_Construct(v8::Local<v8::Object> *out, v8::Isolate *isolate, v8::Local<v8::Function> fun, int32_t argc, v8::Local<v8::Value> argv[]);
@ -95,9 +103,9 @@ extern "C" {
callback_t call,
Neon_DropCallback drop);
// FIXME: get rid of all the "kernel" nomenclature
void *Neon_Class_GetCallKernel(v8::Local<v8::External> wrapper);
void *Neon_Class_GetConstructKernel(v8::Local<v8::External> wrapper);
void *Neon_Class_GetAllocateKernel(v8::Local<v8::External> wrapper);
void *Neon_Class_GetCallKernel(void *wrapper);
void *Neon_Class_GetConstructKernel(void *wrapper);
void *Neon_Class_GetAllocateKernel(void *wrapper);
bool Neon_Class_Constructor(v8::Local<v8::Function> *out, v8::Local<v8::FunctionTemplate> ft);
bool Neon_Class_HasInstance(void *metadata, v8::Local<v8::Value> v);
bool Neon_Class_SetName(v8::Isolate *isolate, void *metadata, const char *name, uint32_t byte_length);
@ -139,6 +147,20 @@ extern "C" {
void* Neon_EventHandler_New(v8::Isolate *isolate, v8::Local<v8::Value> self, v8::Local<v8::Function> callback);
void Neon_EventHandler_Schedule(void* thread_safe_cb, void* rust_callback, Neon_EventHandler handler);
void Neon_EventHandler_Delete(void* thread_safe_cb);
// The `ok` out-parameter can be assumed to be initialized if and only if this function
// returns `CONTROL_RETURNED`.
// The `unwind_value` out-parameter can be assumed to be initialized if and only if this
// function returns `CONTROL_PANICKED`.
typedef try_catch_control_t (*Neon_TryCatchGlue)(void *rust_thunk, void *cx, void *ok, void **unwind_value);
// The `ok` out-parameter can be assumed to be initialized if and only if this function
// returns `CONTROL_RETURNED`.
// The `err` out-parameter can be assumed to be initialized if and only if this function
// returns `CONTROL_THREW`.
// The `unwind_value` out-parameter can be assumed to be initialized if and only if this
// function returns `CONTROL_PANICKED`.
try_catch_control_t Neon_TryCatch_With(Neon_TryCatchGlue glue, void *rust_thunk, void *cx, void *ok, v8::Local<v8::Value> *err, void **unwind_value);
}
#endif

View File

@ -25,6 +25,12 @@ namespace neon {
context_.Reset(isolate, isolate->GetCurrentContext());
}
~EventHandler() {
self_.Reset();
callback_.Reset();
context_.Reset();
}
void schedule(void *rust_callback, Neon_EventHandler handler) {
{
std::lock_guard<std::mutex> lock(mutex_);

View File

@ -1,5 +1,5 @@
use std::os::raw::c_void;
use std::mem;
use std::os::raw::c_void;
use std::ptr::null_mut;
/// A V8 `Local` handle.
@ -9,14 +9,14 @@ use std::ptr::null_mut;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct Local {
pub handle: *mut c_void
pub handle: *mut c_void,
}
/// Represents the details of how the function was called from JavaScript.
///
/// It contains the arguments used to invoke the function, the isolate reference, the `this` object
/// the function is bound to and a mechanism to return a value to the caller.
pub type FunctionCallbackInfo = c_void;
pub type FunctionCallbackInfo = *const c_void;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
@ -38,11 +38,19 @@ const HANDLE_SCOPE_SIZE: usize = 24;
#[derive(Clone, Copy)]
pub struct HandleScope {
pub align_to_pointer: [*mut c_void; 0],
pub fields: [u8; HANDLE_SCOPE_SIZE]
pub fields: [u8; HANDLE_SCOPE_SIZE],
}
impl HandleScope {
pub fn new() -> HandleScope { unsafe { mem::zeroed() } }
pub fn new() -> HandleScope {
unsafe { mem::zeroed() }
}
}
impl Default for HandleScope {
fn default() -> Self {
Self::new()
}
}
const ESCAPABLE_HANDLE_SCOPE_SIZE: usize = 32;
@ -56,73 +64,131 @@ const ESCAPABLE_HANDLE_SCOPE_SIZE: usize = 32;
#[derive(Clone, Copy)]
pub struct EscapableHandleScope {
pub align_to_pointer: [*mut c_void; 0],
pub fields: [u8; ESCAPABLE_HANDLE_SCOPE_SIZE]
pub fields: [u8; ESCAPABLE_HANDLE_SCOPE_SIZE],
}
impl EscapableHandleScope {
pub fn new() -> EscapableHandleScope { unsafe { mem::zeroed() } }
pub fn new() -> EscapableHandleScope {
unsafe { mem::zeroed() }
}
}
impl Default for EscapableHandleScope {
fn default() -> Self {
Self::new()
}
}
#[repr(C)]
pub struct CCallback {
pub static_callback: *mut c_void,
pub dynamic_callback: *mut c_void
pub dynamic_callback: *mut c_void,
}
impl Default for CCallback {
fn default() -> Self {
CCallback {
static_callback: null_mut(),
dynamic_callback: null_mut()
dynamic_callback: null_mut(),
}
}
}
#[repr(u8)]
pub enum TryCatchControl {
Returned = 0,
Threw = 1,
Panicked = 2,
UnexpectedErr = 3,
}
#[derive(Clone, Copy)]
pub struct InheritedHandleScope;
/// A Rust extern "glue function" for C++ to invoke a Rust closure with a `TryCatch`
/// live on the stack.
/// The `result` argument can be assumed to be initialized if and only if the glue
/// function returns `TryCatchControl::Returned`.
/// The `unwind_value` argument can be assumed to be initialized if and only if the
/// glue function returns `TryCatchControl::Panicked`.
pub type TryCatchGlue = extern "C" fn(
rust_thunk: *mut c_void,
cx: *mut c_void,
result: *mut c_void,
unwind_value: *mut *mut c_void,
) -> TryCatchControl;
extern "C" {
pub fn Neon_Array_New(out: &mut Local, isolate: Isolate, length: u32);
pub fn Neon_Array_Length(isolate: Isolate, array: Local) -> u32;
pub fn Neon_ArrayBuffer_New(out: &mut Local, isolate: Isolate, size: u32) -> bool;
pub fn Neon_ArrayBuffer_Data<'a, 'b>(base_out: &'a mut *mut c_void, obj: Local) -> usize;
pub fn Neon_ArrayBuffer_Data<'a, 'b>(
isolate: Isolate,
base_out: &'a mut *mut c_void,
obj: Local,
) -> usize;
pub fn Neon_Buffer_New(out: &mut Local, size: u32) -> bool;
pub fn Neon_Buffer_Uninitialized(out: &mut Local, size: u32) -> bool;
pub fn Neon_Buffer_Data<'a, 'b>(base_out: &'a mut *mut c_void, obj: Local) -> usize;
pub fn Neon_Buffer_New(isolate: Isolate, out: &mut Local, size: u32) -> bool;
pub fn Neon_Buffer_Uninitialized(isolate: Isolate, out: &mut Local, size: u32) -> bool;
pub fn Neon_Buffer_Data<'a, 'b>(
isolate: Isolate,
base_out: &'a mut *mut c_void,
obj: Local,
) -> usize;
pub fn Neon_Call_SetReturn(info: &FunctionCallbackInfo, value: Local);
pub fn Neon_Call_GetIsolate(info: &FunctionCallbackInfo) -> Isolate;
pub fn Neon_Call_SetReturn(info: FunctionCallbackInfo, value: Local);
pub fn Neon_Call_GetIsolate(info: FunctionCallbackInfo) -> Isolate;
pub fn Neon_Call_CurrentIsolate() -> Isolate;
pub fn Neon_Call_IsConstruct(info: &FunctionCallbackInfo) -> bool;
pub fn Neon_Call_This(info: &FunctionCallbackInfo, out: &mut Local);
pub fn Neon_Call_Data(info: &FunctionCallbackInfo, out: &mut Local);
pub fn Neon_Call_Length(info: &FunctionCallbackInfo) -> i32;
pub fn Neon_Call_Get(info: &FunctionCallbackInfo, i: i32, out: &mut Local);
pub fn Neon_Call_IsConstruct(info: FunctionCallbackInfo) -> bool;
pub fn Neon_Call_This(isolate: Isolate, info: FunctionCallbackInfo, out: &mut Local);
pub fn Neon_Call_Data(isolate: Isolate, info: FunctionCallbackInfo, out: &mut *mut c_void);
pub fn Neon_Call_Length(isolate: Isolate, info: FunctionCallbackInfo) -> i32;
pub fn Neon_Call_Get(isolate: Isolate, info: FunctionCallbackInfo, i: i32, out: &mut Local);
pub fn Neon_Class_GetClassMap(isolate: Isolate) -> *mut c_void;
pub fn Neon_Class_SetClassMap(isolate: Isolate, map: *mut c_void, free_map: *mut c_void);
pub fn Neon_Class_CreateBase(isolate: Isolate,
allocate: CCallback,
construct: CCallback,
call: CCallback,
drop: extern "C" fn(*mut c_void)) -> *mut c_void;
pub fn Neon_Class_GetName<'a>(base_out: &'a mut *mut u8, isolate: Isolate, metadata: *const c_void) -> usize;
pub fn Neon_Class_SetName(isolate: Isolate, metadata: *mut c_void, name: *const u8, byte_length: u32) -> bool;
pub fn Neon_Class_CreateBase(
isolate: Isolate,
allocate: CCallback,
construct: CCallback,
call: CCallback,
drop: extern "C" fn(*mut c_void),
) -> *mut c_void;
pub fn Neon_Class_GetName<'a>(
base_out: &'a mut *mut u8,
isolate: Isolate,
metadata: *const c_void,
) -> usize;
pub fn Neon_Class_SetName(
isolate: Isolate,
metadata: *mut c_void,
name: *const u8,
byte_length: u32,
) -> bool;
pub fn Neon_Class_ThrowCallError(isolate: Isolate, metadata: *mut c_void);
pub fn Neon_Class_ThrowThisError(isolate: Isolate, metadata: *mut c_void);
pub fn Neon_Class_AddMethod(isolate: Isolate, metadata: *mut c_void, name: *const u8, byte_length: u32, method: Local) -> bool;
pub fn Neon_Class_MetadataToConstructor(out: &mut Local, isolate: Isolate, metadata: *mut c_void) -> bool;
pub fn Neon_Class_GetAllocateKernel(obj: Local) -> *mut c_void;
pub fn Neon_Class_GetConstructKernel(obj: Local) -> *mut c_void;
pub fn Neon_Class_GetCallKernel(obj: Local) -> *mut c_void;
pub fn Neon_Class_AddMethod(
isolate: Isolate,
metadata: *mut c_void,
name: *const u8,
byte_length: u32,
method: Local,
) -> bool;
pub fn Neon_Class_MetadataToConstructor(
out: &mut Local,
isolate: Isolate,
metadata: *mut c_void,
) -> bool;
pub fn Neon_Class_GetAllocateKernel(data: *mut c_void) -> *mut c_void;
pub fn Neon_Class_GetConstructKernel(data: *mut c_void) -> *mut c_void;
pub fn Neon_Class_GetCallKernel(data: *mut c_void) -> *mut c_void;
pub fn Neon_Class_Constructor(out: &mut Local, ft: Local) -> bool;
pub fn Neon_Class_HasInstance(metadata: *mut c_void, v: Local) -> bool;
pub fn Neon_Class_GetInstanceInternals(obj: Local) -> *mut c_void;
pub fn Neon_Convert_ToObject(out: &mut Local, value: &Local) -> bool;
pub fn Neon_Convert_ToObject(out: &mut Local, isolate: Isolate, value: Local) -> bool;
pub fn Neon_Convert_ToString(out: &mut Local, isolate: Isolate, value: Local) -> bool;
pub fn Neon_Error_Throw(val: Local);
@ -133,23 +199,53 @@ extern "C" {
pub fn Neon_Fun_New(out: &mut Local, isolate: Isolate, callback: CCallback) -> bool;
pub fn Neon_Fun_Template_New(out: &mut Local, isolate: Isolate, callback: CCallback) -> bool;
pub fn Neon_Fun_GetDynamicCallback(obj: Local) -> *mut c_void;
pub fn Neon_Fun_Call(out: &mut Local, isolate: Isolate, fun: Local, this: Local, argc: i32, argv: *mut c_void) -> bool;
pub fn Neon_Fun_Construct(out: &mut Local, isolate: Isolate, fun: Local, argc: i32, argv: *mut c_void) -> bool;
pub fn Neon_Fun_GetDynamicCallback(isolate: Isolate, data: *mut c_void) -> *mut c_void;
pub fn Neon_Fun_Call(
out: &mut Local,
isolate: Isolate,
fun: Local,
this: Local,
argc: i32,
argv: *mut c_void,
) -> bool;
pub fn Neon_Fun_Construct(
out: &mut Local,
isolate: Isolate,
fun: Local,
argc: i32,
argv: *mut c_void,
) -> bool;
pub fn Neon_Mem_SameHandle(h1: Local, h2: Local) -> bool;
pub fn Neon_Module_ExecKernel(kernel: *mut c_void, callback: extern fn(*mut c_void, *mut c_void, *mut c_void, *mut c_void), exports: Local, scope: *mut c_void, vm: *mut c_void);
pub fn Neon_Module_ExecKernel(
kernel: *mut c_void,
callback: extern "C" fn(*mut c_void, *mut c_void, *mut c_void, *mut c_void),
exports: Local,
scope: *mut c_void,
vm: *mut c_void,
);
pub fn Neon_Module_ExecCallback(callback: CCallback, exports: Local, vm: *mut c_void);
pub fn Neon_Module_GetVersion() -> i32;
pub fn Neon_Object_New(out: &mut Local, isolate: Isolate);
pub fn Neon_Object_GetOwnPropertyNames(out: &mut Local, isolate: Isolate, object: Local) -> bool;
pub fn Neon_Object_GetOwnPropertyNames(
out: &mut Local,
isolate: Isolate,
object: Local,
) -> bool;
pub fn Neon_Object_GetIsolate(obj: Local) -> Isolate;
pub fn Neon_Object_Get_Index(out: &mut Local, object: Local, index: u32) -> bool;
pub fn Neon_Object_Set_Index(out: &mut bool, object: Local, index: u32, val: Local) -> bool;
pub fn Neon_Object_Get_String(out: &mut Local, object: Local, key: *const u8, len: i32) -> bool;
pub fn Neon_Object_Set_String(out: &mut bool, object: Local, key: *const u8, len: i32, val: Local) -> bool;
pub fn Neon_Object_Get_String(out: &mut Local, object: Local, key: *const u8, len: i32)
-> bool;
pub fn Neon_Object_Set_String(
out: &mut bool,
object: Local,
key: *const u8,
len: i32,
val: Local,
) -> bool;
pub fn Neon_Object_Get(out: &mut Local, object: Local, key: Local) -> bool;
pub fn Neon_Object_Set(out: &mut bool, object: Local, key: Local, val: Local) -> bool;
@ -164,9 +260,24 @@ extern "C" {
pub fn Neon_Primitive_Number(out: &mut Local, isolate: Isolate, v: f64);
pub fn Neon_Primitive_NumberValue(p: Local) -> f64;
pub fn Neon_Scope_Escape(out: &mut Local, scope: *mut EscapableHandleScope, value: Local);
pub fn Neon_Scope_Chained(out: *mut c_void, closure: *mut c_void, callback: extern fn(&mut c_void, *mut c_void, *mut c_void, *mut c_void), parent_scope: *mut c_void);
pub fn Neon_Scope_Nested(out: *mut c_void, closure: *mut c_void, callback: extern fn(&mut c_void, *mut c_void, *mut c_void), realm: *mut c_void);
pub fn Neon_Scope_Escape(
isolate: Isolate,
out: &mut Local,
scope: *mut EscapableHandleScope,
value: Local,
);
pub fn Neon_Scope_Chained(
out: *mut c_void,
closure: *mut c_void,
callback: extern "C" fn(&mut c_void, *mut c_void, *mut c_void, *mut c_void),
parent_scope: *mut c_void,
);
pub fn Neon_Scope_Nested(
out: *mut c_void,
closure: *mut c_void,
callback: extern "C" fn(&mut c_void, *mut c_void, *mut c_void),
realm: *mut c_void,
);
pub fn Neon_Scope_Enter(scope: &mut HandleScope, isolate: Isolate);
pub fn Neon_Scope_Exit(scope: &mut HandleScope);
pub fn Neon_Scope_Enter_Escapable(scope: &mut EscapableHandleScope, isolate: Isolate);
@ -193,13 +304,32 @@ extern "C" {
pub fn Neon_Tag_IsBuffer(isolate: Isolate, obj: Local) -> bool;
pub fn Neon_Tag_IsArrayBuffer(isolate: Isolate, obj: Local) -> bool;
pub fn Neon_Task_Schedule(task: *mut c_void,
perform: unsafe extern fn(*mut c_void) -> *mut c_void,
complete: unsafe extern fn(*mut c_void, *mut c_void, &mut Local),
callback: Local);
pub fn Neon_Task_Schedule(
task: *mut c_void,
perform: unsafe extern "C" fn(*mut c_void) -> *mut c_void,
complete: unsafe extern "C" fn(*mut c_void, *mut c_void, &mut Local),
callback: Local,
);
pub fn Neon_EventHandler_New(isolate: Isolate, this: Local, callback: Local) -> *mut c_void;
pub fn Neon_EventHandler_Schedule(thread_safe_cb: *mut c_void, rust_callback: *mut c_void,
complete: unsafe extern fn(Local, Local, *mut c_void));
pub fn Neon_EventHandler_Schedule(
thread_safe_cb: *mut c_void,
rust_callback: *mut c_void,
complete: unsafe extern "C" fn(Local, Local, *mut c_void),
);
pub fn Neon_EventHandler_Delete(thread_safe_cb: *mut c_void);
/// Invokes a Rust closure with a `TryCatch` live on the stack.
/// The `result` value can be assumed to be initialized if and only if this function
/// does not return `TryCatchControl::Panicked`.
/// The `unwind_value` value can be assumed to be initialized if and only if this
/// function returns `TryCatchControl::Panicked`.
pub fn Neon_TryCatch_With(
glue: TryCatchGlue,
rust_thunk: *mut c_void,
cx: *mut c_void,
ok: *mut c_void,
err: *mut Local,
unwind_value: *mut *mut c_void,
) -> TryCatchControl;
}

View File

@ -0,0 +1,6 @@
{
"extension": ["ts"],
"spec": "test/**/*.ts",
"require": "ts-node/register",
"timeout": 5000
}

11
create-neon/README.md Normal file
View File

@ -0,0 +1,11 @@
# Create Neon
The `create-neon` tool bootstraps [Neon](https://neon-bindings.com) projects, which allows developers to build binary Node modules written in [Rust](https://www.rust-lang.org).
## Usage
You can conveniently use this tool with the [`npm init`](https://docs.npmjs.com/cli/v7/commands/npm-init) syntax:
```sh
$ npm init neon my-project
```

View File

@ -0,0 +1,5 @@
target
index.node
**/node_modules
**/.DS_Store
npm-debug.log*

View File

@ -0,0 +1,22 @@
[package]
name = "{{package.name}}"
version = "{{package.version}}"
{{#if package.description}}
description = {{package.quotedDescription}}
{{/if}}
{{#if package.author}}
authors = [{{package.quotedAuthor}}]
{{/if}}
{{#if package.license}}
license = "{{package.license}}"
{{/if}}
edition = "2018"
exclude = ["index.node"]
[lib]
crate-type = ["cdylib"]
[dependencies.neon]
version = "{{versions.neon}}"
default-features = false
features = ["napi-{{versions.napi}}"]

View File

@ -0,0 +1,109 @@
# {{package.name}}
{{#if package.description}}
**{{package.name}}:** {{package.description}}
{{/if}}
This project was bootstrapped by [create-neon](https://www.npmjs.com/package/create-neon).
## Installing {{package.name}}
Installing {{package.name}} requires a [supported version of Node and Rust](https://github.com/neon-bindings/neon#platform-support).
You can install the project with npm. In the project directory, run:
```sh
$ npm install
```
This fully installs the project, including installing any dependencies and running the build.
## Building {{package.name}}
If you have already installed the project and only want to run the build, run:
```sh
$ npm run build
```
This command uses the [cargo-cp-artifact](https://github.com/neon-bindings/cargo-cp-artifact) utility to run the Rust build and copy the built library into `./index.node`.
## Exploring {{package.name}}
After building {{package.name}}, you can explore its exports at the Node REPL:
```sh
$ npm install
$ node
> require('.').hello()
"hello node"
```
## Available Scripts
In the project directory, you can run:
### `npm install`
Installs the project, including running `npm run build`.
### `npm build`
Builds the Node addon (`index.node`) from source.
### `npm test`
Runs the unit tests by calling `cargo test`. You can learn more about [adding tests to your Rust code](https://doc.rust-lang.org/book/ch11-01-writing-tests.html) from the [Rust book](https://doc.rust-lang.org/book/).
## Project Layout
The directory structure of this project is:
```
{{package.name}}/
├── Cargo.toml
├── README.md
├── index.node
├── package.json
├── src/
| └── lib.rs
└── target/
```
### Cargo.toml
The Cargo [manifest file](https://doc.rust-lang.org/cargo/reference/manifest.html), which informs the `cargo` command.
### README.md
This file.
### index.node
The Node addon—i.e., a binary Node module—generated by building the project. This is the main module for this package, as dictated by the `"main"` key in `package.json`.
Under the hood, a [Node addon](https://nodejs.org/api/addons.html) is a [dynamically-linked shared object](https://en.wikipedia.org/wiki/Library_(computing)#Shared_libraries). The `"build"` script produces this file by copying it from within the `target/` directory, which is where the Rust build produces the shared object.
### package.json
The npm [manifest file](https://docs.npmjs.com/cli/v7/configuring-npm/package-json), which informs the `npm` command.
### src/
The directory tree containing the Rust source code for the project.
### src/lib.rs
The Rust library's main module.
### target/
Binary artifacts generated by the Rust build.
## Learn More
To learn more about Neon, see the [Neon documentation](https://neon-bindings.com).
To learn more about Rust, see the [Rust documentation](https://www.rust-lang.org).
To learn more about Node, see the [Node documentation](https://nodejs.org).

View File

@ -0,0 +1,11 @@
use neon::prelude::*;
fn hello(mut cx: FunctionContext) -> JsResult<JsString> {
Ok(cx.string("hello node"))
}
#[neon::main]
fn main(mut cx: ModuleContext) -> NeonResult<()> {
cx.export_function("hello", hello)?;
Ok(())
}

View File

@ -0,0 +1,5 @@
{
"neon": "0.8",
"napi": "6",
"cargo-cp-artifact": "0.1"
}

104
create-neon/dev/expect.ts Normal file
View File

@ -0,0 +1,104 @@
import { ChildProcess } from 'child_process';
import { PassThrough, Readable, Writable } from 'stream';
import { StringDecoder } from 'string_decoder';
import readStream from 'stream-to-string';
function readChunks(input: Readable): Readable {
let output = new PassThrough({ objectMode: true });
let decoder = new StringDecoder('utf8');
input.on('data', data => {
output.write(decoder.write(data));
});
input.on('close', () => {
output.write(decoder.end());
output.destroy();
});
return output;
}
function splitLines(s: string): string[] {
return s.split(/([^\n]*\r?\n)/).filter(x => x);
}
function isCompleteLine(s: string): boolean {
return s.endsWith('\n');
}
class LinesBuffer {
// INVARIANT: (this.buffer.length > 0) &&
// !isCompleteLine(this.buffer[this.buffer.length - 1])
// In other words, the last line in the buffer is always incomplete.
private buffer: string[];
constructor() {
this.buffer = [""];
}
add(lines: string[]) {
if (isCompleteLine(lines[lines.length - 1])) {
lines.push("");
}
this.buffer[this.buffer.length - 1] += lines.shift();
this.buffer = this.buffer.concat(lines);
}
find(p: (s: string) => boolean): string[] | null {
let index = this.buffer.findIndex(p);
if (index === -1) {
return null;
}
let extracted = this.buffer.splice(0, index + 1);
if (this.buffer.length === 0) {
this.buffer.push("");
}
return extracted;
}
}
async function* run(script: Record<string, string>, stdin: Writable, stdout: Readable) {
let lines = new LinesBuffer();
let keys = Object.keys(script);
let i = 0;
for await (let chunk of readChunks(stdout)) {
lines.add(splitLines(chunk));
let found = lines.find(line => line.startsWith(keys[i]));
if (found) {
stdin.write(script[keys[i]] + "\n");
yield found;
i++;
if (i >= keys.length) {
break;
}
}
}
}
function exit(child: ChildProcess): Promise<number | null> {
let resolve: (code: number | null) => void;
let result: Promise<number | null> = new Promise(res => { resolve = res; });
child.on('exit', code => {
resolve(code);
});
return result;
}
export default async function expect(child: ChildProcess, script: Record<string, string>): Promise<void> {
let output: string[][] = [];
for await (let lines of run(script, child.stdin!, child.stdout!)) {
output.push(lines);
}
let stderr = await readStream(child.stderr!);
let code = await exit(child);
switch (code) {
case null:
throw new Error("child process interrupted");
case 0:
return;
default:
console.log("stderr: " + stderr.trim());
console.log("stdout: " + JSON.stringify(output));
throw new Error("child process exited with code " + code);
}
}

Some files were not shown because too many files have changed in this diff Show More