506 lines
17 KiB
JavaScript
506 lines
17 KiB
JavaScript
|
/**
|
||
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||
|
*
|
||
|
* This source code is licensed under the MIT license found in the
|
||
|
* LICENSE file in the root directory of this source tree.
|
||
|
*
|
||
|
*
|
||
|
* @format
|
||
|
*/
|
||
|
|
||
|
'use strict';
|
||
|
|
||
|
function _slicedToArray(arr, i) {
|
||
|
return (
|
||
|
_arrayWithHoles(arr) ||
|
||
|
_iterableToArrayLimit(arr, i) ||
|
||
|
_unsupportedIterableToArray(arr, i) ||
|
||
|
_nonIterableRest()
|
||
|
);
|
||
|
}
|
||
|
function _nonIterableRest() {
|
||
|
throw new TypeError(
|
||
|
'Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.',
|
||
|
);
|
||
|
}
|
||
|
function _unsupportedIterableToArray(o, minLen) {
|
||
|
if (!o) return;
|
||
|
if (typeof o === 'string') return _arrayLikeToArray(o, minLen);
|
||
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
||
|
if (n === 'Object' && o.constructor) n = o.constructor.name;
|
||
|
if (n === 'Map' || n === 'Set') return Array.from(o);
|
||
|
if (n === 'Arguments' || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))
|
||
|
return _arrayLikeToArray(o, minLen);
|
||
|
}
|
||
|
function _arrayLikeToArray(arr, len) {
|
||
|
if (len == null || len > arr.length) len = arr.length;
|
||
|
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
||
|
return arr2;
|
||
|
}
|
||
|
function _iterableToArrayLimit(arr, i) {
|
||
|
var _i =
|
||
|
null == arr
|
||
|
? null
|
||
|
: ('undefined' != typeof Symbol && arr[Symbol.iterator]) ||
|
||
|
arr['@@iterator'];
|
||
|
if (null != _i) {
|
||
|
var _s,
|
||
|
_e,
|
||
|
_x,
|
||
|
_r,
|
||
|
_arr = [],
|
||
|
_n = !0,
|
||
|
_d = !1;
|
||
|
try {
|
||
|
if (((_x = (_i = _i.call(arr)).next), 0 === i)) {
|
||
|
if (Object(_i) !== _i) return;
|
||
|
_n = !1;
|
||
|
} else
|
||
|
for (
|
||
|
;
|
||
|
!(_n = (_s = _x.call(_i)).done) &&
|
||
|
(_arr.push(_s.value), _arr.length !== i);
|
||
|
_n = !0
|
||
|
);
|
||
|
} catch (err) {
|
||
|
(_d = !0), (_e = err);
|
||
|
} finally {
|
||
|
try {
|
||
|
if (!_n && null != _i.return && ((_r = _i.return()), Object(_r) !== _r))
|
||
|
return;
|
||
|
} finally {
|
||
|
if (_d) throw _e;
|
||
|
}
|
||
|
}
|
||
|
return _arr;
|
||
|
}
|
||
|
}
|
||
|
function _arrayWithHoles(arr) {
|
||
|
if (Array.isArray(arr)) return arr;
|
||
|
}
|
||
|
const _require = require('./Utils'),
|
||
|
createAliasResolver = _require.createAliasResolver,
|
||
|
getModules = _require.getModules;
|
||
|
const _require2 = require('../../parsers/parsers-commons'),
|
||
|
unwrapNullable = _require2.unwrapNullable;
|
||
|
const HostFunctionTemplate = ({
|
||
|
hasteModuleName,
|
||
|
propertyName,
|
||
|
jniSignature,
|
||
|
jsReturnType,
|
||
|
}) => {
|
||
|
return `static facebook::jsi::Value __hostFunction_${hasteModuleName}SpecJSI_${propertyName}(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||
|
static jmethodID cachedMethodId = nullptr;
|
||
|
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, ${jsReturnType}, "${propertyName}", "${jniSignature}", args, count, cachedMethodId);
|
||
|
}`;
|
||
|
};
|
||
|
const ModuleClassConstructorTemplate = ({hasteModuleName, methods}) => {
|
||
|
return `
|
||
|
${hasteModuleName}SpecJSI::${hasteModuleName}SpecJSI(const JavaTurboModule::InitParams ¶ms)
|
||
|
: JavaTurboModule(params) {
|
||
|
${methods
|
||
|
.map(({propertyName, argCount}) => {
|
||
|
return ` methodMap_["${propertyName}"] = MethodMetadata {${argCount}, __hostFunction_${hasteModuleName}SpecJSI_${propertyName}};`;
|
||
|
})
|
||
|
.join('\n')}
|
||
|
}`.trim();
|
||
|
};
|
||
|
const ModuleLookupTemplate = ({moduleName, hasteModuleName}) => {
|
||
|
return ` if (moduleName == "${moduleName}") {
|
||
|
return std::make_shared<${hasteModuleName}SpecJSI>(params);
|
||
|
}`;
|
||
|
};
|
||
|
const FileTemplate = ({libraryName, include, modules, moduleLookups}) => {
|
||
|
return `
|
||
|
/**
|
||
|
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
||
|
*
|
||
|
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||
|
* once the code is regenerated.
|
||
|
*
|
||
|
* ${'@'}generated by codegen project: GenerateModuleJniCpp.js
|
||
|
*/
|
||
|
|
||
|
#include ${include}
|
||
|
|
||
|
namespace facebook {
|
||
|
namespace react {
|
||
|
|
||
|
${modules}
|
||
|
|
||
|
std::shared_ptr<TurboModule> ${libraryName}_ModuleProvider(const std::string &moduleName, const JavaTurboModule::InitParams ¶ms) {
|
||
|
${moduleLookups.map(ModuleLookupTemplate).join('\n')}
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
} // namespace react
|
||
|
} // namespace facebook
|
||
|
`;
|
||
|
};
|
||
|
function translateReturnTypeToKind(nullableTypeAnnotation, resolveAlias) {
|
||
|
const _unwrapNullable = unwrapNullable(nullableTypeAnnotation),
|
||
|
_unwrapNullable2 = _slicedToArray(_unwrapNullable, 1),
|
||
|
typeAnnotation = _unwrapNullable2[0];
|
||
|
let realTypeAnnotation = typeAnnotation;
|
||
|
if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') {
|
||
|
realTypeAnnotation = resolveAlias(realTypeAnnotation.name);
|
||
|
}
|
||
|
switch (realTypeAnnotation.type) {
|
||
|
case 'ReservedTypeAnnotation':
|
||
|
switch (realTypeAnnotation.name) {
|
||
|
case 'RootTag':
|
||
|
return 'NumberKind';
|
||
|
default:
|
||
|
realTypeAnnotation.name;
|
||
|
throw new Error(
|
||
|
`Invalid ReservedFunctionValueTypeName name, got ${realTypeAnnotation.name}`,
|
||
|
);
|
||
|
}
|
||
|
case 'VoidTypeAnnotation':
|
||
|
return 'VoidKind';
|
||
|
case 'StringTypeAnnotation':
|
||
|
return 'StringKind';
|
||
|
case 'BooleanTypeAnnotation':
|
||
|
return 'BooleanKind';
|
||
|
case 'EnumDeclaration':
|
||
|
switch (typeAnnotation.memberType) {
|
||
|
case 'NumberTypeAnnotation':
|
||
|
return 'NumberKind';
|
||
|
case 'StringTypeAnnotation':
|
||
|
return 'StringKind';
|
||
|
default:
|
||
|
throw new Error(
|
||
|
`Unknown enum prop type for returning value, found: ${realTypeAnnotation.type}"`,
|
||
|
);
|
||
|
}
|
||
|
case 'UnionTypeAnnotation':
|
||
|
switch (typeAnnotation.memberType) {
|
||
|
case 'NumberTypeAnnotation':
|
||
|
return 'NumberKind';
|
||
|
case 'ObjectTypeAnnotation':
|
||
|
return 'ObjectKind';
|
||
|
case 'StringTypeAnnotation':
|
||
|
return 'StringKind';
|
||
|
default:
|
||
|
throw new Error(
|
||
|
`Unsupported union member returning value, found: ${realTypeAnnotation.memberType}"`,
|
||
|
);
|
||
|
}
|
||
|
case 'NumberTypeAnnotation':
|
||
|
return 'NumberKind';
|
||
|
case 'DoubleTypeAnnotation':
|
||
|
return 'NumberKind';
|
||
|
case 'FloatTypeAnnotation':
|
||
|
return 'NumberKind';
|
||
|
case 'Int32TypeAnnotation':
|
||
|
return 'NumberKind';
|
||
|
case 'PromiseTypeAnnotation':
|
||
|
return 'PromiseKind';
|
||
|
case 'GenericObjectTypeAnnotation':
|
||
|
return 'ObjectKind';
|
||
|
case 'ObjectTypeAnnotation':
|
||
|
return 'ObjectKind';
|
||
|
case 'ArrayTypeAnnotation':
|
||
|
return 'ArrayKind';
|
||
|
default:
|
||
|
realTypeAnnotation.type;
|
||
|
throw new Error(
|
||
|
`Unknown prop type for returning value, found: ${realTypeAnnotation.type}"`,
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
function translateParamTypeToJniType(param, resolveAlias) {
|
||
|
const optional = param.optional,
|
||
|
nullableTypeAnnotation = param.typeAnnotation;
|
||
|
const _unwrapNullable3 = unwrapNullable(nullableTypeAnnotation),
|
||
|
_unwrapNullable4 = _slicedToArray(_unwrapNullable3, 2),
|
||
|
typeAnnotation = _unwrapNullable4[0],
|
||
|
nullable = _unwrapNullable4[1];
|
||
|
const isRequired = !optional && !nullable;
|
||
|
let realTypeAnnotation = typeAnnotation;
|
||
|
if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') {
|
||
|
realTypeAnnotation = resolveAlias(realTypeAnnotation.name);
|
||
|
}
|
||
|
switch (realTypeAnnotation.type) {
|
||
|
case 'ReservedTypeAnnotation':
|
||
|
switch (realTypeAnnotation.name) {
|
||
|
case 'RootTag':
|
||
|
return !isRequired ? 'Ljava/lang/Double;' : 'D';
|
||
|
default:
|
||
|
realTypeAnnotation.name;
|
||
|
throw new Error(
|
||
|
`Invalid ReservedFunctionValueTypeName name, got ${realTypeAnnotation.name}`,
|
||
|
);
|
||
|
}
|
||
|
case 'StringTypeAnnotation':
|
||
|
return 'Ljava/lang/String;';
|
||
|
case 'BooleanTypeAnnotation':
|
||
|
return !isRequired ? 'Ljava/lang/Boolean;' : 'Z';
|
||
|
case 'EnumDeclaration':
|
||
|
switch (typeAnnotation.memberType) {
|
||
|
case 'NumberTypeAnnotation':
|
||
|
return !isRequired ? 'Ljava/lang/Double;' : 'D';
|
||
|
case 'StringTypeAnnotation':
|
||
|
return 'Ljava/lang/String;';
|
||
|
default:
|
||
|
throw new Error(
|
||
|
`Unknown enum prop type for method arg, found: ${realTypeAnnotation.type}"`,
|
||
|
);
|
||
|
}
|
||
|
case 'UnionTypeAnnotation':
|
||
|
switch (typeAnnotation.memberType) {
|
||
|
case 'NumberTypeAnnotation':
|
||
|
return !isRequired ? 'Ljava/lang/Double;' : 'D';
|
||
|
case 'ObjectTypeAnnotation':
|
||
|
return 'Lcom/facebook/react/bridge/ReadableMap;';
|
||
|
case 'StringTypeAnnotation':
|
||
|
return 'Ljava/lang/String;';
|
||
|
default:
|
||
|
throw new Error(
|
||
|
`Unsupported union prop value, found: ${realTypeAnnotation.memberType}"`,
|
||
|
);
|
||
|
}
|
||
|
case 'NumberTypeAnnotation':
|
||
|
return !isRequired ? 'Ljava/lang/Double;' : 'D';
|
||
|
case 'DoubleTypeAnnotation':
|
||
|
return !isRequired ? 'Ljava/lang/Double;' : 'D';
|
||
|
case 'FloatTypeAnnotation':
|
||
|
return !isRequired ? 'Ljava/lang/Double;' : 'D';
|
||
|
case 'Int32TypeAnnotation':
|
||
|
return !isRequired ? 'Ljava/lang/Double;' : 'D';
|
||
|
case 'GenericObjectTypeAnnotation':
|
||
|
return 'Lcom/facebook/react/bridge/ReadableMap;';
|
||
|
case 'ObjectTypeAnnotation':
|
||
|
return 'Lcom/facebook/react/bridge/ReadableMap;';
|
||
|
case 'ArrayTypeAnnotation':
|
||
|
return 'Lcom/facebook/react/bridge/ReadableArray;';
|
||
|
case 'FunctionTypeAnnotation':
|
||
|
return 'Lcom/facebook/react/bridge/Callback;';
|
||
|
default:
|
||
|
realTypeAnnotation.type;
|
||
|
throw new Error(
|
||
|
`Unknown prop type for method arg, found: ${realTypeAnnotation.type}"`,
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
function translateReturnTypeToJniType(nullableTypeAnnotation, resolveAlias) {
|
||
|
const _unwrapNullable5 = unwrapNullable(nullableTypeAnnotation),
|
||
|
_unwrapNullable6 = _slicedToArray(_unwrapNullable5, 2),
|
||
|
typeAnnotation = _unwrapNullable6[0],
|
||
|
nullable = _unwrapNullable6[1];
|
||
|
let realTypeAnnotation = typeAnnotation;
|
||
|
if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') {
|
||
|
realTypeAnnotation = resolveAlias(realTypeAnnotation.name);
|
||
|
}
|
||
|
switch (realTypeAnnotation.type) {
|
||
|
case 'ReservedTypeAnnotation':
|
||
|
switch (realTypeAnnotation.name) {
|
||
|
case 'RootTag':
|
||
|
return nullable ? 'Ljava/lang/Double;' : 'D';
|
||
|
default:
|
||
|
realTypeAnnotation.name;
|
||
|
throw new Error(
|
||
|
`Invalid ReservedFunctionValueTypeName name, got ${realTypeAnnotation.name}`,
|
||
|
);
|
||
|
}
|
||
|
case 'VoidTypeAnnotation':
|
||
|
return 'V';
|
||
|
case 'StringTypeAnnotation':
|
||
|
return 'Ljava/lang/String;';
|
||
|
case 'BooleanTypeAnnotation':
|
||
|
return nullable ? 'Ljava/lang/Boolean;' : 'Z';
|
||
|
case 'EnumDeclaration':
|
||
|
switch (typeAnnotation.memberType) {
|
||
|
case 'NumberTypeAnnotation':
|
||
|
return nullable ? 'Ljava/lang/Double;' : 'D';
|
||
|
case 'StringTypeAnnotation':
|
||
|
return 'Ljava/lang/String;';
|
||
|
default:
|
||
|
throw new Error(
|
||
|
`Unknown enum prop type for method return type, found: ${realTypeAnnotation.type}"`,
|
||
|
);
|
||
|
}
|
||
|
case 'UnionTypeAnnotation':
|
||
|
switch (typeAnnotation.memberType) {
|
||
|
case 'NumberTypeAnnotation':
|
||
|
return nullable ? 'Ljava/lang/Double;' : 'D';
|
||
|
case 'ObjectTypeAnnotation':
|
||
|
return 'Lcom/facebook/react/bridge/WritableMap;';
|
||
|
case 'StringTypeAnnotation':
|
||
|
return 'Ljava/lang/String;';
|
||
|
default:
|
||
|
throw new Error(
|
||
|
`Unsupported union member type, found: ${realTypeAnnotation.memberType}"`,
|
||
|
);
|
||
|
}
|
||
|
case 'NumberTypeAnnotation':
|
||
|
return nullable ? 'Ljava/lang/Double;' : 'D';
|
||
|
case 'DoubleTypeAnnotation':
|
||
|
return nullable ? 'Ljava/lang/Double;' : 'D';
|
||
|
case 'FloatTypeAnnotation':
|
||
|
return nullable ? 'Ljava/lang/Double;' : 'D';
|
||
|
case 'Int32TypeAnnotation':
|
||
|
return nullable ? 'Ljava/lang/Double;' : 'D';
|
||
|
case 'PromiseTypeAnnotation':
|
||
|
return 'Lcom/facebook/react/bridge/Promise;';
|
||
|
case 'GenericObjectTypeAnnotation':
|
||
|
return 'Lcom/facebook/react/bridge/WritableMap;';
|
||
|
case 'ObjectTypeAnnotation':
|
||
|
return 'Lcom/facebook/react/bridge/WritableMap;';
|
||
|
case 'ArrayTypeAnnotation':
|
||
|
return 'Lcom/facebook/react/bridge/WritableArray;';
|
||
|
default:
|
||
|
realTypeAnnotation.type;
|
||
|
throw new Error(
|
||
|
`Unknown prop type for method return type, found: ${realTypeAnnotation.type}"`,
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
function translateMethodTypeToJniSignature(property, resolveAlias) {
|
||
|
const name = property.name,
|
||
|
typeAnnotation = property.typeAnnotation;
|
||
|
let _unwrapNullable7 = unwrapNullable(typeAnnotation),
|
||
|
_unwrapNullable8 = _slicedToArray(_unwrapNullable7, 1),
|
||
|
_unwrapNullable8$ = _unwrapNullable8[0],
|
||
|
returnTypeAnnotation = _unwrapNullable8$.returnTypeAnnotation,
|
||
|
params = _unwrapNullable8$.params;
|
||
|
params = [...params];
|
||
|
let processedReturnTypeAnnotation = returnTypeAnnotation;
|
||
|
const isPromiseReturn = returnTypeAnnotation.type === 'PromiseTypeAnnotation';
|
||
|
if (isPromiseReturn) {
|
||
|
processedReturnTypeAnnotation = {
|
||
|
type: 'VoidTypeAnnotation',
|
||
|
};
|
||
|
}
|
||
|
const argsSignatureParts = params.map(t => {
|
||
|
return translateParamTypeToJniType(t, resolveAlias);
|
||
|
});
|
||
|
if (isPromiseReturn) {
|
||
|
// Additional promise arg for this case.
|
||
|
argsSignatureParts.push(
|
||
|
translateReturnTypeToJniType(returnTypeAnnotation, resolveAlias),
|
||
|
);
|
||
|
}
|
||
|
const argsSignature = argsSignatureParts.join('');
|
||
|
const returnSignature =
|
||
|
name === 'getConstants'
|
||
|
? 'Ljava/util/Map;'
|
||
|
: translateReturnTypeToJniType(
|
||
|
processedReturnTypeAnnotation,
|
||
|
resolveAlias,
|
||
|
);
|
||
|
return `(${argsSignature})${returnSignature}`;
|
||
|
}
|
||
|
function translateMethodForImplementation(
|
||
|
hasteModuleName,
|
||
|
property,
|
||
|
resolveAlias,
|
||
|
) {
|
||
|
const _unwrapNullable9 = unwrapNullable(property.typeAnnotation),
|
||
|
_unwrapNullable10 = _slicedToArray(_unwrapNullable9, 1),
|
||
|
propertyTypeAnnotation = _unwrapNullable10[0];
|
||
|
const returnTypeAnnotation = propertyTypeAnnotation.returnTypeAnnotation;
|
||
|
if (
|
||
|
property.name === 'getConstants' &&
|
||
|
returnTypeAnnotation.type === 'ObjectTypeAnnotation' &&
|
||
|
returnTypeAnnotation.properties.length === 0
|
||
|
) {
|
||
|
return '';
|
||
|
}
|
||
|
return HostFunctionTemplate({
|
||
|
hasteModuleName,
|
||
|
propertyName: property.name,
|
||
|
jniSignature: translateMethodTypeToJniSignature(property, resolveAlias),
|
||
|
jsReturnType: translateReturnTypeToKind(returnTypeAnnotation, resolveAlias),
|
||
|
});
|
||
|
}
|
||
|
module.exports = {
|
||
|
generate(libraryName, schema, packageName, assumeNonnull = false) {
|
||
|
const nativeModules = getModules(schema);
|
||
|
const modules = Object.keys(nativeModules)
|
||
|
.filter(hasteModuleName => {
|
||
|
const module = nativeModules[hasteModuleName];
|
||
|
return !(
|
||
|
module.excludedPlatforms != null &&
|
||
|
module.excludedPlatforms.includes('android')
|
||
|
);
|
||
|
})
|
||
|
.sort()
|
||
|
.map(hasteModuleName => {
|
||
|
const _nativeModules$hasteM = nativeModules[hasteModuleName],
|
||
|
aliasMap = _nativeModules$hasteM.aliasMap,
|
||
|
properties = _nativeModules$hasteM.spec.properties;
|
||
|
const resolveAlias = createAliasResolver(aliasMap);
|
||
|
const translatedMethods = properties
|
||
|
.map(property =>
|
||
|
translateMethodForImplementation(
|
||
|
hasteModuleName,
|
||
|
property,
|
||
|
resolveAlias,
|
||
|
),
|
||
|
)
|
||
|
.join('\n\n');
|
||
|
return (
|
||
|
translatedMethods +
|
||
|
'\n\n' +
|
||
|
ModuleClassConstructorTemplate({
|
||
|
hasteModuleName,
|
||
|
methods: properties
|
||
|
.map(({name: propertyName, typeAnnotation}) => {
|
||
|
const _unwrapNullable11 = unwrapNullable(typeAnnotation),
|
||
|
_unwrapNullable12 = _slicedToArray(_unwrapNullable11, 1),
|
||
|
_unwrapNullable12$ = _unwrapNullable12[0],
|
||
|
returnTypeAnnotation =
|
||
|
_unwrapNullable12$.returnTypeAnnotation,
|
||
|
params = _unwrapNullable12$.params;
|
||
|
if (
|
||
|
propertyName === 'getConstants' &&
|
||
|
returnTypeAnnotation.type === 'ObjectTypeAnnotation' &&
|
||
|
returnTypeAnnotation.properties &&
|
||
|
returnTypeAnnotation.properties.length === 0
|
||
|
) {
|
||
|
return null;
|
||
|
}
|
||
|
return {
|
||
|
propertyName,
|
||
|
argCount: params.length,
|
||
|
};
|
||
|
})
|
||
|
.filter(Boolean),
|
||
|
})
|
||
|
);
|
||
|
})
|
||
|
.join('\n');
|
||
|
const moduleLookups = Object.keys(nativeModules)
|
||
|
.filter(hasteModuleName => {
|
||
|
const module = nativeModules[hasteModuleName];
|
||
|
return !(
|
||
|
module.excludedPlatforms != null &&
|
||
|
module.excludedPlatforms.includes('android')
|
||
|
);
|
||
|
})
|
||
|
.sort((a, b) => {
|
||
|
const nameA = nativeModules[a].moduleName;
|
||
|
const nameB = nativeModules[b].moduleName;
|
||
|
if (nameA < nameB) {
|
||
|
return -1;
|
||
|
} else if (nameA > nameB) {
|
||
|
return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
})
|
||
|
.map(hasteModuleName => ({
|
||
|
moduleName: nativeModules[hasteModuleName].moduleName,
|
||
|
hasteModuleName,
|
||
|
}));
|
||
|
const fileName = `${libraryName}-generated.cpp`;
|
||
|
const replacedTemplate = FileTemplate({
|
||
|
modules: modules,
|
||
|
libraryName: libraryName.replace(/-/g, '_'),
|
||
|
moduleLookups,
|
||
|
include: `"${libraryName}.h"`,
|
||
|
});
|
||
|
return new Map([[`jni/${fileName}`, replacedTemplate]]);
|
||
|
},
|
||
|
};
|