UNPKG

nativescript

Version:

Command-line interface for building NativeScript projects

194 lines • 9.7 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ITMSTransporterService = void 0; const path = require("path"); const constants_1 = require("../constants"); const helpers_1 = require("../common/helpers"); const decorators_1 = require("../common/decorators"); const yok_1 = require("../common/yok"); class ITMSTransporterService { constructor($applePortalApplicationService, $childProcess, $errors, $fs, $injector, $logger, $plistParser, $xcodeSelectService, $tempService) { this.$applePortalApplicationService = $applePortalApplicationService; this.$childProcess = $childProcess; this.$errors = $errors; this.$fs = $fs; this.$injector = $injector; this.$logger = $logger; this.$plistParser = $plistParser; this.$xcodeSelectService = $xcodeSelectService; this.$tempService = $tempService; } get $projectData() { return this.$injector.resolve("projectData"); } async validate(appSpecificPassword) { const itmsTransporterPath = await this.getITMSTransporterPath(); const version = await this.$xcodeSelectService.getXcodeVersion(); if (+version.major < 14) { if (!this.$fs.exists(itmsTransporterPath)) { this.$errors.fail("iTMS Transporter not found on this machine - make sure your Xcode installation is not damaged."); } } else { const altoolPath = await this.getAltoolPath(); if (!this.$fs.exists(altoolPath)) { this.$errors.fail("altool not found on this machine - make sure your Xcode installation is not damaged."); } if (!appSpecificPassword) { this.$errors.fail("An app-specific password is required from xCode versions 14 and above, Use the --appleApplicationSpecificPassword to supply it."); } } } async upload(data) { const version = await this.$xcodeSelectService.getXcodeVersion(); if (+version.major < 14) { await this.upload_iTMSTransporter(data); } else { await this.upload_altool(data); } } async upload_iTMSTransporter(data) { const itmsTransporterPath = await this.getITMSTransporterPath(); const ipaFileName = "app.ipa"; const itmsDirectory = await this.$tempService.mkdirSync("itms-"); const innerDirectory = path.join(itmsDirectory, "mybundle.itmsp"); const ipaFileLocation = path.join(innerDirectory, ipaFileName); const loggingLevel = data.verboseLogging ? constants_1.ITMSConstants.VerboseLoggingLevels.Verbose : constants_1.ITMSConstants.VerboseLoggingLevels.Informational; const bundleId = await this.getBundleIdentifier(data); const application = await this.$applePortalApplicationService.getApplicationByBundleId(data.user, bundleId); this.$fs.createDirectory(innerDirectory); this.$fs.copyFile(data.ipaFilePath, ipaFileLocation); const ipaFileHash = await this.$fs.getFileShasum(ipaFileLocation, { algorithm: "md5", }); const ipaFileSize = this.$fs.getFileSize(ipaFileLocation); const metadata = this.getITMSMetadataXml(application.adamId, ipaFileName, ipaFileHash, ipaFileSize); this.$fs.writeFile(path.join(innerDirectory, constants_1.ITMSConstants.ApplicationMetadataFile), metadata); const password = data.user.isTwoFactorAuthenticationEnabled ? data.applicationSpecificPassword : data.credentials.password; await this.$childProcess.spawnFromEvent(itmsTransporterPath, [ "-m", "upload", "-f", itmsDirectory, "-u", (0, helpers_1.quoteString)(data.credentials.username), "-p", (0, helpers_1.quoteString)(password), "-v", loggingLevel, ], "close", { stdio: "inherit" }); } async upload_altool(data) { const altoolPath = await this.getAltoolPath(); const ipaFileName = "app.ipa"; const itmsDirectory = await this.$tempService.mkdirSync("itms-"); const innerDirectory = path.join(itmsDirectory, "mybundle.itmsp"); const ipaFileLocation = path.join(innerDirectory, ipaFileName); this.$fs.createDirectory(innerDirectory); this.$fs.copyFile(data.ipaFilePath, ipaFileLocation); const password = data.applicationSpecificPassword; const args = [ "--upload-app", "-t", "ios", "-f", ipaFileLocation, "-u", data.credentials.username, "-p", password, "-k 100000", ]; if (data.teamId) { args.push("--asc-provider"); args.push(data.teamId); } if (data.verboseLogging) { args.push("--verbose"); } await this.$childProcess.spawnFromEvent(altoolPath, args, "close", { stdio: "inherit", }); } async getBundleIdentifier(data) { const { shouldExtractIpa, ipaFilePath } = data; if (shouldExtractIpa) { if (!this.$fs.exists(ipaFilePath) || path.extname(ipaFilePath) !== ".ipa") { this.$errors.fail(`Cannot use specified ipa file ${ipaFilePath}. File either does not exist or is not an ipa file.`); } this.$logger.trace("--ipa set - extracting .ipa file to get app's bundle identifier"); const destinationDir = await this.$tempService.mkdirSync("ipa-"); await this.$fs.unzip(ipaFilePath, destinationDir); const payloadDir = path.join(destinationDir, "Payload"); let allFiles = this.$fs.readDirectory(payloadDir); this.$logger.trace("ITMSTransporter .ipa Payload files:"); allFiles.forEach((f) => this.$logger.trace(" - " + f)); allFiles = allFiles.filter((f) => path.extname(f).toLowerCase() === ".app"); if (allFiles.length > 1) { this.$errors.fail("In the .ipa the ITMSTransporter is uploading there is more than one .app file. We don't know which one to upload."); } else if (allFiles.length <= 0) { this.$errors.fail("In the .ipa the ITMSTransporter is uploading there must be at least one .app file."); } const appFile = path.join(payloadDir, allFiles[0]); const plistObject = await this.$plistParser.parseFile(path.join(appFile, constants_1.INFO_PLIST_FILE_NAME)); const bundleId = plistObject && plistObject.CFBundleIdentifier; if (!bundleId) { this.$errors.fail(`Unable to determine bundle identifier from ${ipaFilePath}.`); } this.$logger.trace(`bundle identifier determined to be ${bundleId}`); return bundleId; } return this.$projectData.projectIdentifiers.ios; } async getAltoolPath() { const xcodePath = await this.$xcodeSelectService.getContentsDirectoryPath(); let itmsTransporterPath = path.join(xcodePath, "..", "Contents", "Developer", "usr", "bin", constants_1.ITMSConstants.altoolExecutableName); return itmsTransporterPath; } async getITMSTransporterPath() { const xcodePath = await this.$xcodeSelectService.getContentsDirectoryPath(); let itmsTransporterPath = path.join(xcodePath, "..", "Contents", "SharedFrameworks", "ContentDeliveryServices.framework", "Versions", "A", "itms", "bin", constants_1.ITMSConstants.iTMSExecutableName); const xcodeVersionData = await this.$xcodeSelectService.getXcodeVersion(); if (+xcodeVersionData.major < 11) { const loaderAppContentsPath = path.join(xcodePath, "Applications", "Application Loader.app", "Contents"); itmsTransporterPath = path.join(loaderAppContentsPath, constants_1.ITMSConstants.iTMSDirectoryName, "bin", constants_1.ITMSConstants.iTMSExecutableName); } return itmsTransporterPath; } getITMSMetadataXml(appleId, ipaFileName, ipaFileHash, ipaFileSize) { return `<?xml version="1.0" encoding="UTF-8"?> <package version="software4.7" xmlns="http://apple.com/itunes/importer"> <software_assets apple_id="${appleId}"> <asset type="bundle"> <data_file> <file_name>${ipaFileName}</file_name> <checksum type="md5">${ipaFileHash}</checksum> <size>${ipaFileSize}</size> </data_file> </asset> </software_assets> </package>`; } } exports.ITMSTransporterService = ITMSTransporterService; __decorate([ (0, decorators_1.cache)() ], ITMSTransporterService.prototype, "getAltoolPath", null); __decorate([ (0, decorators_1.cache)() ], ITMSTransporterService.prototype, "getITMSTransporterPath", null); yok_1.injector.register("itmsTransporterService", ITMSTransporterService); //# sourceMappingURL=itmstransporter-service.js.map