UNPKG

4.61 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const env_1 = require("./env");
4const fs_1 = require("./fs");
5const util_1 = require("util");
6const apple = require('app-store-scraper');
7const google = require('google-play-scraper');
8const { parseString } = require('xml2js');
9const parseXml = util_1.promisify(parseString);
10const Analytics = require('analytics-node');
11async function scrapeApp(ionicConfig, packageJson, codeDir) {
12 const segmentKey = env_1.env.require('SEGMENT_WRITE_KEY');
13 const userId = env_1.env.require('IONIC_USER_ID');
14 const appId = env_1.env.require('APP_ID');
15 const analytics = new Analytics(segmentKey);
16 const flush = util_1.promisify(analytics.flush.bind(analytics));
17 const configXml = await readXml(`${codeDir}/config.xml`);
18 const appData = { appId: appId };
19 appData.ionic_type = ionicConfig.type;
20 const deps = packageJson.dependencies;
21 if (deps) {
22 appData.pro_client_version = hardVersion(deps['@ionic/pro']);
23 appData.ionic_angular_version = hardVersion(deps['ionic-angular']);
24 appData.cordova_ionic_version = hardVersion(deps['cordova-plugin-ionic']);
25 }
26 let appStoreInfo;
27 let playStoreInfo;
28 if (configXml && configXml.widget) {
29 if (configXml.widget.$ && configXml.widget.$) {
30 appStoreInfo = await scrapeApple(configXml.widget.$);
31 Object.assign(appData, appStoreInfo);
32 playStoreInfo = await scrapeGoogle(configXml.widget.$);
33 Object.assign(appData, playStoreInfo);
34 }
35 if (configXml.widget.plugin) {
36 appData.plugins = configXml.widget.plugin.map((x) => x.$.name).join();
37 }
38 }
39 analytics.track({
40 userId: userId,
41 event: 'Ionic App Info',
42 properties: appData
43 });
44 await flush();
45}
46exports.scrapeApp = scrapeApp;
47function hardVersion(semver) {
48 if (semver) {
49 return semver.split('.').map((s) => s.replace(/\D/g, '')).join('.');
50 }
51}
52function processApple(obj) {
53 let info = { ios_store: false };
54 if (!obj) {
55 return info;
56 }
57 info.ios_store = true;
58 info.ios_id = obj.id;
59 info.ios_bundle_id = obj.appId;
60 info.ios_title = obj.title;
61 info.ios_url = obj.url;
62 info.ios_description = obj.description;
63 info.ios_genre = obj.primaryGenre;
64 info.ios_required_os_version = obj.requiredOsVersion;
65 info.ios_released = new Date(obj.released);
66 info.ios_updated = new Date(obj.updated);
67 info.ios_version = obj.version;
68 info.ios_free = obj.free;
69 info.ios_developer_website = obj.developerWebsite;
70 info.ios_developer_url = obj.developerUrl;
71 return info;
72}
73function processGoogle(obj) {
74 let info = { play_store: false };
75 if (!obj) {
76 return info;
77 }
78 info.play_store = true;
79 info.play_title = obj.title;
80 info.play_url = obj.url;
81 info.play_bundle_id = obj.appId;
82 info.play_free = obj.free;
83 info.play_summary = obj.summary;
84 info.play_min_installs = obj.minInstalls;
85 info.play_max_installs = obj.maxInstalls;
86 info.play_score = obj.score;
87 info.play_developer_website = obj.developerWebsite;
88 info.play_developer_email = obj.developerEmail;
89 info.play_developer = obj.developer;
90 info.play_updated = new Date(obj.updated);
91 info.play_version = obj.version;
92 info.play_genre = obj.genre;
93 info.play_required_android_version = obj.androidVersion;
94 info.play_description = obj.description;
95 return info;
96}
97async function scrapeApple(widget) {
98 let bundleId = widget['ios-CFBundleIdentifier'] || widget['id'];
99 if (!bundleId || bundleId === 'io.ionic.starter')
100 return processApple();
101 try {
102 let appleInfo = await apple.app({ appId: bundleId });
103 return processApple(appleInfo);
104 }
105 catch (e) {
106 return processApple();
107 }
108}
109async function scrapeGoogle(widget) {
110 let bundleId = widget['android-packageName'] || widget['id'];
111 if (!bundleId || bundleId === 'io.ionic.starter')
112 return processApple();
113 if (!bundleId)
114 return processGoogle();
115 try {
116 let googleInfo = await google.app({ appId: bundleId });
117 return processGoogle(googleInfo);
118 }
119 catch (e) {
120 return processGoogle();
121 }
122}
123async function readXml(path) {
124 try {
125 const f = await fs_1.fsReadFile(path, { encoding: 'utf-8' });
126 const o = await parseXml(f);
127 return o;
128 }
129 catch (e) {
130 if (e instanceof SyntaxError) {
131 console.log(`Invalid XML in ${path}`);
132 return;
133 }
134 }
135}