Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

native-run

Package Overview
Dependencies
Maintainers
1
Versions
55
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

native-run - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2

dist/android/data/avds/Nexus_5X_API_24.json

17

dist/android/list.js

@@ -11,4 +11,8 @@ "use strict";

.map(device => deviceToTarget(device));
const virtualDevices = (await avd_1.getAVDs(sdk))
.map(avd => avdToTarget(avd));
const avds = await avd_1.getInstalledAVDs(sdk);
const defaultAvd = await avd_1.getDefaultAVD(sdk, avds);
if (!avds.includes(defaultAvd)) {
avds.push(defaultAvd);
}
const virtualDevices = avds.map(avd => avdToTarget(avd));
if (args.includes('--json')) {

@@ -28,5 +32,10 @@ process.stdout.write(JSON.stringify({ devices, virtualDevices }));

process.stdout.write('\nVirtual Devices:\n\n');
for (const avd of virtualDevices) {
process.stdout.write(` ${formatTarget(avd)}\n`);
if (virtualDevices.length === 0) {
process.stdout.write(' No virtual devices found\n');
}
else {
for (const avd of virtualDevices) {
process.stdout.write(` ${formatTarget(avd)}\n`);
}
}
}

@@ -33,0 +42,0 @@ exports.run = run;

@@ -5,2 +5,3 @@ "use strict";

const cli_1 = require("../utils/cli");
const log_1 = require("../utils/log");
const adb_1 = require("./utils/adb");

@@ -23,8 +24,8 @@ const avd_1 = require("./utils/avd");

const device = await selectDevice(sdk, args);
process.stdout.write(`Selected ${device.type === 'hardware' ? 'hardware device' : 'emulator'} ${device.serial}\n`);
log_1.log(`Selected ${device.type === 'hardware' ? 'hardware device' : 'emulator'} ${device.serial}\n`);
await adb_1.waitForBoot(sdk, device);
await run_1.installApkToDevice(sdk, device, apk, app);
process.stdout.write(`Starting application activity ${app}/${activity}...\n`);
log_1.log(`Starting application activity ${app}/${activity}...\n`);
await adb_1.startActivity(sdk, device, app, activity);
process.stdout.write(`Run Successful\n`);
log_1.log(`Run Successful\n`);
}

@@ -34,3 +35,3 @@ exports.run = run;

const devices = await adb_1.getDevices(sdk);
const avds = await avd_1.getAVDs(sdk);
const avds = await avd_1.getInstalledAVDs(sdk);
const target = cli_1.getOptionValue(args, '--target');

@@ -44,4 +45,3 @@ const preferEmulator = args.includes('--emulator');

else {
throw new errors_1.RunException(`Target not found: ${target}\n` +
`Use --list to select a valid target`);
throw new errors_1.RunException(`Target not found: ${target}`, errors_1.ERR_TARGET_NOT_FOUND);
}

@@ -48,0 +48,0 @@ }

@@ -6,17 +6,24 @@ "use strict";

const sdk = await sdk_1.getSDK();
const packages = await sdk_1.findAllSDKPackages(sdk);
const sdkinfo = Object.assign({}, sdk, { packages });
if (args.includes('--json')) {
process.stdout.write(JSON.stringify(sdk));
process.stdout.write(JSON.stringify(sdkinfo));
return;
}
process.stdout.write(`${formatSDK(sdk)}\n\n`);
process.stdout.write(`${formatSDKInfo(sdkinfo)}\n\n`);
}
exports.run = run;
function formatSDK(sdk) {
function formatSDKInfo(sdk) {
return `
SDK Root: ${sdk.root}
SDK Tools: ${sdk.tools.path} (${sdk.tools.version})
SDK Platform Tools: ${sdk.platformTools.path} (${sdk.platformTools.version})
Android Emulator: ${sdk.emulator.path} (${sdk.emulator.version})
AVDs Home: ${sdk.avds.home}
SDK: ${sdk.root}
${sdk.packages.map(p => formatSDKPackage(p)).join('')}
`.trim();
}
function formatSDKPackage(p) {
return `
Name: ${p.name}
Path: ${p.path}
Version: ${p.version}${p.apiLevel ? ` (API ${p.apiLevel})` : ''}
Location: ${p.location}
`;
}

@@ -5,2 +5,3 @@ "use strict";

const Debug = require("debug");
const path = require("path");
const split2 = require("split2");

@@ -10,2 +11,3 @@ const through2 = require("through2");

const process_1 = require("../../utils/process");
const sdk_1 = require("./sdk");
const modulePrefix = 'native-run:android:utils:adb';

@@ -20,6 +22,7 @@ const ADB_GETPROP_MAP = new Map([

const debug = Debug(`${modulePrefix}:${getDevices.name}`);
const adbBin = `${sdk.platformTools.path}/adb`;
const platformTools = await sdk_1.getSDKPackage(path.join(sdk.root, 'platform-tools'));
const adbBin = `${platformTools.location}/adb`;
const args = ['devices', '-l'];
debug('Invoking adb: %O %O', adbBin, args);
const { stdout } = await process_1.execFile(adbBin, args);
const { stdout } = await process_1.execFile(adbBin, args, { env: sdk_1.supplementProcessEnv(sdk) });
const devices = parseAdbDevices(stdout);

@@ -40,6 +43,7 @@ await Promise.all(devices.map(async (device) => {

const debug = Debug(`${modulePrefix}:${getDeviceProperty.name}`);
const adbBin = `${sdk.platformTools.path}/adb`;
const platformTools = await sdk_1.getSDKPackage(path.join(sdk.root, 'platform-tools'));
const adbBin = `${platformTools.location}/adb`;
const args = ['-s', device.serial, 'shell', 'getprop', property];
debug('Invoking adb: %O %O', adbBin, args);
const { stdout } = await process_1.execFile(adbBin, args);
const { stdout } = await process_1.execFile(adbBin, args, { env: sdk_1.supplementProcessEnv(sdk) });
return stdout.trim();

@@ -51,7 +55,8 @@ }

const re = /^\[([a-z0-9\.]+)\]: \[(.*)\]$/;
const adbBin = `${sdk.platformTools.path}/adb`;
const platformTools = await sdk_1.getSDKPackage(path.join(sdk.root, 'platform-tools'));
const adbBin = `${platformTools.location}/adb`;
const args = ['-s', device.serial, 'shell', 'getprop'];
debug('Invoking adb: %O %O', adbBin, args);
const propAllowList = [...ADB_GETPROP_MAP.keys()];
const { stdout } = await process_1.execFile(adbBin, args);
const { stdout } = await process_1.execFile(adbBin, args, { env: sdk_1.supplementProcessEnv(sdk) });
const properties = {};

@@ -72,6 +77,7 @@ for (const line of stdout.split('\n')) {

const debug = Debug(`${modulePrefix}:${waitForDevice.name}`);
const adbBin = `${sdk.platformTools.path}/adb`;
const platformTools = await sdk_1.getSDKPackage(path.join(sdk.root, 'platform-tools'));
const adbBin = `${platformTools.location}/adb`;
const args = ['-s', serial, 'wait-for-any-device'];
debug('Invoking adb: %O %O', adbBin, args);
await process_1.execFile(adbBin, args);
await process_1.execFile(adbBin, args, { env: sdk_1.supplementProcessEnv(sdk) });
debug('Device %s is connected to ADB!', serial);

@@ -96,6 +102,7 @@ }

const debug = Debug(`${modulePrefix}:${installApk.name}`);
const adbBin = `${sdk.platformTools.path}/adb`;
const platformTools = await sdk_1.getSDKPackage(path.join(sdk.root, 'platform-tools'));
const adbBin = `${platformTools.location}/adb`;
const args = ['-s', device.serial, 'install', '-r', '-t', apk];
debug('Invoking adb: %O %O', adbBin, args);
const p = child_process_1.spawn(adbBin, args, { stdio: 'pipe' });
const p = child_process_1.spawn(adbBin, args, { stdio: 'pipe', env: sdk_1.supplementProcessEnv(sdk) });
return new Promise((resolve, reject) => {

@@ -128,6 +135,7 @@ p.on('close', code => {

const debug = Debug(`${modulePrefix}:${uninstallApp.name}`);
const adbBin = `${sdk.platformTools.path}/adb`;
const platformTools = await sdk_1.getSDKPackage(path.join(sdk.root, 'platform-tools'));
const adbBin = `${platformTools.location}/adb`;
const args = ['-s', device.serial, 'uninstall', app];
debug('Invoking adb: %O %O', adbBin, args);
await process_1.execFile(adbBin, args);
await process_1.execFile(adbBin, args, { env: sdk_1.supplementProcessEnv(sdk) });
}

@@ -153,6 +161,7 @@ exports.uninstallApp = uninstallApp;

const debug = Debug(`${modulePrefix}:${startActivity.name}`);
const adbBin = `${sdk.platformTools.path}/adb`;
const platformTools = await sdk_1.getSDKPackage(path.join(sdk.root, 'platform-tools'));
const adbBin = `${platformTools.location}/adb`;
const args = ['-s', device.serial, 'shell', 'am', 'start', '-W', '-n', `${packageName}/${activityName}`];
debug('Invoking adb: %O %O', adbBin, args);
await process_1.execFile(adbBin, args);
await process_1.execFile(adbBin, args, { env: sdk_1.supplementProcessEnv(sdk) });
}

@@ -159,0 +168,0 @@ exports.startActivity = startActivity;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_fs_1 = require("@ionic/utils-fs");
const Debug = require("debug");
const path = require("path");
const fs_1 = require("../../utils/fs");
const pathlib = require("path");
const errors_1 = require("../../errors");
const ini_1 = require("../../utils/ini");
const object_1 = require("../../utils/object");
const sdk_1 = require("./sdk");
const modulePrefix = 'native-run:android:utils:avd';

@@ -14,12 +17,13 @@ exports.isAVDINI = (o) => o

exports.isAVDConfigINI = (o) => o
&& (typeof o.AvdId === 'undefined' || typeof o.AvdId === 'string')
&& (typeof o['avd.ini.displayname'] === 'undefined' || typeof o['avd.ini.displayname'] === 'string')
&& (typeof o['hw.lcd.density'] === 'undefined' || typeof o['hw.lcd.density'] === 'string')
&& (typeof o['hw.lcd.height'] === 'undefined' || typeof o['hw.lcd.height'] === 'string')
&& (typeof o['hw.lcd.width'] === 'undefined' || typeof o['hw.lcd.width'] === 'string');
&& (typeof o['hw.lcd.width'] === 'undefined' || typeof o['hw.lcd.width'] === 'string')
&& (typeof o['image.sysdir.1'] === 'undefined' || typeof o['image.sysdir.1'] === 'string');
async function getAVDINIs(sdk) {
const debug = Debug(`${modulePrefix}:${getAVDINIs.name}`);
const contents = await fs_1.readdir(sdk.avds.home);
const contents = await utils_fs_1.readDir(sdk.avdHome);
const iniFilePaths = contents
.filter(f => path.extname(f) === '.ini')
.map(f => path.resolve(sdk.avds.home, f));
.filter(f => pathlib.extname(f) === '.ini')
.map(f => pathlib.resolve(sdk.avdHome, f));
debug('Discovered AVD ini files: %O', iniFilePaths);

@@ -33,4 +37,4 @@ const iniFiles = await Promise.all(iniFilePaths.map(async (f) => [f, await ini_1.readINI(f, exports.isAVDINI)]));

function getAVDFromConfigINI(inipath, ini, configini) {
const inibasename = path.basename(inipath);
const id = inibasename.substring(0, inibasename.length - path.extname(inibasename).length);
const inibasename = pathlib.basename(inipath);
const id = inibasename.substring(0, inibasename.length - pathlib.extname(inibasename).length);
const name = configini['avd.ini.displayname']

@@ -54,3 +58,3 @@ ? String(configini['avd.ini.displayname'])

async function getAVDFromINI(inipath, ini) {
const configini = await ini_1.readINI(path.resolve(ini.path, 'config.ini'), exports.isAVDConfigINI);
const configini = await ini_1.readINI(pathlib.resolve(ini.path, 'config.ini'), exports.isAVDConfigINI);
if (configini) {

@@ -61,99 +65,122 @@ return getAVDFromConfigINI(inipath, ini, configini);

exports.getAVDFromINI = getAVDFromINI;
async function getAVDs(sdk) {
async function getInstalledAVDs(sdk) {
const avdInis = await getAVDINIs(sdk);
const possibleAvds = await Promise.all(avdInis.map(([inipath, ini]) => getAVDFromINI(inipath, ini)));
const avds = possibleAvds.filter((avd) => typeof avd !== 'undefined');
const defaultAvd = await getDefaultAVD(sdk, avds);
if (!avds.includes(defaultAvd)) {
avds.push(defaultAvd);
}
return avds;
}
exports.getAVDs = getAVDs;
const DEFAULT_AVD_ID = 'Pixel_2_API_28';
const DEFAULT_AVD_INI = {
'avd.ini.encoding': 'UTF-8',
'target': 'android-28',
'path.rel': `avd/${DEFAULT_AVD_ID}.avd`,
};
const DEFAULT_AVD_CONFIG_INI = {
'AvdId': DEFAULT_AVD_ID,
'abi.type': 'x86',
'avd.ini.displayname': 'Pixel 2 API 28',
'avd.ini.encoding': 'UTF-8',
'hw.accelerometer': 'yes',
'hw.audioInput': 'yes',
'hw.battery': 'yes',
'hw.camera.back': 'virtualscene',
'hw.camera.front': 'emulated',
'hw.cpu.arch': 'x86',
'hw.cpu.ncore': '4',
// 'hw.device.hash2': 'MD5:bc5032b2a871da511332401af3ac6bb0',
'hw.device.manufacturer': 'Google',
'hw.device.name': 'pixel_2',
'hw.gps': 'yes',
'hw.gpu.enabled': 'yes',
'hw.gpu.mode': 'auto',
'hw.initialOrientation': 'Portrait',
'hw.keyboard': 'yes',
'hw.lcd.density': '420',
'hw.lcd.height': '1920',
'hw.lcd.width': '1080',
'hw.ramSize': '1536',
'hw.sdCard': 'yes',
'hw.sensors.orientation': 'yes',
'hw.sensors.proximity': 'yes',
'image.sysdir.1': 'system-images/android-28/google_apis/x86/',
'sdcard.size': '100M',
'showDeviceFrame': 'yes',
'skin.dynamic': 'yes',
'skin.name': 'pixel_2',
'tag.display': 'Google APIs',
'tag.id': 'google_apis',
};
function getDefaultAVDPath(sdk) {
return path.join(sdk.avds.home, `${DEFAULT_AVD_ID}.avd`);
exports.getInstalledAVDs = getInstalledAVDs;
async function getDefaultAVDSchematic(sdk) {
const debug = Debug(`${modulePrefix}:${getDefaultAVDSchematic.name}`);
const packages = await sdk_1.findAllSDKPackages(sdk);
const apis = await sdk_1.getAPILevels(packages);
const fullAPILevels = apis.filter(api => api.full);
if (fullAPILevels.length === 0) {
throw new errors_1.AVDException('No full API installation found. Install the platform and sources of an API level.', errors_1.ERR_NO_FULL_API_INSTALLATION);
}
for (const api of fullAPILevels) {
try {
const schematic = await createAVDSchematic(sdk, api);
if (schematic) {
debug('Using schematic %s for default AVD', schematic.id);
return schematic;
}
}
catch (e) {
if (!(e instanceof errors_1.AVDException)) {
throw e;
}
debug('Issue with API %s: %s', api.level, e.message);
}
}
throw new errors_1.AVDException('No suitable API installation found.', errors_1.ERR_NO_SUITABLE_API_INSTALLATION);
}
exports.getDefaultAVDPath = getDefaultAVDPath;
function getDefaultAVDINI(sdk) {
const avdpath = getDefaultAVDPath(sdk);
return [
path.join(sdk.avds.home, `${DEFAULT_AVD_ID}.ini`),
Object.assign({ 'path': avdpath }, DEFAULT_AVD_INI),
];
}
exports.getDefaultAVDINI = getDefaultAVDINI;
function getDefaultAVDConfigINI(sdk) {
const avdpath = getDefaultAVDPath(sdk);
return [
path.join(avdpath, 'config.ini'),
Object.assign({ 'skin.path': path.join(sdk.root, 'skins', 'pixel_2') }, DEFAULT_AVD_CONFIG_INI),
];
}
exports.getDefaultAVDConfigINI = getDefaultAVDConfigINI;
exports.getDefaultAVDSchematic = getDefaultAVDSchematic;
async function getDefaultAVD(sdk, avds) {
const defaultAvd = avds.find(avd => avd.id === DEFAULT_AVD_ID);
const defaultAvdSchematic = await getDefaultAVDSchematic(sdk);
const defaultAvd = avds.find(avd => avd.id === defaultAvdSchematic.id);
if (defaultAvd) {
return defaultAvd;
}
return createDefaultAVD(sdk);
return createAVD(sdk, defaultAvdSchematic);
}
exports.getDefaultAVD = getDefaultAVD;
async function createDefaultAVD(sdk) {
const [inipath, ini] = getDefaultAVDINI(sdk);
const [configinipath, configini] = getDefaultAVDConfigINI(sdk);
await fs_1.mkdirp(path.dirname(configinipath));
const writeConfigFile = async (p, f) => {
const ini = Object.keys(f).sort().reduce((acc, k) => {
acc[k] = f[k];
return acc;
}, {});
await ini_1.writeINI(p, ini);
};
async function createAVD(sdk, schematic) {
const { id, ini, configini } = schematic;
await utils_fs_1.mkdirp(pathlib.join(sdk.avdHome, `${id}.avd`));
await Promise.all([
writeConfigFile(inipath, ini),
writeConfigFile(configinipath, configini),
ini_1.writeINI(pathlib.join(sdk.avdHome, `${id}.ini`), ini),
ini_1.writeINI(pathlib.join(sdk.avdHome, `${id}.avd`, 'config.ini'), configini),
]);
return getAVDFromConfigINI(inipath, ini, configini);
return getAVDFromConfigINI(pathlib.join(sdk.avdHome, `${id}.ini`), ini, configini);
}
exports.createDefaultAVD = createDefaultAVD;
exports.createAVD = createAVD;
async function loadPartialSchematic(api) {
if (api.level === '28') {
return Promise.resolve().then(() => require('../data/avds/Pixel_2_API_28.json'));
}
else if (api.level === '27') {
return Promise.resolve().then(() => require('../data/avds/Pixel_2_API_27.json'));
}
else if (api.level === '26') {
return Promise.resolve().then(() => require('../data/avds/Pixel_2_API_26.json'));
}
else if (api.level === '25') {
return Promise.resolve().then(() => require('../data/avds/Pixel_API_25.json'));
}
else if (api.level === '24') {
return Promise.resolve().then(() => require('../data/avds/Nexus_5X_API_24.json'));
}
throw new errors_1.AVDException(`Unsupported API level: ${api.level}`, errors_1.ERR_UNSUPPORTED_API_LEVEL);
}
exports.loadPartialSchematic = loadPartialSchematic;
async function createAVDSchematic(sdk, api) {
const debug = Debug(`${modulePrefix}:${createAVDSchematic.name}`);
debug('Attempting to build AVD schematic for API %s', api.level);
const partialSchematic = await loadPartialSchematic(api);
debug('Schematic %s matches', partialSchematic.id);
const avdpath = pathlib.join(sdk.avdHome, `${partialSchematic.id}.avd`);
const skinpath = getSkinPathByName(sdk, partialSchematic.configini['skin.name']);
const schematic = {
id: partialSchematic.id,
ini: object_1.sort(Object.assign({}, partialSchematic.ini, { 'path': avdpath, 'path.rel': `avd/${partialSchematic.id}.avd` })),
configini: object_1.sort(Object.assign({}, partialSchematic.configini, { 'skin.path': skinpath })),
};
await validateAVDSchematic(sdk, schematic);
return schematic;
}
exports.createAVDSchematic = createAVDSchematic;
async function validateAVDSchematic(sdk, schematic) {
const { configini } = schematic;
const skinpath = configini['skin.path'];
const sysdir = configini['image.sysdir.1'];
if (!skinpath) {
throw new errors_1.AVDException(`${schematic.id} does not have a skin defined.`, errors_1.ERR_INVALID_SKIN);
}
if (!sysdir) {
throw new errors_1.AVDException(`${schematic.id} does not have a system image defined.`, errors_1.ERR_INVALID_SYSTEM_IMAGE);
}
await validateSkinPath(skinpath);
await validateSystemImagePath(sdk, sysdir);
}
exports.validateAVDSchematic = validateAVDSchematic;
async function validateSkinPath(skinpath) {
const stat = await utils_fs_1.statSafe(pathlib.join(skinpath, 'layout'));
if (!stat || !stat.isFile()) {
throw new errors_1.AVDException(`${skinpath} is an invalid skin.`, errors_1.ERR_INVALID_SKIN);
}
}
exports.validateSkinPath = validateSkinPath;
async function validateSystemImagePath(sdk, sysdir) {
const p = pathlib.join(sdk.root, sysdir, 'package.xml');
const stat = await utils_fs_1.statSafe(p);
if (!stat || !stat.isFile()) {
throw new errors_1.AVDException(`${p} is an invalid system image package.`, errors_1.ERR_INVALID_SYSTEM_IMAGE);
}
}
exports.validateSystemImagePath = validateSystemImagePath;
function getSkinPathByName(sdk, name) {
const path = pathlib.join(sdk.root, 'skins', name);
return path;
}
exports.getSkinPathByName = getSkinPathByName;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_fs_1 = require("@ionic/utils-fs");
const child_process_1 = require("child_process");

@@ -11,4 +12,5 @@ const Debug = require("debug");

const errors_1 = require("../../errors");
const fs_1 = require("../../utils/fs");
const fn_1 = require("../../utils/fn");
const adb_1 = require("./adb");
const sdk_1 = require("./sdk");
const modulePrefix = 'native-run:android:utils:emulator';

@@ -38,10 +40,11 @@ /**

const debug = Debug(`${modulePrefix}:${spawnEmulator.name}`);
const emulatorBin = `${sdk.emulator.path}/emulator`;
const args = ['-avd', avd.id, '-port', port.toString()];
const emulator = await sdk_1.getSDKPackage(path.join(sdk.root, 'emulator'));
const emulatorBin = `${emulator.location}/emulator`;
const args = ['-avd', avd.id, '-port', port.toString(), '-verbose'];
debug('Invoking emulator: %O %O', emulatorBin, args);
const p = child_process_1.spawn(emulatorBin, args, { detached: true, stdio: ['ignore', 'pipe', 'pipe'] });
const p = child_process_1.spawn(emulatorBin, args, { detached: true, stdio: ['ignore', 'pipe', 'pipe'], env: sdk_1.supplementProcessEnv(sdk) });
p.unref();
return new Promise((_resolve, _reject) => {
const resolve = () => { _resolve(); cleanup(); };
const reject = err => { _reject(err); cleanup(); };
const resolve = fn_1.once(() => { _resolve(); cleanup(); });
const reject = fn_1.once(err => { _reject(err); cleanup(); });
adb_1.waitForDevice(sdk, `emulator-${port}`).then(() => resolve(), err => reject(err));

@@ -124,3 +127,3 @@ const eventParser = through2((chunk, enc, cb) => {

debug('Connected to %s:%d', host, port);
fs_1.readFile(path.resolve(os.homedir(), '.emulator_console_auth_token'), 'utf8')
utils_fs_1.readFile(path.resolve(os.homedir(), '.emulator_console_auth_token'), { encoding: 'utf8' })
.then(contents => resolve(contents.trim()), err => reject(err));

@@ -144,6 +147,6 @@ });

}, 3000);
const cleanup = () => {
const cleanup = fn_1.once(() => {
clearTimeout(timer);
sock.end();
};
});
sock.on('timeout', () => {

@@ -150,0 +153,0 @@ reject(new errors_1.EmulatorException(`Socket timeout on ${host}:${port}`));

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_fs_1 = require("@ionic/utils-fs");
const Debug = require("debug");
const os = require("os");
const path = require("path");
const fs_1 = require("../../utils/fs");
const properties_1 = require("./properties");
const pathlib = require("path");
const errors_1 = require("../../errors");
const modulePrefix = 'native-run:android:utils:sdk';
const homedir = os.homedir();
const SDK_DIRECTORIES = new Map([
['darwin', [pathlib.join(homedir, 'Library', 'Android', 'sdk')]],
['linux', [pathlib.join(homedir, 'Android', 'sdk')]],
['win32', [pathlib.join('%LOCALAPPDATA%', 'Android', 'sdk')]],
]);
async function getSDK() {
const debug = Debug(`${modulePrefix}:${getSDK.name}`);
const root = await resolveSDKRoot();
// TODO: validate root and resolve source.properties
const [toolsPath, platformToolsPath, emulatorPath, avdHome,] = await Promise.all([
resolveToolsPath(root),
resolvePlatformToolsPath(root),
resolveEmulatorPath(root),
resolveAVDHome(root),
]);
const [toolsVersion, platformToolsVersion, emulatorVersion,] = await Promise.all([
getAndroidPackageVersion(toolsPath),
getAndroidPackageVersion(platformToolsPath),
getAndroidPackageVersion(emulatorPath),
]);
const sdk = {
root,
tools: {
path: toolsPath,
version: toolsVersion,
const emulatorHome = await resolveEmulatorHome();
const avdHome = await resolveAVDHome();
return { root, emulatorHome, avdHome };
}
exports.getSDK = getSDK;
async function getAPILevels(packages) {
const debug = Debug(`${modulePrefix}:${getAPILevels.name}`);
const levels = [
...new Set(packages
.map(pkg => pkg.apiLevel)
.filter((apiLevel) => typeof apiLevel !== 'undefined')),
].sort((a, b) => a <= b ? 1 : -1);
debug('Discovered installed API Levels: %O', levels);
return levels.map(level => {
const pkgs = packages.filter(pkg => pkg.apiLevel === level);
const full = Boolean(pkgs.find(pkg => pkg.path === `platforms;android-${level}`) &&
pkgs.find(pkg => pkg.path === `sources;android-${level}`));
return {
level,
packages: pkgs,
full,
};
});
}
exports.getAPILevels = getAPILevels;
const pkgcache = new Map();
async function findAllSDKPackages(sdk) {
const debug = Debug(`${modulePrefix}:${findAllSDKPackages.name}`);
if (sdk.packages) {
return sdk.packages;
}
const sourcesRe = /^sources\/android-\d+\/.+\/.+/;
debug('Walking %s to discover SDK packages', sdk.root);
const contents = await utils_fs_1.readDirp(sdk.root, {
filter: item => pathlib.basename(item.path) === 'package.xml',
walkerOptions: {
pathFilter: p => {
if ([
'bin',
'bin64',
'lib',
'lib64',
'include',
'clang-include',
'skins',
'data',
'examples',
'resources',
'systrace',
'extras',
].includes(pathlib.basename(p))) {
return false;
}
if (p.match(sourcesRe)) {
return false;
}
return true;
},
},
platformTools: {
path: platformToolsPath,
version: platformToolsVersion,
},
emulator: {
path: emulatorPath,
version: emulatorVersion,
},
avds: {
home: avdHome,
},
};
debug('SDK info:\n%O', sdk);
return sdk;
});
sdk.packages = await Promise.all(contents
.map(p => pathlib.dirname(p))
.map(p => getSDKPackage(p)));
sdk.packages.sort((a, b) => a.name >= b.name ? 1 : -1);
return sdk.packages;
}
exports.getSDK = getSDK;
exports.findAllSDKPackages = findAllSDKPackages;
async function getSDKPackage(location) {
const debug = Debug(`${modulePrefix}:${getSDKPackage.name}`);
let pkg = pkgcache.get(location);
if (!pkg) {
const packageXmlPath = pathlib.join(location, 'package.xml');
debug('Parsing %s', packageXmlPath);
try {
const packageXml = await readPackageXml(packageXmlPath);
const name = getNameFromPackageXml(packageXml);
const version = getVersionFromPackageXml(packageXml);
const path = getPathFromPackageXml(packageXml);
const apiLevel = getAPILevelFromPackageXml(packageXml);
pkg = {
path,
location,
version,
name,
apiLevel,
};
}
catch (e) {
debug('Encountered error with %s: %O', packageXmlPath, e);
if (e.code === 'ENOENT') {
throw new errors_1.SDKException(`SDK package not found by location: ${location}.`, errors_1.ERR_SDK_PACKAGE_NOT_FOUND);
}
throw e;
}
pkgcache.set(location, pkg);
}
return pkg;
}
exports.getSDKPackage = getSDKPackage;
async function readPackageXml(path) {
const et = await Promise.resolve().then(() => require('elementtree'));
const contents = await utils_fs_1.readFile(path, { encoding: 'utf8' });
const etree = et.parse(contents);
return etree;
}
exports.readPackageXml = readPackageXml;
function getPathFromPackageXml(packageXml) {
const localPackage = packageXml.find('./localPackage');
if (!localPackage) {
throw new errors_1.SDKException(`Invalid SDK package.`, errors_1.ERR_INVALID_SDK_PACKAGE);
}
const path = localPackage.get('path');
if (!path) {
throw new errors_1.SDKException(`Invalid SDK package path.`, errors_1.ERR_INVALID_SDK_PACKAGE);
}
return path.toString();
}
exports.getPathFromPackageXml = getPathFromPackageXml;
function getAPILevelFromPackageXml(packageXml) {
const apiLevel = packageXml.find('./localPackage/type-details/api-level');
return apiLevel && apiLevel.text ? apiLevel.text.toString() : undefined;
}
exports.getAPILevelFromPackageXml = getAPILevelFromPackageXml;
function getNameFromPackageXml(packageXml) {
const name = packageXml.find('./localPackage/display-name');
if (!name || !name.text) {
throw new errors_1.SDKException(`Invalid SDK package name.`, errors_1.ERR_INVALID_SDK_PACKAGE);
}
return name.text.toString();
}
exports.getNameFromPackageXml = getNameFromPackageXml;
function getVersionFromPackageXml(packageXml) {
const versionElements = [
packageXml.find('./localPackage/revision/major'),
packageXml.find('./localPackage/revision/minor'),
packageXml.find('./localPackage/revision/micro'),
];
const textFromElement = (e) => e && e.text ? e.text.toString() : '';
const versions = [];
for (const version of versionElements.map(textFromElement)) {
if (!version) {
break;
}
versions.push(version);
}
if (versions.length === 0) {
throw new errors_1.SDKException(`Invalid SDK package version.`, errors_1.ERR_INVALID_SDK_PACKAGE);
}
return versions.join('.');
}
exports.getVersionFromPackageXml = getVersionFromPackageXml;
async function resolveSDKRoot() {

@@ -52,3 +173,3 @@ const debug = Debug(`${modulePrefix}:${resolveSDKRoot.name}`);

// defined and valid.
if (process.env.ANDROID_HOME && await fs_1.isDir(process.env.ANDROID_HOME)) {
if (process.env.ANDROID_HOME && await utils_fs_1.isDir(process.env.ANDROID_HOME)) {
debug('Using $ANDROID_HOME at %s', process.env.ANDROID_HOME);

@@ -59,75 +180,57 @@ return process.env.ANDROID_HOME;

// No valid $ANDROID_HOME, try $ANDROID_SDK_ROOT.
if (process.env.ANDROID_SDK_ROOT && await fs_1.isDir(process.env.ANDROID_SDK_ROOT)) {
if (process.env.ANDROID_SDK_ROOT && await utils_fs_1.isDir(process.env.ANDROID_SDK_ROOT)) {
debug('Using $ANDROID_SDK_ROOT at %s', process.env.ANDROID_SDK_ROOT);
return process.env.ANDROID_SDK_ROOT;
}
// TODO: No valid $ANDROID_SDK_ROOT, try searching common SDK directories.
throw new Error(`No valid Android SDK root found.`);
}
exports.resolveSDKRoot = resolveSDKRoot;
async function resolveToolsPath(root) {
const debug = Debug(`${modulePrefix}:${resolveToolsPath.name}`);
const p = path.join(root, 'tools');
debug('Looking at %s for tools path', p);
if (await fs_1.isDir(p)) {
debug('Using %s', p);
return p;
const sdkDirs = SDK_DIRECTORIES.get(process.platform);
if (!sdkDirs) {
throw new errors_1.SDKException(`Unsupported platform: ${process.platform}`);
}
throw new Error(`No valid Android SDK Tools path found.`);
}
exports.resolveToolsPath = resolveToolsPath;
async function resolvePlatformToolsPath(root) {
const debug = Debug(`${modulePrefix}:${resolvePlatformToolsPath.name}`);
const p = path.join(root, 'platform-tools');
debug('Looking at %s for platform-tools path', p);
if (await fs_1.isDir(p)) {
debug('Using %s', p);
return p;
}
throw new Error(`No valid Android SDK Platform Tools path found.`);
}
exports.resolvePlatformToolsPath = resolvePlatformToolsPath;
async function resolveEmulatorPath(root) {
const debug = Debug(`${modulePrefix}:${resolveEmulatorPath.name}`);
// The emulator was separated out from tools as of 25.3.0 (March 2017)
const paths = [path.join(root, 'emulator'), path.join(root, 'tools')];
for (const p of paths) {
debug('Looking at %s for emulator path', p);
if (await fs_1.isDir(p)) {
debug('Using %s', p);
return p;
debug('Looking at following directories: %O', sdkDirs);
for (const sdkDir of sdkDirs) {
if (await utils_fs_1.isDir(sdkDir)) {
debug('Using %s', sdkDir);
return sdkDir;
}
}
throw new Error(`No valid Android Emulator path found.`);
throw new errors_1.SDKException(`No valid Android SDK root found.`, errors_1.ERR_SDK_NOT_FOUND);
}
exports.resolveEmulatorPath = resolveEmulatorPath;
exports.isAndroidPackage = (o) => o && typeof o['Pkg.Revision'] === 'string';
async function getAndroidPackageVersion(pkgPath) {
const sourcePropsPath = path.resolve(pkgPath, 'source.properties');
const sourceProps = await properties_1.readProperties(sourcePropsPath, exports.isAndroidPackage);
if (!sourceProps) {
throw new Error(`Invalid package file: ${sourcePropsPath}`);
exports.resolveSDKRoot = resolveSDKRoot;
async function resolveEmulatorHome() {
const debug = Debug(`${modulePrefix}:${resolveEmulatorHome.name}`);
debug('Looking for $ANDROID_EMULATOR_HOME');
// Try $ANDROID_EMULATOR_HOME
if (process.env.ANDROID_EMULATOR_HOME && await utils_fs_1.isDir(process.env.ANDROID_EMULATOR_HOME)) {
debug('Using $ANDROID_EMULATOR_HOME at %s', process.env.$ANDROID_EMULATOR_HOME);
return process.env.ANDROID_EMULATOR_HOME;
}
return sourceProps['Pkg.Revision'];
// Try $HOME/.android/
const homeEmulatorHome = pathlib.join(homedir, '.android');
if (await utils_fs_1.isDir(homeEmulatorHome)) {
debug('Using $HOME/.android/ at %s', homeEmulatorHome);
return homeEmulatorHome;
}
throw new errors_1.SDKException(`No valid Android Emulator home found.`, errors_1.ERR_EMULATOR_HOME_NOT_FOUND);
}
exports.getAndroidPackageVersion = getAndroidPackageVersion;
async function resolveAVDHome(root) {
exports.resolveEmulatorHome = resolveEmulatorHome;
async function resolveAVDHome() {
const debug = Debug(`${modulePrefix}:${resolveAVDHome.name}`);
debug('Looking for $ANDROID_AVD_HOME');
// Try $ANDROID_AVD_HOME
if (process.env.ANDROID_AVD_HOME && await fs_1.isDir(process.env.ANDROID_AVD_HOME)) {
if (process.env.ANDROID_AVD_HOME && await utils_fs_1.isDir(process.env.ANDROID_AVD_HOME)) {
debug('Using $ANDROID_AVD_HOME at %s', process.env.$ANDROID_AVD_HOME);
return process.env.ANDROID_AVD_HOME;
}
// Try $ANDROID_SDK_ROOT/.android/avd/ and then $HOME/.android/avd/
const paths = [path.join(root, '.android', 'avd'), path.join(homedir, '.android', 'avd')];
for (const p of paths) {
debug('Looking at %s for AVD home', p);
if (await fs_1.isDir(p)) {
debug('Using %s', p);
return p;
}
// Try $HOME/.android/avd/
const homeAvdHome = pathlib.join(homedir, '.android', 'avd');
if (await utils_fs_1.isDir(homeAvdHome)) {
debug('Using $HOME/.android/avd/ at %s', homeAvdHome);
return homeAvdHome;
}
throw new Error(`No valid Android AVD root found.`);
throw new errors_1.SDKException(`No valid Android AVD home found.`, errors_1.ERR_AVD_HOME_NOT_FOUND);
}
exports.resolveAVDHome = resolveAVDHome;
function supplementProcessEnv(sdk) {
return Object.assign({}, process.env, { ANDROID_SDK_ROOT: sdk.root, ANDROID_EMULATOR_HOME: sdk.emulatorHome, ANDROID_AVD_HOME: sdk.avdHome });
}
exports.supplementProcessEnv = supplementProcessEnv;

@@ -14,10 +14,23 @@ "use strict";

exports.ERR_AVD_HOME_NOT_FOUND = 'ERR_AVD_HOME_NOT_FOUND';
exports.ERR_EMULATOR_HOME_NOT_FOUND = 'ERR_EMULATOR_HOME_NOT_FOUND';
exports.ERR_INCOMPATIBLE_UPDATE = 'ERR_INCOMPATIBLE_UPDATE';
exports.ERR_INVALID_SDK_PACKAGE = 'ERR_INVALID_SDK_PACKAGE';
exports.ERR_INVALID_SERIAL = 'ERR_INVALID_SERIAL';
exports.ERR_INVALID_SKIN = 'ERR_INVALID_SKIN';
exports.ERR_INVALID_SYSTEM_IMAGE = 'ERR_INVALID_SYSTEM_IMAGE';
exports.ERR_NON_ZERO_EXIT = 'ERR_NON_ZERO_EXIT';
exports.ERR_NO_AVDS_FOUND = 'ERR_NO_AVDS_FOUND';
exports.ERR_NO_FULL_API_INSTALLATION = 'ERR_NO_FULL_API_INSTALLATION';
exports.ERR_NO_SUITABLE_API_INSTALLATION = 'ERR_NO_SUITABLE_API_INSTALLATION';
exports.ERR_SDK_NOT_FOUND = 'ERR_SDK_NOT_FOUND';
exports.ERR_SDK_PACKAGE_NOT_FOUND = 'ERR_SDK_PACKAGE_NOT_FOUND';
exports.ERR_TARGET_NOT_FOUND = 'ERR_TARGET_NOT_FOUND';
exports.ERR_UNKNOWN_AVD = 'ERR_UNKNOWN_AVD';
exports.ERR_INVALID_SERIAL = 'ERR_INVALID_SERIAL';
exports.ERR_UNSUPPORTED_API_LEVEL = 'ERR_UNSUPPORTED_API_LEVEL';
class ADBException extends Exception {
}
exports.ADBException = ADBException;
class AVDException extends Exception {
}
exports.AVDException = AVDException;
class EmulatorException extends Exception {

@@ -29,1 +42,4 @@ }

exports.RunException = RunException;
class SDKException extends Exception {
}
exports.SDKException = SDKException;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Debug = require("debug");
const path = require("path");
const errors_1 = require("./errors");

@@ -9,3 +10,3 @@ const debug = Debug('native-run');

if (args.includes('--version')) {
const pkg = require('../package.json');
const pkg = await Promise.resolve().then(() => require(path.resolve(__dirname, '../package.json')));
process.stdout.write(pkg.version + '\n');

@@ -33,13 +34,22 @@ return;

catch (e) {
if (e instanceof errors_1.Exception) {
process.stderr.write(`${e.message}\n`);
process.exitCode = e.exitCode;
}
else {
debug('Caught fatal error: %O', e);
process.stderr.write(String(e.stack ? e.stack : e));
process.exitCode = 1;
}
debug('Caught fatal error: %O', e);
process.exitCode = e instanceof errors_1.Exception ? e.exitCode : 1;
process.stdout.write(serializeError(e));
}
}
exports.run = run;
function serializeError(e) {
let error;
let code;
if (e instanceof errors_1.Exception) {
error = e.message;
code = e.code;
}
else {
error = String(e.stack ? e.stack : e);
}
if (process.argv.includes('--json')) {
return JSON.stringify({ error, code });
}
return `${code ? code : 'ERR_UNKNOWN'}: ${error}\n`;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_fs_1 = require("@ionic/utils-fs");
const path_1 = require("path");
const cli_1 = require("../utils/cli");
const fs_1 = require("../utils/fs");
const process_1 = require("../utils/process");

@@ -21,3 +21,3 @@ const list_1 = require("./list");

const developerDiskImagePath = await getDeveloperDiskImagePath(version, xCodePath);
if (!fs_1.safeStat(developerDiskImagePath)) {
if (!utils_fs_1.statSafe(developerDiskImagePath)) {
throw new Error(`No Developer Disk Image found for SDK ${version} at\n${developerDiskImagePath}.`);

@@ -73,3 +73,3 @@ }

try {
const versionDirs = await fs_1.readdir(`${xCodePath}/Platforms/iPhoneOS.platform/DeviceSupport/`);
const versionDirs = await utils_fs_1.readDir(`${xCodePath}/Platforms/iPhoneOS.platform/DeviceSupport/`);
// Can look like "11.2 (15C107)"

@@ -76,0 +76,0 @@ for (const dir of versionDirs) {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_fs_1 = require("@ionic/utils-fs");
const Debug = require("debug");
const util = require("util");
const fs_1 = require("./fs");
const debug = Debug('native-run:android:utils:ini');

@@ -10,3 +10,3 @@ async function readINI(p, guard = (o) => true) {

try {
const contents = await fs_1.readFile(p, 'utf8');
const contents = await utils_fs_1.readFile(p, { encoding: 'utf8' });
const config = ini.decode(contents);

@@ -28,4 +28,4 @@ if (!guard(config)) {

const contents = ini.encode(o);
await fs_1.writeFile(p, contents, 'utf8');
await utils_fs_1.writeFile(p, contents, { encoding: 'utf8' });
}
exports.writeINI = writeINI;
{
"name": "native-run",
"version": "0.0.1",
"version": "0.0.2",
"description": "A CLI for running apps on iOS/Android devices and simulators/emulators",

@@ -30,3 +30,5 @@ "bin": {

"dependencies": {
"@ionic/utils-fs": "0.0.1",
"debug": "^3.1.0",
"elementtree": "^0.1.7",
"ini": "^1.3.5",

@@ -40,2 +42,3 @@ "split2": "^3.0.0",

"@types/ini": "^1.3.29",
"@types/ncp": "^2.0.1",
"@types/node": "~8.9.0",

@@ -49,3 +52,3 @@ "@types/split2": "^2.1.6",

"tslint": "^5.11.0",
"tslint-ionic-rules": "0.0.17",
"tslint-ionic-rules": "0.0.18",
"typescript": "^3.0.1"

@@ -52,0 +55,0 @@ },

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc