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