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