diff --git a/binding.gyp b/binding.gyp index e6de9be..875b197 100644 --- a/binding.gyp +++ b/binding.gyp @@ -13,11 +13,20 @@ 'targets': [ { 'target_name': 'fs_admin', + 'cflags!': [ '-fno-exceptions' ], + 'cflags_cc!': [ '-fno-exceptions' ], + 'xcode_settings': { 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES', + 'CLANG_CXX_LIBRARY': 'libc++', + 'MACOSX_DEPLOYMENT_TARGET': '10.7', + }, + 'msvs_settings': { + 'VCCLCompilerTool': { 'ExceptionHandling': 1 }, + }, 'sources': [ 'src/main.cc', ], 'include_dirs': [ - ' &args, bool test_mode); diff --git a/src/main.cc b/src/main.cc index fc4f7e2..d77c1e0 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,18 +1,19 @@ -#include "nan.h" +#include "napi.h" +#include "uv.h" #include "fs-admin.h" namespace fs_admin { -using namespace v8; +using namespace Napi; -class Worker : public Nan::AsyncWorker { +class Worker : public Napi::AsyncWorker { void *child_process; int exit_code; bool test_mode; public: - Worker(Nan::Callback *callback, void *child_process, bool test_mode) : - Nan::AsyncWorker(callback), + Worker(const Function& callback, void *child_process, bool test_mode) : + Napi::AsyncWorker(callback), child_process(child_process), exit_code(-1), test_mode(test_mode) {} @@ -21,77 +22,76 @@ class Worker : public Nan::AsyncWorker { exit_code = WaitForChildProcessToExit(child_process, test_mode); } - void HandleOKCallback() { - Local argv[] = {Nan::New(exit_code)}; - callback->Call(1, argv, async_resource); + void OnOK() { + const std::vector argv{Napi::Number::New(Env(), exit_code)}; + Callback().Call(argv); } }; -void GetAuthorizationForm(const Nan::FunctionCallbackInfo& info) { +Napi::Value GetAuthorizationForm(const Napi::CallbackInfo& info) { + const Napi::Env& env = info.Env(); auto auth_form = CreateAuthorizationForm(); - auto buffer = Nan::CopyBuffer(auth_form.c_str(), auth_form.size()); - info.GetReturnValue().Set(buffer.ToLocalChecked()); + auto buffer = Napi::Buffer::Copy(env, auth_form.c_str(), auth_form.size()); + return buffer; } -void ClearAuthorizationCache(const Nan::FunctionCallbackInfo& info) { - ClearAuthorizationCache(); +Napi::Value ClearAuthorizationCache(const Napi::CallbackInfo& info) { + ClearAuthorizationCacheImpl(); + return info.Env().Undefined(); } -void SpawnAsAdmin(const Nan::FunctionCallbackInfo& info) { - if (!info[0]->IsString()) { - Nan::ThrowTypeError("Command must be a string"); - return; +Napi::Value SpawnAsAdmin(const Napi::CallbackInfo& info) { + const Napi::Env& env = info.Env(); + if (!info[0].IsString()) { + Napi::TypeError::New(env, "Command must be a string").ThrowAsJavaScriptException(); + return env.Null(); } - Nan::Utf8String commandNan(info[0]); - std::string command(*commandNan, commandNan.length()); + std::string command = info[0].As(); - if (!info[1]->IsArray()) { - Nan::ThrowTypeError("Arguments must be an array"); - return; + if (!info[1].IsArray()) { + Napi::TypeError::New(env, "Arguments must be an array").ThrowAsJavaScriptException(); + return env.Undefined(); } - Local js_args = Local::Cast(info[1]); + Napi::Array js_args = info[1].As(); std::vector args; - args.reserve(js_args->Length()); - for (uint32_t i = 0; i < js_args->Length(); ++i) { - Local context = Nan::GetCurrentContext(); - Local js_arg = js_args->Get(context, i).ToLocalChecked(); - if (!js_arg->IsString()) { - Nan::ThrowTypeError("Arguments must be an array of strings"); - return; + args.reserve(js_args.Length()); + for (uint32_t i = 0; i < js_args.Length(); ++i) { + Napi::Value js_arg = js_args.Get(i); + if (!js_arg.IsString()) { + Napi::TypeError::New(env, "Arguments must be an array of strings").ThrowAsJavaScriptException(); + return env.Undefined(); } - args.push_back(*Nan::Utf8String(js_arg)); + args.push_back(js_arg.As()); } bool test_mode = false; - if (info[2]->IsTrue()) test_mode = true; + if (info[2].ToBoolean().Value()) test_mode = true; - if (!info[3]->IsFunction()) { - Nan::ThrowTypeError("Callback must be a function"); - return; + if (!info[3].IsFunction()) { + Napi::TypeError::New(env, "Callback must be a function").ThrowAsJavaScriptException(); + return env.Undefined(); } void *child_process = StartChildProcess(command, args, test_mode); if (!child_process) { - info.GetReturnValue().Set(Nan::False()); + return Napi::Number::New(env, false); } else { - Nan::AsyncQueueWorker(new Worker(new Nan::Callback(info[3].As()), child_process, test_mode)); - info.GetReturnValue().Set(Nan::True()); + auto worker = new Worker(info[3].As(), child_process, test_mode); + worker->Queue(); + return Napi::Number::New(env, true); } } -NAN_MODULE_INIT(Init) { - Nan::SetMethod(target, "getAuthorizationForm", GetAuthorizationForm); - Nan::SetMethod(target, "clearAuthorizationCache", ClearAuthorizationCache); - Nan::SetMethod(target, "spawnAsAdmin", SpawnAsAdmin); +Napi::Object Init(Napi::Env env, Napi::Object exports) { + exports.Set(Napi::String::New(env, "getAuthorizationForm"), Napi::Function::New(env, GetAuthorizationForm)); + exports.Set(Napi::String::New(env, "clearAuthorizationCache"), Napi::Function::New(env, ClearAuthorizationCache)); + exports.Set(Napi::String::New(env, "spawnAsAdmin"), Napi::Function::New(env, SpawnAsAdmin)); + return exports; } -#if NODE_MAJOR_VERSION >= 10 -NAN_MODULE_WORKER_ENABLED(fs_admin, Init) -#else -NODE_MODULE(fs_admin, Init) -#endif +NODE_API_MODULE(fs_admin, Init) } // namespace spawn_as_admin