@nativescript/nx
Version:
NativeScript Plugin for Nx
338 lines • 17 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.commonExecutor = commonExecutor;
const tslib_1 = require("tslib");
const child_process_1 = tslib_1.__importDefault(require("child_process"));
const enquirer_1 = require("enquirer");
const fast_xml_parser_1 = require("fast-xml-parser");
const fs_extra_1 = require("fs-extra");
const path_1 = require("path");
const plist_1 = require("plist");
const deep_merge_1 = require("../schemas/deep-merge");
const commands_1 = require("./commands");
const helpers_1 = require("./helpers");
function commonExecutor(options, context) {
// global vars
const isWindows = process.platform === 'win32';
let projectCwd;
// eslint-disable-next-line no-async-promise-executor
return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
var _a, _b;
try {
const isBuild = options.command === commands_1.COMMANDS.BUILD;
const isClean = options.command === commands_1.COMMANDS.CLEAN;
const isDebug = options.command === commands_1.COMMANDS.DEBUG;
const isPrepare = options.command === commands_1.COMMANDS.PREPARE;
const isRun = options.command === commands_1.COMMANDS.RUN;
const isTest = options.command === commands_1.COMMANDS.TEST;
const isSilent = options.silent === true;
const platformCheck = [context.configurationName, options.platform].concat(options === null || options === void 0 ? void 0 : options['_']);
let isIos = platformCheck.some((overrides) => overrides === 'ios');
let isAndroid = platformCheck.some((overrides) => overrides === 'android');
let isVision = platformCheck.some((overrides) => overrides === 'vision' || overrides === 'visionos');
if (!isClean && !isSilent && !isIos && !isAndroid && !isVision) {
const platform = yield selectPlatform(options);
isIos = platform === 'ios';
isAndroid = platform === 'android';
isVision = platform === 'visionos';
}
if (!isClean) {
options.platform = isAndroid ? 'android' : isIos ? 'ios' : 'visionos';
}
const projectConfig = context.projectsConfigurations.projects[context.projectName];
projectCwd = projectConfig.root;
const target = projectConfig.targets[options.command];
const targetOptions = target.options;
const targetPlatformOptions = targetOptions[options.platform];
// const targetDescription = JSON.parse(process.argv.find((arg) => arg.indexOf('targetDescription') !== -1));
// fix for nx overwriting android and ios sub properties
(0, deep_merge_1.mergeDeep)(options, targetOptions);
const configurationName = yield selectConfiguration(target.configurations, context.configurationName);
// fix for nx overwriting android and ios sub properties
if (configurationName)
(0, deep_merge_1.mergeDeep)(options, target.configurations[configurationName]);
const nsOptions = prepareNsOptions(options, projectCwd);
const additionalArgs = []; // Assuming any extra flags are handled here
if (options.flags) {
// persisted flags in configurations
additionalArgs.push(...options.flags.split(' '));
}
if ((_a = options.android) === null || _a === void 0 ? void 0 : _a.xmlUpdates)
updateXml(options.android.xmlUpdates, 'android');
if ((_b = options.ios) === null || _b === void 0 ? void 0 : _b.plistUpdates)
updateXml(options.ios.plistUpdates, 'ios');
yield checkOptions();
const result = yield runCommand(nsOptions, additionalArgs);
resolve(result);
}
catch (err) {
console.error(err);
reject(err);
}
}));
function selectPlatform(options) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (options.platform)
return options.platform;
if (options.silent) {
console.warn('No platform was specified. Defaulting to iOS.');
return 'ios';
}
const platformChoices = ['ios', 'android', 'visionos'];
const { platform } = yield (0, enquirer_1.prompt)({
type: 'select',
name: 'platform',
message: 'Which platform do you want to target?',
choices: platformChoices,
});
return platform;
});
}
function selectConfiguration(targetConfigurations, configurationName) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (!configurationName && targetConfigurations && Object.keys(targetConfigurations).length) {
const { configurationName: selectedConfig } = yield (0, enquirer_1.prompt)({
type: 'select',
name: 'configurationName',
message: 'No configuration was provided. Did you mean to select one of these configurations?',
choices: ['No', ...Object.keys(targetConfigurations)],
});
if (selectedConfig == 'No') {
console.warn(`Continuing with no configuration. Specify with --configuration=prod, -c=prod, or :prod`);
}
return selectedConfig !== 'No' ? selectedConfig : undefined;
}
return configurationName;
});
}
function prepareNsOptions(options, projectCwd) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
const nsOptions = [];
if (options.platform === 'visionos') {
// visionos does not support debug with chrome devtools yet
nsOptions.push('run');
}
else {
nsOptions.push(options.command);
}
// early exit for `ns clean`
if (options.command === commands_1.COMMANDS.CLEAN)
return nsOptions;
if (options.platform === 'android') {
if (((_a = options.android) === null || _a === void 0 ? void 0 : _a.aab) || options.aab) {
nsOptions.push('--aab');
}
if (((_b = options.android) === null || _b === void 0 ? void 0 : _b.keyStorePath) || options.keyStorePath) {
nsOptions.push(`--key-store-path=${((_c = options.android) === null || _c === void 0 ? void 0 : _c.keyStorePath) || options.keyStorePath}`);
}
if (((_d = options.android) === null || _d === void 0 ? void 0 : _d.keyStorePassword) || options.keyStorePassword) {
nsOptions.push(`--key-store-password=${((_e = options.android) === null || _e === void 0 ? void 0 : _e.keyStorePassword) || options.keyStorePassword}`);
}
if (((_f = options.android) === null || _f === void 0 ? void 0 : _f.keyStoreAlias) || options.keyStoreAlias) {
nsOptions.push(`--key-store-alias=${((_g = options.android) === null || _g === void 0 ? void 0 : _g.keyStoreAlias) || options.keyStoreAlias}`);
}
if (((_h = options.android) === null || _h === void 0 ? void 0 : _h.keyStoreAliasPassword) || options.keyStoreAliasPassword) {
nsOptions.push(`--key-store-alias-password=${((_j = options.android) === null || _j === void 0 ? void 0 : _j.keyStoreAliasPassword) || options.keyStoreAliasPassword}`);
}
}
if (options.platform === 'ios') {
if ((_k = options.ios) === null || _k === void 0 ? void 0 : _k.provision) {
nsOptions.push(`--provision=${options.ios.provision}`);
}
else if (options.provision) {
nsOptions.push(`--provision=${options.provision}`);
}
}
// Append common options
options.platform && nsOptions.push(options.platform);
options.clean && nsOptions.push('--clean');
options.coverage && nsOptions.push('--env.codeCoverage');
options.device && !options.emulator && nsOptions.push(`--device=${options.device}`);
options.emulator && nsOptions.push('--emulator');
options.noHmr && nsOptions.push('--no-hmr');
options.timeout && options.timeout > -1 && nsOptions.push(`--timeout=${options.timeout}`);
options.uglify && nsOptions.push('--env.uglify');
options.verbose && nsOptions.push('--env.verbose');
options.production && nsOptions.push('--env.production');
options.forDevice && nsOptions.push('--for-device');
options.release && nsOptions.push('--release');
options.copyTo && nsOptions.push(`--copy-to=${options.copyTo}`);
options.force !== false && nsOptions.push('--force');
const nsFileReplacements = [];
for (const fileReplacement of options.fileReplacements) {
nsFileReplacements.push(`${fileReplacement.replace.replace(projectCwd, './')}:${fileReplacement.with.replace(projectCwd, './')}`);
}
nsFileReplacements.length && nsOptions.push(`--env.replace="${nsFileReplacements.join(',')}"`);
return nsOptions;
}
function updateXml(xmlUpdatesConfig, type) {
const xmlUpdatesKeys = Object.keys(xmlUpdatesConfig || {});
for (const filePathKeys of xmlUpdatesKeys) {
let xmlFilePath;
if (filePathKeys.indexOf('.') === 0) {
// resolve relative to project directory
xmlFilePath = (0, path_1.resolve)(projectCwd, filePathKeys);
}
else {
// default to locating in App_Resources
let defaultDir;
if (type === 'ios') {
defaultDir = ['App_Resources', 'iOS'];
}
else if (type === 'visionos') {
defaultDir = ['App_Resources', 'visionOS'];
}
else if (type === 'android') {
defaultDir = ['App_Resources', 'Android'];
}
xmlFilePath = (0, path_1.resolve)(projectCwd, ...defaultDir, filePathKeys);
}
let xmlFileContent;
const fileContent = (0, fs_extra_1.readFileSync)(xmlFilePath, 'utf8');
const xmlUpdates = xmlUpdatesConfig[filePathKeys];
if (type === 'ios' || type === 'visionos') {
xmlFileContent = (0, plist_1.parse)(fileContent);
}
else if (type === 'android') {
const parser = new fast_xml_parser_1.XMLParser({
ignoreAttributes: false,
ignoreDeclaration: false,
ignorePiTags: false,
attributeNamePrefix: '',
allowBooleanAttributes: true,
});
xmlFileContent = parser.parse(fileContent);
}
let needsUpdate = false;
const recursiveUpdate = function (target, updates) {
for (const key in updates) {
if (typeof updates[key] === 'object' && !Array.isArray(updates[key])) {
if (!target[key]) {
target[key] = {};
}
recursiveUpdate(target[key], updates[key]);
}
else {
if (Array.isArray(target[key])) {
recursiveUpdate(target[key], updates[key]);
}
else {
target[key] = updates[key];
needsUpdate = true;
}
}
}
};
recursiveUpdate(xmlFileContent, xmlUpdates);
if (needsUpdate) {
let newXmlFileContent;
if (type === 'ios' || type === 'visionos') {
newXmlFileContent = (0, plist_1.build)(xmlFileContent, { pretty: true, indent: '\t' });
}
else if (type === 'android') {
const builder = new fast_xml_parser_1.XMLBuilder({
ignoreAttributes: false,
format: true,
suppressEmptyNode: true,
attributeNamePrefix: '',
suppressBooleanAttributes: false,
});
newXmlFileContent = builder.build(xmlFileContent);
}
(0, fs_extra_1.writeFileSync)(xmlFilePath, newXmlFileContent);
console.log(`Updated: ${xmlFilePath}`);
}
}
}
function checkOptions() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (!options.id)
return;
const id = yield checkAppId();
if (options.id !== id) {
return new Promise((resolve) => {
let args = ['config', 'set', `${options.platform}.id`, options.id];
if (isWindows) {
args = args.map((arg) => (0, helpers_1.quoteString)(arg));
}
const child = child_process_1.default.spawn(isWindows ? 'ns.cmd' : 'ns', args, {
cwd: projectCwd,
stdio: 'inherit',
shell: isWindows ? true : undefined,
});
child.on('close', (code) => {
child.kill('SIGKILL');
resolve();
});
});
}
});
}
function checkAppId() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => {
let args = ['config', 'get', `id`];
if (isWindows) {
args = args.map((arg) => (0, helpers_1.quoteString)(arg));
}
const child = child_process_1.default.spawn(isWindows ? 'ns.cmd' : 'ns', args, {
cwd: projectCwd,
shell: isWindows ? true : undefined,
});
child.stdout.setEncoding('utf8');
child.stdout.on('data', function (data) {
// ensure no newline chars at the end
const appId = (data || '').toString().replace('\n', '').replace('\r', '');
// console.log('existing app id:', appId);
resolve(appId);
});
child.on('close', (code) => {
child.kill('SIGKILL');
});
});
});
}
function runCommand(nsOptions, additionalArgs) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
let icon = '';
if (!nsOptions.clean) {
if (nsOptions.platform === 'ios') {
icon = '';
}
else if (nsOptions.platform === 'android') {
icon = '🤖';
}
else if (['vision', 'visionos'].includes(nsOptions.platform)) {
icon = '🥽';
}
}
if (isWindows) {
// https://github.com/NativeScript/nativescript-cli/pull/5808
nsOptions = nsOptions.map((arg) => (0, helpers_1.quoteString)(arg));
additionalArgs = additionalArgs.map((arg) => (0, helpers_1.quoteString)(arg));
}
console.log(`―――――――――――――――――――――――― ${icon}`);
console.log(`Running NativeScript ${options.command === commands_1.COMMANDS.TEST ? 'unit tests' : 'CLI'} in ${projectCwd}`);
console.log(' ');
console.log([`ns`, ...nsOptions, ...additionalArgs].join(' '));
console.log(' ');
if (additionalArgs.length) {
console.log('Note: When using extra cli flags, ensure all key/value pairs are separated with =, for example: --provision="Name"');
console.log(' ');
}
console.log(`---`);
return new Promise((resolve) => {
const child = child_process_1.default.spawn(isWindows ? 'ns.cmd' : 'ns', [...nsOptions, ...additionalArgs], {
cwd: projectCwd,
stdio: 'inherit',
shell: isWindows ? true : undefined,
});
child.on('close', (code) => {
child.kill('SIGKILL');
resolve({ success: code === 0 });
});
});
});
}
}
//# sourceMappingURL=executors.js.map
;