Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qnapi_p.h
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QNAPI_P_H
5#define QNAPI_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/private/qohoslogger_p.h>
19#include <QtCore/qstring.h>
20#include <algorithm>
21#include <array>
22#include <functional>
23#include <map>
24#include <memory>
25#include <napi.h>
26#include <string>
27#include <tuple>
28#include <type_traits>
29#include <utility>
30#include <vector>
31
32QT_BEGIN_NAMESPACE
33
34namespace QNapi {
35
36template<typename... ExtraArgs>
38{
39public:
40 template<typename Func>
41 ExtendedCallbackFuncWrapper(Func &&callbackFunc, std::enable_if_t<std::is_void<std::result_of_t<Func(const Napi::CallbackInfo &, ExtraArgs...)>>::value, char *> = nullptr);
42
43 template<typename Func>
44 ExtendedCallbackFuncWrapper(Func &&callbackFunc, std::enable_if_t<std::is_base_of<Napi::Value, std::result_of_t<Func(const Napi::CallbackInfo &, ExtraArgs...)>>::value, short *> = nullptr);
45
46 template<typename Func>
47 ExtendedCallbackFuncWrapper(Func &&callbackFunc, std::enable_if_t<std::is_void<std::result_of_t<Func(ExtraArgs...)>>::value, int *> = nullptr);
48
49 template<typename Func>
50 ExtendedCallbackFuncWrapper(Func &&callbackFunc, std::enable_if_t<std::is_base_of<Napi::Value, std::result_of_t<Func(ExtraArgs...)>>::value, long *> = nullptr);
51
53
54private:
55 std::function<Napi::Value(const Napi::CallbackInfo &, ExtraArgs...)> m_callbackFunc;
56};
57
59
60using Value = Napi::Value;
61
63
65
67
68using Date = Napi::Date;
69
71
73
75
77
79
81
82template<typename BufferT>
84
85template<typename ExternalT>
87
88template<typename T>
90
92{
93public:
94 template<typename T>
95 ValueWrapper(T &&inputValue);
96
97 Napi::Value mapToValue(napi_env env) const;
98
99private:
100 std::function<Napi::Value(napi_env)> m_valueFactory;
101};
102
103class Array : public Napi::Array
104{
105public:
106 using Napi::Array::Array;
107
108 static Array New(napi_env env, std::size_t length = 0);
109
110 Array(const Napi::Array &other);
111 Array &operator=(const Napi::Array &other);
112
113 void fill(const ValueWrapper &value);
114};
115
116class Object : public Napi::Object
117{
118public:
119 using Napi::Object::Object;
120
121 static Object New(napi_env env);
122
123 Object(const Napi::Object &other);
124 Object &operator=(const Napi::Object &other);
125
126 template<typename T = Value>
127 T get(const std::string &expr) const;
128
129 template<typename T = Value>
130 T get(const Napi::Name &name) const;
131
132 template<typename T>
133 T eval(const std::string &expr, const std::vector<ValueWrapper> &exprArgs = {}) const;
134
135 void set(const std::string &name, const ValueWrapper &value);
136
137 void set(const Napi::Name &name, const ValueWrapper &value);
138
139 void set(const std::vector<std::pair<std::string, ValueWrapper>> &namedValues);
140
141 template<typename Result = Value>
142 Result call(const std::string &methodName, const std::vector<ValueWrapper> &args = {}) const;
143};
144
145template<typename Context>
147
148class Promise : public Napi::Promise
149{
150public:
151 using Napi::Promise::Promise;
152
153 Promise();
154 Promise(const Napi::Promise &other);
155 Promise &operator=(const Napi::Promise &other);
156
157 Promise onThen(CallbackFuncWrapper &&onFulfilledFunc);
158 Promise onThen(CallbackFuncWrapper &&onFulfilledFunc, CallbackFuncWrapper &&onRejectedFunc);
159 Promise onCatch(CallbackFuncWrapper &&onRejectedFunc);
160 Promise onFinally(CallbackFuncWrapper &&onFinallyFunc);
162 CallbackFuncWrapper &&onFulfilledFunc, CallbackFuncWrapper &&onRejectedFunc,
163 CallbackFuncWrapper &&onFinallyFunc);
164
165 template<typename Context>
166 PromiseWithContext<Context> withContext(Context &&context);
167};
168
169template<typename Context>
171{
172public:
173 PromiseWithContext(const Promise &promise, std::shared_ptr<Context> context);
174
177 ExtendedCallbackFuncWrapper<Context &> &&onFulfilledFunc, CallbackFuncWrapper &&onRejectedFunc);
180
181private:
182 std::shared_ptr<Context> m_context;
183};
184
185template<typename T = void>
186class Reference : public Napi::Reference<T>
187{
188public:
189 using Napi::Reference<T>::Reference;
190
191 Reference(Reference<T> &&other);
192 Reference<T> &operator=(Reference<T> &&other);
193
194 Reference(const Reference<T> &other) = delete;
195 Reference<T> &operator=(const Reference<T> &other) = delete;
196
197 Reference(Napi::Reference<T> &&other);
198 Reference<T> &operator=(Napi::Reference<T> &&other);
199
200 static Reference<T> makePersistentFrom(const T &value);
201
202 static Reference<T> makeEmpty();
203};
204
205template<>
207{
208public:
210
211 Reference(Reference<Object> &&other);
213
214 Reference(const Reference<Object> &other) = delete;
215 Reference<Object> &operator=(const Reference<Object> &other) = delete;
216
217 Reference(Napi::Reference<Object> &&other);
218 Reference<Object> &operator=(Napi::Reference<Object> &&other);
219
220 template<typename T>
221 T eval(const std::string &expr, const std::vector<ValueWrapper> &exprArgs = {}) const;
222
223 void set(const std::string &name, const ValueWrapper &value);
224
225 void set(const std::vector<std::pair<std::string, ValueWrapper>> &namedValues);
226
227 template<typename Result = ::QNapi::Value>
228 Result call(const std::string &methodName, const std::vector<ValueWrapper> &args = {}) const;
229
230 static Reference<Object> makePersistentFrom(const Object &value);
231
232 static Reference<Object> makeEmpty();
233};
234
235template<>
236class Reference<void>
237{
238public:
239 Reference() = delete;
240
241 template<typename T>
243
244 template<typename T = Value>
245 static Reference<T> makeEmpty();
246};
247
249{
250public:
251 CallbackInfo(const Napi::CallbackInfo &cbInfo);
252
253 CallbackInfo(const CallbackInfo &other) = delete;
254 CallbackInfo &operator=(const CallbackInfo &other) = delete;
255
256 Napi::Env Env() const;
257 std::size_t Length() const;
258
259 template<typename... Args>
260 void getLeadingArgs(const std::string &funcName, Args &...args) const;
261
262 template<typename Arg>
263 Arg getFirstArg(const std::string &funcName) const;
264
265 operator const Napi::CallbackInfo &() const;
266
267private:
268 const Napi::CallbackInfo &m_cbInfo;
269};
270
271std::vector<napi_value> unwrapValues(napi_env env, const std::vector<ValueWrapper> &wrappedValues);
272
273Napi::Error makeLoggedException(napi_env env, const std::string &msg);
274
275template<typename T>
276bool valueTypeMatches(const Napi::Value &value);
277
278template<typename Element>
279bool arrayElementTypesMatch(const Napi::Value &value);
280
281std::string getValueTypeString(const Napi::Value &value);
282
283template<typename T, typename ValueDescriptionSupplier>
284T checkedCast(const Napi::Value &value, ValueDescriptionSupplier &&valueDescSupplier);
285
286template<typename T>
287T checkedCast(const Napi::Value &value);
288
289template<typename OutputContainer, typename Element, typename TransFunc>
290OutputContainer getArrayElements(const Napi::Array &inputArray, TransFunc &&transFunc);
291
292template<typename OutputContainer, typename Element>
293OutputContainer getArrayElements(const Napi::Array &inputArray);
294
295Object makeNewInstance(const Napi::Function &type, const std::vector<ValueWrapper> &args = {});
296
297Object makeNewInstance(const Napi::Object &baseObj, const std::string &typePath, const std::vector<ValueWrapper> &args = {});
298
299Napi::Value getPropOrUndefined(const Napi::Value &obj, const std::string &propName);
300
301template<typename T>
302Napi::Value getPropOrUndefined(const Napi::Reference<T> &objRef, const std::string &propName);
303
304template<typename T>
306getOptionalPropOrEmpty(const Napi::Object &optObj, const std::string &propName, const std::string &objDesc = {});
307
308template<typename T>
310getOptionalPropOrEmpty(const Napi::Object &optObj, const Napi::Name &propName, const std::string &objDesc = {});
311
312Object makeObject(napi_env env, const std::vector<std::pair<std::string, ValueWrapper>> &namedValues = {});
313
314Array makeArray(napi_env env, const std::vector<ValueWrapper> &values = {});
315
316template<typename Result = Napi::Value, typename F>
317Result runEscapingHandleScope(napi_env env, F &&func);
318
319std::string toJsonString(const Napi::Value &value);
320
322
323template<typename T>
325{
326};
327
328template<>
330{
331 static constexpr auto typeCheckMemFun = &Napi::Value::IsBoolean;
332 static constexpr const char *typeName = "Boolean";
333};
334
335template<>
337{
338 static constexpr auto typeCheckMemFun = &Napi::Value::IsNumber;
339 static constexpr const char *typeName = "Number";
340};
341
342template<>
344{
345 static constexpr auto typeCheckMemFun = &Napi::Value::IsBigInt;
346 static constexpr const char *typeName = "BigInt";
347};
348
349template<>
351{
352 static constexpr auto typeCheckMemFun = &Napi::Value::IsDate;
353 static constexpr const char *typeName = "Date";
354};
355
356template<>
358{
359 static constexpr auto typeCheckMemFun = &Napi::Value::IsString;
360 static constexpr const char *typeName = "String";
361};
362
363template<>
365{
366 static constexpr auto typeCheckMemFun = &Napi::Value::IsSymbol;
367 static constexpr const char *typeName = "Symbol";
368};
369
370template<>
372{
373 static constexpr auto typeCheckMemFun = &Napi::Value::IsArray;
374 static constexpr const char *typeName = "Array";
375};
376
377template<>
379{
380};
381
382template<>
384{
385 static constexpr auto typeCheckMemFun = &Napi::Value::IsArrayBuffer;
386 static constexpr const char *typeName = "ArrayBuffer";
387};
388
389template<>
391{
392 static constexpr auto typeCheckMemFun = &Napi::Value::IsTypedArray;
393 static constexpr const char *typeName = "TypedArray";
394};
395
396template<>
398{
399 static constexpr auto typeCheckMemFun = &Napi::Value::IsObject;
400 static constexpr const char *typeName = "Object";
401};
402
403template<>
405{
406};
407
408template<>
410{
411 static constexpr auto typeCheckMemFun = &Napi::Value::IsFunction;
412 static constexpr const char *typeName = "Function";
413};
414
415template<>
417{
418 static constexpr auto typeCheckMemFun = &Napi::Value::IsPromise;
419 static constexpr const char *typeName = "Promise";
420};
421
422template<>
424{
425};
426
427template<>
429{
430 static constexpr auto typeCheckMemFun = &Napi::Value::IsDataView;
431 static constexpr const char *typeName = "DataView";
432};
433
434template<typename BufferT>
436{
437 static constexpr auto typeCheckMemFun = &Napi::Value::IsBuffer;
438 static constexpr const char *typeName = "Buffer";
439};
440
441template<typename ExternalT>
443{
444 static constexpr auto typeCheckMemFun = &Napi::Value::IsExternal;
445 static constexpr const char *typeName = "External";
446};
447
448template<typename T>
450{
451 static constexpr auto typeCheckMemFun = &Napi::Value::IsTypedArray;
452 static constexpr const char *typeName = "TypedArray";
453};
454
455template<typename T>
456constexpr bool isCallbackFuncType()
457{
458 return std::is_constructible<CallbackFuncWrapper, T>::value;
459}
460
461template<typename T>
462inline std::enable_if_t<isCallbackFuncType<T>(), Napi::Value> makeValue(napi_env env, T &&inputValue)
463{
464 return Napi::Function::New(env, std::move(CallbackFuncWrapper(std::forward<T>(inputValue)).callbackFunc()));
465}
466
467template<typename T>
468inline std::enable_if_t<!isCallbackFuncType<T>(), Napi::Value> makeValue(napi_env env, T &&inputValue)
469{
470 return Napi::Value::From(env, std::forward<T>(inputValue));
471}
472
473inline Napi::Error makeLoggedExceptionImpl(napi_env env, const std::string &msg)
474{
475 qOhosPrintfError("QNapi: exception: %s", msg.c_str());
476 return Napi::Error::New(env, msg);
477}
478
479template<typename T>
480std::enable_if_t<std::is_same<T, Napi::Value>::value, bool> valueTypeMatchesImpl(const Napi::Value &)
481{
482 return true;
483}
484
485template<typename T>
486std::enable_if_t<!std::is_same<T, Napi::Value>::value, bool> valueTypeMatchesImpl(const Napi::Value &value)
487{
488 return (value.*ValueTypeTraits<T>::typeCheckMemFun)();
489}
490
491std::string getArrayElementValueTypeString(const Napi::Array &arrayValue);
492
493inline std::string getValueTypeStringImpl(const Napi::Value &value)
494{
495 using namespace std::string_literals;
496
497 if (value.IsArray()) {
498 auto arrayElemTypeString = getArrayElementValueTypeString(value.As<Napi::Array>());
499 return "Array<"s + arrayElemTypeString + ">"s;
500 }
501
502 // put subtypes of the Napi::Object at the beginning, so that we find most specific type name
503 const std::pair<bool (Napi::Value::*)() const, const char *> typesChecksAndNames[] = {
504 {&Napi::Value::IsEmpty, "<empty>"},
505 {&Napi::Value::IsNull, "Null"},
506 {&Napi::Value::IsUndefined, "Undefined"},
507 {&Napi::Value::IsArray, "Array"},
508 {&Napi::Value::IsArrayBuffer, "ArrayBuffer"},
509 {&Napi::Value::IsTypedArray, "TypedArray"},
510 {&Napi::Value::IsDataView, "DataView"},
511 {&Napi::Value::IsFunction, "Function"},
512 {&Napi::Value::IsPromise, "Promise"},
513 {&Napi::Value::IsBigInt, "BigInt"},
514 {&Napi::Value::IsBuffer, "Buffer"},
515 {&Napi::Value::IsBoolean, "Boolean"},
516 {&Napi::Value::IsDate, "Date"},
517 {&Napi::Value::IsExternal, "External"},
518 {&Napi::Value::IsNumber, "Number"},
519 {&Napi::Value::IsObject, "Object"},
520 {&Napi::Value::IsString, "String"},
521 {&Napi::Value::IsSymbol, "Symbol"},
522 };
523
524 const char *foundTypeName = nullptr;
525 for (const auto &typeCheckEntry : typesChecksAndNames) {
526 if ((value.*(typeCheckEntry.first))()) {
527 foundTypeName = typeCheckEntry.second;
528 break;
529 }
530 }
531
532 return foundTypeName != nullptr ? foundTypeName : "?";
533}
534
535inline std::string getArrayElementValueTypeString(const Napi::Array &arrayValue)
536{
537 constexpr std::size_t maxArrayElementsForTypeCheck = 10;
538
539 std::size_t arrayLength = arrayValue.Length();
540 auto checkRangeSize = std::min(arrayLength, maxArrayElementsForTypeCheck);
541
542 std::string commonElemTypeString;
543 for (std::size_t i = 0; i < checkRangeSize; ++i) {
544 auto elemTypeString = getValueTypeStringImpl(arrayValue.Get(i));
545 if (commonElemTypeString.empty()) {
546 commonElemTypeString = elemTypeString;
547 } else if (commonElemTypeString != elemTypeString) {
548 commonElemTypeString = "";
549 break;
550 }
551 }
552
553 return !commonElemTypeString.empty()
554 ? checkRangeSize == arrayLength
555 ? commonElemTypeString
556 : commonElemTypeString + "?"
557 : "?";
558}
559
560template<typename T, typename ValueDescriptionSupplier>
562 const Napi::Value &value, ValueDescriptionSupplier &&)
563{
564 return value;
565}
566
567template<typename T, typename ValueDescriptionSupplier>
569 const Napi::Value &value, ValueDescriptionSupplier &&valueDescSupplier)
570{
571 using namespace std::string_literals;
572
573 if (!valueTypeMatchesImpl<T>(value)) {
574 constexpr const char *expectedTypeName = ValueTypeTraits<T>::typeName;
575 auto valueTypeStr = getValueTypeStringImpl(value);
576 std::string valueDesc = valueDescSupplier();
577 auto baseEerrorMsg =
578 "wrong type (expected '"s + expectedTypeName + "', got '"s + valueTypeStr + "') of Napi value"s;
579 throw makeLoggedExceptionImpl(
580 value.Env(), valueDesc.empty() ? baseEerrorMsg : baseEerrorMsg + ": "s + valueDesc);
581 }
582
583 return T(value.Env(), value);
584}
585
586template<typename Result, typename F>
587Result runEscapingHandleScopeImpl(napi_env env, F &&func)
588{
589 Napi::EscapableHandleScope scope(env);
590 Result result = std::forward<F>(func)();
591 return checkedCastImpl<Result>(
592 scope.Escape(result),
593 [&]() {
594 return "value escaping from HandleScope";
595 });
596}
597
599 napi_env env, const std::string &callArgsSubExpr, const std::vector<napi_value> &exprArgs)
600{
601 using namespace std::string_literals;
602
603 if (callArgsSubExpr.empty()) {
604 return {};
605 } else if (callArgsSubExpr == "*") {
606 return exprArgs;
607 } else {
608 throw makeLoggedException(
609 env, "illegal call arguments in expression: '"s + callArgsSubExpr + "'"s);
610 }
611}
612
613template<typename T>
615 Napi::Object obj, const std::string &expr, const std::vector<napi_value> &exprArgs = {})
616{
617 using namespace details_qnapi_p_h;
618 using namespace std::string_literals;
619
620 static const std::string newCallTag = "<new>";
621
622 std::pair<Napi::Object, Napi::Value> result;
623
624 auto lastDotPos = expr.rfind('.');
625
626 if (!expr.empty() && expr.back() == ')') {
627 auto openingBracketPos = expr.rfind('(');
628 if (openingBracketPos == std::string::npos)
629 throw makeLoggedExceptionImpl(obj.Env(), "missing opening bracket in '"s + expr + "'"s);
630 bool newInstanceCall =
631 openingBracketPos > newCallTag.size()
632 && expr.compare(openingBracketPos - newCallTag.size(), newCallTag.size(), newCallTag) == 0;
633 auto subFuncArgsExpr = expr.substr(
634 openingBracketPos + 1, expr.size() - 1 - (openingBracketPos + 1));
635 auto subFuncArgs = expandEvalCallArgs(obj.Env(), subFuncArgsExpr, exprArgs);
636 auto subFuncExpr = expr.substr(
637 0, newInstanceCall ? openingBracketPos - newCallTag.size() : openingBracketPos);
638 auto subFuncWithCtx = evalWithContextImpl<Napi::Function>(obj, subFuncExpr, exprArgs);
639 Napi::Value funcCallResult;
640 try {
641 funcCallResult =
642 newInstanceCall
643 ? subFuncWithCtx.second.New(subFuncArgs)
644 : !subFuncWithCtx.first.IsEmpty()
645 ? subFuncWithCtx.second.Call(subFuncWithCtx.first, subFuncArgs)
646 : subFuncWithCtx.second.Call(subFuncArgs);
647 } catch (const Napi::Error &error) {
648 auto message = "QNapi: got exception from call '"s + expr + "': "s + error.what();
649 qOhosPrintfError("%s", message.c_str());
650 throw;
651 }
652
653 result = std::make_pair(Napi::Object(), funcCallResult);
654 } else if (lastDotPos != std::string::npos) {
655 auto subObjExpr = expr.substr(0, lastDotPos);
656 auto propName = expr.substr(lastDotPos + 1);
657
658 auto subObj = evalWithContextImpl<Napi::Object>(obj, subObjExpr, exprArgs).second;
659 if (!subObj.Has(propName)) {
660 throw makeLoggedExceptionImpl(
661 obj.Env(), "object '"s + subObjExpr + "' has no property named '"s + propName + "'"s);
662 }
663
664 result = std::make_pair(subObj, subObj.Get(propName));
665 } else {
666 if (!obj.Has(expr)) {
667 throw makeLoggedExceptionImpl(
668 obj.Env(), "object has no property named '"s + expr + "'"s);
669 }
670
671 result = std::make_pair(obj, obj.Get(expr));
672 }
673
674 return std::make_pair(result.first, checkedCastImpl<T>(result.second, [&]() { return expr; }));
675}
676
678 const Napi::Object &obj, const std::string &methodName, const std::vector<napi_value> &args)
679{
680 using namespace std::string_literals;
681 return runEscapingHandleScopeImpl<Napi::Value>(
682 obj.Env(),
683 [&]() {
684 auto funcWithCtx = evalWithContextImpl<Napi::Function>(obj, methodName);
685 auto funcResult = funcWithCtx.second.Call(funcWithCtx.first, args);
686 return funcResult;
687 });
688}
689
690template<typename Result>
691Result callMethodImpl(const Napi::Object &obj, const std::string &methodName, const std::vector<napi_value> &args)
692{
693 using namespace std::string_literals;
694
695 return checkedCastImpl<Result>(
696 callMethodWithValueResultImpl(obj, methodName, args),
697 [&]() {
698 return "result of '"s + methodName + "' method call"s;
699 });
700}
701
702template<typename Result = Value>
703Result callMethod(const Napi::Object &obj, const std::string &methodName, const std::vector<ValueWrapper> &args)
704{
705 return runEscapingHandleScopeImpl<Result>(
706 obj.Env(),
707 [&]() {
708 return callMethodImpl<Result>(obj, methodName, unwrapValues(obj.Env(), args));
709 });
710}
711
712template<typename Arg>
713void getArgImpl(const std::string &funcName, const Napi::CallbackInfo &cbInfo, Arg &arg, std::size_t argIndex)
714{
715 using namespace std::string_literals;
716
717 arg = checkedCastImpl<Arg>(
718 cbInfo[argIndex],
719 [&]() {
720 return "arg #"s + std::to_string(argIndex) + " of '"s + funcName + "' func call"s;
721 });
722}
723
724template<typename... Args, std::size_t... Is>
726 const std::string &funcName, const Napi::CallbackInfo &cbInfo, std::tuple<Args...> args, std::index_sequence<Is...>)
727{
728 using namespace std::string_literals;
729
730 if (cbInfo.Length() < sizeof...(Args)) {
731 throw makeLoggedExceptionImpl(
732 cbInfo.Env(),
733 "getArgs: func '"s + funcName + "' received less args than expected minimum: "s
734 + std::to_string(cbInfo.Length()) + " vs "s + std::to_string(sizeof...(Args)));
735 }
736
737 auto unused = {(getArgImpl(funcName, cbInfo, std::get<Is>(args), Is), 0)..., 0};
738 (void) unused;
739}
740
741template<typename T>
743getOptionalPropOrEmptyImpl(const Napi::Object &optObj, const Napi::Name &propName, const std::string &objDesc)
744{
745 using namespace std::string_literals;
746
747 if (optObj.IsEmpty() || !optObj.Has(propName))
748 return T();
749
750 auto propValue = optObj.Get(propName);
751
752 return !propValue.IsUndefined()
753 ? QNapi::checkedCast<T>(
754 propValue,
755 [&]() {
756 auto baseDesc = "property '"s + propName.ToString().Utf8Value() + "' of object"s;
757 return !objDesc.empty()
758 ? baseDesc + ": "s + objDesc
759 : baseDesc;
760 })
761 : T();
762}
763
764}
765
766template<typename T>
771 })
772{
773}
774
775inline Napi::Value ValueWrapper::mapToValue(napi_env env) const
776{
777 return m_valueFactory(env);
778}
779
780template<typename... ExtraArgs>
781template<typename Func>
783 Func &&callbackFunc, std::enable_if_t<std::is_void<std::result_of_t<Func(const Napi::CallbackInfo &, ExtraArgs...)>>::value, char *>)
787 return Napi::Value();
788 })
789{
790}
791
792template<typename... ExtraArgs>
793template<typename Func>
799
800template<typename... ExtraArgs>
801template<typename Func>
806 return Napi::Value();
807 })
808{
809}
810
811template<typename... ExtraArgs>
812template<typename Func>
814 Func &&callbackFunc, std::enable_if_t<std::is_base_of<Napi::Value, std::result_of_t<Func(ExtraArgs...)>>::value, long *>)
817 return callbackFunc(extraArgs...);
818 })
819{
820}
821
822template<typename... ExtraArgs>
824{
825 return m_callbackFunc;
826}
827
828inline Object Object::New(napi_env env)
829{
830 return Napi::Object::New(env);
831}
832
833inline Array Array::New(napi_env env, std::size_t length)
834{
835 return length != 0
836 ? Napi::Array::New(env, length)
837 : Napi::Array::New(env);
838}
839
840inline Array::Array(const Napi::Array &other)
841 : Napi::Array(other)
842{
843}
844
845inline Array &Array::operator=(const Napi::Array &other)
846{
847 Napi::Array::operator=(other);
848 return *this;
849}
850
851inline void Array::fill(const ValueWrapper &value)
852{
853 details_qnapi_p_h::callMethod(*this, "fill", {value});
854}
855
856inline Object::Object(const Napi::Object &other)
857 : Napi::Object(other)
858{
859}
860
861inline Object &Object::operator=(const Napi::Object &other)
862{
863 Napi::Object::operator=(other);
864 return *this;
865}
866
867template<typename T>
868T Object::get(const std::string &expr) const
869{
870 return details_qnapi_p_h::runEscapingHandleScopeImpl<T>(
871 Env(),
872 [&]() {
873 return details_qnapi_p_h::evalWithContextImpl<T>(*this, expr).second;
874 });
875}
876
877template<typename T>
878T Object::get(const Napi::Name &name) const
879{
880 using namespace std::string_literals;
881
882 if (!Has(name)) {
883 throw makeLoggedException(
884 Env(), "object has no property '"s + name.ToString().Utf8Value() + "'"s);
885 }
886
887 return checkedCast<T>(
888 Get(name),
889 [&]() {
890 return "property '"s + name.ToString().Utf8Value() + "'"s;
891 });
892}
893
894template<typename T>
895T Object::eval(const std::string &expr, const std::vector<ValueWrapper> &exprArgs) const
896{
897 using namespace details_qnapi_p_h;
898
899 return runEscapingHandleScope<T>(
900 Env(),
901 [&]() {
902 return evalWithContextImpl<T>(*this, expr, unwrapValues(Env(), exprArgs)).second;
903 });
904}
905
906inline void Object::set(const std::string &name, const ValueWrapper &value)
907{
908 Napi::HandleScope setPropScope(Env());
909 Set(name, value.mapToValue(Env()));
910}
911
912inline void Object::set(const Napi::Name &name, const ValueWrapper &value)
913{
914 Napi::HandleScope setPropScope(Env());
915 Set(name, value.mapToValue(Env()));
916}
917
918inline void Object::set(const std::vector<std::pair<std::string, ValueWrapper>> &namedValues)
919{
920 Napi::HandleScope setPropsScope(Env());
921 for (const auto &namedValue : namedValues)
922 Set(namedValue.first, namedValue.second.mapToValue(Env()));
923}
924
925template<typename Result>
926Result Object::call(const std::string &methodName, const std::vector<ValueWrapper> &args) const
927{
928 return details_qnapi_p_h::callMethod<Result>(*this, methodName, args);
929}
930
932 : Napi::Promise(nullptr, nullptr)
933{
934}
935
936inline Promise::Promise(const Napi::Promise &other)
937 : Napi::Promise(other)
938{
939}
940
941inline Promise &Promise::operator=(const Napi::Promise &other)
942{
943 Napi::Promise::operator=(other);
944 return *this;
945}
946
947inline Promise Promise::onThen(CallbackFuncWrapper &&onFulfilledFunc)
948{
949 return details_qnapi_p_h::callMethod<Promise>(
950 *this, "then", {std::move(onFulfilledFunc.callbackFunc())});
951}
952
953inline Promise Promise::onThen(CallbackFuncWrapper &&onFulfilledFunc, CallbackFuncWrapper &&onRejectedFunc)
954{
955 return details_qnapi_p_h::callMethod<Promise>(
956 *this, "then", {std::move(onFulfilledFunc.callbackFunc()), std::move(onRejectedFunc.callbackFunc())});
957}
958
960{
961 return details_qnapi_p_h::callMethod<Promise>(
962 *this, "catch", {std::move(onRejectedFunc.callbackFunc())});
963}
964
966{
967 return details_qnapi_p_h::callMethod<Promise>(
968 *this, "finally", {std::move(onFinallyFunc.callbackFunc())});
969}
970
972 CallbackFuncWrapper &&onFulfilledFunc, CallbackFuncWrapper &&onRejectedFunc,
973 CallbackFuncWrapper &&onFinallyFunc)
974{
975 return onThen(std::move(onFulfilledFunc), std::move(onRejectedFunc)).onFinally(std::move(onFinallyFunc));
976}
977
978template<typename Context>
979PromiseWithContext<Context> Promise::withContext(Context &&context)
980{
981 return PromiseWithContext<Context>(*this, std::make_shared<Context>(std::forward<Context>(context)));
982}
983
984template<typename Context>
985PromiseWithContext<Context>::PromiseWithContext(const Promise &promise, std::shared_ptr<Context> context)
986 : Promise(promise)
987 , m_context(context)
988{
989}
990
991template<typename Context>
993 ExtendedCallbackFuncWrapper<Context &> &&onFulfilledFunc)
994{
995 return PromiseWithContext(
996 Promise::onThen(
997 [context = m_context, onFulfilledFunc = std::move(onFulfilledFunc.callbackFunc())](const Napi::CallbackInfo &cbInfo) {
998 return onFulfilledFunc(cbInfo, *context);
999 }),
1000 m_context);
1001}
1002
1003template<typename Context>
1005 ExtendedCallbackFuncWrapper<Context &> &&onFulfilledFunc, CallbackFuncWrapper &&onRejectedFunc)
1006{
1007 return PromiseWithContext(
1008 Promise::onThen(
1009 [context = m_context, onFulfilledFunc = std::move(onFulfilledFunc.callbackFunc())](const Napi::CallbackInfo &cbInfo) {
1010 return onFulfilledFunc(cbInfo, *context);
1011 },
1012 [context = m_context, onRejectedFunc = std::move(onRejectedFunc.callbackFunc())](const Napi::CallbackInfo &cbInfo) {
1013 return onRejectedFunc(cbInfo, *context);
1014 }),
1015 m_context);
1016}
1017
1018template<typename Context>
1020 ExtendedCallbackFuncWrapper<Context &> &&onRejectedFunc)
1021{
1022 return PromiseWithContext(
1024 [context = m_context, onRejectedFunc = std::move(onRejectedFunc.callbackFunc())](const Napi::CallbackInfo &cbInfo) {
1025 return onRejectedFunc(cbInfo, *context);
1026 }),
1027 m_context);
1028}
1029
1030template<typename Context>
1032 ExtendedCallbackFuncWrapper<Context &> &&onFinallyFunc)
1033{
1034 return PromiseWithContext(
1036 [context = m_context, onFinallyFunc = std::move(onFinallyFunc.callbackFunc())](const Napi::CallbackInfo &cbInfo) {
1037 return onFinallyFunc(cbInfo, *context);
1038 }),
1039 m_context);
1040}
1041
1042template<typename T>
1044 : Napi::Reference<T>(std::move(other))
1045{
1046}
1047
1048template<typename T>
1050{
1051 Napi::Reference<T>::operator=(std::move(other));
1052 return *this;
1053}
1054
1055template<typename T>
1056Reference<T>::Reference(Napi::Reference<T> &&other)
1057 : Napi::Reference<T>(std::move(other))
1058{
1059}
1060
1061template<typename T>
1062Reference<T> &Reference<T>::operator=(Napi::Reference<T> &&other)
1063{
1064 Napi::Reference<T>::operator=(std::move(other));
1065 return *this;
1066}
1067
1068template<typename T>
1070{
1071 return Napi::Persistent(value);
1072}
1073
1074template<typename T>
1076{
1077 return Napi::Reference<T>();
1078}
1079
1082{
1083}
1084
1086{
1087 Napi::Reference<Object>::operator=(std::move(other));
1088 return *this;
1089}
1090
1091inline Reference<Object>::Reference(Napi::Reference<Object> &&other)
1093{
1094}
1095
1096inline Reference<Object> &Reference<Object>::operator=(Napi::Reference<Object> &&other)
1097{
1098 Napi::Reference<Object>::operator=(std::move(other));
1099 return *this;
1100}
1101
1102template<typename T>
1103T Reference<Object>::eval(const std::string &expr, const std::vector<ValueWrapper> &exprArgs) const
1104{
1105 return runEscapingHandleScope<T>(
1106 Env(),
1107 [&]() {
1108 return Value().eval<T>(expr, exprArgs);
1109 });
1110}
1111
1112inline void Reference<Object>::set(const std::string &name, const ValueWrapper &value)
1113{
1114 Napi::HandleScope scope(Env());
1115 Value().set(name, value);
1116}
1117
1118inline void Reference<Object>::set(const std::vector<std::pair<std::string, ValueWrapper>> &namedValues)
1119{
1120 Napi::HandleScope scope(Env());
1121 Value().set(namedValues);
1122}
1123
1124template<typename Result>
1125Result Reference<Object>::call(const std::string &methodName, const std::vector<ValueWrapper> &args) const
1126{
1127 return runEscapingHandleScope<Result>(
1128 Env(),
1129 [&]() {
1130 return Value().call<Result>(methodName, args);
1131 });
1132}
1133
1135{
1136 return Napi::Persistent(value);
1137}
1138
1140{
1141 return Napi::Reference<Object>();
1142}
1143
1144template<typename T>
1147{
1148 return Napi::Persistent(value);
1149}
1150
1151template<typename T>
1153{
1154 return Napi::Reference<T>();
1155}
1156
1157inline CallbackInfo::CallbackInfo(const Napi::CallbackInfo &cbInfo)
1158 : m_cbInfo(cbInfo)
1159{
1160}
1161
1162inline Napi::Env CallbackInfo::Env() const
1163{
1164 return m_cbInfo.Env();
1165}
1166
1167inline std::size_t CallbackInfo::Length() const
1168{
1169 return m_cbInfo.Length();
1170}
1171
1172template<typename... Args>
1173void CallbackInfo::getLeadingArgs(const std::string &funcName, Args &...args) const
1174{
1175 details_qnapi_p_h::getLeadingArgsImpl(
1176 funcName, m_cbInfo, std::tie(args...), std::make_index_sequence<sizeof...(Args)>());
1177}
1178
1179template<typename Arg>
1180Arg CallbackInfo::getFirstArg(const std::string &funcName) const
1181{
1182 Arg arg;
1183 getLeadingArgs(funcName, arg);
1184 return arg;
1185}
1186
1187inline CallbackInfo::operator const Napi::CallbackInfo &() const
1188{
1189 return m_cbInfo;
1190}
1191
1192inline std::vector<napi_value> unwrapValues(napi_env env, const std::vector<ValueWrapper> &wrappedValues)
1193{
1194 std::vector<napi_value> unwrappedValues;
1195 std::transform(
1196 wrappedValues.begin(), wrappedValues.end(),
1197 std::back_inserter(unwrappedValues),
1198 [&](const ValueWrapper &arg) {
1199 return arg.mapToValue(env);
1200 });
1201 return unwrappedValues;
1202}
1203
1204inline Napi::Error makeLoggedException(napi_env env, const std::string &msg)
1205{
1206 return details_qnapi_p_h::makeLoggedExceptionImpl(env, msg);
1207}
1208
1209template<typename T>
1210bool valueTypeMatches(const Napi::Value &value)
1211{
1212 return details_qnapi_p_h::valueTypeMatchesImpl<T>(value);
1213}
1214
1215template<typename Element>
1216bool arrayElementTypesMatch(const Napi::Value &value)
1217{
1218 if (!valueTypeMatches<Napi::Array>(value))
1219 return false;
1220
1221 auto arrayValue = checkedCast<Napi::Array>(value);
1222 auto arrayLength = arrayValue.Length();
1223
1224 bool allElementsMatch = true;
1225 for (std::size_t i = 0; i < arrayLength; ++i) {
1226 if (!valueTypeMatches<Element>(arrayValue.Get(i))) {
1227 allElementsMatch = false;
1228 break;
1229 }
1230 }
1231
1232 return allElementsMatch;
1233}
1234
1235inline std::string getValueTypeString(const Napi::Value &value)
1236{
1237 return details_qnapi_p_h::getValueTypeStringImpl(value);
1238}
1239
1240template<typename T, typename ValueDescriptionSupplier>
1241T checkedCast(const Napi::Value &value, ValueDescriptionSupplier &&valueDescSupplier)
1242{
1243 return details_qnapi_p_h::checkedCastImpl<T>(
1244 value, std::forward<ValueDescriptionSupplier>(valueDescSupplier));
1245}
1246
1247template<typename T>
1248T checkedCast(const Napi::Value &value)
1249{
1250 return details_qnapi_p_h::checkedCastImpl<T>(
1251 value,
1252 []() {
1253 return std::string();
1254 });
1255}
1256
1257template<typename OutputContainer, typename Element, typename TransFunc>
1258OutputContainer getArrayElements(const Napi::Array &inputArray, TransFunc &&transFunc)
1259{
1260 using namespace std::string_literals;
1261
1262 OutputContainer result;
1263 auto arrayLength = inputArray.Length();
1264 for (std::size_t i = 0; i < arrayLength; ++i) {
1265 auto arg = inputArray.Get(i);
1266 if (!valueTypeMatches<Element>(arg)) {
1267 constexpr const char *expectedTypeName = details_qnapi_p_h::ValueTypeTraits<Element>::typeName;
1268 auto argTypeStr = getValueTypeString(arg);
1269 throw makeLoggedException(
1270 inputArray.Env(),
1271 "wrong type of Napi array element #"s + std::to_string(i)
1272 + ", expected '"s + expectedTypeName + "', got '"s + argTypeStr + "'"s);
1273 }
1274 result.insert(result.end(), transFunc(checkedCast<Element>(arg)));
1275 }
1276
1277 return result;
1278}
1279
1280template<typename OutputContainer, typename Element>
1281OutputContainer getArrayElements(const Napi::Array &inputArray)
1282{
1283 return getArrayElements<OutputContainer, Element>(
1284 inputArray,
1285 [](Element &&elem) {
1286 return std::forward<Element>(elem);
1287 });
1288}
1289
1290inline Object makeNewInstance(const Napi::Function &type, const std::vector<ValueWrapper> &args)
1291{
1292 return type.New(unwrapValues(type.Env(), args));
1293}
1294
1295inline Object makeNewInstance(const Napi::Object &baseObj, const std::string &typePath, const std::vector<ValueWrapper> &args)
1296{
1297 return makeNewInstance(Object(baseObj).get<Napi::Function>(typePath), args);
1298}
1299
1300inline Napi::Value getPropOrUndefined(const Napi::Value &obj, const std::string &propName)
1301{
1302 if (!obj.IsObject())
1303 return obj.Env().Undefined();
1304
1305 auto typedObj = checkedCast<Napi::Object>(obj);
1306
1307 return typedObj.Has(propName)
1308 ? typedObj.Get(propName)
1309 : typedObj.Env().Undefined();
1310}
1311
1312template<typename T>
1313Napi::Value getPropOrUndefined(const Napi::Reference<T> &objRef, const std::string &propName)
1314{
1315 return details_qnapi_p_h::runEscapingHandleScopeImpl<Napi::Value>(
1316 objRef.Env(),
1317 [&]() {
1318 return getPropOrUndefined(objRef.Value(), propName);
1319 });
1320}
1321
1322template<typename T>
1324getOptionalPropOrEmpty(const Napi::Object &optObj, const std::string &propName, const std::string &objDesc)
1325{
1326 return !optObj.IsEmpty()
1327 ? details_qnapi_p_h::getOptionalPropOrEmptyImpl<T>(
1328 optObj, Napi::String::New(optObj.Env(), propName), objDesc)
1329 : T();
1330}
1331
1332template<typename T>
1334getOptionalPropOrEmpty(const Napi::Object &optObj, const Napi::Name &propName, const std::string &objDesc)
1335{
1336 return details_qnapi_p_h::getOptionalPropOrEmptyImpl<T>(optObj, propName, objDesc);
1337}
1338
1339inline Object makeObject(napi_env env, const std::vector<std::pair<std::string, ValueWrapper>> &namedValues)
1340{
1341 auto obj = QNapi::Object::New(env);
1342 obj.set(namedValues);
1343 return obj;
1344}
1345
1346inline Array makeArray(napi_env env, const std::vector<ValueWrapper> &values)
1347{
1348 return details_qnapi_p_h::runEscapingHandleScopeImpl<Napi::Array>(
1349 env,
1350 [&]() {
1351 auto array = Napi::Array::New(env, values.size());
1352 for (std::size_t i = 0; i < values.size(); ++i)
1353 array.Set(i, values[i].mapToValue(env));
1354 return array;
1355 });
1356}
1357
1358template<typename Result, typename F>
1359Result runEscapingHandleScope(napi_env env, F &&func)
1360{
1361 return details_qnapi_p_h::runEscapingHandleScopeImpl<Result>(env, std::forward<F>(func));
1362}
1363
1364inline std::string toJsonString(const Napi::Value &value)
1365{
1366 std::string jsonString;
1367 try {
1368 Napi::HandleScope stringifyScope(value.Env());
1369 jsonString = details_qnapi_p_h::callMethod<String>(value.Env().Global(), "JSON.stringify", {value});
1370 } catch (...) {
1371 jsonString = "<stringify-error>";
1372 }
1373 return jsonString;
1374}
1375
1376}
1377
1378QT_END_NAMESPACE
1379
1380#endif // QNAPI_P_H
void fill(const ValueWrapper &value)
Definition qnapi_p.h:851
Array & operator=(const Napi::Array &other)
Definition qnapi_p.h:845
static Array New(napi_env env, std::size_t length=0)
Definition qnapi_p.h:833
Array(const Napi::Array &other)
Definition qnapi_p.h:840
Arg getFirstArg(const std::string &funcName) const
Definition qnapi_p.h:1180
CallbackInfo(const Napi::CallbackInfo &cbInfo)
Definition qnapi_p.h:1157
void getLeadingArgs(const std::string &funcName, Args &...args) const
Definition qnapi_p.h:1173
CallbackInfo(const CallbackInfo &other)=delete
CallbackInfo & operator=(const CallbackInfo &other)=delete
std::size_t Length() const
Definition qnapi_p.h:1167
Napi::Env Env() const
Definition qnapi_p.h:1162
ExtendedCallbackFuncWrapper(Func &&callbackFunc, std::enable_if_t< std::is_base_of< Napi::Value, std::result_of_t< Func(const Napi::CallbackInfo &, ExtraArgs...)> >::value, short * >=nullptr)
Definition qnapi_p.h:794
ExtendedCallbackFuncWrapper(Func &&callbackFunc, std::enable_if_t< std::is_void< std::result_of_t< Func(const Napi::CallbackInfo &, ExtraArgs...)> >::value, char * >=nullptr)
Definition qnapi_p.h:782
std::function< Napi::Value(const Napi::CallbackInfo &, ExtraArgs...)> & callbackFunc()
Definition qnapi_p.h:823
ExtendedCallbackFuncWrapper(Func &&callbackFunc, std::enable_if_t< std::is_base_of< Napi::Value, std::result_of_t< Func(ExtraArgs...)> >::value, long * >=nullptr)
Definition qnapi_p.h:813
Result call(const std::string &methodName, const std::vector< ValueWrapper > &args={}) const
Definition qnapi_p.h:926
Object(const Napi::Object &other)
Definition object.cpp:12
T eval(const std::string &expr, const std::vector< ValueWrapper > &exprArgs={}) const
Definition qnapi_p.h:895
void set(const std::vector< std::pair< std::string, ValueWrapper > > &namedValues)
Definition qnapi_p.h:918
void set(const std::string &name, const ValueWrapper &value)
Definition qnapi_p.h:906
T get(const std::string &expr) const
Definition qnapi_p.h:868
static Object New(napi_env env)
Definition qnapi_p.h:828
Object & operator=(const Napi::Object &other)
Definition qnapi_p.h:861
PromiseWithContext onFinallyWithContext(ExtendedCallbackFuncWrapper< Context & > &&onFinallyFunc)
Definition qnapi_p.h:1031
PromiseWithContext onCatchWithContext(ExtendedCallbackFuncWrapper< Context & > &&onRejectedFunc)
Definition qnapi_p.h:1019
PromiseWithContext(const Promise &promise, std::shared_ptr< Context > context)
Definition qnapi_p.h:985
PromiseWithContext onThenWithContext(ExtendedCallbackFuncWrapper< Context & > &&onFulfilledFunc, CallbackFuncWrapper &&onRejectedFunc)
Definition qnapi_p.h:1004
PromiseWithContext onThenWithContext(ExtendedCallbackFuncWrapper< Context & > &&onFulfilledFunc)
Definition qnapi_p.h:992
Promise onThen(CallbackFuncWrapper &&onFulfilledFunc)
Definition qnapi_p.h:947
Promise onFinally(CallbackFuncWrapper &&onFinallyFunc)
Definition qnapi_p.h:965
Promise(const Napi::Promise &other)
Definition qnapi_p.h:936
Promise & operator=(const Napi::Promise &other)
Definition qnapi_p.h:941
Promise onThen(CallbackFuncWrapper &&onFulfilledFunc, CallbackFuncWrapper &&onRejectedFunc)
Definition qnapi_p.h:953
Promise onCatch(CallbackFuncWrapper &&onRejectedFunc)
Definition qnapi_p.h:959
PromiseWithContext< Context > withContext(Context &&context)
Definition qnapi_p.h:979
Promise onThenAndFinally(CallbackFuncWrapper &&onFulfilledFunc, CallbackFuncWrapper &&onRejectedFunc, CallbackFuncWrapper &&onFinallyFunc)
Definition qnapi_p.h:971
static Reference< Object > makePersistentFrom(const Object &value)
Definition qnapi_p.h:1134
static Reference< Object > makeEmpty()
Definition qnapi_p.h:1139
void set(const std::string &name, const ValueWrapper &value)
Definition qnapi_p.h:1112
Result call(const std::string &methodName, const std::vector< ValueWrapper > &args={}) const
Definition qnapi_p.h:1125
Reference< Object > & operator=(Reference< Object > &&other)
Definition qnapi_p.h:1085
void set(const std::vector< std::pair< std::string, ValueWrapper > > &namedValues)
Definition qnapi_p.h:1118
T eval(const std::string &expr, const std::vector< ValueWrapper > &exprArgs={}) const
Definition qnapi_p.h:1103
Reference< Object > & operator=(Napi::Reference< Object > &&other)
Definition qnapi_p.h:1096
Reference< Object > & operator=(const Reference< Object > &other)=delete
Reference(Napi::Reference< Object > &&other)
Definition qnapi_p.h:1091
Reference(const Reference< Object > &other)=delete
Reference(Reference< Object > &&other)
Definition qnapi_p.h:1080
static Reference< T > makeEmpty()
Definition qnapi_p.h:1152
static Reference< T > makePersistentFrom(const T &value)
Definition qnapi_p.h:1069
Reference< T > & operator=(Reference< T > &&other)
Definition qnapi_p.h:1049
Reference(Reference< T > &&other)
Definition qnapi_p.h:1043
static Reference< T > makeEmpty()
Definition qnapi_p.h:1075
Reference(Napi::Reference< T > &&other)
Definition qnapi_p.h:1056
Reference(const Reference< T > &other)=delete
Reference< T > & operator=(const Reference< T > &other)=delete
Reference< T > & operator=(Napi::Reference< T > &&other)
Definition qnapi_p.h:1062
Napi::Value mapToValue(napi_env env) const
Definition qnapi_p.h:775
ValueWrapper(T &&inputValue)
Definition qnapi_p.h:767
Result callMethod(const Napi::Object &obj, const std::string &methodName, const std::vector< ValueWrapper > &args)
Definition qnapi_p.h:703
std::enable_if_t< std::is_same< T, Napi::Value >::value, bool > valueTypeMatchesImpl(const Napi::Value &)
Definition qnapi_p.h:480
constexpr bool isCallbackFuncType()
Definition qnapi_p.h:456
std::enable_if_t< std::is_base_of< Napi::Value, T >::value, T > getOptionalPropOrEmptyImpl(const Napi::Object &optObj, const Napi::Name &propName, const std::string &objDesc)
Definition qnapi_p.h:743
std::enable_if_t< isCallbackFuncType< T >(), Napi::Value > makeValue(napi_env env, T &&inputValue)
Definition qnapi_p.h:462
void getLeadingArgsImpl(const std::string &funcName, const Napi::CallbackInfo &cbInfo, std::tuple< Args... > args, std::index_sequence< Is... >)
Definition qnapi_p.h:725
std::string getArrayElementValueTypeString(const Napi::Array &arrayValue)
Definition qnapi_p.h:535
std::string getValueTypeStringImpl(const Napi::Value &value)
Definition qnapi_p.h:493
Result runEscapingHandleScopeImpl(napi_env env, F &&func)
Definition qnapi_p.h:587
std::pair< Napi::Object, T > evalWithContextImpl(Napi::Object obj, const std::string &expr, const std::vector< napi_value > &exprArgs={})
Definition qnapi_p.h:614
void getArgImpl(const std::string &funcName, const Napi::CallbackInfo &cbInfo, Arg &arg, std::size_t argIndex)
Definition qnapi_p.h:713
Napi::Error makeLoggedExceptionImpl(napi_env env, const std::string &msg)
Definition qnapi_p.h:473
Napi::Value callMethodWithValueResultImpl(const Napi::Object &obj, const std::string &methodName, const std::vector< napi_value > &args)
Definition qnapi_p.h:677
Result callMethodImpl(const Napi::Object &obj, const std::string &methodName, const std::vector< napi_value > &args)
Definition qnapi_p.h:691
std::vector< napi_value > expandEvalCallArgs(napi_env env, const std::string &callArgsSubExpr, const std::vector< napi_value > &exprArgs)
Definition qnapi_p.h:598
std::enable_if_t< std::is_same< T, Napi::Value >::value, T > checkedCastImpl(const Napi::Value &value, ValueDescriptionSupplier &&)
Definition qnapi_p.h:561
Napi::Error makeLoggedException(napi_env env, const std::string &msg)
Definition qnapi_p.h:1204
std::string getValueTypeString(const Napi::Value &value)
Definition qnapi_p.h:1235
Napi::Value getPropOrUndefined(const Napi::Reference< T > &objRef, const std::string &propName)
Definition qnapi_p.h:1313
Array makeArray(napi_env env, const std::vector< ValueWrapper > &values={})
Definition qnapi_p.h:1346
Object makeObject(napi_env env, const std::vector< std::pair< std::string, ValueWrapper > > &namedValues={})
Definition qnapi_p.h:1339
std::enable_if_t< std::is_base_of< Napi::Value, T >::value, T > getOptionalPropOrEmpty(const Napi::Object &optObj, const std::string &propName, const std::string &objDesc={})
Definition qnapi_p.h:1324
T checkedCast(const Napi::Value &value)
Definition qnapi_p.h:1248
OutputContainer getArrayElements(const Napi::Array &inputArray, TransFunc &&transFunc)
Definition qnapi_p.h:1258
std::vector< napi_value > unwrapValues(napi_env env, const std::vector< ValueWrapper > &wrappedValues)
Definition qnapi_p.h:1192
bool valueTypeMatches(const Napi::Value &value)
Definition qnapi_p.h:1210
bool arrayElementTypesMatch(const Napi::Value &value)
Definition qnapi_p.h:1216
OutputContainer getArrayElements(const Napi::Array &inputArray)
Definition qnapi_p.h:1281
Object makeNewInstance(const Napi::Object &baseObj, const std::string &typePath, const std::vector< ValueWrapper > &args={})
Definition qnapi_p.h:1295
T checkedCast(const Napi::Value &value, ValueDescriptionSupplier &&valueDescSupplier)
Definition qnapi_p.h:1241
Result runEscapingHandleScope(napi_env env, F &&func)
Definition qnapi_p.h:1359
ExtendedCallbackFuncWrapper<> CallbackFuncWrapper
Definition qnapi_p.h:58
std::string toJsonString(const Napi::Value &value)
Definition qnapi_p.h:1364
Napi::Value getPropOrUndefined(const Napi::Value &obj, const std::string &propName)
Definition qnapi_p.h:1300
Object makeNewInstance(const Napi::Function &type, const std::vector< ValueWrapper > &args={})
Definition qnapi_p.h:1290