UNPKG

@nativescript/nx

Version:

NativeScript Plugin for Nx

338 lines 17 kB
"use strict"; 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