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