@applicaster/zapplicaster-cli
Version:
CLI Tool for the zapp app and Quick Brick project
201 lines (170 loc) • 5.73 kB
JavaScript
/* eslint-disable indent */
/* eslint-disable max-len */
const R = require("ramda");
const camelize = require("camelize");
const logger = require("../logger");
const fs = require("fs");
/**
* module plugins
* @module @applicaster/zapplicaster-cli/src/plugins
*/
const JS_PLUGIN_CATEGORIES = ["data_source_provider"];
function isJSPlugin(pluginConfiguration) {
const {
plugin: { type, react_native },
} = pluginConfiguration;
return JS_PLUGIN_CATEGORIES.includes(type) || react_native;
}
/**
* maps plugin_configurations.json entries to js dependency object
*
* @param {any} pluginConfiguration
* @returns {any} dependency object
*/
function pluginConfigurationMapper(pluginConfiguration) {
const {
plugin: {
name,
type,
dependency_name,
dependency_version,
identifier,
api,
npm_dependencies = [],
},
configuration_json,
} = pluginConfiguration;
return dependency_name && identifier
? {
name,
identifier,
type: [type],
packageName: dependency_name,
version: dependency_version,
moduleName: camelize(identifier),
configuration: configuration_json,
api,
npm_dependencies,
}
: null;
}
/**
* formats the plugin data gathered from the plugin configurations to a format
* which can be easily injected in a package.json
* @param {Object} plugin
* @param {String} plugin.packageName name of the npm package
* @param {String} plugin.version version of the npm package
* @returns {Object}
*/
function pluginDependencyMapper({ packageName, version }) {
return {
type: "dependencies",
name: packageName,
version,
};
}
/**
* maps plugins gathered from plugin configurations to get extra dependencies
* @param {[Object]} plugins array of plugins data to map out
* @returns {[Object]}
*/
const getExtraPluginDependencies = (plugins) => {
const dependencies = [];
for (const plugin of plugins) {
const npmDependencies = plugin.npm_dependencies;
if (R.isNil(npmDependencies) || R.isEmpty(npmDependencies)) {
continue;
}
if (Array.isArray(npmDependencies)) {
for (const dependency of npmDependencies) {
// Example: @applicaster/quick-brick-xray@1.0.0
const splittedIndex = dependency.lastIndexOf("@");
const firstVersionIndex = splittedIndex + 1;
if (splittedIndex && dependency.length < firstVersionIndex) {
logger.error(
`Can not add extra dependency for plugin: ${plugin.name}, extraDependency: ${dependency}. Version splitter not exist, check manifest`
);
throw Error(
`Can not add extra dependency for plugin: ${plugin.name}, extraDependency: ${dependency}. Package name or version not exist`
);
}
const version = dependency.substring(firstVersionIndex);
const packageName = dependency.substring(0, splittedIndex);
if (R.not(R.isNil(version)) && R.not(R.isNil(packageName))) {
dependencies.push(pluginDependencyMapper({ version, packageName }));
} else {
logger.error(
`Can not add extra dependency for plugin: ${plugin.name}, extraDependency: ${dependency}. Package name or version not exist`
);
throw Error(
`Can not add extra dependency for plugin: ${plugin.name}, extraDependency: ${dependency}. Package name or version not exist`
);
}
}
}
}
return dependencies;
};
/**
* maps plugins gathered from plugin configurations with the above function
* @param {[Object]} plugins array of plugins data to map out
* @returns {[Object]}
*/
const getPluginDependencies = R.map(pluginDependencyMapper);
/**
* gather dependencies from plugin configurations
* @param {array} pluginConfigurations array coming from the app's config files
* @returns {array} formatted js dependencies
*/
const gatherDependencies = R.compose(
R.reject(R.isNil),
R.map(pluginConfigurationMapper),
R.filter(isJSPlugin)
);
/**
* Returns an object with the list of SDK assets found in the given path
* Structure used by webpack and ejs templates on prepare
* @param {String} platform - "lg_tv, android"
* @param {String} resolvedPath - the full path to the quick brick repo assets being built
* @returns {Object} assetObject - object with all of the assets to be used in template
*/
async function getSDKAssets(platform, resolvedPath) {
const assetPath = `${resolvedPath}/assets/${platform}`;
try {
const assetsWithPath = {};
const assets = fs.readdirSync(assetPath);
const addToAssetObject = (asset, dir = null) => {
const fileName = asset.substring(0, asset.lastIndexOf("."));
const relativePath = assetPath.replace(resolvedPath, "");
const path = dir ? `${relativePath}/${dir}` : relativePath;
assetsWithPath[fileName] = `.${path}/${asset}`;
};
assets.forEach((assetOrDir) => {
const assetDir = `${assetPath}/${assetOrDir}`;
const isDirectory = fs.statSync(assetDir).isDirectory();
if (isDirectory) {
const dir = assetOrDir;
const nestedAssets = fs.readdirSync(assetDir);
nestedAssets.forEach((asset) => addToAssetObject(asset, dir));
} else {
const asset = assetOrDir;
addToAssetObject(asset);
}
});
return assetsWithPath;
} catch (error) {
logger.error(
`There was an error retrieving SDK Assets.
Platform: ${platform}
AssetPath: ${assetPath}
ResolvedPath: ${resolvedPath}`,
error
);
}
}
module.exports = {
gatherDependencies,
getPluginDependencies,
getExtraPluginDependencies,
getSDKAssets,
};