diff --git a/.clang-format b/.clang-format
new file mode 100644
index 00000000..173f8a6a
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,2 @@
+BasedOnStyle: LLVM
+ColumnLimit: 120
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
new file mode 100644
index 00000000..5645602c
--- /dev/null
+++ b/.devcontainer/Dockerfile
@@ -0,0 +1,4 @@
+FROM mcr.microsoft.com/devcontainers/javascript-node:24
+
+# need to run update and install at the same time to prevent stale update layer
+RUN apt-get update && apt-get install -y gdb clang-format openjdk-21-jdk maven
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 00000000..fb149f0e
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,17 @@
+{
+ "build": {
+ "dockerfile": "Dockerfile"
+ },
+ "runArgs": [],
+ "customizations": {
+ "vscode": {
+ "extensions": [
+ "streetsidesoftware.code-spell-checker",
+ "bierner.markdown-emoji",
+ "smulyono.reveal",
+ "ms-azuretools.vscode-docker",
+ "ms-vscode.cpptools-extension-pack"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..424e53c3
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,11 @@
+# These files will be normalized on commit (CRLF converted to LF) - asterisk is a wildcard
+* text eol=lf
+
+# These files will NOT be normalized
+*.png -text
+*.gif -text
+*.jpg -text
+*.jpeg -text
+*.ico -text
+*.jar -text
+*.class -text
diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml
new file mode 100644
index 00000000..fbfa09d2
--- /dev/null
+++ b/.github/workflows/master.yml
@@ -0,0 +1,29 @@
+name: master
+on:
+ push:
+ branches:
+ - master
+jobs:
+ unit-test:
+ name: Unit Test
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ nodeVersion: [ 20, 22, 24 ]
+ jdkVersion: [ openjdk9, openjdk10, openjdk11, openjdk21 ]
+ steps:
+ - name: Checkout source code
+ uses: actions/checkout@v3
+ - uses: actions/setup-node@v3
+ with:
+ node-version: ${{ matrix.nodeVersion }}
+ - name: npm ci
+ run: npm ci
+ - name: npm run format-cpp
+ run: npm run format-cpp
+ - name: npm run format
+ run: npm run format
+ - name: npm run lint
+ run: npm run lint
+ - name: Unit test
+ run: npm test
diff --git a/.github/workflows/pull-requests.yml b/.github/workflows/pull-requests.yml
new file mode 100644
index 00000000..2d20d7f7
--- /dev/null
+++ b/.github/workflows/pull-requests.yml
@@ -0,0 +1,30 @@
+name: Pull Requests
+on:
+ pull_request:
+ types: [opened, edited, reopened, synchronize]
+ branches:
+ - master
+jobs:
+ unit-test:
+ name: Unit Test
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ nodeVersion: [ 20, 22, 24 ]
+ jdkVersion: [ openjdk9, openjdk10, openjdk11, openjdk21 ]
+ steps:
+ - name: Checkout source code
+ uses: actions/checkout@v3
+ - uses: actions/setup-node@v3
+ with:
+ node-version: ${{ matrix.nodeVersion }}
+ - name: npm ci
+ run: npm ci
+ - name: npm run format-cpp
+ run: npm run format-cpp
+ - name: npm run format
+ run: npm run format
+ - name: npm run lint
+ run: npm run lint
+ - name: Unit test
+ run: npm test
diff --git a/.gitignore b/.gitignore
index ef47a1f1..633ce199 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,9 @@ node_modules
npm-debug.log
.idea
node-java.cbp
+*.iml
+*.kdev4
+*/.kdev_include_paths
+CMakeLists.txt
+cmake-build-debug/
+hs_err*
\ No newline at end of file
diff --git a/.npmignore b/.npmignore
index 4c82cca7..5c81151b 100644
--- a/.npmignore
+++ b/.npmignore
@@ -1,3 +1,4 @@
+/test
/testIntegration
/.idea
/build
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 00000000..60c971ca
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,23 @@
+**/*.cpp
+**/*.h
+**/*.ppt
+**/*.jar
+**/*.class
+**/*.java
+**/*.sh
+**/*.html
+**/*.json
+**/*.png
+**/*.md
+**/*.rule
+**/*.rules
+**/*.gyp
+**/*.yml
+**/Dockerfile
+.clang-format
+.prettierrc
+.prettierignore
+.npmignore
+.gitignore
+.gitattributes
+LICENSE
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 00000000..53fee0e9
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,10 @@
+{
+ "parser": "typescript",
+ "semi": true,
+ "singleQuote": false,
+ "tabWidth": 2,
+ "trailingComma": "es5",
+ "useTabs": false,
+ "printWidth": 120,
+ "endOfLine": "lf"
+}
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 13f74519..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-language: node_js
-node_js:
- - "0.11"
- - "0.10"
- - "0.8"
-notifications:
- email:
- on_success: "never"
diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
new file mode 100644
index 00000000..5c437f51
--- /dev/null
+++ b/.vscode/c_cpp_properties.json
@@ -0,0 +1,19 @@
+{
+ "configurations": [
+ {
+ "name": "Linux",
+ "includePath": [
+ "${workspaceFolder}/**",
+ "/usr/local/include/node",
+ "/usr/lib/jvm/java-17-openjdk-amd64/include/",
+ "/usr/lib/jvm/java-17-openjdk-amd64/include/linux"
+ ],
+ "defines": [],
+ "compilerPath": "/usr/bin/gcc",
+ "cStandard": "c17",
+ "cppStandard": "gnu++17",
+ "intelliSenseMode": "linux-gcc-x64"
+ }
+ ],
+ "version": 4
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..8b4e243e
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,26 @@
+{
+ "cSpell.words": [
+ "clazz",
+ "clazzclazz",
+ "Ferner",
+ "jarray",
+ "javac",
+ "jboolean",
+ "jbyte",
+ "jchar",
+ "jclass",
+ "jdouble",
+ "jfloat",
+ "jint",
+ "jlong",
+ "jmethod",
+ "jobj",
+ "jobject",
+ "jshort",
+ "jsize",
+ "jthrowable",
+ "jvalue",
+ "Ljava",
+ "varargs"
+ ]
+}
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index 8dec2a01..3e23b3ec 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2013 Near Infinity Corporation
+Copyright (c) 2025 Joe Ferner
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/README.md b/README.md
index 213eee9d..c10cc364 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,15 @@
-[](https://travis-ci.org/joeferner/node-java)
-# java
+
+[](https://github.com/joeferner/node-java/actions/workflows/master.yml)
Bridge API to connect with existing Java APIs.
[Google Groups Discussion Forum](https://groups.google.com/forum/#!forum/node-java)
-###Other projects that might be helpful
+### Other projects that might be helpful
-* [node-java-maven](https://github.com/joeferner/node-java-maven) - manages your node-java classpath by using maven dependency mangement.
+* [node-java-maven](https://github.com/joeferner/node-java-maven) - manages your node-java classpath by using maven dependency management.
+* [ts-java](https://github.com/RedSeal-co/ts-java) - Create TypeScript declaration files for Java packages.
## Installation
@@ -20,10 +21,15 @@ Notes:
* node-gyp requires python 2.x not python 3.x. See https://github.com/TooTallNate/node-gyp/issues/155 for more details.
* If you see an error such as "Call to 'node findJavaHome.js' returned exit status 1"
- Try running `node findJavaHome.js` in the node-java directory to see the full failure message.
+ Try running `node ./scripts/findJavaHome.js` in the node-java directory to see the full failure message.
* If you are having problems finding 'jni.h'. Make sure you have the JDK installed not just the JRE. If you are using
OpenJDK you want the openjdk-7-jdk package, not openjdk-7-jre. _Mavericks users see [Issue #86](https://github.com/nearinfinity/node-java/issues/86) if you run into this._
+### Installation Ubuntu
+
+- `sudo apt install make g++`
+- If u've error (on global installation): `EACCES user nobody does not have permission to access the dev dir /root/.cache/node-gyp/10.16.0`, then just run: `npm i -g java --unsafe-perm`
+
### Installation OSX
* If you run into strange runtime issues, it could be because the Oracle JDK does not advertise itself as available for JNI. See [Issue 90](https://github.com/joeferner/node-java/issues/90#issuecomment-45613235) for more details and manual workarounds. If this does occur for you, please update the issue.
@@ -42,6 +48,12 @@ npm install -g node-gyp
If you get `D9025` warnings and `C1083` errors when looking for `.sln` or `.h` files, be sure you've got the `node-gyp`'s dependencies, [as explained here](https://github.com/joeferner/node-java#installation).
+Alternatively, Windows users can easily install all required tools by running the following command in PowerShell as administrator. For more information see [windows-build-tools project page](https://github.com/felixrieseberg/windows-build-tools):
+
+```sh
+npm install --global --production windows-build-tools
+```
+
### Installation ARM (Raspberry Pi)
```bash
@@ -51,46 +63,141 @@ GYP_DEFINES="armv7=0" CCFLAGS='-march=armv6' CXXFLAGS='-march=armv6' npm install
## Manual compile (Using node-gyp)
```bash
-./compile-java-code.sh
+./scripts/compile-java.sh
node-gyp configure build
npm test
```
_NOTE: You will need node-gyp installed using "npm install -g node-gyp"_
+On Raspian you might need a:
+
+* sudo ln -s /usr/lib/jvm/jdk-7-oracle-arm-vfp-hflt /opt/jdk
+
+Some issues with the OpenSDK7 so take the Oracle version for compiling.
+
+## Docker
+
+If you want to play with node-java but don't want to setup the build environment you can run it in docker.
+
+```
+docker run -it joeferner/node-java bash
+```
+
+Then inside the docker container create a directory and run
+
+```bash
+npm install --unsafe-perm java
+```
+
+Then create a file called `test.js` with the following contents
+
+```
+const java = require('java');
+const javaLangSystem = java.import('java.lang.System');
+
+javaLangSystem.out.printlnSync('Hello World');
+```
+
+Then run
+
+```bash
+node test.js
+```
+
+## Installation node-webkit
+
+```bash
+npm install -g nw-gyp
+npm install java
+cd node_modules/java
+nw-gyp configure --target=0.10.5
+nw-gyp build
+```
+
+_See testIntegration/webkit for a working example_
+
+## Using node-java in existing maven projects
+
+When using node-java in existing maven projects, all the dependencies and the class files of the project have to be pushed to the classpath.
+
+One possible solution would be:
+
+Issue the command:
+
+> mvn dependency:copy-dependencies
+
+Then create the following module javaInit:
+
+```javascript
+"use strict";
+const fs = require("fs");
+const java = require("java");
+const baseDir = "./target/dependency";
+const dependencies = fs.readdirSync(baseDir);
+
+dependencies.forEach(function(dependency){
+ java.classpath.push(baseDir + "/" + dependency);
+})
+
+java.classpath.push("./target/classes");
+java.classpath.push("./target/test-classes");
+
+exports.getJavaInstance = function() {
+ return java;
+}
+```
+
+and then in the consuming class write:
+
+```javascript
+
+const javaInit = require('./javaInit');
+const java = javaInit.getJavaInstance();
+
+//your code goes here
+```
+
+
+
## Quick Examples
```javascript
-var java = require("java");
-java.classpath.push("commons-lang3-3.1.jar");
+const java = require("java");
+java.classpath.push("commons-lang3-3.19.0.jar");
java.classpath.push("commons-io.jar");
-var list = java.newInstanceSync("java.util.ArrayList");
+const list1 = java.newInstanceSync("java.util.ArrayList");
+console.log(list1.sizeSync()); // 0
+list1.addSync('item1');
+console.log(list1.sizeSync()); // 1
-java.newInstance("java.util.ArrayList", function(err, list) {
- list.addSync("item1");
- list.addSync("item2");
+java.newInstance("java.util.ArrayList", function(err, list2) {
+ list2.addSync("item1");
+ list2.addSync("item2");
+ console.log(list2.toStringSync()); // [item1, item2]
});
-var ArrayList = java.import('java.util.ArrayList');
-var list = new ArrayList();
-list.addSync('item1');
+const ArrayList = java.import('java.util.ArrayList');
+const list3 = new ArrayList();
+list3.addSync('item1');
+list3.equalsSync(list1); // true
```
### Create a char array
```javascript
-var charArray = java.newArray("char", "hello world\n".split(''));
+const charArray = java.newArray("char", "hello world\n".split(''));
```
### Create a byte array
```javascript
-var byteArray = java.newArray(
+const byteArray = java.newArray(
"byte",
"hello world\n"
.split('')
- .map(function(c) { return java.newByte(str.charCodeAt(c)); });
+ .map(function(c) { return java.newByte(String.prototype.charCodeAt(c)); }));
```
### Using java.lang.Long and long
@@ -101,7 +208,7 @@ a property off of the result called "longValue" which contains the un-truncated
If you are calling a method that takes a long you must create it using [java.newInstance](#javaNewInstance).
```javascript
-var javaLong = java.newInstanceSync("java.lang.Long", 5);
+const javaLong = java.newInstanceSync("java.lang.Long", 5);
console.log('Possibly truncated long value: ' + javaLong);
console.log('Original long value (as a string): ' + javaLong.longValue);
java.callStaticMethodSync("Test", "staticMethodThatTakesALong", javaLong);
@@ -121,8 +228,70 @@ try {
}
```
+
+
+### AsyncOptions: control over the generation of sync, async & promise method variants.
+
+As of release 0.4.5 it became possible to create async methods that return promises by setting the `asyncOptions` property of the java object. With release 0.4.7 this feature is extended to allow changing the suffix assigned for sync and async method variants, and to further configure this module to optionally omit generation of any of these variants.
+
+Example:
+
+```javascript
+const java = require("java");
+java.asyncOptions = {
+ asyncSuffix: undefined, // Don't generate node-style methods taking callbacks
+ syncSuffix: "", // Sync methods use the base name(!!)
+ promiseSuffix: "Promise", // Generate methods returning promises, using the suffix Promise.
+};
+java.classpath.push("commons-lang3-3.19.0.jar");
+java.classpath.push("commons-io.jar");
+
+java.import("java.util.ArrayList"); // see NOTE below
+
+java.newInstancePromise("java.util.ArrayList")
+ .then(function(list) { return list.addPromise("item1"); })
+ .then(function(list) { return list.addPromise("item2"); })
+ .catch(function(err) { /* handle error */ });
+```
+
+#### NOTES:
+
+* If you want the defacto standard behavior, simply don't set java.asyncOptions.
+* If you do provide asyncOptions, be aware that this module will not generate method variants of a given flavor if you don't provide a string value for the corresponding suffix (`asyncSuffix`, `syncSuffix`, `promiseSuffix`). In the example above, the application is configured to omit the method variants using node-style async callback functions.
+* Either (but not both) `asyncSuffix` or `syncSuffix` can be the empty string. If you want the defacto standard behavior for no suffix on async methods, you must provide an empty string for `asyncSuffix`.
+* We've tested promises with five Promises/A+ implementations. See `testHelpers.js` for more information.
+* NOTE: Due to specifics of initialization order, the methods `java.newInstancePromise`, `java.callMethodPromise`, and `java.callStaticMethodPromise` are not available until the JVM has been created. You may need to call some other java method such as `java.import()` to finalize java initialization, or even better, the function `java.ensureJvm()`.
+
+##### Special note about the exported module functions `newInstance`, `callMethod`, and `callStaticMethod`.
+These methods come in both async and sync variants. If you provide the `promiseSuffix` attributes in asyncOptions then you'll also get the Promises/A+ variant for these three functions. However, if you change the defacto conventions for the `syncSuffix` (i.e. 'Sync') and/or `asyncSuffix` (i.e. '') it will not affect the naming for these three functions. I.e. no matter what you specify in asyncOptions, the async variants are named `newInstance`, `callMethod`, and `callStaticMethod`, and the sync variants are named `newInstanceSync`, `callMethodSync`, and `callStaticMethodSync`.
+
+## Varargs support
+
+With v0.5.0 node-java now supports methods with variadic arguments (varargs). Prior to v0.5.0, a JavaScript call to a Java varargs method had to construct an array of the variadic arguments using `java.newArray()`. With v0.5.0 JavaScript applications can simply use the variadic style.
+
+In most cases it is still acceptable to use `java.newArray()`. But it is now possible to pass a plain JavaScript array, or use the variadic style. For example, consider these snippets from the unit test file `test/varargs-test.js`:
+
+```
+ test.equal(Test.staticVarargsSync(5, 'a', 'b', 'c'), '5abc');
+ test.equal(Test.staticVarargsSync(5, ['a', 'b', 'c']), '5abc');
+ test.equal(Test.staticVarargsSync(5, java.newArray('java.lang.String', ['a', 'b', 'c'])), '5abc');
+
+```
+
+Note that when passing a JavaScript array (e.g. `['a', 'b', 'c']`) for a varargs parameter, node-java must infer the Java type of the array. If all of the elements are of the same JavaScript primitive type (`string` in this example) then node-java will create a Java array of the corresponding type (e.g. `java.lang.String`). The Java types that node-java can infer are: `java.lang.String`, `java.lang.Boolean`, `java.lang.Integer`, `java.lang.Long`, and `java.lang.Double`. If an array has a mix of `Integer`, `Long`, and `Double`, then the inferred type will be `java.lang.Number`. Any other mix will result in an inferred type of `java.lang.Object`.
+
+Methods accepting varargs of a generic type are also problematic. You will need to fall back to using `java.newArray()`. See [Issue #285](https://github.com/joeferner/node-java/issues/285).
+
+## JVM Creation
+
+With v0.5.1 a new API is available to make it easier for a complex application to have full control over JVM creation. In particular, it is now easier to compose an application from several modules, each of which must add to the Java classpath and possibly do other operations just before or just after the JVM has been created. See the methods [ensureJvm](#javaEnsureJvm) and [registerClient](#javaRegisterClient). See also several of the tests in the testAsyncOptions directory.
+
# Release Notes
+### v0.5.0
+
+* Support for varargs. This change is not 100% backwards compatible, but the fix is generally easy and results in more natural code.
+
### v0.2.0
* java.lang.Long and long primitives are handled better. See
@@ -134,6 +303,7 @@ try {
## java
* [classpath](#javaClasspath)
* [options](#javaOptions)
+ * [asyncOptions](#javaAsyncOptions)
* [import](#javaImport)
* [newInstance](#javaNewInstance)
* [instanceOf](#javaInstanceOf)
@@ -149,6 +319,10 @@ try {
* [newDouble](#javaNewDouble)
* [newFloat](#javaNewFloat)
* [newProxy](#javaNewProxy)
+ * [isJvmCreated](#javaIsJvmCreated)
+ * [registerClient](#javaRegisterClient)
+ * [registerClientP](#javaRegisterClientP)
+ * [ensureJvm](#javaEnsureJvm)
## java objects
* [Call Method](#javaObjectCallMethod)
@@ -156,11 +330,15 @@ try {
# API Documentation
-
-## java
+
+
+# java
+
+
-
-**java.classpath**
+## classpath
+
+*java.classpath**
Array of paths or jars to pass to the creation of the JVM.
@@ -169,9 +347,13 @@ All items must be added to the classpath before calling any other node-java meth
__Example__
java.classpath.push('commons.io.jar');
+ java.classpath.push('src');
+
+## options
+
+
-
-**java.options**
+*java.options**
Array of options to pass to the creation of the JVM.
@@ -182,50 +364,77 @@ __Example__
java.options.push('-Djava.awt.headless=true');
java.options.push('-Xmx1024m');
-
-**java.import(className)**
+## asyncOptions
+
+```javascript
+java.asyncOptions = {
+ asyncSuffix: undefined, // Don't generate node-style methods taking callbacks
+ syncSuffix: "", // Sync methods use the base name(!!)
+ promiseSuffix: "Promise", // Generate methods returning promises, using the suffix Promise.
+ ifReadOnlySuffix: "_alt"
+};
+```
+
+ * `asyncSuffix` Suffix for callback-based async method call signatures.
+ * `syncSuffix` Suffix for synchronous method call signatures.
+ * `promiseSuffix` Suffix for promise-based async method call signatures
+ * `ifReadOnlySuffix` See [Static Member Name Conflicts](#staticMemberNameConflicts).
+
+See [Async Options](#asyncOptionsDetails) for details.
+
+## import
+
+
+
+*java.import(className)**
-Loads the class given by className such that it acts and feels like a javascript object.
+Loads the class given by className such that it acts and feels like a JavaScript object.
__Arguments__
- * className - The name of the class to create. For subclasses seperate using a '$' (eg. com.nearinfinty.MyClass$SubClass)
+ * className - The name of the class to create. Separate nested classes using `'$'` (eg. `com.nearinfinty.MyClass$NestedClass`).
__Example__
- var Test = java.import('Test');
+ const Test = java.import('Test');
Test.someStaticMethodSync(5);
console.log(Test.someStaticField);
-
- var value1 = Test.NestedEnum.Value1;
- var test = new Test();
+ const value1 = Test.NestedEnum.Value1;
+
+ const test = new Test();
list.instanceMethodSync('item1');
-
-**java.newInstance(className, [args...], callback)**
+## newInstance
+
+
+
+*java.newInstance(className, [args...], callback)**
**java.newInstanceSync(className, [args...]) : result**
-Creates an instance of the specified class. If you are using the sync method an exception will be throw if an error occures,
+Creates an instance of the specified class. If you are using the sync method an exception will be throw if an error occurs,
otherwise it will be the first argument in the callback.
__Arguments__
- * className - The name of the class to create. For subclasses seperate using a '$' (eg. com.nearinfinty.MyClass$SubClass)
+ * className - The name of the class to create. Separate nested classes using `'$'` (eg. `com.nearinfinty.MyClass$NestedClass`).
* callback(err, item) - Callback to be called when the class is created.
__Example__
- var list = java.newInstanceSync("java.util.ArrayList");
+ const list = java.newInstanceSync("java.util.ArrayList");
java.newInstance("java.util.ArrayList", function(err, list) {
if(err) { console.error(err); return; }
// new list
});
-
-**java.instanceOf(javaObject, className)**
+## instanceOf
+
+
+
+*java.instanceOf(javaObject, className)**
Determines of a javaObject is an instance of a class.
@@ -236,41 +445,46 @@ __Arguments__
__Example__
- var obj = java.newInstanceSync("my.package.SubClass");
+ const obj = java.newInstanceSync("my.package.SubClass");
if(java.instanceOf(obj, "my.package.SuperClass")) {
console.log("obj is an instance of SuperClass");
}
-
-**java.callStaticMethod(className, methodName, [args...], callback)**
+## callStaticMethod
+
+
+
+*java.callStaticMethod(className, methodName, [args...], callback)**
**java.callStaticMethodSync(className, methodName, [args...]) : result**
-Calls a static method on the specified class. If you are using the sync method an exception will be throw if an error occures,
-otherwise it will be the first argument in the callback.
+Calls a static method on the specified class. If you are using the sync method an exception will be throw if an error occurs, otherwise it will be the first argument in the callback.
__Arguments__
- * className - The name of the class to call the method on. For subclasses seperate using a '$' (eg. com.nearinfinty.MyClass$SubClass)
+ * className - The name of the class to call the method on. Separate nested classes using `'$'` (eg. `com.nearinfinty.MyClass$NestedClass`).
* methodName - The name of the method to call. The method name can include the full signature (see [Getting the full method signature](#getFullMethodSignature)).
* callback(err, item) - Callback to be called when the class is created.
__Example__
- var result = java.callStaticMethodSync("com.nearinfinty.MyClass", "doSomething", 42, "test");
+ const result = java.callStaticMethodSync("com.nearinfinty.MyClass", "doSomething", 42, "test");
java.callStaticMethod("com.nearinfinty.MyClass", "doSomething", 42, "test", function(err, results) {
if(err) { console.error(err); return; }
// results from doSomething
});
-
-**java.callMethod(instance, methodName, [args...], callback)**
+## callMethod
+
+
+
+*java.callMethod(instance, methodName, [args...], callback)**
**java.callMethodSync(instance, methodName, [args...]) : result**
-Calls a method on the specified instance. If you are using the sync method an exception will be throw if an error occures,
+Calls a method on the specified instance. If you are using the sync method an exception will be throw if an error occurs,
otherwise it will be the first argument in the callback.
__Arguments__
@@ -281,37 +495,43 @@ __Arguments__
__Example__
- var instance = java.newInstanceSync("com.nearinfinty.MyClass");
+ const instance = java.newInstanceSync("com.nearinfinty.MyClass");
- var result = java.callMethodSync("com.nearinfinty.MyClass", "doSomething", 42, "test");
+ const result = java.callMethodSync("com.nearinfinty.MyClass", "doSomething", 42, "test");
- java.callMethodSync(instance, "doSomething", 42, "test", function(err, results) {
+ java.callMethod(instance, "doSomething", 42, "test", function(err, results) {
if(err) { console.error(err); return; }
// results from doSomething
});
-
-**java.getStaticFieldValue(className, fieldName)**
+## getStaticFieldValue
+
+
+
+*java.getStaticFieldValue(className, fieldName)**
Gets a static field value from the specified class.
__Arguments__
- * className - The name of the class to get the value from. For subclasses seperate using a '$' (eg. com.nearinfinty.MyClass$SubClass)
+ * className - The name of the class to get the value from. Separate nested classes using `'$'` (eg. `com.nearinfinty.MyClass$NestedClass`).
* fieldName - The name of the field to get the value from.
__Example__
- var data = java.getStaticFieldValue("com.nearinfinty.MyClass", "data");
+ const data = java.getStaticFieldValue("com.nearinfinty.MyClass", "data");
-
-**java.setStaticFieldValue(className, fieldName, newValue)**
+## setStaticFieldValue
+
+
+
+*java.setStaticFieldValue(className, fieldName, newValue)**
Sets a static field value on the specified class.
__Arguments__
- * className - The name of the class to set the value on. For subclasses seperate using a '$' (eg. com.nearinfinty.MyClass$SubClass)
+ * className - The name of the class to set the value on. Separate nested classes using `'$'` (eg. `com.nearinfinty.MyClass$NestedClass`).
* fieldName - The name of the field to set the value on.
* newValue - The new value to assign to the field.
@@ -319,24 +539,30 @@ __Example__
java.setStaticFieldValue("com.nearinfinty.MyClass", "data", "Hello World");
-
-**java.newArray(className, values[])**
+## newArray
+
+
-Creates a new java array of type class.
+*java.newArray(className, values[])**
+
+Creates a new java array of given glass type. To create array of primitive types like `char`, `byte`, etc, pass the primitive type name (eg. `java.newArray("char", "hello world\n".split(''))`).
__Arguments__
- * className - The name of the type of array elements. For subclasses seperate using a '$' (eg. com.nearinfinty.MyClass$SubClass)
- * values - A javascript array of values to assign to the java array.
+ * className - The name of the type of array elements. Separate nested classes using `'$'` (eg. `com.nearinfinty.MyClass$NestedClass`).
+ * values - A JavaScript array of values to assign to the java array.
__Example__
- var newArray = java.newArray("java.lang.String", ["item1", "item2", "item3"]);
+ const newArray = java.newArray("java.lang.String", ["item1", "item2", "item3"]);
+
+## newByte
-
-**java.newByte(val)**
+
-Creates a new java byte. This is needed because javascript does not have the concept of a byte.
+*java.newByte(val)**
+
+Creates a new java byte. This is needed because JavaScript does not have the concept of a byte.
__Arguments__
@@ -344,12 +570,15 @@ __Arguments__
__Example__
- var b = java.newByte(12);
+ const b = java.newByte(12);
+
+## newShort
+
+
-
-**java.newShort(val)**
+*java.newShort(val)**
-Creates a new java short. This is needed because javascript does not have the concept of a short.
+Creates a new java short. This is needed because JavaScript does not have the concept of a short.
__Arguments__
@@ -357,12 +586,15 @@ __Arguments__
__Example__
- var s = java.newShort(12);
+ const s = java.newShort(12);
-
-**java.newLong(val)**
+## newLong
-Creates a new java long. This is needed because javascript does not have the concept of a long.
+
+
+*java.newLong(val)**
+
+Creates a new java long. This is needed because JavaScript does not have the concept of a long.
__Arguments__
@@ -370,12 +602,15 @@ __Arguments__
__Example__
- var s = java.newLong(12);
+ const s = java.newLong(12);
+
+## newChar
-
-**java.newChar(val)**
+
-Creates a new java char. This is needed because javascript does not have the concept of a char.
+*java.newChar(val)**
+
+Creates a new java char. This is needed because JavaScript does not have the concept of a char.
__Arguments__
@@ -383,12 +618,15 @@ __Arguments__
__Example__
- var ch = java.newChar('a');
+ const ch = java.newChar('a');
+
+## newDouble
+
+
-
-**java.newDouble(val)**
+*java.newDouble(val)**
-Creates a new java double. This is needed to force javascript's number to a double to call some methods.
+Creates a new java double. This is needed to force JavaScript's number to a double to call some methods.
__Arguments__
@@ -396,12 +634,15 @@ __Arguments__
__Example__
- var d = java.newDouble(3.14);
+ const d = java.newDouble(3.14);
+
+## newFloat
+
+
-
-**java.newFloat(val)**
+*java.newFloat(val)**
-Creates a new java float. This is needed to force javascript's number to a float to call some methods.
+Creates a new java float. This is needed to force JavaScript's number to a float to call some methods.
__Arguments__
@@ -409,10 +650,13 @@ __Arguments__
__Example__
- var f = java.newFloat(3.14);
+ const f = java.newFloat(3.14);
-
-**java.newProxy(interfaceName, functions)**
+## newProxy
+
+
+
+*java.newProxy(interfaceName, functions)**
Creates a new java Proxy for the given interface. Functions passed in will run on the v8 main thread and not a new thread.
@@ -421,26 +665,64 @@ garbage collection.
__Arguments__
- * interfaceName - The name of the interface to proxy. For subclasses seperate using a '$' (eg. com.nearinfinty.MyClass$SubClass)
+ * interfaceName - The name of the interface to proxy. Separate nested classes using `'$'` (eg. `com.nearinfinty.MyClass$NestedClass`).
* functions - A hash of functions matching the function in the interface.
__Example__
- var myProxy = java.newProxy('java.lang.Runnable', {
+ const myProxy = java.newProxy('java.lang.Runnable', {
run: function () {
// This is actually run on the v8 thread and not the new java thread
console.log("hello from thread");
}
});
- var thread = java.newInstanceSync("java.lang.Thread", myProxy);
+ const thread = java.newInstanceSync("java.lang.Thread", myProxy);
thread.start();
-
-## java object
+## isJvmCreated
+
+
+
+*java.isJvmCreated()**
+
+Returns true if the JVM has been created. The JVM can only be created once.
+
+## registerClient
+
+
+
+*java.registerClient(before, after)**
+
+Register that a client wants to be called back immediately before and/or immediately after the JVM is created. If used, this function must be called before the JVM has been created. The before function is typically used to add to the classpath. The function may execute asynchronous operations (such as a async glob function). The after function is sometimes useful for doing one-time initialization that requires the JVM to first be initialized. If either function is unnecessary, use `null` or `undefined`. See also `registerClientP` and `ensureJvm`. See the unit tests in `testAsyncOptions` for examples.
+
+## registerClientP
+
+
-
-**obj._methodName_([args...], callback)**
+*java.registerClientP(before, after)**
+
+Like java.registerClient, but before and after are assumed to be functions returning promises.
+
+## ensureJvm
+
+
+
+*java.ensureJvm(callback)**
+
+If the JVM has not yet been created, execute the full JVM initialization process, then call callback function when initialization is complete. If the JVM has been created, just call the callback. Note that the full initialization process includes: 1) executing all registered client *before* hooks, 2) creating the JVM, then 3) executing all registered client *after* hooks.
+
+
+
+
+
+# `java` object
+
+## Call Method
+
+
+
+*obj._methodName_([args...], callback)**
**obj._methodNameSync_([args...]) : result**
@@ -454,14 +736,17 @@ __Arguments__
__Example__
- var list = java.newInstanceSync("java.util.ArrayList");
+ const list = java.newInstanceSync("java.util.ArrayList");
list.addSync("item1");
list.add("item2", function(err, result) {
if(err) { console.error(err); return; }
});
-
-**obj._fieldName_ = val**
+## Field Access
+
+
+
+*obj._fieldName_ = val**
**val = obj._fieldName_**
@@ -470,12 +755,13 @@ field values.
__Example__
- var list = java.newInstanceSync("com.nearinfinty.MyClass");
+ const list = java.newInstanceSync("com.nearinfinty.MyClass");
list.data = "test";
- var data = list.data;
+ const data = list.data;
-
-# Getting the Full Method Signature
+## Getting the Full Method Signature
+
+
Run `javap -s -classpath `. Find the method name you are looking for. For example:
@@ -524,9 +810,9 @@ public class ShutdownHookHelper {
Compile ShutdownHookHelper and then use it as follows.
```javascript
-var java = require('./');
+const java = require('./');
java.classpath.push('.');
-var ShutdownHookHelper = java.import('ShutdownHookHelper');
+const ShutdownHookHelper = java.import('ShutdownHookHelper');
ShutdownHookHelper.setShutdownHookSync(java.newProxy('java.lang.Runnable', {
run: function () {
@@ -539,6 +825,68 @@ ShutdownHookHelper.setShutdownHookSync(java.newProxy('java.lang.Runnable', {
When you call a Java method through node-java, any arguments (V8/JavaScript objects) will be converted to Java objects on the v8 main thread via a call to v8ToJava (found in utils.cpp). The JavaScript object is not held on to and can be garbage collected by v8. If this is an async call, the reference count on the Java objects will be incremented. The Java method will be invoked in a node.js async thread (see uv_queue_work). When the method returns, the resulting object will be returned to the main v8 thread and converted to JavaScript objects via a call to javaToV8 and the Java object's reference count will then be decremented to allow for garbage collection. The resulting v8 object will then be returned to the callers callback function.
+
+
+
+# Static member name conflicts ('name', 'arguments', 'caller')
+
+The JavaScript object returned by `java.import(classname)` is a JavaScript constructor Function, implemented such that you can create instances of the Java class. For example:
+
+```javascript
+const Test = java.import('Test');
+const test = new Test();
+
+Test.someStaticMethod(function(err, result) { ... });
+
+const value1 = Test.NestedEnum.Value1;
+```
+
+But JavaScript reserves a few property names of Function objects: `name`, `arguments`, and `caller`. If your class has public static members (either methods or fields) with these names, node-java is unable to create the necessary property to implement the class's API. For example, suppose your class `Test` implements a static method named `caller`, or has a `NestedEnum` with a value `name`:
+
+```java
+public class Test {
+ ...
+ public static String caller() { return "something"; }
+ public enum NestedEnum { foo, name };
+}
+```
+
+In JavaScript, you would expect to be able to use those static members like this:
+
+```javascript
+const Test = java.import('Test');
+Test.caller(function(err, result) { ... }); // ERROR
+const value = Test.NestedEnum.name; // ERROR
+```
+
+Node-java can't create those properties, so the above code won't work. Instead, node-java appends a suffix to the name. The default suffix is simply an underscore `_`, but you can change the suffix using `asyncOptions`:
+
+```javascript
+const java = require('java');
+
+java.asyncOptions = {
+ asyncSuffix: "",
+ syncSuffix: "Sync",
+ ifReadOnlySuffix: "_alt"
+};
+
+const Test = java.import('Test');
+Test.caller_alt(function(err, result) { ... }); // OK
+const value = Test.NestedEnum.name_alt; // OK
+```
+
+# Troubleshooting
+
+## Error: Cannot find module '../build/jvm_dll_path.json'
+
+Either `./scripts/postInstall.js` didn't run or there was a problem detecting java. Try running `./scripts/postInstall.js` manually.
+
+## Debugging
+
+ npm install
+ npx node-gyp build --debug
+ gdb --args "$(which node)" ./node_modules/.bin/vitest test
+
## License
(The MIT License)
diff --git a/binding.gyp b/binding.gyp
index 66462bfd..25fa488c 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -1,37 +1,41 @@
{
'variables': {
'arch%': 'amd64', # linux JVM architecture. See $(JAVA_HOME)/jre/lib/<@(arch)/server/
+ 'uname_m': '',
'conditions': [
['target_arch=="ia32"', {
'arch%': 'i386'
}],
+ ['OS!="win"', {
+ 'uname_m': '=8.0.0"
+ }
+ },
+ "node_modules/@types/find-root": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@types/find-root/-/find-root-1.1.4.tgz",
+ "integrity": "sha512-2EXK/+gVhVgtt4JqThbEncORvpYJKzi9tQGmI3EkU2jTgMzQsrPm/hbd5xe5uPdeFzIW5gh2PRvvPjaUsI8vpg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/find-root": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
+ "license": "MIT"
+ },
+ "node_modules/java": {
+ "resolved": "../..",
+ "link": true
+ },
+ "node_modules/typescript": {
+ "version": "5.8.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
+ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ }
+ }
+}
diff --git a/examples/lucene/package.json b/examples/lucene/package.json
new file mode 100644
index 00000000..b436b24c
--- /dev/null
+++ b/examples/lucene/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "java-example-lucene",
+ "private": true,
+ "scripts": {
+ "build": "tsc --build",
+ "build:watch": "tsc --build --watch",
+ "start": "node build/example.js"
+ },
+ "dependencies": {
+ "find-root": "^1.1.0",
+ "java": "file:../.."
+ },
+ "devDependencies": {
+ "@types/find-root": "^1.1.4",
+ "typescript": "^5.8.3"
+ }
+}
diff --git a/examples/lucene/tsconfig.json b/examples/lucene/tsconfig.json
new file mode 100644
index 00000000..53c363e6
--- /dev/null
+++ b/examples/lucene/tsconfig.json
@@ -0,0 +1,113 @@
+{
+ "compilerOptions": {
+ /* Visit https://aka.ms/tsconfig to read more about this file */
+
+ /* Projects */
+ // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
+ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
+ // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
+ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
+ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
+ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
+
+ /* Language and Environment */
+ "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
+ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
+ // "jsx": "preserve", /* Specify what JSX code is generated. */
+ // "libReplacement": true, /* Enable lib replacement. */
+ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
+ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
+ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
+ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
+ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
+ // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
+ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
+ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
+ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
+
+ /* Modules */
+ "module": "commonjs", /* Specify what module code is generated. */
+ // "rootDir": "./", /* Specify the root folder within your source files. */
+ // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
+ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
+ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
+ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
+ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
+ // "types": [], /* Specify type package names to be included without being referenced in a source file. */
+ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
+ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
+ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
+ // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */
+ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
+ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
+ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
+ // "noUncheckedSideEffectImports": true, /* Check side effect imports. */
+ // "resolveJsonModule": true, /* Enable importing .json files. */
+ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
+ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
+
+ /* JavaScript Support */
+ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
+ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
+ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
+
+ /* Emit */
+ // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
+ // "declarationMap": true, /* Create sourcemaps for d.ts files. */
+ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
+ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
+ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
+ // "noEmit": true, /* Disable emitting files from a compilation. */
+ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
+ "outDir": "./build", /* Specify an output folder for all emitted files. */
+ // "removeComments": true, /* Disable emitting comments. */
+ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
+ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
+ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
+ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
+ // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
+ // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
+ // "newLine": "crlf", /* Set the newline character for emitting files. */
+ // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
+ // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
+ // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
+ // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
+ // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
+
+ /* Interop Constraints */
+ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
+ // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
+ // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
+ // "erasableSyntaxOnly": true, /* Do not allow runtime constructs that are not part of ECMAScript. */
+ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
+ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
+ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
+ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
+
+ /* Type Checking */
+ "strict": true, /* Enable all strict type-checking options. */
+ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
+ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
+ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
+ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
+ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
+ // "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */
+ // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
+ // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
+ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
+ // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
+ // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
+ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
+ // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
+ // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
+ // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
+ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
+ // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
+ // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
+ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
+
+ /* Completeness */
+ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
+ "skipLibCheck": false /* Skip type checking all .d.ts files. */
+ }
+}
diff --git a/examples/mixJavaAndNode/runMyClass.js b/examples/mixJavaAndNode/runMyClass.js
index d3fb834f..8c285c94 100755
--- a/examples/mixJavaAndNode/runMyClass.js
+++ b/examples/mixJavaAndNode/runMyClass.js
@@ -1,11 +1,9 @@
#!/usr/bin/env node
-var java = require("../../");
+const java = require("../../");
java.classpath.push("./src");
-var MyClass = java.import("com.nearinfinity.nodeJava.MyClass");
+const MyClass = java.import("com.nearinfinity.nodeJava.MyClass");
-var result = MyClass.addNumbersSync(1, 2);
+const result = MyClass.addNumbersSync(1, 2);
console.log(result);
-
-
diff --git a/findJavaHome.js b/findJavaHome.js
deleted file mode 100644
index 2421daf6..00000000
--- a/findJavaHome.js
+++ /dev/null
@@ -1,7 +0,0 @@
-require('find-java-home')(function(err, home){
- if(err){
- console.error("[node-java] "+err);
- process.exit(1);
- }
- process.stdout.write(home);
-});
diff --git a/index.js b/index.js
index f9e0d85a..73442826 100644
--- a/index.js
+++ b/index.js
@@ -1,2 +1 @@
-
-module.exports = require("./lib/nodeJavaBridge");
+module.exports = require("./src-node/nodeJavaBridge");
diff --git a/jarjar.rule b/jarjar.rule
deleted file mode 100644
index 35923389..00000000
--- a/jarjar.rule
+++ /dev/null
@@ -1 +0,0 @@
-rule org.apache.commons.lang3.** com.nearinfinity.org.apache.commons.lang3.@1
diff --git a/java.d.ts b/java.d.ts
new file mode 100644
index 00000000..c2248377
--- /dev/null
+++ b/java.d.ts
@@ -0,0 +1,343 @@
+/* eslint-disable @typescript-eslint/no-unsafe-function-type */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+declare const NodeJavaCore: NodeJavaCore.Java;
+export = NodeJavaCore;
+
+declare namespace NodeJavaCore {
+ type JavaObject = any;
+ type JavaError = Error & { cause?: JavaObject };
+
+ export interface Callback {
+ (err?: Error, result?: T): void;
+ }
+
+ export interface JavaCallback {
+ (err?: JavaError, result?: T): void;
+ }
+
+ interface AsyncOptions {
+ /**
+ * Suffix for synchronous method call signatures.
+ */
+ syncSuffix: string;
+
+ /**
+ * Suffix for callback-based async method call signatures.
+ */
+ asyncSuffix?: string | undefined;
+
+ /**
+ * Suffix for promise-based async method call signatures
+ */
+ promiseSuffix?: string | undefined;
+
+ /**
+ * The JavaScript object returned by `java.import(classname)` is a JavaScript constructor
+ * Function, implemented such that you can create instances of the Java class. For example:
+ */
+ ifReadOnlySuffix?: string | undefined;
+ }
+
+ interface ProxyFunctions {
+ [index: string]: Function;
+ }
+
+ interface Java {
+ /**
+ * Array of paths or jars to pass to the creation of the JVM.
+ *
+ * All items must be added to the classpath before calling any other node-java methods.
+ *
+ * @example
+ * java.classpath.push('commons.io.jar');
+ * java.classpath.push('src');
+ */
+ classpath: string[];
+
+ /**
+ * Array of options to pass to the creation of the JVM.
+ *
+ * All items must be added to the options before calling any other node-java methods.
+ *
+ * @example
+ * java.options.push('-Djava.awt.headless=true');
+ * java.options.push('-Xmx1024m');
+ */
+ options: string[];
+
+ /**
+ * @see AsyncOptions
+ */
+ asyncOptions: AsyncOptions;
+
+ /**
+ * Location of nodejavabridge_bindings.node
+ */
+ nativeBindingLocation: string;
+
+ /**
+ * Calls a method on the specified instance. If you are using the sync method an exception
+ * will be throw if an error occurs, otherwise it will be the first argument in the callback.
+ *
+ * @param instance An instance of the class from newInstance.
+ * @param methodName The name of the method to call. The method name can include the full
+ * signature (see [Getting the full method signature](README.md#getFullMethodSignature)).
+ * @param args The arguments to pass to the method, the last argument will be the callback to the function
+ *
+ * @example
+ * const instance = java.newInstanceSync("com.nearinfinty.MyClass");
+ * java.callMethod(instance, "doSomething", 42, "test", function(err, results) {
+ * if(err) { console.error(err); return; }
+ * // results from doSomething
+ * });
+ */
+ callMethod(instance: JavaObject, methodName: string, ...args: any[]): void;
+
+ /**
+ * Calls a method on the specified instance. If you are using the sync method an exception
+ * will be throw if an error occurs, otherwise it will be the first argument in the callback.
+ *
+ * @param instance An instance of the class from newInstance.
+ * @param methodName The name of the method to call. The method name can include the full
+ * signature (see [Getting the full method signature](README.md#getFullMethodSignature)).
+ * @param args The arguments to pass to the method
+ * @returns The result of the method call
+ *
+ * @example
+ * const instance = java.newInstanceSync("com.nearinfinty.MyClass");
+ * const result = java.callMethodSync("com.nearinfinty.MyClass", "doSomething", 42, "test");
+ */
+ callMethodSync(instance: JavaObject, methodName: string, ...args: any[]): any;
+
+ /**
+ * Calls a static method on the specified class. If you are using the sync method an exception will be
+ * throw if an error occurs, otherwise it will be the first argument in the callback.
+ *
+ * @param className The name of the class to call the method on. Separate nested classes
+ * using `'$'` (eg. `com.nearinfinty.MyClass$NestedClass`).
+ * @param methodName The name of the method to call. The method name can include the full
+ * signature (see [Getting the full method signature](README.md#getFullMethodSignature)).
+ * @param args The arguments to pass to the method, the last argument will be the callback to the function
+ */
+ callStaticMethod(className: string, methodName: string, ...args: any[]): void;
+
+ /**
+ * Calls a static method on the specified class. If you are using the sync method an exception will be
+ * throw if an error occurs, otherwise it will be the first argument in the callback.
+ *
+ * @param className The name of the class to call the method on. Separate nested classes
+ * using `'$'` (eg. `com.nearinfinty.MyClass$NestedClass`).
+ * @param methodName The name of the method to call. The method name can include the full
+ * signature (see [Getting the full method signature](README.md#getFullMethodSignature)).
+ * @param args The arguments to pass to the method
+ * @returns The result of the method call
+ */
+ callStaticMethodSync(className: string, methodName: string, ...args: any[]): any;
+
+ /**
+ * Finds the class with the specified binary name. This method should be overridden by class loader
+ * implementations that follow the delegation model for loading classes, and will be invoked by the
+ * loadClass method after checking the parent class loader for the requested class. The default
+ * implementation throws a ClassNotFoundException.
+ *
+ * @param className The binary name of the class
+ * @returns The resulting Class object
+ */
+ findClassSync(className: string): JavaObject;
+
+ /**
+ * Gets a static field value from the specified class.
+ *
+ * @param className The name of the class to get the value from. Separate nested classes
+ * using `'$'` (eg. `com.nearinfinty.MyClass$NestedClass`).
+ * @param fieldName The name of the field to get the value from.
+ * @returns The valid of the static field
+ */
+ getStaticFieldValue(className: string, fieldName: string): any;
+
+ /**
+ * Sets a static field value on the specified class.
+ *
+ * @param className The name of the class to set the value on. Separate nested classes
+ * using `'$'` (eg. `com.nearinfinty.MyClass$NestedClass`).
+ * @param fieldName The name of the field to set the value on.
+ * @param newValue The new value to assign to the field.
+ */
+ setStaticFieldValue(className: string, fieldName: string, newValue: any): void;
+
+ /**
+ * Determines of a javaObject is an instance of a class.
+ *
+ * @param javaObject Instance of a java object returned from a method or from newInstance.
+ * @param className A string class name.
+ *
+ * @example
+ * const obj = java.newInstanceSync("my.package.SubClass");
+ * if(java.instanceOf(obj, "my.package.SuperClass")) {
+ * console.log("obj is an instance of SuperClass");
+ * }
+ */
+ instanceOf(javaObject: JavaObject, className: string): boolean;
+
+ /**
+ * Register that a client wants to be called back immediately before and/or immediately
+ * after the JVM is created. If used, this function must be called before the JVM has been
+ * created. The before function is typically used to add to the classpath. The function may
+ * execute asynchronous operations (such as a async glob function). The after function is
+ * sometimes useful for doing one-time initialization that requires the JVM to first be
+ * initialized. If either function is unnecessary, use `null` or `undefined`. See also
+ * `registerClientP` and `ensureJvm`. See the unit tests in `testAsyncOptions` for examples.
+ */
+ registerClient(
+ before: ((cb: Callback) => void) | undefined | null,
+ after?: (cb: Callback) => void
+ ): void;
+
+ /**
+ * Register that a client wants to be called back immediately before and/or immediately
+ * after the JVM is created. If used, this function must be called before the JVM has been
+ * created. The before function is typically used to add to the classpath. The function may
+ * execute asynchronous operations (such as a async glob function). The after function is
+ * sometimes useful for doing one-time initialization that requires the JVM to first be
+ * initialized. If either function is unnecessary, use `null` or `undefined`. See also
+ * `registerClientP` and `ensureJvm`. See the unit tests in `testAsyncOptions` for examples.
+ */
+ registerClientP(beforeP: (() => Promise) | undefined | null, afterP?: () => Promise): void;
+
+ /**
+ * If the JVM has not yet been created, execute the full JVM initialization process, then
+ * call callback function when initialization is complete. If the JVM has been created, just
+ * call the callback. Note that the full initialization process includes: 1) executing all
+ * registered client *before* hooks, 2) creating the JVM, then 3) executing all registered
+ * client *after* hooks.
+ */
+ ensureJvm(done: Callback): void;
+
+ /**
+ * If the JVM has not yet been created, execute the full JVM initialization process, then
+ * call callback function when initialization is complete. If the JVM has been created, just
+ * call the callback. Note that the full initialization process includes: 1) executing all
+ * registered client *before* hooks, 2) creating the JVM, then 3) executing all registered
+ * client *after* hooks.
+ */
+ ensureJvm(): Promise;
+
+ /**
+ * Returns true if the JVM has been created. The JVM can only be created once.
+ */
+ isJvmCreated(): boolean;
+
+ /**
+ * Creates a new java byte. This is needed because JavaScript does not have the concept of a byte.
+ */
+ newByte(val: number): JavaObject;
+
+ /**
+ * Creates a new java short. This is needed because JavaScript does not have the concept of a short.
+ */
+ newShort(val: number): JavaObject;
+
+ /**
+ * Creates a new java long. This is needed because JavaScript does not have the concept of a long.
+ */
+ newLong(val: number): JavaObject;
+
+ /**
+ * Creates a new java char. This is needed because JavaScript does not have the concept of a char.
+ */
+ newChar(val: string | number): JavaObject;
+
+ /**
+ * Creates a new java float. This is needed to force JavaScript's number to a float to call some methods.
+ */
+ newFloat(val: number): JavaObject;
+
+ /**
+ * Creates a new java double. This is needed to force JavaScript's number to a double to call some methods.
+ */
+ newDouble(val: number): JavaObject;
+
+ /**
+ * Loads the class given by className such that it acts and feels like a JavaScript object.
+ *
+ * @param className The name of the class to create. Separate nested classes
+ * using `'$'` (eg. `com.nearinfinty.MyClass$NestedClass`).
+ *
+ * @example
+ * const Test = java.import('Test');
+ * Test.someStaticMethodSync(5);
+ * console.log(Test.someStaticField);
+ *
+ * const value1 = Test.NestedEnum.Value1;
+ *
+ * const test = new Test();
+ * list.instanceMethodSync('item1');
+ */
+ import(className: string): JavaObject;
+
+ /**
+ * Creates an instance of the specified class. If you are using the sync method an exception will
+ * be throw if an error occurs, otherwise it will be the first argument in the callback.
+ *
+ * @param className The name of the class to create. Separate nested classes
+ * using `'$'` (eg. `com.nearinfinty.MyClass$NestedClass`).
+ * @param args Arguments to pass to the constructor, the last argument is a callback function
+ */
+ newInstance(className: string, ...args: any[]): void;
+
+ /**
+ * Creates an instance of the specified class. If you are using the sync method an exception will
+ * be throw if an error occurs, otherwise it will be the first argument in the callback.
+ *
+ * @param className The name of the class to create. Separate nested classes
+ * using `'$'` (eg. `com.nearinfinty.MyClass$NestedClass`).
+ * @param args Arguments to pass to the constructor
+ */
+ newInstanceSync(className: string, ...args: any[]): JavaObject;
+
+ /**
+ * Creates a new java array of given glass type. To create array of primitive types
+ * like `char`, `byte`, etc, pass the primitive typename
+ * (eg. `java.newArray("char", "hello world\n".split(''))`).
+ *
+ * @param className The name of the type of array elements. Separate nested classes
+ * using `'$'` (eg. `com.nearinfinty.MyClass$NestedClass`).
+ * @param arg A JavaScript array of values to assign to the java array.
+ */
+ newArray(className: string, arg: any[]): JavaObject;
+
+ /**
+ * Get the current class loader
+ */
+ getClassLoader(): JavaObject;
+
+ /**
+ * Creates a new java Proxy for the given interface. Functions passed in will run on the v8
+ * main thread and not a new thread.
+ *
+ * The returned object has a method unref() which you can use to free the object for garbage
+ * collection.
+ *
+ * @param interfaceName The name of the interface to proxy. Separate nested classes
+ * using `'$'` (eg. `com.nearinfinty.MyClass$NestedClass`).
+ * @param functions A hash of functions matching the function in the interface.
+ *
+ * @example
+ * const myProxy = java.newProxy('java.lang.Runnable', {
+ * run: function () {
+ * // This is actually run on the v8 thread and not the new java thread
+ * console.log("hello from thread");
+ * }
+ * });
+ *
+ * const thread = java.newInstanceSync("java.lang.Thread", myProxy);
+ * thread.start();
+ */
+ newProxy(interfaceName: string, functions: ProxyFunctions): JavaObject;
+
+ /**
+ * Stops the running event loop
+ */
+ stop(): void;
+ }
+}
diff --git a/lib/nodeJavaBridge.js b/lib/nodeJavaBridge.js
deleted file mode 100644
index a72b8c6b..00000000
--- a/lib/nodeJavaBridge.js
+++ /dev/null
@@ -1,81 +0,0 @@
-'use strict';
-
-process.env.PATH += require('../build/jvm_dll_path.json');
-
-var path = require('path');
-var binaryPath = path.resolve(path.join(__dirname, "../build/Release/nodejavabridge_bindings.node"));
-var bindings = require(binaryPath);
-
-var java = module.exports = new bindings.Java();
-java.classpath.push(path.resolve(__dirname, "../commons-lang3-node-java.jar"));
-java.classpath.push(path.resolve(__dirname, __dirname, "../src-java"));
-java.nativeBindingLocation = binaryPath;
-
-var MODIFIER_PUBLIC = 1;
-var MODIFIER_STATIC = 8;
-
-java.import = function(name) {
- var clazz = java.findClassSync(name); // TODO: change to Class.forName when classloader issue is resolved.
- var result = function() {
- var args = [name];
- for (var i = 0; i < arguments.length; i++) {
- args.push(arguments[i]);
- }
- return java.newInstanceSync.apply(java, args);
- };
- var i;
-
- result.class = clazz;
-
- // copy static fields
- var fields = clazz.getDeclaredFieldsSync();
- for (i = 0; i < fields.length; i++) {
- if (((fields[i].getModifiersSync() & MODIFIER_PUBLIC) === MODIFIER_PUBLIC)
- && ((fields[i].getModifiersSync() & MODIFIER_STATIC) === MODIFIER_STATIC)) {
- var fieldName = fields[i].getNameSync();
- result.__defineGetter__(fieldName, function(name, fieldName) {
- return java.getStaticFieldValue(name, fieldName);
- }.bind(this, name, fieldName));
- result.__defineSetter__(fieldName, function(name, fieldName, val) {
- java.setStaticFieldValue(name, fieldName, val);
- }.bind(this, name, fieldName));
- }
- }
-
- // copy static methods
- var methods = clazz.getDeclaredMethodsSync();
- for (i = 0; i < methods.length; i++) {
- if (((methods[i].getModifiersSync() & MODIFIER_PUBLIC) === MODIFIER_PUBLIC)
- && ((methods[i].getModifiersSync() & MODIFIER_STATIC) === MODIFIER_STATIC)) {
- var methodName = methods[i].getNameSync();
- result[methodName + 'Sync'] = java.callStaticMethodSync.bind(java, name, methodName);
- result[methodName] = java.callStaticMethod.bind(java, name, methodName);
- }
- }
-
- // copy static classes/enums
- var classes = clazz.getDeclaredClassesSync();
- for (i = 0; i < classes.length; i++) {
- if (((classes[i].getModifiersSync() & MODIFIER_PUBLIC) === MODIFIER_PUBLIC)
- && ((classes[i].getModifiersSync() & MODIFIER_STATIC) === MODIFIER_STATIC)) {
- var className = classes[i].getNameSync();
- var simpleName = classes[i].getSimpleNameSync();
- Object.defineProperty(result, simpleName, {
- get: function(result, simpleName, className) {
- var c = java.import(className);
-
- // memoize the import
- var d = Object.getOwnPropertyDescriptor(result, simpleName);
- d.get = function(c) { return c; }.bind(null, c);
- Object.defineProperty(result, simpleName, d);
-
- return c;
- }.bind(this, result, simpleName, className),
- enumerable: true,
- configurable: true
- });
- }
- }
-
- return result;
-};
diff --git a/mnm.js b/mnm.js
deleted file mode 100755
index f3ac930b..00000000
--- a/mnm.js
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env node
-
-var path = require('path');
-var fs = require('fs');
-var Builder = require('mnm');
-var builder = new Builder();
-
-var existsSync = fs.existsSync || path.existsSync;
-var javaHome = builder.trimQuotes(process.env["JAVA_HOME"]);
-
-builder.appendUnique('CXXFLAGS', ['-Isrc/']);
-builder.appendUnique('CXXFLAGS', ['-DHAVE_CONFIG_H']);
-
-// MAC has a built in JVM
-if (existsSync("/System/Library/Frameworks/JavaVM.framework/")) {
- var jdkIncludeDir = "/System/Library/Frameworks/JavaVM.framework/Headers";
- if(process.env["JDK_INCLUDE_DIR"]) jdkIncludeDir = process.env["JDK_INCLUDE_DIR"];
- else if(javaHome && javaHome.substr(0, 7) !== '/System') jdkIncludeDir = path.join(javaHome, 'include');
-
- builder.appendUnique('CXXFLAGS', '-I' + jdkIncludeDir);
- if(jdkIncludeDir.substr(0, 7) !== '/System') builder.appendUnique('CXXFLAGS', '-I' + path.join(jdkIncludeDir, 'darwin'));
- builder.appendUnique('LINKFLAGS', ['-framework', 'JavaVM']);
-} else {
- // JDK Include directory
- var jdkIncludeDir = process.env["JDK_INCLUDE_DIR"];
- if (!javaHome && !jdkIncludeDir) {
- builder.fail("You must set JAVA_HOME or JDK_INCLUDE_DIR environment variable");
- }
- jdkIncludeDir = jdkIncludeDir || path.join(javaHome, "include");
- builder.failIfNotExists(jdkIncludeDir, 'Could not find "%s" check JAVA_HOME or JDK_INCLUDE_DIR environment variable.');
- builder.appendUnique('CXXFLAGS', '-I' + jdkIncludeDir);
-
- // JDK additional include directory
- var jdkAdditionalIncludeDirGuess;
- if (process.platform == 'win32') {
- jdkAdditionalIncludeDirGuess = path.join(jdkIncludeDir, "win32");
- } else {
- jdkAdditionalIncludeDirGuess = path.join(jdkIncludeDir, "linux");
- }
- var jdkAdditionalIncludeDir = process.env["JDK_AUX_INCLUDE_DIR"] || jdkAdditionalIncludeDirGuess;
- builder.failIfNotExists(jdkAdditionalIncludeDir, 'Could not find "%s" check JAVA_HOME or JDK_AUX_INCLUDE_DIR environment variable.');
- builder.appendUnique('CXXFLAGS', '-I' + jdkAdditionalIncludeDir);
-
- // JDK lib directory
- if (process.platform == 'win32') {
- var jdkLibDir = process.env["JDK_LIB_DIR"] || path.join(javaHome, "lib");
- if (!jdkLibDir) {
- builder.fail("You must set JAVA_HOME or JDK_LIB_DIR environment variable");
- }
- builder.appendLinkerSearchDir(jdkLibDir);
- } else {
- var jdkLibDirGuess = null;
- if (javaHome) {
- if (existsSync(path.join(javaHome, "/jre/lib/i386/server/"))) {
- jdkLibDirGuess = path.join(javaHome, "/jre/lib/i386/server/");
- } else {
- jdkLibDirGuess = path.join(javaHome, "/jre/lib/amd64/server/");
- }
- }
- var jdkLibDir = process.env["JDK_LIB_DIR"];
- if (!jdkLibDirGuess && !jdkLibDir) {
- builder.fail("You must set JAVA_HOME or JDK_LIB_DIR environment variable");
- }
- jdkLibDir = jdkLibDir || jdkLibDirGuess;
- builder.failIfNotExists(jdkLibDir, 'Could not find "%s" check JAVA_HOME or JDK_LIB_DIR environment variable.');
- builder.appendLinkerSearchDir(jdkLibDir);
- builder.appendUnique('LINKFLAGS', '-Wl,-rpath,' + jdkLibDir);
- }
-
- builder.appendLinkerLibrary('jvm');
-}
-
-builder.target = "nodejavabridge_bindings";
-builder.appendSourceDir('./src');
-builder.appendUnique('CXXFLAGS', '-Isrc/');
-
-builder.run();
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..fb5faeba
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,3589 @@
+{
+ "name": "java",
+ "version": "0.18.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "java",
+ "version": "0.18.0",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-java-home": "^2.0.0",
+ "glob": "^11.0.3",
+ "nan": "^2.23.0",
+ "node-gyp": "^11.5.0"
+ },
+ "devDependencies": {
+ "@eslint/js": "^9.37.0",
+ "@types/find-root": "^1.1.4",
+ "@types/node": "^24.8.0",
+ "chalk": "^5.6.2",
+ "eslint": "^9.37.0",
+ "find-root": "^1.1.0",
+ "globals": "^16.4.0",
+ "prettier": "^3.6.2",
+ "typescript": "^5.9.3",
+ "typescript-eslint": "^8.46.1",
+ "vitest": "^3.2.4"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz",
+ "integrity": "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
+ "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz",
+ "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.6",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.0.tgz",
+ "integrity": "sha512-WUFvV4WoIwW8Bv0KeKCIIEgdSiFOsulyN0xrMu+7z43q/hkOLXjvb5u7UC9jDxvRzcrbEmuZBX5yJZz1741jog==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.16.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.16.0",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz",
+ "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
+ "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.37.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.37.0.tgz",
+ "integrity": "sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
+ "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz",
+ "integrity": "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.16.0",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.6",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz",
+ "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz",
+ "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
+ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@isaacs/balanced-match": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
+ "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==",
+ "license": "MIT",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/@isaacs/brace-expansion": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz",
+ "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==",
+ "license": "MIT",
+ "dependencies": {
+ "@isaacs/balanced-match": "^4.0.1"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@isaacs/fs-minipass": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
+ "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.4"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@npmcli/agent": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz",
+ "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==",
+ "license": "ISC",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.1",
+ "lru-cache": "^10.0.1",
+ "socks-proxy-agent": "^8.0.3"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@npmcli/agent/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "license": "ISC"
+ },
+ "node_modules/@npmcli/fs": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-4.0.0.tgz",
+ "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==",
+ "license": "ISC",
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.4.tgz",
+ "integrity": "sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@types/chai": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz",
+ "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/deep-eql": "*"
+ }
+ },
+ "node_modules/@types/deep-eql": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
+ "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/find-root": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@types/find-root/-/find-root-1.1.4.tgz",
+ "integrity": "sha512-2EXK/+gVhVgtt4JqThbEncORvpYJKzi9tQGmI3EkU2jTgMzQsrPm/hbd5xe5uPdeFzIW5gh2PRvvPjaUsI8vpg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "24.8.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.8.0.tgz",
+ "integrity": "sha512-5x08bUtU8hfboMTrJ7mEO4CpepS9yBwAqcL52y86SWNmbPX8LVbNs3EP4cNrIZgdjk2NAlP2ahNihozpoZIxSg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "undici-types": "~7.14.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.46.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.1.tgz",
+ "integrity": "sha512-rUsLh8PXmBjdiPY+Emjz9NX2yHvhS11v0SR6xNJkm5GM1MO9ea/1GoDKlHHZGrOJclL/cZ2i/vRUYVtjRhrHVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "8.46.1",
+ "@typescript-eslint/type-utils": "8.46.1",
+ "@typescript-eslint/utils": "8.46.1",
+ "@typescript-eslint/visitor-keys": "8.46.1",
+ "graphemer": "^1.4.0",
+ "ignore": "^7.0.0",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.46.1",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.46.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.1.tgz",
+ "integrity": "sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.46.1",
+ "@typescript-eslint/types": "8.46.1",
+ "@typescript-eslint/typescript-estree": "8.46.1",
+ "@typescript-eslint/visitor-keys": "8.46.1",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.46.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.1.tgz",
+ "integrity": "sha512-FOIaFVMHzRskXr5J4Jp8lFVV0gz5ngv3RHmn+E4HYxSJ3DgDzU7fVI1/M7Ijh1zf6S7HIoaIOtln1H5y8V+9Zg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/tsconfig-utils": "^8.46.1",
+ "@typescript-eslint/types": "^8.46.1",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.46.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.1.tgz",
+ "integrity": "sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.46.1",
+ "@typescript-eslint/visitor-keys": "8.46.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/tsconfig-utils": {
+ "version": "8.46.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.1.tgz",
+ "integrity": "sha512-X88+J/CwFvlJB+mK09VFqx5FE4H5cXD+H/Bdza2aEWkSb8hnWIQorNcscRl4IEo1Cz9VI/+/r/jnGWkbWPx54g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.46.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.1.tgz",
+ "integrity": "sha512-+BlmiHIiqufBxkVnOtFwjah/vrkF4MtKKvpXrKSPLCkCtAp8H01/VV43sfqA98Od7nJpDcFnkwgyfQbOG0AMvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.46.1",
+ "@typescript-eslint/typescript-estree": "8.46.1",
+ "@typescript-eslint/utils": "8.46.1",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.46.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.1.tgz",
+ "integrity": "sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.46.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.1.tgz",
+ "integrity": "sha512-uIifjT4s8cQKFQ8ZBXXyoUODtRoAd7F7+G8MKmtzj17+1UbdzFl52AzRyZRyKqPHhgzvXunnSckVu36flGy8cg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/project-service": "8.46.1",
+ "@typescript-eslint/tsconfig-utils": "8.46.1",
+ "@typescript-eslint/types": "8.46.1",
+ "@typescript-eslint/visitor-keys": "8.46.1",
+ "debug": "^4.3.4",
+ "fast-glob": "^3.3.2",
+ "is-glob": "^4.0.3",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.46.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.1.tgz",
+ "integrity": "sha512-vkYUy6LdZS7q1v/Gxb2Zs7zziuXN0wxqsetJdeZdRe/f5dwJFglmuvZBfTUivCtjH725C1jWCDfpadadD95EDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.7.0",
+ "@typescript-eslint/scope-manager": "8.46.1",
+ "@typescript-eslint/types": "8.46.1",
+ "@typescript-eslint/typescript-estree": "8.46.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.46.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.1.tgz",
+ "integrity": "sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.46.1",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@vitest/expect": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz",
+ "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/chai": "^5.2.2",
+ "@vitest/spy": "3.2.4",
+ "@vitest/utils": "3.2.4",
+ "chai": "^5.2.0",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/mocker": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz",
+ "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/spy": "3.2.4",
+ "estree-walker": "^3.0.3",
+ "magic-string": "^0.30.17"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "msw": "^2.4.9",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "msw": {
+ "optional": true
+ },
+ "vite": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vitest/pretty-format": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz",
+ "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/runner": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz",
+ "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/utils": "3.2.4",
+ "pathe": "^2.0.3",
+ "strip-literal": "^3.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/snapshot": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz",
+ "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "3.2.4",
+ "magic-string": "^0.30.17",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/spy": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz",
+ "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyspy": "^4.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/utils": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz",
+ "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "3.2.4",
+ "loupe": "^3.1.4",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/abbrev": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz",
+ "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==",
+ "license": "ISC",
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
+ "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/assertion-error": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cac": {
+ "version": "6.7.14",
+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cacache": {
+ "version": "19.0.1",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-19.0.1.tgz",
+ "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==",
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/fs": "^4.0.0",
+ "fs-minipass": "^3.0.0",
+ "glob": "^10.2.2",
+ "lru-cache": "^10.0.1",
+ "minipass": "^7.0.3",
+ "minipass-collect": "^2.0.1",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "p-map": "^7.0.2",
+ "ssri": "^12.0.0",
+ "tar": "^7.4.3",
+ "unique-filename": "^4.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/cacache/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/cacache/node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/cacache/node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/cacache/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "license": "ISC"
+ },
+ "node_modules/cacache/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/cacache/node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chai": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz",
+ "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assertion-error": "^2.0.1",
+ "check-error": "^2.1.1",
+ "deep-eql": "^5.0.1",
+ "loupe": "^3.1.0",
+ "pathval": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/check-error": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
+ "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 16"
+ }
+ },
+ "node_modules/chownr": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
+ "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==",
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "license": "MIT"
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/cross-spawn/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-eql": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
+ "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "license": "MIT"
+ },
+ "node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "license": "MIT"
+ },
+ "node_modules/encoding": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
+ "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "iconv-lite": "^0.6.2"
+ }
+ },
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/err-code": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
+ "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
+ "license": "MIT"
+ },
+ "node_modules/es-module-lexer": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
+ "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/esbuild": {
+ "version": "0.25.11",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.11.tgz",
+ "integrity": "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.11",
+ "@esbuild/android-arm": "0.25.11",
+ "@esbuild/android-arm64": "0.25.11",
+ "@esbuild/android-x64": "0.25.11",
+ "@esbuild/darwin-arm64": "0.25.11",
+ "@esbuild/darwin-x64": "0.25.11",
+ "@esbuild/freebsd-arm64": "0.25.11",
+ "@esbuild/freebsd-x64": "0.25.11",
+ "@esbuild/linux-arm": "0.25.11",
+ "@esbuild/linux-arm64": "0.25.11",
+ "@esbuild/linux-ia32": "0.25.11",
+ "@esbuild/linux-loong64": "0.25.11",
+ "@esbuild/linux-mips64el": "0.25.11",
+ "@esbuild/linux-ppc64": "0.25.11",
+ "@esbuild/linux-riscv64": "0.25.11",
+ "@esbuild/linux-s390x": "0.25.11",
+ "@esbuild/linux-x64": "0.25.11",
+ "@esbuild/netbsd-arm64": "0.25.11",
+ "@esbuild/netbsd-x64": "0.25.11",
+ "@esbuild/openbsd-arm64": "0.25.11",
+ "@esbuild/openbsd-x64": "0.25.11",
+ "@esbuild/openharmony-arm64": "0.25.11",
+ "@esbuild/sunos-x64": "0.25.11",
+ "@esbuild/win32-arm64": "0.25.11",
+ "@esbuild/win32-ia32": "0.25.11",
+ "@esbuild/win32-x64": "0.25.11"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.37.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.37.0.tgz",
+ "integrity": "sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.8.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.21.0",
+ "@eslint/config-helpers": "^0.4.0",
+ "@eslint/core": "^0.16.0",
+ "@eslint/eslintrc": "^3.3.1",
+ "@eslint/js": "9.37.0",
+ "@eslint/plugin-kit": "^0.4.0",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/eslint/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/expect-type": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.1.tgz",
+ "integrity": "sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/exponential-backoff": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz",
+ "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw=="
+ },
+ "node_modules/fast-deep-equal": {
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-java-home": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/find-java-home/-/find-java-home-2.0.0.tgz",
+ "integrity": "sha512-m4Cf5WM5Y9UupofsLgcJuY5oFXVfVnfHx43pg3HJoVdtY2PN4Wfs7ex9svf7W7eLTP+6wmyBToaqGOCffHBHVA==",
+ "dependencies": {
+ "which": "~1.0.5",
+ "winreg": "~1.2.2"
+ }
+ },
+ "node_modules/find-root": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/fs-minipass": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz",
+ "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/glob": {
+ "version": "11.0.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz",
+ "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==",
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.3.1",
+ "jackspeak": "^4.1.1",
+ "minimatch": "^10.0.3",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^2.0.0"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/glob/node_modules/minimatch": {
+ "version": "10.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz",
+ "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==",
+ "license": "ISC",
+ "dependencies": {
+ "@isaacs/brace-expansion": "^5.0.0"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/globals": {
+ "version": "16.4.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz",
+ "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "license": "ISC"
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/http-cache-semantics": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz",
+ "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/ip-address": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
+ "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
+ "license": "MIT",
+ "dependencies": {
+ "jsbn": "1.1.0",
+ "sprintf-js": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "license": "ISC"
+ },
+ "node_modules/jackspeak": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz",
+ "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz",
+ "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsbn": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
+ "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==",
+ "license": "MIT"
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/loupe": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz",
+ "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lru-cache": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz",
+ "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==",
+ "license": "ISC",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.19",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz",
+ "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/make-fetch-happen": {
+ "version": "14.0.3",
+ "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz",
+ "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==",
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/agent": "^3.0.0",
+ "cacache": "^19.0.1",
+ "http-cache-semantics": "^4.1.1",
+ "minipass": "^7.0.2",
+ "minipass-fetch": "^4.0.0",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "negotiator": "^1.0.0",
+ "proc-log": "^5.0.0",
+ "promise-retry": "^2.0.1",
+ "ssri": "^12.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/micromatch/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/minipass-collect": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz",
+ "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/minipass-fetch": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.1.tgz",
+ "integrity": "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==",
+ "license": "MIT",
+ "dependencies": {
+ "minipass": "^7.0.3",
+ "minipass-sized": "^1.0.3",
+ "minizlib": "^3.0.1"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ },
+ "optionalDependencies": {
+ "encoding": "^0.1.13"
+ }
+ },
+ "node_modules/minipass-flush": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
+ "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/minipass-flush/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-flush/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "license": "ISC"
+ },
+ "node_modules/minipass-pipeline": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
+ "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-pipeline/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-pipeline/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "license": "ISC"
+ },
+ "node_modules/minipass-sized": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
+ "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-sized/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-sized/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "license": "ISC"
+ },
+ "node_modules/minizlib": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz",
+ "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==",
+ "license": "MIT",
+ "dependencies": {
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
+ "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
+ "license": "MIT",
+ "bin": {
+ "mkdirp": "dist/cjs/src/bin.js"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/nan": {
+ "version": "2.23.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz",
+ "integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==",
+ "license": "MIT"
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/negotiator": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
+ "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/node-gyp": {
+ "version": "11.5.0",
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.5.0.tgz",
+ "integrity": "sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ==",
+ "license": "MIT",
+ "dependencies": {
+ "env-paths": "^2.2.0",
+ "exponential-backoff": "^3.1.1",
+ "graceful-fs": "^4.2.6",
+ "make-fetch-happen": "^14.0.3",
+ "nopt": "^8.0.0",
+ "proc-log": "^5.0.0",
+ "semver": "^7.3.5",
+ "tar": "^7.4.3",
+ "tinyglobby": "^0.2.12",
+ "which": "^5.0.0"
+ },
+ "bin": {
+ "node-gyp": "bin/node-gyp.js"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/node-gyp/node_modules/isexe": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz",
+ "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/node-gyp/node_modules/which": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz",
+ "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==",
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^3.1.1"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/nopt": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz",
+ "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==",
+ "license": "ISC",
+ "dependencies": {
+ "abbrev": "^3.0.0"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-map": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz",
+ "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+ "license": "BlueOak-1.0.0"
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-scurry": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
+ "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^11.0.0",
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pathval": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz",
+ "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.16"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
+ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/proc-log": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz",
+ "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==",
+ "license": "ISC",
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/promise-retry": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
+ "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
+ "license": "MIT",
+ "dependencies": {
+ "err-code": "^2.0.2",
+ "retry": "^0.12.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/retry": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+ "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.52.4",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.4.tgz",
+ "integrity": "sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.8"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.52.4",
+ "@rollup/rollup-android-arm64": "4.52.4",
+ "@rollup/rollup-darwin-arm64": "4.52.4",
+ "@rollup/rollup-darwin-x64": "4.52.4",
+ "@rollup/rollup-freebsd-arm64": "4.52.4",
+ "@rollup/rollup-freebsd-x64": "4.52.4",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.52.4",
+ "@rollup/rollup-linux-arm-musleabihf": "4.52.4",
+ "@rollup/rollup-linux-arm64-gnu": "4.52.4",
+ "@rollup/rollup-linux-arm64-musl": "4.52.4",
+ "@rollup/rollup-linux-loong64-gnu": "4.52.4",
+ "@rollup/rollup-linux-ppc64-gnu": "4.52.4",
+ "@rollup/rollup-linux-riscv64-gnu": "4.52.4",
+ "@rollup/rollup-linux-riscv64-musl": "4.52.4",
+ "@rollup/rollup-linux-s390x-gnu": "4.52.4",
+ "@rollup/rollup-linux-x64-gnu": "4.52.4",
+ "@rollup/rollup-linux-x64-musl": "4.52.4",
+ "@rollup/rollup-openharmony-arm64": "4.52.4",
+ "@rollup/rollup-win32-arm64-msvc": "4.52.4",
+ "@rollup/rollup-win32-ia32-msvc": "4.52.4",
+ "@rollup/rollup-win32-x64-gnu": "4.52.4",
+ "@rollup/rollup-win32-x64-msvc": "4.52.4",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/siginfo": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
+ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/smart-buffer": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socks": {
+ "version": "2.8.4",
+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz",
+ "integrity": "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ip-address": "^9.0.5",
+ "smart-buffer": "^4.2.0"
+ },
+ "engines": {
+ "node": ">= 10.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/socks-proxy-agent": {
+ "version": "8.0.5",
+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz",
+ "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "^4.3.4",
+ "socks": "^2.8.3"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
+ "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/ssri": {
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz",
+ "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/stackback": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
+ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/std-env": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz",
+ "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "license": "MIT"
+ },
+ "node_modules/string-width-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-literal": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz",
+ "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^9.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/tar": {
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz",
+ "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==",
+ "license": "ISC",
+ "dependencies": {
+ "@isaacs/fs-minipass": "^4.0.0",
+ "chownr": "^3.0.0",
+ "minipass": "^7.1.2",
+ "minizlib": "^3.0.1",
+ "mkdirp": "^3.0.1",
+ "yallist": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tinybench": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
+ "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyexec": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
+ "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.15",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tinypool": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz",
+ "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ }
+ },
+ "node_modules/tinyrainbow": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz",
+ "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/tinyspy": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz",
+ "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
+ "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/typescript-eslint": {
+ "version": "8.46.1",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.46.1.tgz",
+ "integrity": "sha512-VHgijW803JafdSsDO8I761r3SHrgk4T00IdyQ+/UsthtgPRsBWQLqoSxOolxTpxRKi1kGXK0bSz4CoAc9ObqJA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.46.1",
+ "@typescript-eslint/parser": "8.46.1",
+ "@typescript-eslint/typescript-estree": "8.46.1",
+ "@typescript-eslint/utils": "8.46.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "7.14.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.14.0.tgz",
+ "integrity": "sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unique-filename": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz",
+ "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==",
+ "license": "ISC",
+ "dependencies": {
+ "unique-slug": "^5.0.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/unique-slug": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz",
+ "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==",
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/vite": {
+ "version": "7.1.10",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.10.tgz",
+ "integrity": "sha512-CmuvUBzVJ/e3HGxhg6cYk88NGgTnBoOo7ogtfJJ0fefUWAxN/WDSUa50o+oVBxuIhO8FoEZW0j2eW7sfjs5EtA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "esbuild": "^0.25.0",
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3",
+ "postcss": "^8.5.6",
+ "rollup": "^4.43.0",
+ "tinyglobby": "^0.2.15"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "lightningcss": "^1.21.0",
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-node": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz",
+ "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cac": "^6.7.14",
+ "debug": "^4.4.1",
+ "es-module-lexer": "^1.7.0",
+ "pathe": "^2.0.3",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
+ },
+ "bin": {
+ "vite-node": "vite-node.mjs"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/vitest": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz",
+ "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/chai": "^5.2.2",
+ "@vitest/expect": "3.2.4",
+ "@vitest/mocker": "3.2.4",
+ "@vitest/pretty-format": "^3.2.4",
+ "@vitest/runner": "3.2.4",
+ "@vitest/snapshot": "3.2.4",
+ "@vitest/spy": "3.2.4",
+ "@vitest/utils": "3.2.4",
+ "chai": "^5.2.0",
+ "debug": "^4.4.1",
+ "expect-type": "^1.2.1",
+ "magic-string": "^0.30.17",
+ "pathe": "^2.0.3",
+ "picomatch": "^4.0.2",
+ "std-env": "^3.9.0",
+ "tinybench": "^2.9.0",
+ "tinyexec": "^0.3.2",
+ "tinyglobby": "^0.2.14",
+ "tinypool": "^1.1.1",
+ "tinyrainbow": "^2.0.0",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0",
+ "vite-node": "3.2.4",
+ "why-is-node-running": "^2.3.0"
+ },
+ "bin": {
+ "vitest": "vitest.mjs"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@edge-runtime/vm": "*",
+ "@types/debug": "^4.1.12",
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "@vitest/browser": "3.2.4",
+ "@vitest/ui": "3.2.4",
+ "happy-dom": "*",
+ "jsdom": "*"
+ },
+ "peerDependenciesMeta": {
+ "@edge-runtime/vm": {
+ "optional": true
+ },
+ "@types/debug": {
+ "optional": true
+ },
+ "@types/node": {
+ "optional": true
+ },
+ "@vitest/browser": {
+ "optional": true
+ },
+ "@vitest/ui": {
+ "optional": true
+ },
+ "happy-dom": {
+ "optional": true
+ },
+ "jsdom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/which": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz",
+ "integrity": "sha1-RgwdoPgQED0DIam2M6+eV15kSG8=",
+ "bin": {
+ "which": "bin/which"
+ }
+ },
+ "node_modules/why-is-node-running": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
+ "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "siginfo": "^2.0.0",
+ "stackback": "0.0.2"
+ },
+ "bin": {
+ "why-is-node-running": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/winreg": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.4.tgz",
+ "integrity": "sha1-ugZWKbepJRMOFXeRCM9UCZDpjRs="
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",
+ "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==",
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index 358dbc77..df60ce65 100644
--- a/package.json
+++ b/package.json
@@ -7,9 +7,9 @@
"jvm",
"bridge"
],
- "version": "0.4.2",
+ "version": "0.18.0",
"engines": {
- "node": ">=0.8.0"
+ "node": ">=8.0.0"
},
"maintainers": [
{
@@ -26,17 +26,36 @@
"url": "https://github.com/joeferner/node-java.git"
},
"dependencies": {
- "find-java-home": "0.1.1",
- "glob": "~3.2.9",
- "nan": "1.2.0"
+ "find-java-home": "^2.0.0",
+ "glob": "^11.0.3",
+ "nan": "^2.23.0",
+ "node-gyp": "^11.5.0"
},
"devDependencies": {
- "async": "~0.1.22",
- "nodeunit": "0.9.0"
+ "@eslint/js": "^9.37.0",
+ "@types/find-root": "^1.1.4",
+ "@types/node": "^24.8.0",
+ "chalk": "^5.6.2",
+ "eslint": "^9.37.0",
+ "find-root": "^1.1.0",
+ "globals": "^16.4.0",
+ "prettier": "^3.6.2",
+ "typescript": "^5.9.3",
+ "typescript-eslint": "^8.46.1",
+ "vitest": "^3.2.4"
},
"scripts": {
- "test": "nodeunit test",
- "postinstall": "node postInstall.js"
+ "install": "node-gyp rebuild",
+ "clean": "rm -rf build",
+ "test": "tsc && node ./build/ts/scripts/testRunner.js",
+ "postinstall": "node ./scripts/postInstall.js",
+ "lint": "eslint --ext js,ts,tsx --report-unused-disable-directives --max-warnings 0 .",
+ "format": "prettier --write .",
+ "format-cpp": "clang-format --version; find src-cpp/ -iname '*.h' -o -iname '*.cpp' | xargs clang-format -i",
+ "build-ts": "tsc",
+ "build-ts:watch": "tsc --watch",
+ "precommit": "npm run format-cpp && npm run format && npm run lint && npm run build-ts && npm test"
},
- "main": "./index.js"
+ "main": "./index.js",
+ "types": "./java.d.ts"
}
diff --git a/postInstall.js b/postInstall.js
deleted file mode 100644
index 6a9c2987..00000000
--- a/postInstall.js
+++ /dev/null
@@ -1,27 +0,0 @@
-var glob = require('glob');
-var fs = require('fs');
-var path = require('path');
-
-require('find-java-home')(function(err, home){
- var dll;
- var dylib;
- var so;
- var binary;
-
- if(home){
- dll = glob.sync('**/jvm.dll', {cwd: home})[0];
- so = glob.sync('**/libjvm.so', {cwd: home})[0];
- dylib = glob.sync('**/libjvm.dylib', {cwd: home})[0];
- binary = dll || dylib || so;
-
- fs.writeFileSync(
- path.resolve(__dirname, './build/jvm_dll_path.json'),
- binary
- ? JSON.stringify(
- path.delimiter
- + path.dirname(path.resolve(home, binary))
- )
- : '""'
- );
- }
-});
diff --git a/scripts/commons-lang/.gitignore b/scripts/commons-lang/.gitignore
new file mode 100644
index 00000000..8b8c81d7
--- /dev/null
+++ b/scripts/commons-lang/.gitignore
@@ -0,0 +1,2 @@
+target/
+dependency-reduced-pom.xml
diff --git a/scripts/commons-lang/pom.xml b/scripts/commons-lang/pom.xml
new file mode 100644
index 00000000..11c3470b
--- /dev/null
+++ b/scripts/commons-lang/pom.xml
@@ -0,0 +1,40 @@
+
+ 4.0.0
+ commons-lang
+ commons-lang
+ 1
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.19.0
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.6.0
+
+
+ package
+
+ shade
+
+
+
+
+ org.apache
+ nodejava.org.apache
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/scripts/compile-java.sh b/scripts/compile-java.sh
new file mode 100755
index 00000000..ba590fe8
--- /dev/null
+++ b/scripts/compile-java.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+set -eu
+
+SCRIPT_DIR=$(dirname "$0")
+cd "${SCRIPT_DIR}/.."
+
+if [ -z "${JAVA_HOME:-}" ] && [ -e "/usr/libexec/java_home" ]; then
+ export JAVA_HOME=$(/usr/libexec/java_home -v 11)
+fi
+
+echo "Using $(javac -version)."
+set -x
+
+javac -source 1.8 -target 1.8 src-java/node/*.java
+javac -source 1.8 -target 1.8 test/*.java
+javac -classpath src-java -h ./src-cpp src-java/node/NodeDynamicProxyClass.java
+echo "complete!"
diff --git a/scripts/findJavaHome.js b/scripts/findJavaHome.js
new file mode 100644
index 00000000..53ffa337
--- /dev/null
+++ b/scripts/findJavaHome.js
@@ -0,0 +1,9 @@
+require("find-java-home")(function (err, home) {
+ if (err || !home) {
+ if (!err) {
+ err = Error("Unable to determine Java home location");
+ }
+ process.exit(1);
+ }
+ process.stdout.write(home);
+});
diff --git a/scripts/find_java_libdir.sh b/scripts/find_java_libdir.sh
new file mode 100755
index 00000000..f638569e
--- /dev/null
+++ b/scripts/find_java_libdir.sh
@@ -0,0 +1,77 @@
+#!/usr/bin/env bash
+set -eu
+
+SCRIPT_DIR=$(dirname "$0")
+cd "${SCRIPT_DIR}/.."
+
+error() {
+ echo "error: $*" >&2
+ exit 1
+}
+
+main () {
+ local target_arch=$1
+ local os=$2
+
+ local java_home full_java_version java_version
+ java_home=$(node ./scripts/findJavaHome.js)
+ full_java_version=$(${java_home}/bin/java -version 2>&1 | grep version | sed -e 's/.*version "\(.*\)"\(.*\)/\1/; 1q')
+
+ if [[ "${full_java_version}" = "1."* ]]
+ then
+ java_version=$(echo "${full_java_version}" | sed -e 's/1\.\([0-9]*\)\(.*\)/\1/; 1q')
+ else
+ java_version=$(echo "${full_java_version}" | sed -e 's/\([0-9]*\)\(.*\)/\1/; 1q')
+ fi
+
+ local jre_dir
+ if [[ "${java_version}" =~ ^(6|7|8)$ && "${os}" != "zos" ]]; then
+ jre_dir="${java_home}/jre/lib"
+ else
+ jre_dir="${java_home}/lib"
+ fi
+
+ local lib_dir=""
+ if [[ "${os}" == "linux" && ! "${java_version}" =~ ^(6|7|8)$ ]]; then
+ # no arch on JDK 9+
+ lib_dir="${jre_dir}/server"
+ elif [[ "${os}" == "linux" && "${target_arch}" == "arm" ]]; then
+ if [[ -d ${jre_dir}/arm/classic ]]; then lib_dir="${jre_dir}"/arm/classic; else lib_dir="${jre_dir}"/arm/server; fi
+ elif [[ "${os}" == "linux" && "${target_arch}" == "arm64" ]]; then
+ if [[ -d ${jre_dir}/aarch64/classic ]]; then lib_dir="${jre_dir}"/aarch64/classic; else lib_dir="${jre_dir}"/aarch64/server; fi
+ elif [[ "${os}" == "linux" && "${target_arch}" == "ia32" ]]; then
+ if [[ -d ${jre_dir}/i386/classic ]]; then lib_dir="${jre_dir}"/i386/classic; else lib_dir="${jre_dir}"/i386/server; fi
+ elif [[ "${os}" == "linux" && "${target_arch}" == "x64" ]]; then
+ if [[ -d ${jre_dir}/amd64/classic ]]; then lib_dir="${jre_dir}"/amd64/classic; else lib_dir="${jre_dir}"/amd64/server; fi
+ elif [[ "${os}" == "linux" ]] && [[ "${target_arch}" == "s390x" || "${target_arch}" == "s390" ]]; then
+ if [[ -d ${jre_dir}/s390x/classic ]]; then lib_dir="${jre_dir}"/s390x/classic; else lib_dir="${jre_dir}"/s390/classic; fi
+ elif [[ "${os}" == "zos" ]]; then
+ lib_dir="${jre_dir}"/s390x/classic
+ elif [[ "${os}" == "linux" ]] && [[ "${target_arch}" == "ppc64" || "${target_arch}" == "ppc" ]]; then
+ target_arch=`uname -m`
+ if [[ -d ${jre_dir}/${target_arch}/classic ]]; then lib_dir="${jre_dir}"/${target_arch}/classic; else lib_dir="${jre_dir}"/${target_arch}/server; fi
+ elif [[ "${os}" == "mac" ]]; then
+ if [[ -d ${jre_dir}/jli ]]; then lib_dir="${jre_dir}/jli"; else lib_dir="${jre_dir}"; fi
+ else
+ local arch
+ if [[ "${target_arch}" =~ (32|386) ]]; then
+ arch=i386
+ else
+ arch=amd64
+ fi
+ if [[ "${os}" == "solaris" ]]; then
+ lib_dir="${jre_dir}/${arch}/server"
+ elif [[ "${os}" == "freebsd" ]]; then
+ lib_dir="${jre_dir}/${arch}/server"
+ elif [[ "${os}" == "openbsd" ]]; then
+ lib_dir="${jre_dir}/${arch}/server"
+ fi
+ fi
+
+ if [[ ! -d "${lib_dir}" ]]; then
+ error "Can't find lib dir '${lib_dir}' for ${os} ${target_arch}, java home: ${java_home}"
+ fi
+ echo "${lib_dir}"
+}
+
+main "$@"
diff --git a/scripts/postInstall.js b/scripts/postInstall.js
new file mode 100644
index 00000000..50d3ec95
--- /dev/null
+++ b/scripts/postInstall.js
@@ -0,0 +1,61 @@
+const glob = require("glob");
+const fs = require("fs");
+const path = require("path");
+const os = require("os");
+
+require("find-java-home")((err, home) => {
+ if (home) {
+ const dll = glob.sync("**/jvm.dll", { cwd: home })[0];
+ const dylib = glob.sync("**/libjli.dylib", { cwd: home })[0];
+ const soFiles = glob.sync("**/libjvm.so", { cwd: home });
+
+ let so;
+ if (soFiles.length > 0) {
+ so = getCorrectSoForPlatform(soFiles);
+ }
+
+ const binary = dll ?? dylib ?? so;
+
+ fs.writeFileSync(
+ path.resolve(__dirname, "../build/jvm_dll_path.json"),
+ binary ? JSON.stringify(path.delimiter + path.dirname(path.resolve(home, binary))) : '""'
+ );
+ }
+});
+
+function getCorrectSoForPlatform(soFiles) {
+ let so = _getCorrectSoForPlatform(soFiles);
+ if (so) {
+ so = removeDuplicateJre(so);
+ }
+ return so;
+}
+
+function removeDuplicateJre(filePath) {
+ while (filePath.indexOf("jre/jre") >= 0) {
+ filePath = filePath.replace("jre/jre", "jre");
+ }
+ return filePath;
+}
+
+function _getCorrectSoForPlatform(soFiles) {
+ const architectureFolderNames = {
+ ia32: "i386",
+ x64: "amd64",
+ };
+
+ if (os.platform() != "sunos") {
+ return soFiles[0];
+ }
+
+ const requiredFolderName = architectureFolderNames[os.arch()];
+
+ for (let i = 0; i < soFiles.length; i++) {
+ const so = soFiles[i];
+ if (so.indexOf("server") > 0 && so.indexOf(requiredFolderName) > 0) {
+ return so;
+ }
+ }
+
+ return soFiles[0];
+}
diff --git a/scripts/testRunner.ts b/scripts/testRunner.ts
new file mode 100644
index 00000000..fe36d289
--- /dev/null
+++ b/scripts/testRunner.ts
@@ -0,0 +1,55 @@
+// testRunner.js
+
+// This is a custom test runner. All tests are run with vitest, but in separate
+// processes, which allows us to test java with different configuration options.
+
+import chalk from "chalk";
+import findRoot from "find-root";
+import * as glob from "glob";
+import childProcess, { ExecException } from "node:child_process";
+import path from "node:path";
+
+const root = findRoot(__dirname);
+
+const tests = glob
+ .sync("*.test.ts", { cwd: path.join(root, "testAsyncOptions") })
+ .sort((a: string, b: string) => a.toLocaleLowerCase().localeCompare(b.toLocaleLowerCase()));
+
+tests.unshift("test"); // Arrange to run the primary tests first, in a single process
+
+async function runTest(testIndex: number, testArgs: string): Promise {
+ const vitest = path.join("node_modules", ".bin", "vitest");
+ const cmd = testArgs === "test" ? `vitest --dir test` : `${vitest} ${testArgs}`;
+ console.log(chalk.cyan(`(${testIndex + 1}/${tests.length}) running "${cmd}"...`));
+ return new Promise((resolve, reject) => {
+ childProcess.exec(cmd, (error: ExecException | null, stdout: string, stderr: string) => {
+ const errText = stderr.toString();
+ if (errText !== "") {
+ console.error(chalk.bold.red(errText));
+ }
+
+ process.stdout.write(stdout.toString());
+ if (error) {
+ return reject(error);
+ }
+ resolve();
+ });
+ });
+}
+
+console.log("test to run", tests);
+async function runAll(): Promise {
+ for (let i = 0; i < tests.length; i++) {
+ const test = tests[i];
+ await runTest(i, test);
+ }
+}
+
+runAll()
+ .then(() => {
+ console.log(chalk.green("Tests completed successfully!"));
+ })
+ .catch((err) => {
+ console.error(chalk.bold.red(err));
+ process.exit(1);
+ });
diff --git a/scripts/update-commons-lang.sh b/scripts/update-commons-lang.sh
new file mode 100755
index 00000000..e3eb71ae
--- /dev/null
+++ b/scripts/update-commons-lang.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+set -eu
+SCRIPT_DIR=$(dirname $(realpath $0))
+
+cd "${SCRIPT_DIR}/commons-lang"
+mvn package
+cp "${SCRIPT_DIR}/commons-lang/target/commons-lang-1.jar" "${SCRIPT_DIR}/../src-java/commons-lang3-node-java.jar"
+
+echo "complete!"
diff --git a/src-cpp/java.cpp b/src-cpp/java.cpp
new file mode 100644
index 00000000..e124b4dc
--- /dev/null
+++ b/src-cpp/java.cpp
@@ -0,0 +1,1434 @@
+#include "java.h"
+#include
+#ifdef WIN32
+#else
+#include
+#endif
+#include "javaObject.h"
+#include "javaScope.h"
+#include "methodCallBaton.h"
+#include "node_NodeDynamicProxyClass.h"
+#include
+#include
+#include
+#include
+
+#define DYNAMIC_PROXY_JS_ERROR -4
+
+#ifdef WIN32
+typedef long threadId;
+#else
+typedef pthread_t threadId;
+#endif
+
+threadId v8ThreadId;
+bool isDefaultLoopRunning = false;
+
+std::queue queue_dynamicProxyJsCallData;
+uv_mutex_t uvMutex_dynamicProxyJsCall;
+uv_async_t uvAsync_dynamicProxyJsCall;
+
+/*static*/ Nan::Persistent Java::s_ct;
+/*static*/ std::string Java::s_nativeBindingLocation;
+
+void my_sleep(int dur) {
+#ifdef WIN32
+ Sleep(dur);
+#else
+ usleep(dur);
+#endif
+}
+
+threadId my_getThreadId() {
+#ifdef WIN32
+ return (long)GetCurrentThreadId();
+#else
+ return pthread_self();
+#endif
+}
+
+bool v8ThreadIdEquals(threadId a, threadId b) {
+#ifdef WIN32
+ return a == b;
+#else
+ return pthread_equal(a, b);
+#endif
+}
+
+void EIO_CallJs(DynamicProxyJsCallData *callData);
+
+void uvAsyncCb_dynamicProxyJsCall(uv_async_t *handle) {
+ DynamicProxyJsCallData *callData;
+ do {
+ uv_mutex_lock(&uvMutex_dynamicProxyJsCall);
+ if (!queue_dynamicProxyJsCallData.empty()) {
+ callData = queue_dynamicProxyJsCallData.front();
+ queue_dynamicProxyJsCallData.pop();
+ } else {
+ callData = NULL;
+ }
+ uv_mutex_unlock(&uvMutex_dynamicProxyJsCall);
+
+ if (callData) {
+ EIO_CallJs(callData);
+ }
+ } while (callData);
+}
+
+/*static*/ void Java::Init(v8::Local target) {
+ Nan::HandleScope scope;
+
+ v8ThreadId = my_getThreadId();
+ isDefaultLoopRunning = false; // init as false
+
+ uv_mutex_init(&uvMutex_dynamicProxyJsCall);
+
+ v8::Local t = Nan::New(New);
+ s_ct.Reset(t);
+ t->InstanceTemplate()->SetInternalFieldCount(1);
+ t->SetClassName(Nan::New("Java").ToLocalChecked());
+
+ Nan::SetPrototypeMethod(t, "getClassLoader", getClassLoader);
+ Nan::SetPrototypeMethod(t, "newInstance", newInstance);
+ Nan::SetPrototypeMethod(t, "newInstanceSync", newInstanceSync);
+ Nan::SetPrototypeMethod(t, "newProxy", newProxy);
+ Nan::SetPrototypeMethod(t, "callStaticMethod", callStaticMethod);
+ Nan::SetPrototypeMethod(t, "callStaticMethodSync", callStaticMethodSync);
+ Nan::SetPrototypeMethod(t, "callMethod", callMethod);
+ Nan::SetPrototypeMethod(t, "callMethodSync", callMethodSync);
+ Nan::SetPrototypeMethod(t, "findClassSync", findClassSync);
+ Nan::SetPrototypeMethod(t, "newArray", newArray);
+ Nan::SetPrototypeMethod(t, "newByte", newByte);
+ Nan::SetPrototypeMethod(t, "newShort", newShort);
+ Nan::SetPrototypeMethod(t, "newLong", newLong);
+ Nan::SetPrototypeMethod(t, "newChar", newChar);
+ Nan::SetPrototypeMethod(t, "newFloat", newFloat);
+ Nan::SetPrototypeMethod(t, "newDouble", newDouble);
+ Nan::SetPrototypeMethod(t, "getStaticFieldValue", getStaticFieldValue);
+ Nan::SetPrototypeMethod(t, "setStaticFieldValue", setStaticFieldValue);
+ Nan::SetPrototypeMethod(t, "instanceOf", instanceOf);
+ Nan::SetPrototypeMethod(t, "stop", stop);
+
+ Nan::Set(target, Nan::New("Java").ToLocalChecked(), Nan::GetFunction(t).ToLocalChecked());
+
+ JavaProxyObject::init();
+}
+
+NAN_METHOD(Java::New) {
+ Nan::HandleScope scope;
+
+ if (!isDefaultLoopRunning) {
+ uv_async_init(uv_default_loop(), &uvAsync_dynamicProxyJsCall, uvAsyncCb_dynamicProxyJsCall);
+ isDefaultLoopRunning = true;
+ }
+
+ Java *self = new Java();
+ self->Wrap(info.This());
+
+ Nan::Set(self->handle(), Nan::New("classpath").ToLocalChecked(), Nan::New());
+ Nan::Set(self->handle(), Nan::New("options").ToLocalChecked(), Nan::New());
+ Nan::Set(self->handle(), Nan::New("nativeBindingLocation").ToLocalChecked(),
+ Nan::New("Not Set").ToLocalChecked());
+ Nan::Set(self->handle(), Nan::New("asyncOptions").ToLocalChecked(), Nan::Null());
+
+ info.GetReturnValue().Set(info.This());
+}
+
+Java::Java() {
+ this->m_jvm = NULL;
+ this->m_env = NULL;
+
+ m_SyncSuffix = "Sync";
+ m_AsyncSuffix = "";
+ doSync = true;
+ doAsync = true;
+ doPromise = false;
+}
+
+Java::~Java() { this->destroyJVM(&this->m_jvm, &this->m_env); }
+
+v8::Local Java::ensureJvm() {
+ if (!m_jvm) {
+ v8::Local result = createJVM(&this->m_jvm, &this->m_env);
+ assert(result->IsNull());
+ return result;
+ }
+
+ return Nan::Null();
+}
+
+void Java::configureAsync(v8::Local &asyncOptions) {
+ v8::Local asyncOptionsObj = asyncOptions.As();
+
+ m_SyncSuffix = "invalid";
+ m_AsyncSuffix = "invalid";
+ m_PromiseSuffix = "invalid";
+ doSync = false;
+ doAsync = false;
+ doPromise = false;
+
+ v8::MaybeLocal maybeSuffixValue =
+ Nan::Get(asyncOptionsObj, Nan::New("syncSuffix").ToLocalChecked());
+ v8::Local suffixValue;
+ if (maybeSuffixValue.ToLocal(&suffixValue) && suffixValue->IsString()) {
+ v8::Local suffix = suffixValue->ToString(Nan::GetCurrentContext()).ToLocalChecked();
+ Nan::Utf8String utf8(suffix);
+ m_SyncSuffix.assign(*utf8);
+ doSync = true;
+ }
+
+ maybeSuffixValue = Nan::Get(asyncOptionsObj, Nan::New("asyncSuffix").ToLocalChecked());
+ if (maybeSuffixValue.ToLocal(&suffixValue) && suffixValue->IsString()) {
+ v8::Local suffix = suffixValue->ToString(Nan::GetCurrentContext()).ToLocalChecked();
+ Nan::Utf8String utf8(suffix);
+ m_AsyncSuffix.assign(*utf8);
+ doAsync = true;
+ }
+
+ maybeSuffixValue = Nan::Get(asyncOptionsObj, Nan::New("promiseSuffix").ToLocalChecked());
+ if (maybeSuffixValue.ToLocal(&suffixValue) && suffixValue->IsString()) {
+ v8::Local suffix = suffixValue->ToString(Nan::GetCurrentContext()).ToLocalChecked();
+ Nan::Utf8String utf8(suffix);
+ m_PromiseSuffix.assign(*utf8);
+ doPromise = true;
+ }
+
+ if (doSync && doAsync) {
+ assert(m_SyncSuffix != m_AsyncSuffix);
+ }
+ if (doSync && doPromise) {
+ assert(m_SyncSuffix != m_PromiseSuffix);
+ }
+ if (doAsync && doPromise) {
+ assert(m_AsyncSuffix != m_PromiseSuffix);
+ }
+
+ m_asyncOptions.Reset(asyncOptionsObj);
+}
+
+v8::Local Java::createJVM(JavaVM **jvm, JNIEnv **env) {
+ v8::MaybeLocal maybeAsyncOptions =
+ Nan::Get(this->handle(), Nan::New("asyncOptions").ToLocalChecked());
+ v8::Local asyncOptions;
+ if (maybeAsyncOptions.ToLocal(&asyncOptions) && asyncOptions->IsObject()) {
+ configureAsync(asyncOptions);
+ }
+
+ // setup classpath
+ std::ostringstream classPath;
+ classPath << "-Djava.class.path=";
+
+ v8::MaybeLocal maybeClassPathValue =
+ Nan::Get(this->handle(), Nan::New("classpath").ToLocalChecked());
+ v8::Local classPathValue;
+ if (!maybeClassPathValue.ToLocal(&classPathValue) || !classPathValue->IsArray()) {
+ return Nan::TypeError("Classpath must be an array");
+ }
+ v8::Local classPathArrayTemp = v8::Local::Cast(classPathValue);
+ m_classPathArray.Reset(classPathArrayTemp);
+ for (uint32_t i = 0; i < classPathArrayTemp->Length(); i++) {
+ if (i != 0) {
+#ifdef WIN32
+ classPath << ";";
+#else
+ classPath << ":";
+#endif
+ }
+ v8::Local arrayItemValue = classPathArrayTemp->Get(Nan::GetCurrentContext(), i).ToLocalChecked();
+ if (!arrayItemValue->IsString()) {
+ return Nan::TypeError("Classpath must only contain strings");
+ }
+ v8::Local arrayItem = arrayItemValue->ToString(Nan::GetCurrentContext()).ToLocalChecked();
+ Nan::Utf8String arrayItemStr(arrayItem);
+ classPath << *arrayItemStr;
+ }
+
+ // set the native binding location
+ v8::Local v8NativeBindingLocation =
+ Nan::Get(this->handle(), Nan::New("nativeBindingLocation").ToLocalChecked())
+ .FromMaybe(v8::Local());
+ Nan::Utf8String nativeBindingLocationStr(v8NativeBindingLocation);
+ s_nativeBindingLocation = *nativeBindingLocationStr;
+
+ // get other options
+ v8::Local optionsValue =
+ Nan::Get(this->handle(), Nan::New("options").ToLocalChecked()).FromMaybe(v8::Local());
+ if (!optionsValue->IsArray()) {
+ return Nan::TypeError("options must be an array");
+ }
+ v8::Local optionsArrayTemp = v8::Local::Cast(optionsValue);
+ m_optionsArray.Reset(optionsArrayTemp);
+
+ // create vm options
+ int vmOptionsCount = optionsArrayTemp->Length() + 1;
+ JavaVMOption *vmOptions = new JavaVMOption[vmOptionsCount];
+ // printf("classPath: %s\n", classPath.str().c_str());
+ vmOptions[0].optionString = strdup(classPath.str().c_str());
+ for (uint32_t i = 0; i < optionsArrayTemp->Length(); i++) {
+ v8::Local arrayItemValue = optionsArrayTemp->Get(Nan::GetCurrentContext(), i).ToLocalChecked();
+ if (!arrayItemValue->IsString()) {
+ delete[] vmOptions;
+ return Nan::TypeError("options must only contain strings");
+ }
+ v8::Local arrayItem = arrayItemValue->ToString(Nan::GetCurrentContext()).ToLocalChecked();
+ Nan::Utf8String arrayItemStr(arrayItem);
+ vmOptions[i + 1].optionString = strdup(*arrayItemStr);
+ }
+
+ JavaVMInitArgs args;
+ // The JNI invocation is documented to include a function JNI_GetDefaultJavaVMInitArgs that
+ // was formerly called here. But the documentation from Oracle is confusing/contradictory.
+ // 1) It claims that the caller must set args.version before calling JNI_GetDefaultJavaVMInitArgs, which
+ // we did not do.
+ // 2) The sample code provide at the top of the doc doesn't even call JNI_GetDefaultJavaVMInitArgs.
+ // 3) The Oracle documentation for Java 6 through Java 8 all contain a comment "Note that in the JDK/JRE, there is no
+ // longer any need to call JNI_GetDefaultJavaVMInitArgs."
+ // 4) It seems that some platforms don't implement JNI_GetDefaultJavaVMInitArgs, or have
+ // marked it deprecated.
+ // Omitting the call to JNI_GetDefaultJavaVMInitArgs works fine on Mac and Linux with Java 7 and Java 8.
+ // The Oracle documentation is here:
+ // http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/invocation.html
+ // http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html
+ // http://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html
+ args.version = JNI_BEST_VERSION;
+ // JNI_GetDefaultJavaVMInitArgs(&args); // If this turns out to be necessary, it should be called here.
+ args.ignoreUnrecognized = false;
+ args.options = vmOptions;
+ args.nOptions = vmOptionsCount;
+
+ JavaVM *jvmTemp;
+ JNI_CreateJavaVM(&jvmTemp, (void **)env, &args);
+ *jvm = jvmTemp;
+
+ delete[] vmOptions;
+
+ m_classLoader = getSystemClassLoader(*env);
+
+ v8::Local onJvmCreated =
+ Nan::Get(this->handle(), Nan::New("onJvmCreated").ToLocalChecked()).FromMaybe(v8::Local());
+
+ // TODO: this handles sets put doesn't prevent modifing the underlying data. So java.classpath.push will still work
+ // which is invalid.
+ Nan::SetAccessor(this->handle(), Nan::New("classpath").ToLocalChecked(),
+ AccessorProhibitsOverwritingGetter, AccessorProhibitsOverwritingSetter);
+ Nan::SetAccessor(this->handle(), Nan::New("options").ToLocalChecked(), AccessorProhibitsOverwritingGetter,
+ AccessorProhibitsOverwritingSetter);
+ Nan::SetAccessor(this->handle(), Nan::New("nativeBindingLocation").ToLocalChecked(),
+ AccessorProhibitsOverwritingGetter, AccessorProhibitsOverwritingSetter);
+ Nan::SetAccessor(this->handle(), Nan::New("asyncOptions").ToLocalChecked(),
+ AccessorProhibitsOverwritingGetter, AccessorProhibitsOverwritingSetter);
+ Nan::SetAccessor(this->handle(), Nan::New("onJvmCreated").ToLocalChecked(),
+ AccessorProhibitsOverwritingGetter, AccessorProhibitsOverwritingSetter);
+
+ if (onJvmCreated->IsFunction()) {
+ v8::Local onJvmCreatedFunc = onJvmCreated.As();
+ v8::Local context = Nan::New();
+ Nan::Call(onJvmCreatedFunc, context, 0, NULL);
+ }
+
+ return Nan::Null();
+}
+
+NAN_GETTER(Java::AccessorProhibitsOverwritingGetter) {
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ Nan::HandleScope scope;
+ Nan::Utf8String nameStr(property);
+ if (!strcmp("classpath", *nameStr)) {
+ info.GetReturnValue().Set(Nan::New(self->m_classPathArray));
+ return;
+ } else if (!strcmp("options", *nameStr)) {
+ info.GetReturnValue().Set(Nan::New(self->m_optionsArray));
+ return;
+ } else if (!strcmp("nativeBindingLocation", *nameStr)) {
+ info.GetReturnValue().Set(Nan::New(Java::s_nativeBindingLocation.c_str()).ToLocalChecked());
+ return;
+ } else if (!strcmp("asyncOptions", *nameStr)) {
+ info.GetReturnValue().Set(Nan::New(self->m_asyncOptions));
+ return;
+ } else if (!strcmp("onJvmCreated", *nameStr)) {
+ // There is no good reason to get onJvmCreated, so just fall through to error below.
+ }
+
+ std::ostringstream errStr;
+ errStr << "Invalid call to accessor " << *nameStr;
+ info.GetReturnValue().Set(Nan::Error(errStr.str().c_str()));
+}
+
+NAN_SETTER(Java::AccessorProhibitsOverwritingSetter) {
+ Nan::Utf8String nameStr(property);
+ std::ostringstream errStr;
+ errStr << "Cannot set " << *nameStr << " after calling any other java function.";
+ Nan::ThrowError(errStr.str().c_str());
+}
+
+void Java::destroyJVM(JavaVM **jvm, JNIEnv **env) {
+ (*jvm)->DestroyJavaVM();
+ *jvm = NULL;
+ *env = NULL;
+}
+
+NAN_METHOD(Java::getClassLoader) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ jclass classClazz = env->FindClass("java/lang/ClassLoader");
+ jmethodID class_getClassLoader =
+ env->GetStaticMethodID(classClazz, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
+ jobject classLoader = env->CallStaticObjectMethod(classClazz, class_getClassLoader);
+ checkJavaException(env);
+
+ jobject result = env->NewGlobalRef(classLoader);
+ info.GetReturnValue().Set(javaToV8(self, env, result));
+}
+
+NAN_METHOD(Java::newInstance) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ int argsStart = 0;
+ int argsEnd = info.Length();
+
+ // arguments
+ ARGS_FRONT_CLASSNAME();
+ ARGS_BACK_CALLBACK();
+
+ // find class
+ jclass clazz = javaFindClass(env, className);
+ if (clazz == NULL) {
+ EXCEPTION_CALL_CALLBACK(self, "Could not find class " << className.c_str());
+ info.GetReturnValue().SetUndefined();
+ return;
+ }
+
+ // get method
+ jobjectArray methodArgs = v8ToJava(env, info, argsStart, argsEnd);
+ jobject method = javaFindConstructor(env, clazz, methodArgs);
+ if (method == NULL) {
+ std::string msg = methodNotFoundToString(env, clazz, className, true, info, argsStart, argsEnd);
+ EXCEPTION_CALL_CALLBACK(self, msg);
+ info.GetReturnValue().SetUndefined();
+ return;
+ }
+
+ // run
+ NewInstanceBaton *baton = new NewInstanceBaton(self, clazz, method, methodArgs, callback);
+ baton->run();
+
+ END_CALLBACK_FUNCTION("\"Constructor for class '"
+ << className << "' called without a callback did you mean to use the Sync version?\"");
+}
+
+NAN_METHOD(Java::newInstanceSync) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ int argsStart = 0;
+ int argsEnd = info.Length();
+
+ // arguments
+ ARGS_FRONT_CLASSNAME();
+
+ // find class
+ jclass clazz = javaFindClass(env, className);
+ if (clazz == NULL) {
+ std::ostringstream errStr;
+ errStr << "Could not create class " << className.c_str();
+ return Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ }
+
+ // find method
+ jobjectArray methodArgs = v8ToJava(env, info, argsStart, argsEnd);
+ jobject method = javaFindConstructor(env, clazz, methodArgs);
+ if (method == NULL) {
+ std::string msg = methodNotFoundToString(env, clazz, className, true, info, argsStart, argsEnd);
+ return Nan::ThrowError(javaExceptionToV8(self, env, msg));
+ }
+
+ // run
+ v8::Local callback = Nan::Null();
+ NewInstanceBaton *baton = new NewInstanceBaton(self, clazz, method, methodArgs, callback);
+ v8::Local result = baton->runSync();
+ delete baton;
+ if (result->IsNativeError()) {
+ return Nan::ThrowError(result);
+ }
+ info.GetReturnValue().Set(result);
+}
+
+NAN_METHOD(Java::newProxy) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ int argsStart = 0;
+
+ ARGS_FRONT_STRING(interfaceName);
+ ARGS_FRONT_OBJECT(functions);
+
+ DynamicProxyData *dynamicProxyData = new DynamicProxyData();
+ dynamicProxyData->markerStart = DYNAMIC_PROXY_DATA_MARKER_START;
+ dynamicProxyData->markerEnd = DYNAMIC_PROXY_DATA_MARKER_END;
+ dynamicProxyData->java = self;
+ dynamicProxyData->interfaceName = interfaceName;
+ dynamicProxyData->functions.Reset(functions);
+
+ // find NodeDynamicProxyClass
+ std::string className = "node.NodeDynamicProxyClass";
+ jclass clazz = javaFindClass(env, className);
+ if (clazz == NULL) {
+ std::ostringstream errStr;
+ errStr << "Could not create class node/NodeDynamicProxyClass";
+ delete dynamicProxyData;
+ return Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ }
+
+ // find constructor
+ jclass objectClazz = env->FindClass("java/lang/Object");
+ jobjectArray methodArgs = env->NewObjectArray(2, objectClazz, NULL);
+ env->SetObjectArrayElement(methodArgs, 0,
+ v8ToJava(env, Nan::New(s_nativeBindingLocation.c_str()).ToLocalChecked()));
+ env->SetObjectArrayElement(methodArgs, 1, longToJavaLongObj(env, (jlong)dynamicProxyData));
+ jobject method = javaFindConstructor(env, clazz, methodArgs);
+ if (method == NULL) {
+ std::ostringstream errStr;
+ errStr << "Could not find constructor for class node/NodeDynamicProxyClass";
+ return Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ }
+
+ // create the NodeDynamicProxyClass
+ jclass constructorClazz = env->FindClass("java/lang/reflect/Constructor");
+ jmethodID constructor_newInstance =
+ env->GetMethodID(constructorClazz, "newInstance", "([Ljava/lang/Object;)Ljava/lang/Object;");
+
+ // printf("invoke: %s\n", javaMethodCallToString(env, m_method, constructor_newInstance, m_args).c_str());
+
+ // run constructor
+ jobject dynamicProxy = env->CallObjectMethod(method, constructor_newInstance, methodArgs);
+ if (env->ExceptionCheck()) {
+ std::ostringstream errStr;
+ errStr << "Error creating class";
+ return Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ }
+
+ jclass dynamicInterface = javaFindClass(env, interfaceName);
+ if (dynamicInterface == NULL) {
+ std::ostringstream errStr;
+ errStr << "Could not find interface ";
+ errStr << interfaceName;
+ return Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ }
+ jclass classClazz = env->FindClass("java/lang/Class");
+ jobjectArray classArray = env->NewObjectArray(1, classClazz, NULL);
+ if (classArray == NULL) {
+ std::ostringstream errStr;
+ errStr << "Could not create class array for Proxy";
+ return Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ }
+ env->SetObjectArrayElement(classArray, 0, dynamicInterface);
+
+ jmethodID class_getClassLoader = env->GetMethodID(classClazz, "getClassLoader", "()Ljava/lang/ClassLoader;");
+ jobject classLoader = env->CallObjectMethod(dynamicInterface, class_getClassLoader);
+ assertNoException(env);
+
+ if (classLoader == NULL) {
+ jclass objectClazz = env->FindClass("java/lang/Object");
+ jmethodID object_getClass = env->GetMethodID(objectClazz, "getClass", "()Ljava/lang/Class;");
+ jobject jobjClass = env->CallObjectMethod(dynamicProxy, object_getClass);
+ checkJavaException(env);
+ classLoader = env->CallObjectMethod(jobjClass, class_getClassLoader);
+ checkJavaException(env);
+ }
+ if (classLoader == NULL) {
+ std::ostringstream errStr;
+ errStr << "Could not get classloader for Proxy";
+ return Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ }
+
+ // create proxy instance
+ jclass proxyClass = env->FindClass("java/lang/reflect/Proxy");
+ jmethodID proxy_newProxyInstance = env->GetStaticMethodID(
+ proxyClass, "newProxyInstance",
+ "(Ljava/lang/ClassLoader;[Ljava/lang/Class;Ljava/lang/reflect/InvocationHandler;)Ljava/lang/Object;");
+ jobject proxyInstance =
+ env->CallStaticObjectMethod(proxyClass, proxy_newProxyInstance, classLoader, classArray, dynamicProxy);
+ if (env->ExceptionCheck()) {
+ std::ostringstream errStr;
+ errStr << "Error creating java.lang.reflect.Proxy";
+ return Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ }
+
+ v8::Local result = javaToV8(self, env, proxyInstance, dynamicProxyData);
+
+ dynamicProxyData->jsObject.Reset(result);
+ info.GetReturnValue().Set(result);
+}
+
+NAN_METHOD(Java::callStaticMethod) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ int argsStart = 0;
+ int argsEnd = info.Length();
+
+ // arguments
+ ARGS_FRONT_CLASSNAME();
+ ARGS_FRONT_STRING(methodName);
+ ARGS_BACK_CALLBACK();
+
+ // find class
+ jclass clazz = javaFindClass(env, className);
+ if (clazz == NULL) {
+ EXCEPTION_CALL_CALLBACK(self, "Could not create class " << className.c_str());
+ info.GetReturnValue().SetUndefined();
+ return;
+ }
+
+ // find method
+ jobjectArray methodArgs = v8ToJava(env, info, argsStart, argsEnd);
+ jobject method = javaFindMethod(env, clazz, methodName, methodArgs);
+ if (method == NULL) {
+ std::string msg = methodNotFoundToString(env, clazz, methodName, false, info, argsStart, argsEnd);
+ EXCEPTION_CALL_CALLBACK(self, msg);
+ info.GetReturnValue().SetUndefined();
+ return;
+ }
+
+ // run
+ StaticMethodCallBaton *baton = new StaticMethodCallBaton(self, clazz, method, methodArgs, callback);
+ baton->run();
+
+ END_CALLBACK_FUNCTION("\"Static method '" << methodName
+ << "' called without a callback did you mean to use the Sync version?\"");
+}
+
+NAN_METHOD(Java::callStaticMethodSync) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ int argsStart = 0;
+ int argsEnd = info.Length();
+
+ // arguments
+ ARGS_FRONT_CLASSNAME();
+ ARGS_FRONT_STRING(methodName);
+
+ // find class
+ jclass clazz = javaFindClass(env, className);
+ if (clazz == NULL) {
+ std::ostringstream errStr;
+ errStr << "Could not create class " << className.c_str();
+ return Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ }
+
+ // find method
+ jobjectArray methodArgs = v8ToJava(env, info, argsStart, argsEnd);
+ jobject method = javaFindMethod(env, clazz, methodName, methodArgs);
+ if (method == NULL) {
+ std::string msg = methodNotFoundToString(env, clazz, methodName, false, info, argsStart, argsEnd);
+ return Nan::ThrowError(javaExceptionToV8(self, env, msg));
+ }
+
+ // run
+ v8::Local callback = Nan::Null();
+ StaticMethodCallBaton *baton = new StaticMethodCallBaton(self, clazz, method, methodArgs, callback);
+ v8::Local result = baton->runSync();
+ delete baton;
+ if (result->IsNativeError()) {
+ Nan::ThrowError(result);
+ return;
+ }
+ info.GetReturnValue().Set(result);
+}
+
+NAN_METHOD(Java::callMethodSync) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ int argsStart = 0;
+ int argsEnd = info.Length();
+
+ // arguments
+ ARGS_FRONT_OBJECT(instanceObj);
+ ARGS_FRONT_STRING(methodName);
+
+ JavaObject *javaObj = Nan::ObjectWrap::Unwrap(instanceObj);
+
+ // find method
+ jclass clazz = javaObj->getClass();
+ jobjectArray methodArgs = v8ToJava(env, info, argsStart, argsEnd);
+ jobject method = javaFindMethod(env, clazz, methodName, methodArgs);
+ if (method == NULL) {
+ std::string msg = methodNotFoundToString(env, clazz, methodName, false, info, argsStart, argsEnd);
+ return Nan::ThrowError(javaExceptionToV8(self, env, msg));
+ }
+
+ // run
+ v8::Local callback = Nan::Null();
+ InstanceMethodCallBaton *baton = new InstanceMethodCallBaton(self, javaObj, method, methodArgs, callback);
+ v8::Local result = baton->runSync();
+ delete baton;
+ if (result->IsNativeError()) {
+ return Nan::ThrowError(result);
+ }
+ info.GetReturnValue().Set(result);
+}
+
+NAN_METHOD(Java::callMethod) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ int argsStart = 0;
+ int argsEnd = info.Length();
+
+ // arguments
+ ARGS_FRONT_OBJECT(instanceObj);
+ ARGS_FRONT_STRING(methodName);
+ ARGS_BACK_CALLBACK();
+
+ JavaObject *javaObj = Nan::ObjectWrap::Unwrap(instanceObj);
+
+ // find method
+ jclass clazz = javaObj->getClass();
+ jobjectArray methodArgs = v8ToJava(env, info, argsStart, argsEnd);
+ jobject method = javaFindMethod(env, clazz, methodName, methodArgs);
+ if (method == NULL) {
+ std::string msg = methodNotFoundToString(env, clazz, methodName, false, info, argsStart, argsEnd);
+ EXCEPTION_CALL_CALLBACK(self, msg);
+ info.GetReturnValue().SetUndefined();
+ return;
+ }
+
+ // run
+ InstanceMethodCallBaton *baton = new InstanceMethodCallBaton(self, javaObj, method, methodArgs, callback);
+ baton->run();
+
+ END_CALLBACK_FUNCTION("\"method '" << methodName
+ << "' called without a callback did you mean to use the Sync version?\"");
+}
+
+NAN_METHOD(Java::findClassSync) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ int argsStart = 0;
+
+ // arguments
+ ARGS_FRONT_CLASSNAME();
+
+ // find class
+ jclass clazz = javaFindClass(env, className);
+ if (clazz == NULL) {
+ std::ostringstream errStr;
+ errStr << "Could not create class " << className.c_str();
+ return Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ }
+
+ // run
+ v8::Local result = javaToV8(self, env, clazz);
+ info.GetReturnValue().Set(result);
+}
+
+NAN_METHOD(Java::newArray) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ int argsStart = 0;
+
+ // arguments
+ ARGS_FRONT_CLASSNAME();
+
+ // argument - array
+ if (info.Length() < argsStart + 1 || !info[argsStart]->IsArray()) {
+ std::ostringstream errStr;
+ errStr << "Argument " << (argsStart + 1) << " must be an array";
+ return Nan::ThrowError(Nan::TypeError(errStr.str().c_str()));
+ }
+ v8::Local arrayObj = v8::Local::Cast(info[argsStart]);
+
+ // find class and method
+ jarray results;
+ if (strcmp(className.c_str(), "byte") == 0) {
+ results = env->NewByteArray(arrayObj->Length());
+ for (uint32_t i = 0; i < arrayObj->Length(); i++) {
+ v8::Local item = arrayObj->Get(Nan::GetCurrentContext(), i).ToLocalChecked();
+ jobject val = v8ToJava(env, item);
+ jclass byteClazz = env->FindClass("java/lang/Byte");
+ jmethodID byte_byteValue = env->GetMethodID(byteClazz, "byteValue", "()B");
+ jbyte byteValues[1];
+ byteValues[0] = env->CallByteMethod(val, byte_byteValue);
+ assertNoException(env);
+ env->SetByteArrayRegion((jbyteArray)results, i, 1, byteValues);
+ }
+ }
+
+ else if (strcmp(className.c_str(), "char") == 0) {
+ results = env->NewCharArray(arrayObj->Length());
+ for (uint32_t i = 0; i < arrayObj->Length(); i++) {
+ v8::Local item = arrayObj->Get(Nan::GetCurrentContext(), i).ToLocalChecked();
+ jobject val = v8ToJava(env, item);
+ jclass stringClazz = env->FindClass("java/lang/String");
+ jmethodID string_charAt = env->GetMethodID(stringClazz, "charAt", "(I)C");
+ jchar itemValues[1];
+ itemValues[0] = env->CallCharMethod(val, string_charAt, 0);
+ checkJavaException(env);
+ env->SetCharArrayRegion((jcharArray)results, i, 1, itemValues);
+ }
+ }
+
+ else if (strcmp(className.c_str(), "short") == 0) {
+ results = env->NewShortArray(arrayObj->Length());
+ for (uint32_t i = 0; i < arrayObj->Length(); i++) {
+ v8::Local item = arrayObj->Get(Nan::GetCurrentContext(), i).ToLocalChecked();
+ jobject val = v8ToJava(env, item);
+ jclass shortClazz = env->FindClass("java/lang/Short");
+ jmethodID short_shortValue = env->GetMethodID(shortClazz, "shortValue", "()S");
+ jshort shortValues[1];
+ shortValues[0] = env->CallShortMethod(val, short_shortValue);
+ assertNoException(env);
+ env->SetShortArrayRegion((jshortArray)results, i, 1, shortValues);
+ }
+ }
+
+ else if (strcmp(className.c_str(), "double") == 0) {
+ results = env->NewDoubleArray(arrayObj->Length());
+ for (uint32_t i = 0; i < arrayObj->Length(); i++) {
+ v8::Local item = arrayObj->Get(Nan::GetCurrentContext(), i).ToLocalChecked();
+ jobject val = v8ToJava(env, item);
+ jclass doubleClazz = env->FindClass("java/lang/Double");
+ jmethodID double_doubleValue = env->GetMethodID(doubleClazz, "doubleValue", "()D");
+ jdouble doubleValues[1];
+ doubleValues[0] = env->CallDoubleMethod(val, double_doubleValue);
+ assertNoException(env);
+ env->SetDoubleArrayRegion((jdoubleArray)results, i, 1, doubleValues);
+ }
+ }
+
+ else if (strcmp(className.c_str(), "int") == 0) {
+ results = env->NewIntArray(arrayObj->Length());
+ for (uint32_t i = 0; i < arrayObj->Length(); i++) {
+ v8::Local item = arrayObj->Get(Nan::GetCurrentContext(), i).ToLocalChecked();
+ jobject val = v8ToJava(env, item);
+ jclass integerClazz = env->FindClass("java/lang/Integer");
+ jmethodID integer_intValue = env->GetMethodID(integerClazz, "intValue", "()I");
+ jint intValues[1];
+ intValues[0] = env->CallIntMethod(val, integer_intValue);
+ assertNoException(env);
+ env->SetIntArrayRegion((jintArray)results, i, 1, intValues);
+ }
+ }
+
+ else if (strcmp(className.c_str(), "float") == 0) {
+ results = env->NewFloatArray(arrayObj->Length());
+ for (uint32_t i = 0; i < arrayObj->Length(); i++) {
+ v8::Local item = arrayObj->Get(Nan::GetCurrentContext(), i).ToLocalChecked();
+ jobject val = v8ToJava(env, item);
+ jclass floatClazz = env->FindClass("java/lang/Float");
+ jmethodID float_floatValue = env->GetMethodID(floatClazz, "floatValue", "()F");
+ jfloat floatValues[1];
+ floatValues[0] = env->CallFloatMethod(val, float_floatValue);
+ checkJavaException(env);
+ env->SetFloatArrayRegion((jfloatArray)results, i, 1, floatValues);
+ }
+ }
+
+ else if (strcmp(className.c_str(), "boolean") == 0) {
+ results = env->NewBooleanArray(arrayObj->Length());
+ for (uint32_t i = 0; i < arrayObj->Length(); i++) {
+ v8::Local item = arrayObj->Get(Nan::GetCurrentContext(), i).ToLocalChecked();
+ jobject val = v8ToJava(env, item);
+ jclass booleanClazz = env->FindClass("java/lang/Boolean");
+ jmethodID boolean_booleanValue = env->GetMethodID(booleanClazz, "booleanValue", "()Z");
+ jboolean booleanValues[1];
+ booleanValues[0] = env->CallBooleanMethod(val, boolean_booleanValue);
+ checkJavaException(env);
+ env->SetBooleanArrayRegion((jbooleanArray)results, i, 1, booleanValues);
+ }
+ }
+
+ else {
+ jclass clazz = javaFindClass(env, className);
+ if (clazz == NULL) {
+ std::ostringstream errStr;
+ errStr << "Could not create class " << className.c_str();
+ return Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ }
+
+ // create array
+ results = env->NewObjectArray(arrayObj->Length(), clazz, NULL);
+
+ for (uint32_t i = 0; i < arrayObj->Length(); i++) {
+ v8::Local item = arrayObj->Get(Nan::GetCurrentContext(), i).ToLocalChecked();
+ jobject val = v8ToJava(env, item);
+ env->SetObjectArrayElement((jobjectArray)results, i, val);
+ if (env->ExceptionOccurred()) {
+ std::ostringstream errStr;
+ Nan::Utf8String valStr(item);
+ errStr << "Could not add item \"" << *valStr << "\" to array.";
+ return Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ }
+ }
+ }
+
+ info.GetReturnValue().Set(JavaObject::New(self, results));
+}
+
+NAN_METHOD(Java::newByte) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ if (info.Length() != 1) {
+ return Nan::ThrowError(Nan::TypeError("newByte only takes 1 argument"));
+ }
+
+ // argument - value
+ if (!info[0]->IsNumber()) {
+ return Nan::ThrowError(Nan::TypeError("Argument 1 must be a number"));
+ }
+
+ jbyte val = Nan::To(info[0]).FromJust();
+
+ jclass clazz = env->FindClass("java/lang/Byte");
+ jmethodID constructor = env->GetMethodID(clazz, "", "(B)V");
+ jobject newObj = env->NewObject(clazz, constructor, val);
+
+ info.GetReturnValue().Set(JavaObject::New(self, newObj));
+ return;
+}
+
+NAN_METHOD(Java::newShort) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ if (info.Length() != 1) {
+ return Nan::ThrowError(Nan::TypeError("newShort only takes 1 argument"));
+ }
+
+ // argument - value
+ if (!info[0]->IsNumber()) {
+ return Nan::ThrowError(Nan::TypeError("Argument 1 must be a number"));
+ }
+
+ jshort val = Nan::To(info[0]).FromJust();
+
+ jclass clazz = env->FindClass("java/lang/Short");
+ jmethodID constructor = env->GetMethodID(clazz, "", "(S)V");
+ jobject newObj = env->NewObject(clazz, constructor, val);
+
+ info.GetReturnValue().Set(JavaObject::New(self, newObj));
+}
+
+NAN_METHOD(Java::newLong) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ if (info.Length() != 1) {
+ return Nan::ThrowError(Nan::TypeError("newLong only takes 1 argument"));
+ }
+
+ // argument - value
+ if (!info[0]->IsNumber()) {
+ return Nan::ThrowError(Nan::TypeError("Argument 1 must be a number"));
+ }
+
+ jlong val = Nan::To(info[0]).FromJust();
+
+ jclass clazz = env->FindClass("java/lang/Long");
+ jmethodID constructor = env->GetMethodID(clazz, "", "(J)V");
+ jobject newObj = env->NewObject(clazz, constructor, val);
+
+ info.GetReturnValue().Set(JavaObject::New(self, newObj));
+}
+
+NAN_METHOD(Java::newChar) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ if (info.Length() != 1) {
+ return Nan::ThrowError(Nan::TypeError("newChar only takes 1 argument"));
+ }
+
+ // argument - value
+ jchar charVal;
+ if (info[0]->IsNumber()) {
+ charVal = (jchar)Nan::To(info[0]).FromJust();
+ } else if (info[0]->IsString()) {
+ v8::Local val = info[0]->ToString(Nan::GetCurrentContext()).ToLocalChecked();
+ if (val->Length() != 1) {
+ return Nan::ThrowError(Nan::TypeError("Argument 1 must be a string of 1 character."));
+ }
+ std::string strVal = std::string(*Nan::Utf8String(val));
+ charVal = (jchar)strVal[0];
+ } else {
+ return Nan::ThrowError(Nan::TypeError("Argument 1 must be a number or string"));
+ }
+
+ jclass clazz = env->FindClass("java/lang/Character");
+ jmethodID constructor = env->GetMethodID(clazz, "", "(C)V");
+ jobject newObj = env->NewObject(clazz, constructor, charVal);
+
+ info.GetReturnValue().Set(JavaObject::New(self, newObj));
+}
+
+NAN_METHOD(Java::newFloat) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ if (info.Length() != 1) {
+ return Nan::ThrowError(Nan::TypeError("newFloat only takes 1 argument"));
+ } else if (!info[0]->IsNumber()) {
+ return Nan::ThrowError(Nan::TypeError("Argument 1 must be a number"));
+ }
+ jfloat val = (jfloat)Nan::To(info[0]).FromJust();
+
+ jclass clazz = env->FindClass("java/lang/Float");
+ jmethodID constructor = env->GetMethodID(clazz, "", "(F)V");
+ jobject newObj = env->NewObject(clazz, constructor, val);
+
+ info.GetReturnValue().Set(JavaObject::New(self, newObj));
+}
+
+NAN_METHOD(Java::newDouble) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ if (info.Length() != 1) {
+ return Nan::ThrowError(Nan::TypeError("newDouble only takes 1 argument"));
+ } else if (!info[0]->IsNumber()) {
+ return Nan::ThrowError(Nan::TypeError("Argument 1 must be a number"));
+ }
+
+ jdouble val = (jdouble)Nan::To(info[0]).FromJust();
+
+ jclass clazz = env->FindClass("java/lang/Double");
+ jmethodID constructor = env->GetMethodID(clazz, "", "(D)V");
+ jobject newObj = env->NewObject(clazz, constructor, val);
+
+ info.GetReturnValue().Set(JavaObject::New(self, newObj));
+}
+
+NAN_METHOD(Java::getStaticFieldValue) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ int argsStart = 0;
+
+ // arguments
+ ARGS_FRONT_CLASSNAME();
+ ARGS_FRONT_STRING(fieldName);
+
+ // find the class
+ jclass clazz = javaFindClass(env, className);
+ if (clazz == NULL) {
+ std::ostringstream errStr;
+ errStr << "Could not create class " << className.c_str();
+ return Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ }
+
+ // get the field
+ jobject field = javaFindField(env, clazz, fieldName);
+ if (field == NULL) {
+ std::ostringstream errStr;
+ errStr << "Could not find field \"" << fieldName.c_str() << "\" on class \"" << className.c_str() << "\"";
+ return Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ }
+
+ jclass fieldClazz = env->FindClass("java/lang/reflect/Field");
+ jmethodID field_get = env->GetMethodID(fieldClazz, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
+
+ // get field value
+ jobject val = env->CallObjectMethod(field, field_get, NULL);
+ if (env->ExceptionOccurred()) {
+ std::ostringstream errStr;
+ errStr << "Could not get field " << fieldName.c_str() << " on class " << className.c_str();
+ return Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ }
+
+ info.GetReturnValue().Set(javaToV8(self, env, val));
+}
+
+NAN_METHOD(Java::setStaticFieldValue) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ int argsStart = 0;
+
+ // arguments
+ ARGS_FRONT_CLASSNAME();
+ ARGS_FRONT_STRING(fieldName);
+
+ // argument - new value
+ if (info.Length() < argsStart + 1) {
+ std::ostringstream errStr;
+ errStr << "setStaticFieldValue requires " << (argsStart + 1) << " arguments";
+ Nan::ThrowError(Nan::TypeError(errStr.str().c_str()));
+ return;
+ }
+ jobject newValue = v8ToJava(env, info[argsStart]);
+ argsStart++;
+
+ // find the class
+ jclass clazz = javaFindClass(env, className);
+ if (clazz == NULL) {
+ std::ostringstream errStr;
+ errStr << "Could not create class " << className.c_str();
+ Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ return;
+ }
+
+ // get the field
+ jobject field = javaFindField(env, clazz, fieldName);
+ if (field == NULL) {
+ std::ostringstream errStr;
+ errStr << "Could not find field \"" << fieldName.c_str() << "\" on class \"" << className.c_str() << "\"";
+ Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ return;
+ }
+
+ jclass fieldClazz = env->FindClass("java/lang/reflect/Field");
+ jmethodID field_set = env->GetMethodID(fieldClazz, "set", "(Ljava/lang/Object;Ljava/lang/Object;)V");
+
+ // printf("newValue: %s\n", javaObjectToString(env, newValue).c_str());
+
+ // set field value
+ env->CallObjectMethod(field, field_set, NULL, newValue);
+ if (env->ExceptionOccurred()) {
+ std::ostringstream errStr;
+ errStr << "Could not set field " << fieldName.c_str() << " on class " << className.c_str();
+ Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ return;
+ }
+
+ info.GetReturnValue().SetUndefined();
+}
+
+NAN_METHOD(Java::instanceOf) {
+ Nan::HandleScope scope;
+ Java *self = Nan::ObjectWrap::Unwrap(info.This());
+ v8::Local ensureJvmResults = self->ensureJvm();
+ if (!ensureJvmResults->IsNull()) {
+ info.GetReturnValue().Set(ensureJvmResults);
+ return;
+ }
+ JNIEnv *env = self->getJavaEnv();
+ JavaScope javaScope(env);
+
+ int argsStart = 0;
+ ARGS_FRONT_OBJECT(obj);
+ ARGS_FRONT_STRING(className);
+
+ jobject instance = v8ToJava(env, obj);
+ if (!instance) {
+ // not even a Java object
+ info.GetReturnValue().Set(Nan::New(false));
+ return;
+ }
+
+ jclass clazz = javaFindClass(env, className);
+ if (!clazz) {
+ std::ostringstream errStr;
+ errStr << "Could not find class " << className.c_str();
+ Nan::ThrowError(javaExceptionToV8(self, env, errStr.str()));
+ return;
+ }
+
+ jboolean res = env->IsInstanceOf(instance, clazz);
+ info.GetReturnValue().Set(Nan::New(res));
+}
+
+NAN_METHOD(Java::stop) {
+ if (isDefaultLoopRunning) {
+ uv_close((uv_handle_t *)&uvAsync_dynamicProxyJsCall, NULL);
+ }
+}
+
+template std::string to_string(T value) {
+ std::ostringstream os;
+ os << value;
+ return os.str();
+}
+
+void EIO_CallJs(DynamicProxyJsCallData *callData) {
+ DynamicProxyData *dynamicProxyData = callData->dynamicProxyData;
+
+ assert(callData->done == 0);
+
+ if (!dynamicProxyDataVerify(dynamicProxyData)) {
+ return;
+ }
+ callData->result = NULL;
+
+ JNIEnv *env;
+ int ret = dynamicProxyData->java->getJvm()->GetEnv((void **)&env, JNI_BEST_VERSION);
+ if (ret != JNI_OK) {
+ callData->throwableClass = "java/lang/IllegalStateException";
+ callData->throwableMessage = "Could not retrieve JNIEnv: jvm->GetEnv returned " + to_string(ret);
+ callData->done = DYNAMIC_PROXY_JS_ERROR;
+ return;
+ }
+
+ Nan::HandleScope scope;
+ v8::Array *v8Args;
+ v8::Local fn;
+ v8::Local *argv;
+ int argc;
+ int i;
+ v8::Local v8Result;
+ jobject javaResult;
+
+ v8::Local dynamicProxyDataFunctions = Nan::New(dynamicProxyData->functions);
+ v8::Local fnObj =
+ dynamicProxyDataFunctions
+ ->Get(Nan::GetCurrentContext(), Nan::New(callData->methodName.c_str()).ToLocalChecked())
+ .ToLocalChecked();
+ if (fnObj->IsUndefined() || fnObj->IsNull()) {
+ callData->throwableClass = "java/lang/NoSuchMethodError";
+ callData->throwableMessage = "Could not find js function " + callData->methodName;
+ callData->done = DYNAMIC_PROXY_JS_ERROR;
+ return;
+ }
+ if (!fnObj->IsFunction()) {
+ callData->throwableClass = "java/lang/IllegalStateException";
+ callData->throwableMessage = callData->methodName + " is not a function";
+ callData->done = DYNAMIC_PROXY_JS_ERROR;
+ return;
+ }
+
+ fn = fnObj.As();
+
+ if (callData->args) {
+ v8Args = v8::Array::Cast(*javaArrayToV8(dynamicProxyData->java, env, callData->args));
+ argc = v8Args->Length();
+ } else {
+ argc = 0;
+ }
+ argv = new v8::Local[argc];
+ for (i = 0; i < argc; i++) {
+ argv[i] = v8Args->Get(Nan::GetCurrentContext(), i).ToLocalChecked();
+ }
+
+ Nan::TryCatch tryCatch;
+ tryCatch.SetCaptureMessage(true);
+ v8Result = Nan::Call(fn, dynamicProxyDataFunctions, argc, argv).FromMaybe(v8::Local());
+ delete[] argv;
+ if (tryCatch.HasCaught()) {
+ callData->throwableClass = "node/NodeJsException";
+ Nan::Utf8String message(tryCatch.Message()->Get());
+ callData->throwableMessage = std::string(*message);
+ tryCatch.Reset();
+ callData->done = DYNAMIC_PROXY_JS_ERROR;
+ return;
+ }
+
+ if (!dynamicProxyDataVerify(dynamicProxyData)) {
+ return;
+ }
+
+ javaResult = v8ToJava(env, v8Result);
+ if (javaResult == NULL) {
+ callData->result = NULL;
+ } else {
+ callData->result = env->NewGlobalRef(javaResult);
+ }
+
+ callData->done = true;
+}
+
+void throwNewThrowable(JNIEnv *env, const char *excClassName, std::string msg) {
+ jclass newExcCls = env->FindClass(excClassName);
+ jthrowable throwable = env->ExceptionOccurred();
+ if (throwable != NULL) {
+ env->Throw(throwable); // this should only be Errors, according to the docs
+ }
+ env->ThrowNew(newExcCls, msg.c_str());
+}
+
+JNIEXPORT jobject JNICALL Java_node_NodeDynamicProxyClass_callJs(JNIEnv *env, jobject src, jlong ptr, jobject method,
+ jobjectArray args) {
+ threadId myThreadId = my_getThreadId();
+
+ bool hasArgsGlobalRef = false;
+
+ DynamicProxyData *dynamicProxyData = (DynamicProxyData *)ptr;
+
+ // args needs to be global, you can't send env across thread boundaries
+ DynamicProxyJsCallData callData;
+ callData.dynamicProxyData = dynamicProxyData;
+ callData.args = args;
+ callData.done = false;
+ callData.result = NULL;
+ callData.throwableClass = "";
+ callData.throwableMessage = "";
+
+ jclass methodClazz = env->FindClass("java/lang/reflect/Method");
+ jmethodID method_getName = env->GetMethodID(methodClazz, "getName", "()Ljava/lang/String;");
+ callData.methodName = javaObjectToString(env, env->CallObjectMethod(method, method_getName));
+ assertNoException(env);
+
+ if (v8ThreadIdEquals(myThreadId, v8ThreadId)) {
+ EIO_CallJs(&callData);
+ } else {
+ if (args) {
+ // if args is not null and we have to kick this across the thread boundary, make it a global ref
+ callData.args = (jobjectArray)env->NewGlobalRef(args);
+ hasArgsGlobalRef = true;
+ }
+
+ uv_mutex_lock(&uvMutex_dynamicProxyJsCall);
+ queue_dynamicProxyJsCallData.push(&callData); // we wait for work to finish, so ok to pass ref to local var
+ uv_mutex_unlock(&uvMutex_dynamicProxyJsCall);
+ uv_async_send(&uvAsync_dynamicProxyJsCall);
+
+ while (!callData.done) {
+ my_sleep(100);
+ }
+ }
+
+ if (!dynamicProxyDataVerify(dynamicProxyData)) {
+ throwNewThrowable(env, "java/lang/IllegalStateException", "dynamicProxyData was corrupted");
+ }
+ if (hasArgsGlobalRef) {
+ env->DeleteGlobalRef(callData.args);
+ }
+
+ if (callData.done == DYNAMIC_PROXY_JS_ERROR) {
+ throwNewThrowable(env, callData.throwableClass.c_str(), callData.throwableMessage);
+ }
+
+ jobject result = NULL;
+ if (callData.result) {
+ // need to retain a local ref so that we can return it, otherwise the returned object gets corrupted
+ result = env->NewLocalRef(callData.result);
+ env->DeleteGlobalRef(callData.result);
+ }
+ return result;
+}
+
+JNIEXPORT void JNICALL Java_node_NodeDynamicProxyClass_unref(JNIEnv *env, jobject src, jlong ptr) {
+ DynamicProxyData *dynamicProxyData = (DynamicProxyData *)ptr;
+ unref(dynamicProxyData);
+}
diff --git a/src-cpp/java.h b/src-cpp/java.h
new file mode 100644
index 00000000..83c5cfcd
--- /dev/null
+++ b/src-cpp/java.h
@@ -0,0 +1,85 @@
+
+#ifndef _node_java_h_
+#define _node_java_h_
+
+#include
+#include
+#include
+#include
+#include
+
+#ifdef JNI_VERSION_1_8
+#define JNI_BEST_VERSION JNI_VERSION_1_8
+#else
+#define JNI_BEST_VERSION JNI_VERSION_1_6
+#endif
+
+class Java : public Nan::ObjectWrap {
+public:
+ static void Init(v8::Local target);
+ JavaVM *getJvm() { return m_jvm; }
+ JNIEnv *getJavaEnv() {
+ return m_env;
+ } // can only be used safely by the main thread as this is the thread it belongs to
+ jobject getClassLoader() { return m_classLoader; }
+
+public:
+ bool DoSync() const { return doSync; }
+ bool DoAsync() const { return doAsync; }
+ bool DoPromise() const { return doPromise; }
+ std::string SyncSuffix() const { return m_SyncSuffix; }
+ std::string AsyncSuffix() const { return m_AsyncSuffix; }
+ std::string PromiseSuffix() const { return m_PromiseSuffix; }
+
+private:
+ Java();
+ ~Java();
+ v8::Local createJVM(JavaVM **jvm, JNIEnv **env);
+ void destroyJVM(JavaVM **jvm, JNIEnv **env);
+ void configureAsync(v8::Local &asyncOptions);
+
+ static NAN_METHOD(New);
+ static NAN_METHOD(getClassLoader);
+ static NAN_METHOD(newInstance);
+ static NAN_METHOD(newInstanceSync);
+ static NAN_METHOD(newProxy);
+ static NAN_METHOD(callStaticMethod);
+ static NAN_METHOD(callStaticMethodSync);
+ static NAN_METHOD(callMethod);
+ static NAN_METHOD(callMethodSync);
+ static NAN_METHOD(findClassSync);
+ static NAN_METHOD(newArray);
+ static NAN_METHOD(newByte);
+ static NAN_METHOD(newChar);
+ static NAN_METHOD(newShort);
+ static NAN_METHOD(newLong);
+ static NAN_METHOD(newFloat);
+ static NAN_METHOD(newDouble);
+ static NAN_METHOD(getStaticFieldValue);
+ static NAN_METHOD(setStaticFieldValue);
+ static NAN_METHOD(instanceOf);
+ static NAN_METHOD(stop);
+ static NAN_GETTER(AccessorProhibitsOverwritingGetter);
+ static NAN_SETTER(AccessorProhibitsOverwritingSetter);
+ v8::Local ensureJvm();
+
+ static Nan::Persistent s_ct;
+ JavaVM *m_jvm;
+ JNIEnv *m_env; // can only be used safely by the main thread as this is the thread it belongs to
+ jobject m_classLoader;
+ std::string m_classPath;
+ static std::string s_nativeBindingLocation;
+ Nan::Persistent m_classPathArray;
+ Nan::Persistent m_optionsArray;
+ Nan::Persistent m_asyncOptions;
+
+ std::string m_SyncSuffix;
+ std::string m_AsyncSuffix;
+ std::string m_PromiseSuffix;
+
+ bool doSync;
+ bool doAsync;
+ bool doPromise;
+};
+
+#endif
diff --git a/src-cpp/javaObject.cpp b/src-cpp/javaObject.cpp
new file mode 100644
index 00000000..0dd23920
--- /dev/null
+++ b/src-cpp/javaObject.cpp
@@ -0,0 +1,393 @@
+#include "javaObject.h"
+#include "java.h"
+#include "javaScope.h"
+#include "utils.h"
+#include
+#include
+
+/*static*/ std::map *> JavaObject::sFunctionTemplates;
+
+/*static*/ void JavaObject::Init(v8::Local target) {}
+
+/*static*/ v8::Local JavaObject::New(Java *java, jobject obj) {
+ Nan::EscapableHandleScope scope;
+
+ JNIEnv *env = java->getJavaEnv();
+ JavaScope javaScope(env);
+
+ jclass objClazz = env->GetObjectClass(obj);
+ jclass classClazz = env->FindClass("java/lang/Class");
+ jmethodID class_getName = env->GetMethodID(classClazz, "getName", "()Ljava/lang/String;");
+ jobject classNameJava = env->CallObjectMethod(objClazz, class_getName);
+ checkJavaException(env);
+ std::string className = javaObjectToString(env, classNameJava);
+ std::replace(className.begin(), className.end(), '.', '_');
+ std::replace(className.begin(), className.end(), '$', '_');
+ std::replace(className.begin(), className.end(), '[', 'a');
+ className = "nodeJava_" + className;
+
+ v8::Local promisify;
+ if (java->DoPromise()) {
+ v8::Local promisifyValue =
+ java->handle()
+ ->Get(Nan::GetCurrentContext(), Nan::New("promisify").ToLocalChecked())
+ .ToLocalChecked();
+ promisify = promisifyValue.As();
+ }
+
+ v8::Local funcTemplate;
+ if (sFunctionTemplates.find(className) != sFunctionTemplates.end()) {
+ // printf("existing className: %s\n", className.c_str());
+ funcTemplate = Nan::New(*sFunctionTemplates[className]);
+ } else {
+ // printf("create className: %s\n", className.c_str());
+
+ funcTemplate = Nan::New();
+ funcTemplate->InstanceTemplate()->SetInternalFieldCount(1);
+ funcTemplate->SetClassName(Nan::New(className.c_str()).ToLocalChecked());
+
+ // copy methods to template
+ std::list methods;
+ javaReflectionGetMethods(env, objClazz, &methods, false);
+ jclass methodClazz = env->FindClass("java/lang/reflect/Method");
+ jmethodID method_getName = env->GetMethodID(methodClazz, "getName", "()Ljava/lang/String;");
+ for (std::list::iterator it = methods.begin(); it != methods.end(); ++it) {
+ jstring methodNameJava = (jstring)env->CallObjectMethod(*it, method_getName);
+ assertNoException(env);
+ std::string methodNameStr = javaToString(env, methodNameJava);
+
+ v8::Local baseMethodName = Nan::New(methodNameStr.c_str()).ToLocalChecked();
+
+ std::string methodNameAsyncStr = methodNameStr;
+ const char *methodNameAsync = methodNameAsyncStr.append(java->AsyncSuffix()).c_str();
+ v8::Local methodCallTemplate = Nan::New(methodCall, baseMethodName);
+ Nan::SetPrototypeTemplate(funcTemplate, methodNameAsync, methodCallTemplate);
+
+ std::string methodNameSyncStr = methodNameStr;
+ const char *methodNameSync = methodNameSyncStr.append(java->SyncSuffix()).c_str();
+ v8::Local methodCallSyncTemplate =
+ Nan::New(methodCallSync, baseMethodName);
+ Nan::SetPrototypeTemplate(funcTemplate, methodNameSync, methodCallSyncTemplate);
+
+ if (java->DoPromise()) {
+ v8::Local recv = Nan::New();
+ v8::Local argv[] = {methodCallTemplate->GetFunction(Nan::GetCurrentContext()).ToLocalChecked()};
+ v8::Local result = Nan::Call(promisify, recv, 1, argv).FromMaybe(v8::Local());
+ if (!result->IsFunction()) {
+ fprintf(stderr, "Promisified result is not a function.\n");
+ assert(result->IsFunction());
+ }
+ v8::Local promFunction = result.As();
+ v8::Local promFunctionTemplate =
+ Nan::New(methodCallPromise, promFunction);
+ std::string methodNamePromiseStr = methodNameStr;
+ const char *methodNamePromise = methodNamePromiseStr.append(java->PromiseSuffix()).c_str();
+ Nan::SetPrototypeTemplate(funcTemplate, methodNamePromise, promFunctionTemplate);
+ }
+ }
+
+ // copy fields to template
+ std::list fields;
+ javaReflectionGetFields(env, objClazz, &fields);
+ jclass fieldClazz = env->FindClass("java/lang/reflect/Field");
+ jmethodID field_getName = env->GetMethodID(fieldClazz, "getName", "()Ljava/lang/String;");
+ for (std::list::iterator it = fields.begin(); it != fields.end(); ++it) {
+ jstring fieldNameJava = (jstring)env->CallObjectMethod(*it, field_getName);
+ checkJavaException(env);
+ std::string fieldNameStr = javaToString(env, fieldNameJava);
+
+ v8::Local fieldName = Nan::New(fieldNameStr.c_str()).ToLocalChecked();
+ Nan::SetAccessor(funcTemplate->InstanceTemplate(), fieldName, fieldGetter, fieldSetter);
+ }
+
+ // copy array methods to template
+ jmethodID class_isArray = env->GetMethodID(classClazz, "isArray", "()Z");
+ jboolean isArray = env->CallBooleanMethod(objClazz, class_isArray);
+ if (isArray) {
+ v8::Local fieldName = Nan::New("length").ToLocalChecked();
+ Nan::SetAccessor(funcTemplate->InstanceTemplate(), fieldName, fieldGetter, NULL);
+
+ Nan::SetIndexedPropertyHandler(funcTemplate->InstanceTemplate(), indexGetter);
+ }
+
+ Nan::Persistent *persistentFuncTemplate = new Nan::Persistent();
+ persistentFuncTemplate->Reset(funcTemplate);
+ sFunctionTemplates[className] = persistentFuncTemplate;
+ }
+
+ v8::Local ctor = Nan::GetFunction(funcTemplate).ToLocalChecked();
+ v8::Local javaObjectObj = Nan::NewInstance(ctor).ToLocalChecked();
+ SetHiddenValue(javaObjectObj, Nan::New(V8_HIDDEN_MARKER_JAVA_OBJECT).ToLocalChecked(),
+ Nan::New(true));
+ JavaObject *self = new JavaObject(java, obj);
+ self->Wrap(javaObjectObj);
+
+ return scope.Escape(javaObjectObj);
+}
+
+JavaObject::JavaObject(Java *java, jobject obj) {
+ m_java = java;
+ JNIEnv *env = m_java->getJavaEnv();
+ m_obj = env->NewGlobalRef(obj);
+ m_class = (jclass)env->NewGlobalRef(env->GetObjectClass(obj));
+}
+
+JavaObject::~JavaObject() {
+ JNIEnv *env = m_java->getJavaEnv();
+ env->DeleteGlobalRef(m_obj);
+ env->DeleteGlobalRef(m_class);
+}
+
+NAN_METHOD(JavaObject::methodCall) {
+ Nan::HandleScope scope;
+ JavaObject *self = Nan::ObjectWrap::Unwrap(info.This());
+ JNIEnv *env = self->m_java->getJavaEnv();
+ JavaScope javaScope(env);
+
+ Nan::Utf8String methodName(info.Data());
+ std::string methodNameStr = *methodName;
+
+ int argsStart = 0;
+ int argsEnd = info.Length();
+
+ // arguments
+ ARGS_BACK_CALLBACK();
+
+ if (!callbackProvided && methodNameStr == "toString") {
+ return methodCallSync(info);
+ }
+
+ jobjectArray methodArgs = v8ToJava(env, info, argsStart, argsEnd);
+
+ jobject method = javaFindMethod(env, self->m_class, methodNameStr, methodArgs);
+ if (method == NULL) {
+ std::string msg = methodNotFoundToString(env, self->m_class, methodNameStr, false, info, argsStart, argsEnd);
+ EXCEPTION_CALL_CALLBACK(self->m_java, msg);
+ info.GetReturnValue().SetUndefined();
+ return;
+ }
+
+ // run
+ InstanceMethodCallBaton *baton = new InstanceMethodCallBaton(self->m_java, self, method, methodArgs, callback);
+ baton->run();
+
+ END_CALLBACK_FUNCTION("\"Method '" << methodNameStr
+ << "' called without a callback did you mean to use the Sync version?\"");
+}
+
+NAN_METHOD(JavaObject::methodCallSync) {
+ Nan::HandleScope scope;
+ JavaObject *self = Nan::ObjectWrap::Unwrap(info.This());
+ JNIEnv *env = self->m_java->getJavaEnv();
+ JavaScope javaScope(env);
+
+ Nan::Utf8String methodName(info.Data());
+ std::string methodNameStr = *methodName;
+
+ int argsStart = 0;
+ int argsEnd = info.Length();
+
+ jobjectArray methodArgs = v8ToJava(env, info, argsStart, argsEnd);
+
+ jobject method = javaFindMethod(env, self->m_class, methodNameStr, methodArgs);
+ if (method == NULL) {
+ std::string msg = methodNotFoundToString(env, self->m_class, methodNameStr, false, info, argsStart, argsEnd);
+ v8::Local ex = javaExceptionToV8(self->m_java, env, msg);
+ Nan::ThrowError(ex);
+ return;
+ }
+
+ // run
+ v8::Local callback = Nan::Undefined();
+ InstanceMethodCallBaton *baton = new InstanceMethodCallBaton(self->m_java, self, method, methodArgs, callback);
+ v8::Local result = baton->runSync();
+ delete baton;
+
+ if (result->IsNativeError()) {
+ Nan::ThrowError(result);
+ return;
+ }
+
+ info.GetReturnValue().Set(result);
+}
+
+NAN_METHOD(JavaObject::methodCallPromise) {
+ Nan::HandleScope scope;
+ v8::Local fn = info.Data().As();
+ v8::Local *argv = new v8::Local[info.Length()];
+ for (int i = 0; i < info.Length(); i++) {
+ argv[i] = info[i];
+ }
+
+ v8::MaybeLocal result = Nan::Call(fn, info.This(), info.Length(), argv);
+
+ delete[] argv;
+
+ if (!result.IsEmpty()) {
+ info.GetReturnValue().Set(result.ToLocalChecked());
+ }
+}
+
+NAN_GETTER(JavaObject::fieldGetter) {
+ Nan::HandleScope scope;
+ JavaObject *self = Nan::ObjectWrap::Unwrap(info.This());
+ JNIEnv *env = self->m_java->getJavaEnv();
+ JavaScope javaScope(env);
+
+ Nan::Utf8String propertyCStr(property);
+ std::string propertyStr = *propertyCStr;
+ jobject field = javaFindField(env, self->m_class, propertyStr);
+ if (field == NULL) {
+ if (propertyStr == "length") {
+ jclass classClazz = env->FindClass("java/lang/Class");
+ jmethodID class_isArray = env->GetMethodID(classClazz, "isArray", "()Z");
+ jboolean isArray = env->CallBooleanMethod(self->m_class, class_isArray);
+ if (isArray) {
+ jclass arrayClass = env->FindClass("java/lang/reflect/Array");
+ jmethodID array_getLength = env->GetStaticMethodID(arrayClass, "getLength", "(Ljava/lang/Object;)I");
+ jint arrayLength = env->CallStaticIntMethod(arrayClass, array_getLength, self->m_obj);
+ assertNoException(env);
+ info.GetReturnValue().Set(Nan::New(static_cast(arrayLength)));
+ return;
+ }
+ }
+
+ std::ostringstream errStr;
+ errStr << "Could not find field \"" << propertyStr << "\" for get";
+ v8::Local ex = javaExceptionToV8(self->m_java, env, errStr.str());
+ Nan::ThrowError(ex);
+ return;
+ }
+
+ jclass fieldClazz = env->FindClass("java/lang/reflect/Field");
+ jmethodID field_get = env->GetMethodID(fieldClazz, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
+
+ // get field value
+ jobject val = env->CallObjectMethod(field, field_get, self->m_obj);
+ if (env->ExceptionOccurred()) {
+ std::ostringstream errStr;
+ errStr << "Could not get field " << propertyStr;
+ v8::Local ex = javaExceptionToV8(self->m_java, env, errStr.str());
+ Nan::ThrowError(ex);
+ return;
+ }
+
+ v8::Local result = javaToV8(self->m_java, env, val);
+
+ info.GetReturnValue().Set(result);
+}
+
+NAN_SETTER(JavaObject::fieldSetter) {
+ Nan::HandleScope scope;
+ JavaObject *self = Nan::ObjectWrap::Unwrap(info.This());
+ JNIEnv *env = self->m_java->getJavaEnv();
+ JavaScope javaScope(env);
+
+ jobject newValue = v8ToJava(env, value);
+
+ Nan::Utf8String propertyCStr(property);
+ std::string propertyStr = *propertyCStr;
+ jobject field = javaFindField(env, self->m_class, propertyStr);
+ if (field == NULL) {
+ std::ostringstream errStr;
+ errStr << "Could not find field \"" << propertyStr << "\" for set";
+ v8::Local error = javaExceptionToV8(self->m_java, env, errStr.str());
+ Nan::ThrowError(error);
+ return;
+ }
+
+ jclass fieldClazz = env->FindClass("java/lang/reflect/Field");
+ jmethodID field_set = env->GetMethodID(fieldClazz, "set", "(Ljava/lang/Object;Ljava/lang/Object;)V");
+
+ // printf("newValue: %s\n", javaObjectToString(env, newValue).c_str());
+
+ // set field value
+ env->CallObjectMethod(field, field_set, self->m_obj, newValue);
+ if (env->ExceptionOccurred()) {
+ std::ostringstream errStr;
+ errStr << "Could not set field " << propertyStr;
+ v8::Local error = javaExceptionToV8(self->m_java, env, errStr.str());
+ Nan::ThrowError(error);
+ return;
+ }
+}
+
+NAN_INDEX_GETTER(JavaObject::indexGetter) {
+ Nan::HandleScope scope;
+ JavaObject *self = Nan::ObjectWrap::Unwrap(info.This());
+ JNIEnv *env = self->m_java->getJavaEnv();
+ JavaScope javaScope(env);
+
+ jclass arrayClass = env->FindClass("java/lang/reflect/Array");
+
+ jmethodID array_getLength = env->GetStaticMethodID(arrayClass, "getLength", "(Ljava/lang/Object;)I");
+ jint arrayLength = env->CallStaticIntMethod(arrayClass, array_getLength, self->m_obj);
+ assertNoException(env);
+ if ((jint)index >= arrayLength) {
+ info.GetReturnValue().SetUndefined();
+ RETURN_INTERCEPTED_YES;
+ }
+
+ jmethodID array_get = env->GetStaticMethodID(arrayClass, "get", "(Ljava/lang/Object;I)Ljava/lang/Object;");
+ jobject item = env->CallStaticObjectMethod(arrayClass, array_get, self->m_obj, index);
+ assertNoException(env);
+ v8::Local result = javaToV8(self->m_java, env, item);
+ info.GetReturnValue().Set(result);
+ RETURN_INTERCEPTED_YES;
+}
+
+/*static*/ Nan::Persistent JavaProxyObject::s_proxyCt;
+
+/*static*/ void JavaProxyObject::init() {
+ v8::Local t = Nan::New();
+ s_proxyCt.Reset(t);
+ t->InstanceTemplate()->SetInternalFieldCount(1);
+ t->SetClassName(Nan::New("NodeDynamicProxy").ToLocalChecked());
+
+ Nan::SetPrototypeTemplate(t, "unref", Nan::New(doUnref));
+
+ v8::Local fieldName = Nan::New("invocationHandler").ToLocalChecked();
+ Nan::SetAccessor(t->InstanceTemplate(), fieldName, invocationHandlerGetter);
+}
+
+v8::Local JavaProxyObject::New(Java *java, jobject obj, DynamicProxyData *dynamicProxyData) {
+ Nan::EscapableHandleScope scope;
+
+ v8::Local ctor = Nan::New(s_proxyCt)->GetFunction(Nan::GetCurrentContext()).ToLocalChecked();
+ v8::Local javaObjectObj = Nan::NewInstance(ctor).ToLocalChecked();
+ SetHiddenValue(javaObjectObj, Nan::New(V8_HIDDEN_MARKER_JAVA_OBJECT).ToLocalChecked(),
+ Nan::New