From eeabccb8c65761e06447bf7be460d61f47992161 Mon Sep 17 00:00:00 2001 From: Keaton Sentak <54916859+ksentak@users.noreply.github.com> Date: Mon, 29 Jul 2024 14:01:35 -0400 Subject: [PATCH] feat: CPP App-Passthrough (#196) * fix: Added app-passthrough functionality for cpp sdk * cPP: Updates based on provider schema changes * CPP: Updates based on provider schema changes * fix: Make small adjustment to interface template and engine logic * fix: Revert changes that were being tested * feat: Pass config flag to types.mjs to modify schema title * fix: Update cpp templates for discoverySDK WIP * fix: Added support for players and fixed few provider issues * fix: Commented file permission code for debug * fix: Update templates to be more verbose * fix: Added version opt in include.sh * fix: Added set -e in build.sh * fix: Make focuable interface separate * fix: Comment out side-effect ridden code * fix: Added IModule.h in firebolt.cpp --------- Co-authored-by: HaseenaSainul Co-authored-by: Shah, Kevin Co-authored-by: kschrief --- languages/cpp/language.config.json | 1 + .../cpp/src/shared/src/Logger/Logger.cpp | 2 + languages/cpp/src/shared/src/Logger/Logger.h | 4 +- .../callback-initialization/tuple.cpp | 1 + .../sub-property/array.cpp | 3 +- .../codeblocks/interface-focusable.cpp | 47 +++++++++++++++++++ .../codeblocks/interface-focusable.h | 12 +++++ .../cpp/templates/codeblocks/interface.cpp | 26 ---------- .../cpp/templates/codeblocks/interface.h | 9 +--- .../cpp/templates/interfaces/default.cpp | 17 +++++-- languages/cpp/templates/interfaces/default.h | 2 +- languages/cpp/templates/methods/default.cpp | 10 ++-- .../parameter-serialization/enum.cpp | 8 ++-- .../sub-property/array.cpp | 16 +++---- .../sub-property/object-array.cpp | 4 +- languages/cpp/templates/sdk/scripts/build.sh | 1 + .../cpp/templates/sdk/scripts/install.sh | 9 ++-- languages/cpp/templates/sdk/src/firebolt.cpp | 1 + src/macrofier/engine.mjs | 39 +++++++++++---- src/macrofier/types.mjs | 13 +++-- src/sdk/index.mjs | 5 +- src/shared/configLoader.mjs | 18 +++++++ src/shared/modules.mjs | 2 +- 23 files changed, 173 insertions(+), 77 deletions(-) create mode 100644 languages/cpp/templates/callback-initialization/tuple.cpp create mode 100644 languages/cpp/templates/codeblocks/interface-focusable.cpp create mode 100644 languages/cpp/templates/codeblocks/interface-focusable.h create mode 100644 src/shared/configLoader.mjs diff --git a/languages/cpp/language.config.json b/languages/cpp/language.config.json index 724a1359..a1ed5f8b 100644 --- a/languages/cpp/language.config.json +++ b/languages/cpp/language.config.json @@ -7,6 +7,7 @@ "createPolymorphicMethods": true, "excludeDeclarations": true, "extractProviderSchema": true, + "enableUnionTypes": false, "aggregateFiles": [ "/include/firebolt.h", "/src/firebolt.cpp" diff --git a/languages/cpp/src/shared/src/Logger/Logger.cpp b/languages/cpp/src/shared/src/Logger/Logger.cpp index c66c6b68..35ffdc29 100644 --- a/languages/cpp/src/shared/src/Logger/Logger.cpp +++ b/languages/cpp/src/shared/src/Logger/Logger.cpp @@ -37,6 +37,8 @@ ENUM_CONVERSION_BEGIN(FireboltSDK::Logger::Category) { FireboltSDK::Logger::Category::Core, _TXT("FireboltSDK::Core") }, { FireboltSDK::Logger::Category::Manage, _TXT("FireboltSDK::Manage") }, { FireboltSDK::Logger::Category::Discovery, _TXT("FireboltSDK::Discovery") }, + { FireboltSDK::Logger::Category::PlayerProvider, _TXT("FireboltSDK::PlayerProvider") }, + { FireboltSDK::Logger::Category::PlayerProvider, _TXT("FireboltSDK::PlayerManager") }, ENUM_CONVERSION_END(FireboltSDK::Logger::Category) diff --git a/languages/cpp/src/shared/src/Logger/Logger.h b/languages/cpp/src/shared/src/Logger/Logger.h index c88b87e8..e8b6946a 100644 --- a/languages/cpp/src/shared/src/Logger/Logger.h +++ b/languages/cpp/src/shared/src/Logger/Logger.h @@ -39,7 +39,9 @@ namespace FireboltSDK { OpenRPC, Core, Manage, - Discovery + Discovery, + PlayerProvider, + PlayerManager, }; public: diff --git a/languages/cpp/templates/callback-initialization/tuple.cpp b/languages/cpp/templates/callback-initialization/tuple.cpp new file mode 100644 index 00000000..5cc23aca --- /dev/null +++ b/languages/cpp/templates/callback-initialization/tuple.cpp @@ -0,0 +1 @@ +${if.namespace.notsame}${parent.Title}::${end.if.namespace.notsame}${title} ${property}; \ No newline at end of file diff --git a/languages/cpp/templates/callback-result-instantiation/sub-property/array.cpp b/languages/cpp/templates/callback-result-instantiation/sub-property/array.cpp index c9775b99..f3049436 100644 --- a/languages/cpp/templates/callback-result-instantiation/sub-property/array.cpp +++ b/languages/cpp/templates/callback-result-instantiation/sub-property/array.cpp @@ -6,5 +6,4 @@ } }${end.if.optional}${if.non.optional}auto index((*proxyResponse)${Property.dependency}.${Property}.Elements()); while (index.Next() == true) { -${if.object}${items.with.indent}${end.if.object}${if.non.object} ${base.title}${property.dependency}${if.impl.optional}.value()${end.if.impl.optional}.${property}.value().push_back(index.Current().Value());${end.if.non.object} - }${end.if.non.optional} +${if.object}${items.with.indent}${end.if.object}${if.non.object} ${base.title}${property.dependency}${if.impl.optional}.value()${end.if.impl.optional}.${property}.push_back(index.Current().Value());${end.if.non.object} }${end.if.non.optional} diff --git a/languages/cpp/templates/codeblocks/interface-focusable.cpp b/languages/cpp/templates/codeblocks/interface-focusable.cpp new file mode 100644 index 00000000..b62df483 --- /dev/null +++ b/languages/cpp/templates/codeblocks/interface-focusable.cpp @@ -0,0 +1,47 @@ + static void ProviderInvokeSession(std::string& methodName, JsonObject& jsonParameters, Firebolt::Error *err = nullptr) + { + Firebolt::Error status = Firebolt::Error::NotConnected; + FireboltSDK::Transport* transport = FireboltSDK::Accessor::Instance().GetTransport(); + if (transport != nullptr) { + + JsonObject jsonResult; + status = transport->Invoke(methodName, jsonParameters, jsonResult); + if (status == Firebolt::Error::None) { + FIREBOLT_LOG_INFO(FireboltSDK::Logger::Category::OpenRPC, FireboltSDK::Logger::Module(), "%s is successfully invoked", methodName.c_str()); + } + + } else { + FIREBOLT_LOG_ERROR(FireboltSDK::Logger::Category::OpenRPC, FireboltSDK::Logger::Module(), "Error in getting Transport err = %d", status); + } + if (err != nullptr) { + *err = status; + } + } + static void ProviderFocusSession(std::string methodName, std::string& correlationId, Firebolt::Error *err = nullptr) + { + JsonObject jsonParameters; + WPEFramework::Core::JSON::Variant CorrelationId(correlationId); + jsonParameters.Set(_T("correlationId"), CorrelationId); + + ProviderInvokeSession(methodName, jsonParameters, err); + } + static void ProviderResultSession(std::string methodName, std::string& correlationId, ${provider.xresponse.name} result, Firebolt::Error *err = nullptr) + { + JsonObject jsonParameters; + WPEFramework::Core::JSON::Variant CorrelationId(correlationId); + jsonParameters.Set(_T("correlationId"), CorrelationId); + +${provider.xresponse.serialization} + ProviderInvokeSession(methodName, jsonParameters, err); + } + static void ProviderErrorSession(std::string methodName, std::string& correlationId, ${provider.xerror.name} result, Firebolt::Error *err = nullptr) + { + JsonObject jsonParameters; + WPEFramework::Core::JSON::Variant CorrelationId(correlationId); + jsonParameters.Set(_T("correlationId"), CorrelationId); + +${provider.xerror.serialization} + ProviderInvokeSession(methodName, jsonParameters, err); + } + +${methods} diff --git a/languages/cpp/templates/codeblocks/interface-focusable.h b/languages/cpp/templates/codeblocks/interface-focusable.h new file mode 100644 index 00000000..5a6032f0 --- /dev/null +++ b/languages/cpp/templates/codeblocks/interface-focusable.h @@ -0,0 +1,12 @@ +struct I${info.Title}Session : virtual public IFocussableProviderSession { + virtual ~I${info.Title}Session() override = default; + + virtual void error( ${provider.xerror.name} error, Firebolt::Error *err = nullptr ) = 0; + virtual void result( ${provider.xresponse.name} result, Firebolt::Error *err = nullptr ) = 0; +}; + +struct I${info.Title}Provider { + virtual ~I${info.Title}Provider() = default; + +${methods} +}; diff --git a/languages/cpp/templates/codeblocks/interface.cpp b/languages/cpp/templates/codeblocks/interface.cpp index b62df483..abab1e57 100644 --- a/languages/cpp/templates/codeblocks/interface.cpp +++ b/languages/cpp/templates/codeblocks/interface.cpp @@ -17,31 +17,5 @@ *err = status; } } - static void ProviderFocusSession(std::string methodName, std::string& correlationId, Firebolt::Error *err = nullptr) - { - JsonObject jsonParameters; - WPEFramework::Core::JSON::Variant CorrelationId(correlationId); - jsonParameters.Set(_T("correlationId"), CorrelationId); - - ProviderInvokeSession(methodName, jsonParameters, err); - } - static void ProviderResultSession(std::string methodName, std::string& correlationId, ${provider.xresponse.name} result, Firebolt::Error *err = nullptr) - { - JsonObject jsonParameters; - WPEFramework::Core::JSON::Variant CorrelationId(correlationId); - jsonParameters.Set(_T("correlationId"), CorrelationId); - -${provider.xresponse.serialization} - ProviderInvokeSession(methodName, jsonParameters, err); - } - static void ProviderErrorSession(std::string methodName, std::string& correlationId, ${provider.xerror.name} result, Firebolt::Error *err = nullptr) - { - JsonObject jsonParameters; - WPEFramework::Core::JSON::Variant CorrelationId(correlationId); - jsonParameters.Set(_T("correlationId"), CorrelationId); - -${provider.xerror.serialization} - ProviderInvokeSession(methodName, jsonParameters, err); - } ${methods} diff --git a/languages/cpp/templates/codeblocks/interface.h b/languages/cpp/templates/codeblocks/interface.h index eb299a9c..5d4f4056 100644 --- a/languages/cpp/templates/codeblocks/interface.h +++ b/languages/cpp/templates/codeblocks/interface.h @@ -1,12 +1,5 @@ -struct I${info.Title}Session : virtual public IFocussableProviderSession { - virtual ~I${info.Title}Session() override = default; - - virtual void error( ${provider.xerror.name} error, Firebolt::Error *err = nullptr ) = 0; - virtual void result( ${provider.xresponse.name} result, Firebolt::Error *err = nullptr ) = 0; -}; - struct I${info.Title}Provider { virtual ~I${info.Title}Provider() = default; ${methods} -}; \ No newline at end of file +}; diff --git a/languages/cpp/templates/interfaces/default.cpp b/languages/cpp/templates/interfaces/default.cpp index 4cba2764..055c8feb 100644 --- a/languages/cpp/templates/interfaces/default.cpp +++ b/languages/cpp/templates/interfaces/default.cpp @@ -10,8 +10,17 @@ }; static void ${info.Title}${method.Name}SessionInnerCallback( void* provider, const void* userData, void* jsonResponse ) { - //TODO: code to convert jsonResponse to ${method.name} session - I${info.Title}Provider& ${info.title.lowercase}Provider = *(reinterpret_cast(provider)); - ${info.title.lowercase}Provider.${method.name}( parameters, session ); - } +${event.callback.serialization} + ASSERT(proxyResponse.IsValid() == true); + + if (proxyResponse.IsValid() == true) { +${event.callback.initialization} +${event.callback.instantiation} + proxyResponse.Release(); + + std::unique_ptr ${info.title.lowercase}${method.Name}Session = std::make_unique<${info.Title}${method.Name}Session>(); + I${info.Title}Provider& ${info.title.lowercase}Provider = *(reinterpret_cast(provider)); + ${info.title.lowercase}Provider.${method.name}(${method.result.name}.parameters, std::move(${info.title.lowercase}${method.Name}Session)); + } + } diff --git a/languages/cpp/templates/interfaces/default.h b/languages/cpp/templates/interfaces/default.h index 05ebc463..072c0c63 100644 --- a/languages/cpp/templates/interfaces/default.h +++ b/languages/cpp/templates/interfaces/default.h @@ -1 +1 @@ - virtual void ${method.name}( ${method.signature.params}, IProviderSession& session ) = 0; \ No newline at end of file + virtual void ${method.name}( ${method.signature.params}, std::unique_ptr session ) = 0; \ No newline at end of file diff --git a/languages/cpp/templates/methods/default.cpp b/languages/cpp/templates/methods/default.cpp index 0b5b31bf..533c914e 100644 --- a/languages/cpp/templates/methods/default.cpp +++ b/languages/cpp/templates/methods/default.cpp @@ -1,7 +1,7 @@ /* ${method.name} - ${method.description} */ ${method.signature.result} ${info.Title}Impl::${method.name}( ${method.signature.params}${if.params}, ${end.if.params}Firebolt::Error *err ) ${if.result.nonvoid}${if.params.empty} const${end.if.params.empty}${end.if.result.nonvoid} { - Firebolt::Error status = Firebolt::Error::NotConnected; + Firebolt::Error statusError = Firebolt::Error::NotConnected; ${if.result.nonvoid}${method.result.initialization}${end.if.result.nonvoid} FireboltSDK::Transport* transport = FireboltSDK::Accessor::Instance().GetTransport(); if (transport != nullptr) { @@ -9,17 +9,17 @@ JsonObject jsonParameters; ${method.params.serialization.with.indent} ${method.result.json.type} jsonResult; - status = transport->Invoke("${info.title.lowercase}.${method.name}", jsonParameters, jsonResult); - if (status == Firebolt::Error::None) { + statusError = transport->Invoke("${info.title.lowercase}.${method.name}", jsonParameters, jsonResult); + if (statusError == Firebolt::Error::None) { FIREBOLT_LOG_INFO(FireboltSDK::Logger::Category::OpenRPC, FireboltSDK::Logger::Module(), "${info.Title}.${method.name} is successfully invoked"); ${if.result.nonvoid}${method.result.instantiation.with.indent}${end.if.result.nonvoid} } } else { - FIREBOLT_LOG_ERROR(FireboltSDK::Logger::Category::OpenRPC, FireboltSDK::Logger::Module(), "Error in getting Transport err = %d", status); + FIREBOLT_LOG_ERROR(FireboltSDK::Logger::Category::OpenRPC, FireboltSDK::Logger::Module(), "Error in getting Transport err = %d", statusError); } if (err != nullptr) { - *err = status; + *err = statusError; } return${if.result.nonvoid} ${method.result.name}${end.if.result.nonvoid}; diff --git a/languages/cpp/templates/parameter-serialization/enum.cpp b/languages/cpp/templates/parameter-serialization/enum.cpp index 478e1d8e..c8a82f9c 100644 --- a/languages/cpp/templates/parameter-serialization/enum.cpp +++ b/languages/cpp/templates/parameter-serialization/enum.cpp @@ -1,7 +1,7 @@ ${if.optional}if (${property}.has_value()) { - ${if.namespace.notsame}Firebolt::${info.Title}::${end.if.namespace.notsame}JsonData_${title} jsonValue = ${property}.value(); - WPEFramework::Core::JSON::Variant ${property}Variant(jsonValue.Data()); + ${if.namespace.notsame}Firebolt::${info.Title}::${end.if.namespace.notsame}JsonData_${title} json${Property} = ${property}.value(); + WPEFramework::Core::JSON::Variant ${property}Variant(json${Property}.Data()); jsonParameters.Set(_T("${property}"), ${property}Variant); - }${end.if.optional}${if.non.optional}${if.namespace.notsame}Firebolt::${info.Title}::${end.if.namespace.notsame}JsonData_${title} jsonValue = ${property}; - WPEFramework::Core::JSON::Variant ${property}Variant(jsonValue.Data()); + }${end.if.optional}${if.non.optional}${if.namespace.notsame}Firebolt::${info.Title}::${end.if.namespace.notsame}JsonData_${title} json${Property} = ${property}; + WPEFramework::Core::JSON::Variant ${property}Variant(json${Property}.Data()); jsonParameters.Set(_T("${property}"), ${property}Variant);${end.if.non.optional} \ No newline at end of file diff --git a/languages/cpp/templates/result-instantiation/sub-property/array.cpp b/languages/cpp/templates/result-instantiation/sub-property/array.cpp index a9badd14..0404dc8c 100644 --- a/languages/cpp/templates/result-instantiation/sub-property/array.cpp +++ b/languages/cpp/templates/result-instantiation/sub-property/array.cpp @@ -1,10 +1,10 @@ - ${if.optional}if (jsonResult.${Property}.IsSet()) { - ${base.title}Result${level}.${property} = std::make_optional<${type}>(); - auto index(jsonResult.${Property}.Elements()); - while (index.Next() == true) { - ${if.object}${items.with.indent}${end.if.object}${if.non.object} ${base.title}Result${level}.${property}.value().push_back(index.Current().Value());${end.if.non.object} + ${if.optional}if (jsonResult${Property.dependency}.${Property}.IsSet()) { + ${base.title}Result${level}${property.dependency}${if.impl.optional}.value()${end.if.impl.optional}.${property} = std::make_optional<${type}>(); + auto ${property}Index(jsonResult${Property.dependency}.${Property}.Elements()); + while (${property}Index.Next() == true) { + ${if.object}${items.with.indent}${end.if.object}${if.non.object} ${base.title}Result${level}.${property}.value().push_back(${property}Index.Current().Value());${end.if.non.object} } - }${end.if.optional}${if.non.optional}auto index(jsonResult.${Property}.Elements()); - while (index.Next() == true) { - ${if.object}${items.with.indent}${end.if.object}${if.non.object} ${base.title}Result${level}.${property}.push_back(index.Current().Value());${end.if.non.object} + }${end.if.optional}${if.non.optional}auto ${property}Index(jsonResult.${Property}.Elements()); + while (${property}Index.Next() == true) { + ${if.object}${items.with.indent}${end.if.object}${if.non.object} ${base.title}Result${level}.${property}.push_back(${property}Index.Current().Value());${end.if.non.object} }${end.if.non.optional} diff --git a/languages/cpp/templates/result-instantiation/sub-property/object-array.cpp b/languages/cpp/templates/result-instantiation/sub-property/object-array.cpp index 1274a0da..c7286760 100644 --- a/languages/cpp/templates/result-instantiation/sub-property/object-array.cpp +++ b/languages/cpp/templates/result-instantiation/sub-property/object-array.cpp @@ -1,6 +1,6 @@ ${type} ${property}Result${level}; - ${if.namespace.notsame}Firebolt::${info.Title}::${end.if.namespace.notsame}JsonData_${title} jsonResult = index.Current(); + ${if.namespace.notsame}Firebolt::${info.Title}::${end.if.namespace.notsame}JsonData_${title} jsonResult = ${property}Index.Current(); { ${properties} } - ${property}Result.${property}${if.impl.array.optional}.value()${end.if.impl.array.optional}.push_back(${property}Result${level}); \ No newline at end of file + ${base.title}Result${property.dependency}${if.impl.optional}.value()${end.if.impl.optional}.${property}.push_back(${property}Result${level}); \ No newline at end of file diff --git a/languages/cpp/templates/sdk/scripts/build.sh b/languages/cpp/templates/sdk/scripts/build.sh index 8f2142df..415225a1 100755 --- a/languages/cpp/templates/sdk/scripts/build.sh +++ b/languages/cpp/templates/sdk/scripts/build.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -e usage() { echo "options:" diff --git a/languages/cpp/templates/sdk/scripts/install.sh b/languages/cpp/templates/sdk/scripts/install.sh index b31556a2..cbabe217 100755 --- a/languages/cpp/templates/sdk/scripts/install.sh +++ b/languages/cpp/templates/sdk/scripts/install.sh @@ -5,6 +5,7 @@ usage() echo " -i install path" echo " -s sdk path" echo " -m module name. i.e, core/manage" + echo " -v sdk version. i.e, 1.3.0" echo echo "usage: " echo " ./install.sh -i path -s sdk path -m core" @@ -13,12 +14,15 @@ usage() SdkPath=".." InstallPath=".." ModuleName="core" -while getopts i:s:m:h flag +Version=1.3.0-next.1 + +while getopts i:s:m:v:h flag do case "${flag}" in i) InstallPath="${OPTARG}";; s) SdkPath="${OPTARG}";; m) ModuleName="${OPTARG}";; + v) Version="${OPTARG}";; h) usage && exit 1;; esac done @@ -40,8 +44,7 @@ GetVersion() Version=${array[2]} } -Version=0.0 -GetVersion +#GetVersion ReleaseName=firebolt-${ModuleName}-native-sdk-${Version} ReleasePath=${InstallPath}/${ReleaseName} diff --git a/languages/cpp/templates/sdk/src/firebolt.cpp b/languages/cpp/templates/sdk/src/firebolt.cpp index a864c2c4..c426f127 100644 --- a/languages/cpp/templates/sdk/src/firebolt.cpp +++ b/languages/cpp/templates/sdk/src/firebolt.cpp @@ -18,6 +18,7 @@ #include #include "FireboltSDK.h" +#include "IModule.h" ${module.includes.private} namespace Firebolt { diff --git a/src/macrofier/engine.mjs b/src/macrofier/engine.mjs index fc0b437a..aedcc4e9 100644 --- a/src/macrofier/engine.mjs +++ b/src/macrofier/engine.mjs @@ -1775,16 +1775,24 @@ function getProviderXValues(method) { return xValues } -function insertProviderXValues(template, moduleJson, xValues) { +function insertProviderXValues(template, module, xValues) { if (xValues['x-response']) { - const xResponseInst = types.getSchemaShape(xValues['x-response'], moduleJson, { templateDir: 'parameter-serialization', property: 'result', required: true, destination: state.destination, section: state.section, primitive: true, skipTitleOnce: true }) + let schema = localizeDependencies(xValues['x-response'], module) + const moduleTitle = types.getXSchemaGroup(schema, module) + const xResponseInst = types.getSchemaShape(schema, module, { templateDir: 'parameter-serialization', property: 'result', required: true, destination: state.destination, section: state.section, primitive: true, skipTitleOnce: true }) + const type = types.getSchemaType(schema, module, { moduleTitle: moduleTitle, result: true, namespace: true}) template = template.replace(/\$\{provider\.xresponse\.serialization\}/gms, xResponseInst) - .replace(/\$\{provider\.xresponse\.name\}/gms, xValues['x-response'].title) + .replace(/\$\{provider\.xresponse\.name\}/gms, type) + .replace(/\$\{parent\.Title\}/g, capitalize(moduleTitle)) } if (xValues['x-error']) { - const xErrorInst = types.getSchemaShape(xValues['x-error'], moduleJson, { templateDir: 'parameter-serialization', property: 'result', required: true, destination: state.destination, section: state.section, primitive: true, skipTitleOnce: true }) + let schema = localizeDependencies(xValues['x-error'], module) + const moduleTitle = types.getXSchemaGroup(schema, module) + const xErrorInst = types.getSchemaShape(schema, module, { templateDir: 'parameter-serialization', property: 'result', required: true, destination: state.destination, section: state.section, primitive: true, skipTitleOnce: true }) + const type = types.getSchemaType(schema, module, { moduleTitle: moduleTitle, result: true, namespace: true}) template = template.replace(/\$\{provider\.xerror\.serialization\}/gms, xErrorInst) - .replace(/\$\{provider\.xerror\.name\}/gms, xValues['x-error'].title) + .replace(/\$\{provider\.xerror\.name\}/gms, type) + .replace(/\$\{parent\.Title\}/g, capitalize(moduleTitle)) } return template } @@ -1805,9 +1813,24 @@ function insertProviderInterfaceMacros(template, capability, moduleJson = {}, te let name = getProviderInterfaceName(iface, capability, moduleJson) let xValues const suffix = state.destination ? state.destination.split('.').pop() : '' - let interfaceShape = getTemplate(suffix ? `/codeblocks/interface.${suffix}` : '/codeblocks/interface', templates) - if (!interfaceShape) { - interfaceShape = getTemplate('/codeblocks/interface', templates) + + // Determine if any method has the 'x-allow-focus' tag set to true + const hasFocusableMethods = iface.some(method => + method.tags.some(tag => tag['x-allow-focus'] === true) + ) + + // Determine the appropriate template based on hasFocusableMethods and suffix + let interfaceShape; + if (hasFocusableMethods) { + interfaceShape = getTemplate(suffix ? `/codeblocks/interface-focusable.${suffix}` : '/codeblocks/interface-focusable', templates); + if (!interfaceShape) { + interfaceShape = getTemplate('/codeblocks/interface-focusable', templates); + } + } else { + interfaceShape = getTemplate(suffix ? `/codeblocks/interface.${suffix}` : '/codeblocks/interface', templates); + if (!interfaceShape) { + interfaceShape = getTemplate('/codeblocks/interface', templates); + } } interfaceShape = interfaceShape.replace(/\$\{name\}/g, name) diff --git a/src/macrofier/types.mjs b/src/macrofier/types.mjs index 6e854d15..acfb0d9b 100644 --- a/src/macrofier/types.mjs +++ b/src/macrofier/types.mjs @@ -19,7 +19,9 @@ import deepmerge from 'deepmerge' import { getPath, localizeDependencies, getSafeEnumKeyName } from '../shared/json-schema.mjs' import path from "path" +import { getConfig } from '../shared/configLoader.mjs' +const config = getConfig() let convertTuplesToArraysOrObjects = false const templates = {} const state = {} @@ -360,7 +362,7 @@ const insertObjectMacros = (content, schema, module, title, property, options) = .replace(/\$\{if\.base\.optional\}(.*?)\$\{end\.if\.base\.optional\}/gms, options.required ? '' : '$1') .replace(/\$\{if\.non\.object\}(.*?)\$\{end\.if\.non\.object\}/gms, isObject(localizedProp) ? '' : '$1') .replace(/\$\{if\.non\.array\}(.*?)\$\{end\.if\.non\.array\}/gms, (localizedProp.type === 'array') ? '' : '$1') - .replace(/\$\{if\.non\.anyOf\}(.*?)\$\{end\.if\.non\.anyOf\}/gms, (localizedProp.anyOf || localizedProp.anyOneOf) ? '' : '$1') + .replace(/\$\{if\.non\.anyOf\}(.*?)\$\{end\.if\.non\.anyOf\}/gms, (localizedProp.anyOf || localizedProp.oneOf) ? '' : '$1') .replace(/\$\{if\.non\.const\}(.*?)\$\{end\.if\.non\.const\}/gms, (typeof localizedProp.const === 'string') ? '' : '$1') let baseTitle = options.property @@ -724,7 +726,11 @@ function getSchemaType(schema, module, { destination, templateDir = 'types', lin const theTitle = insertSchemaMacros(namespaceStr + getTemplate(path.join(templateDir, 'title' + suffix)), schema, module, { name: schema.title, parent: getXSchemaGroup(schema, module), recursive: false }) const allocatedProxy = event || result - const title = schema.type === "object" || schema.anyOf || schema.oneOf || Array.isArray(schema.type) && schema.type.includes("object") || schema.enum ? true : false + let title = schema.type === "object" || schema.anyOf || schema.oneOf || Array.isArray(schema.type) && schema.type.includes("object") || schema.enum ? true : false + + if (config?.enableUnionTypes === false) { + title = schema.type === "object" || Array.isArray(schema.type) && schema.type.includes("object") || schema.enum ? true : false + } if (schema['$ref']) { if (schema['$ref'][0] === '#') { @@ -929,5 +935,6 @@ export default { getMethodSignatureResult, getSchemaShape, getSchemaType, - getSchemaInstantiation + getSchemaInstantiation, + getXSchemaGroup } diff --git a/src/sdk/index.mjs b/src/sdk/index.mjs index f6fd0f5e..2a0c6da4 100755 --- a/src/sdk/index.mjs +++ b/src/sdk/index.mjs @@ -21,6 +21,7 @@ import path from 'path' import { readJson } from '../shared/filesystem.mjs' import macrofy from '../macrofier/index.mjs' +import { loadConfig, getConfig } from '../shared/configLoader.mjs'; /************************************************************************************************/ /******************************************** MAIN **********************************************/ @@ -48,7 +49,9 @@ const run = async ({ // fail silently } - const config = await readJson(path.join(language, 'language.config.json')) + // Load in config + await loadConfig(language) + const config = getConfig() return macrofy(input, template, output, { headline: 'SDK code', diff --git a/src/shared/configLoader.mjs b/src/shared/configLoader.mjs new file mode 100644 index 00000000..644a7f4e --- /dev/null +++ b/src/shared/configLoader.mjs @@ -0,0 +1,18 @@ +import path from 'path' +import { readJson } from './filesystem.mjs' + +let config = null + +export const loadConfig = async (language) => { + if (!config) { + config = await readJson(path.join(language, 'language.config.json')) + } + return config +} + +export const getConfig = () => { + if (!config) { + return null; + } + return config +} diff --git a/src/shared/modules.mjs b/src/shared/modules.mjs index 5fa64c6a..ae7dca1f 100644 --- a/src/shared/modules.mjs +++ b/src/shared/modules.mjs @@ -92,7 +92,7 @@ const getProviderInterfaceMethods = (capability, json) => { function getProviderInterface(capability, module, extractProviderSchema = false) { module = JSON.parse(JSON.stringify(module)) const iface = getProviderInterfaceMethods(capability, module)//.map(method => localizeDependencies(method, module, null, { mergeAllOfs: true })) - + iface.forEach(method => { const payload = getPayloadFromEvent(method) const focusable = method.tags.find(t => t['x-allow-focus'])