MOBILE-3501 gulp: Create task to push and update tracker
This commit is contained in:
		
							parent
							
								
									0d6d4a9326
								
							
						
					
					
						commit
						22257e5b49
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -46,3 +46,4 @@ e2e/build | ||||
| !/desktop/assets/ | ||||
| !/desktop/electron.js | ||||
| src/configconstants.ts | ||||
| .moodleapp-dev-config | ||||
|  | ||||
							
								
								
									
										69
									
								
								gulp/dev-config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								gulp/dev-config.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,69 @@ | ||||
| // (C) Copyright 2015 Moodle Pty Ltd.
 | ||||
| //
 | ||||
| // Licensed under the Apache License, Version 2.0 (the "License");
 | ||||
| // you may not use this file except in compliance with the License.
 | ||||
| // You may obtain a copy of the License at
 | ||||
| //
 | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| //
 | ||||
| // Unless required by applicable law or agreed to in writing, software
 | ||||
| // distributed under the License is distributed on an "AS IS" BASIS,
 | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| const fs = require('fs'); | ||||
| 
 | ||||
| const DEV_CONFIG_FILE = '.moodleapp-dev-config'; | ||||
| 
 | ||||
| /** | ||||
|  * Class to read and write dev-config data from a file. | ||||
|  */ | ||||
| class DevConfig { | ||||
| 
 | ||||
|     constructor() { | ||||
|         this.loadFileData(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get a setting. | ||||
|      * | ||||
|      * @param name Name of the setting to get. | ||||
|      * @param defaultValue Value to use if not found. | ||||
|      */ | ||||
|     get(name, defaultValue) { | ||||
|         return typeof this.config[name] != 'undefined' ? this.config[name] : defaultValue; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Load file data to memory. | ||||
|      */ | ||||
|     loadFileData() { | ||||
|         if (!fs.existsSync(DEV_CONFIG_FILE)) { | ||||
|             this.config = {}; | ||||
| 
 | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         try { | ||||
|             this.config = JSON.parse(fs.readFileSync(DEV_CONFIG_FILE)); | ||||
|         } catch (error) { | ||||
|             console.error('Error reading dev config file.', error); | ||||
|             this.config = {}; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Save some settings. | ||||
|      * | ||||
|      * @param settings Object with the settings to save. | ||||
|      */ | ||||
|     save(settings) { | ||||
|         this.config = Object.assign(this.config, settings); | ||||
| 
 | ||||
|         // Save the data in the dev file.
 | ||||
|         fs.writeFileSync(DEV_CONFIG_FILE, JSON.stringify(this.config, null, 4)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| module.exports = new DevConfig(); | ||||
							
								
								
									
										185
									
								
								gulp/git.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								gulp/git.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,185 @@ | ||||
| // (C) Copyright 2015 Moodle Pty Ltd.
 | ||||
| //
 | ||||
| // Licensed under the Apache License, Version 2.0 (the "License");
 | ||||
| // you may not use this file except in compliance with the License.
 | ||||
| // You may obtain a copy of the License at
 | ||||
| //
 | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| //
 | ||||
| // Unless required by applicable law or agreed to in writing, software
 | ||||
| // distributed under the License is distributed on an "AS IS" BASIS,
 | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| const exec = require('child_process').exec; | ||||
| const DevConfig = require('./dev-config'); | ||||
| const Utils = require('./utils'); | ||||
| 
 | ||||
| /** | ||||
|  * Class to run git commands. | ||||
|  */ | ||||
| class Git { | ||||
| 
 | ||||
|     /** | ||||
|      * Get current branch. | ||||
|      * | ||||
|      * @return Promise resolved with the branch name. | ||||
|      */ | ||||
|     getCurrentBranch() { | ||||
|         return new Promise((resolve, reject) => { | ||||
|             exec('git branch --show-current', (err, branch) => { | ||||
|                 if (branch) { | ||||
|                     resolve(branch.replace('\n', '')); | ||||
|                 } else { | ||||
|                     reject (err || 'Current branch not found.'); | ||||
|                 } | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get the HEAD commit for a certain branch. | ||||
|      * | ||||
|      * @param branch Name of the branch. | ||||
|      * @param branchData Parsed branch data. If not provided it will be calculated. | ||||
|      * @return HEAD commit. | ||||
|      */ | ||||
|     async getHeadCommit(branch, branchData) { | ||||
|         if (!branchData) { | ||||
|             // Parse the branch to get the project and issue number.
 | ||||
|             branchData = Utils.parseBranch(branch); | ||||
|         } | ||||
| 
 | ||||
|         // Loop over the last commits to find the first commit messages that doesn't belong to the issue.
 | ||||
|         const commitsString = await this.log(50, branch, '%s_____%H'); | ||||
|         const commits = commitsString.split('\n'); | ||||
|         commits.pop(); // Remove last element, it's an empty string.
 | ||||
| 
 | ||||
|         for (let i = 0; i < commits.length; i++) { | ||||
|             const commit = commits[i]; | ||||
|             const match = Utils.getIssueFromCommitMessage(commit) == branchData.issue; | ||||
| 
 | ||||
|             if (i === 0 && !match) { | ||||
|                 // Most recent commit doesn't belong to the issue. Stop looking.
 | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             if (!match) { | ||||
|                 // The commit does not match any more, we found it!
 | ||||
|                 return commit.split('_____')[1]; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // Couldn't find the commit using the commit names, get the last commit in the integration branch.
 | ||||
|         const remote = DevConfig.get('upstreamRemote', 'origin'); | ||||
|         console.log(`Head commit not found using commit messages. Get last commit from ${remote}/integration`); | ||||
|         const hashes = await this.hashes(1, `${remote}/integration`); | ||||
| 
 | ||||
|         return hashes[0]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get the URL of a certain remote. | ||||
|      * | ||||
|      * @param remote Remote name. | ||||
|      * @return Promise resolved with the remote URL. | ||||
|      */ | ||||
|     getRemoteUrl(remote) { | ||||
|         return new Promise((resolve, reject) => { | ||||
|             exec(`git remote get-url ${remote}`, (err, url) => { | ||||
|                 if (url) { | ||||
|                     resolve(url.replace('\n', '')); | ||||
|                 } else { | ||||
|                     reject (err || 'Remote not found.'); | ||||
|                 } | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Return the latest hashes from git log. | ||||
|      * | ||||
|      * @param count Number of commits to display. | ||||
|      * @param range Show only commits in the specified revision range. | ||||
|      * @param format Pretty-print the contents of the commit logs in a given format. | ||||
|      * @return Promise resolved with the list of hashes. | ||||
|      */ | ||||
|     async hashes(count, range, format) { | ||||
|         format = format || '%H'; | ||||
| 
 | ||||
|         const hashList = await this.log(count, range, format); | ||||
| 
 | ||||
|         const hashes = hashList.split('\n'); | ||||
|         hashes.pop(); // Remove last element, it's an empty string.
 | ||||
| 
 | ||||
|         return hashes; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Calls the log command and returns the raw output. | ||||
|      * | ||||
|      * @param count Number of commits to display. | ||||
|      * @param range Show only commits in the specified revision range. | ||||
|      * @param format Pretty-print the contents of the commit logs in a given format. | ||||
|      * @param path Show only commits that are enough to explain how the files that match the specified paths came to be. | ||||
|      * @return Promise resolved with the result. | ||||
|      */ | ||||
|     log(count, range, format, path) { | ||||
|         if (typeof count == 'undefined') { | ||||
|             count = 10; | ||||
|         } | ||||
| 
 | ||||
|         let command = 'git log'; | ||||
| 
 | ||||
|         if (count > 0) { | ||||
|             command += ` -n ${count} `; | ||||
|         } | ||||
|         if (format) { | ||||
|             command += ` --format=${format} `; | ||||
|         } | ||||
|         if (range){ | ||||
|             command += ` ${range} `; | ||||
|         } | ||||
|         if (path) { | ||||
|             command += ` -- ${path}`; | ||||
|         } | ||||
| 
 | ||||
|         return new Promise((resolve, reject) => { | ||||
|             exec(command, (err, result, stderr) => { | ||||
|                 if (err) { | ||||
|                     reject(err); | ||||
|                 } else { | ||||
|                     resolve(result); | ||||
|                 } | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Push a branch. | ||||
|      * | ||||
|      * @param remote Remote to use. | ||||
|      * @param branch Branch to push. | ||||
|      * @param force Whether to force the push. | ||||
|      * @return Promise resolved when done. | ||||
|      */ | ||||
|     push(remote, branch, force) { | ||||
|         return new Promise((resolve, reject) => { | ||||
|             let command = `git push ${remote} ${branch}`; | ||||
|             if (force) { | ||||
|                 command += ' -f'; | ||||
|             } | ||||
| 
 | ||||
|             exec(command, (err, result, stderr) => { | ||||
|                 if (err) { | ||||
|                     reject(err); | ||||
|                 } else { | ||||
|                     resolve(); | ||||
|                 } | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| module.exports = new Git(); | ||||
							
								
								
									
										364
									
								
								gulp/jira.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										364
									
								
								gulp/jira.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,364 @@ | ||||
| // (C) Copyright 2015 Moodle Pty Ltd.
 | ||||
| //
 | ||||
| // Licensed under the Apache License, Version 2.0 (the "License");
 | ||||
| // you may not use this file except in compliance with the License.
 | ||||
| // You may obtain a copy of the License at
 | ||||
| //
 | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| //
 | ||||
| // Unless required by applicable law or agreed to in writing, software
 | ||||
| // distributed under the License is distributed on an "AS IS" BASIS,
 | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| const exec = require('child_process').exec; | ||||
| const https = require('https'); | ||||
| const keytar = require('keytar'); | ||||
| const inquirer = require('inquirer'); | ||||
| const DevConfig = require('./dev-config'); | ||||
| const Git = require('./git'); | ||||
| const Url = require('./url'); | ||||
| const Utils = require('./utils'); | ||||
| 
 | ||||
| const apiVersion = 2; | ||||
| 
 | ||||
| /** | ||||
|  * Class to interact with Jira. | ||||
|  */ | ||||
| class Jira { | ||||
| 
 | ||||
|     /** | ||||
|      * Ask the password to the user. | ||||
|      * | ||||
|      * @return Promise resolved with the password. | ||||
|      */ | ||||
|     async askPassword() { | ||||
|         const data = await inquirer.prompt([ | ||||
|             { | ||||
|                 type: 'password', | ||||
|                 name: 'password', | ||||
|                 message: `Please enter the password for the username ${this.username}.`, | ||||
|             }, | ||||
|         ]); | ||||
| 
 | ||||
|         return data.password; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Ask the user the tracker data. | ||||
|      * | ||||
|      * @return Promise resolved with the data, rejected if cannot get. | ||||
|      */ | ||||
|     async askTrackerData() { | ||||
|         const data = await inquirer.prompt([ | ||||
|             { | ||||
|                 type: 'input', | ||||
|                 name: 'url', | ||||
|                 message: 'Please enter the tracker URL.', | ||||
|                 default: 'https://tracker.moodle.org/', | ||||
|             }, | ||||
|             { | ||||
|                 type: 'input', | ||||
|                 name: 'username', | ||||
|                 message: 'Please enter your tracker username.', | ||||
|             }, | ||||
|         ]); | ||||
| 
 | ||||
|         DevConfig.save({ | ||||
|             'tracker.url': data.url, | ||||
|             'tracker.username': data.username, | ||||
|         }); | ||||
| 
 | ||||
|         return data; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Load the issue info from jira server using a REST API call. | ||||
|      * | ||||
|      * @param key Key to identify the issue. E.g. MOBILE-1234. | ||||
|      * @param fields Fields to get. | ||||
|      * @return Promise resolved with the issue data. | ||||
|      */ | ||||
|     async getIssue(key, fields) { | ||||
|         fields = fields || '*all,-comment'; | ||||
| 
 | ||||
|         await this.init(); // Initialize data if needed.
 | ||||
| 
 | ||||
|         const response = await this.request(`issue/${key}`, 'GET', {'fields': fields, 'expand': 'names'}); | ||||
| 
 | ||||
|         if (response.status == 404) { | ||||
|             throw new Error('Issue could not be found.'); | ||||
|         } else if (response.status != 200) { | ||||
|             throw new Error('The tracker is not available.') | ||||
|         } | ||||
| 
 | ||||
|         const issue = response.data; | ||||
|         issue.named = {}; | ||||
| 
 | ||||
|         // Populate the named fields in a separate key. Allows us to easily find them without knowing the field ID.
 | ||||
|         const nameList = issue.names || {}; | ||||
|         for (const fieldKey in issue.fields) { | ||||
|             if (nameList[fieldKey]) { | ||||
|                 issue.named[nameList[fieldKey]] = issue.fields[fieldKey]; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return issue | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Load the version info from the jira server using a rest api call. | ||||
|      * | ||||
|      * @return Promise resolved when done. | ||||
|      */ | ||||
|     async getServerInfo() { | ||||
|         const response = await this.request('serverInfo'); | ||||
| 
 | ||||
|         if (response.status != 200) { | ||||
|             throw new Error(`Unexpected response code: ${response.status}`, response); | ||||
|         } | ||||
| 
 | ||||
|         this.version = response.data; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get tracker data to push an issue. | ||||
|      * | ||||
|      * @return Promise resolved with the data. | ||||
|      */ | ||||
|     async getTrackerData() { | ||||
|         // Check dev-config file first.
 | ||||
|         let data = this.getTrackerDataFromDevConfig(); | ||||
| 
 | ||||
|         if (data) { | ||||
|             console.log('Using tracker data from dev-config file'); | ||||
|             return data; | ||||
|         } | ||||
| 
 | ||||
|         // Try to use mdk now.
 | ||||
|         try { | ||||
|             data = await this.getTrackerDataFromMdk(); | ||||
| 
 | ||||
|             console.log('Using tracker data from mdk'); | ||||
| 
 | ||||
|             return data; | ||||
|         } catch (error) { | ||||
|             // MDK not available or not configured. Ask for the data.
 | ||||
|             const data = await this.askTrackerData(); | ||||
| 
 | ||||
|             data.fromInput = true; | ||||
| 
 | ||||
|             return data; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get tracker data from dev config file. | ||||
|      * | ||||
|      * @return Data, undefined if cannot get. | ||||
|      */ | ||||
|     getTrackerDataFromDevConfig() { | ||||
|         const url = DevConfig.get('tracker.url'); | ||||
|         const username = DevConfig.get('tracker.username'); | ||||
| 
 | ||||
|         if (url && username) { | ||||
|             return { | ||||
|                 url, | ||||
|                 username, | ||||
|             }; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get tracker URL and username from mdk. | ||||
|      * | ||||
|      * @return Promise resolved with the data, rejected if cannot get. | ||||
|      */ | ||||
|     getTrackerDataFromMdk() { | ||||
|         return new Promise((resolve, reject) => { | ||||
|             exec('mdk config show tracker.url', (err, url) => { | ||||
|                 if (!url) { | ||||
|                     reject(err || 'URL not found.'); | ||||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|                 exec('mdk config show tracker.username', (err, username) => { | ||||
|                     if (username) { | ||||
|                         resolve({ | ||||
|                             url: url.replace('\n', ''), | ||||
|                             username: username.replace('\n', ''), | ||||
|                         }); | ||||
|                     } else { | ||||
|                         reject(err | 'Username not found.'); | ||||
|                     } | ||||
|                 }); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Initialize some data. | ||||
|      * | ||||
|      * @return Promise resolved when done. | ||||
|      */ | ||||
|     async init() { | ||||
|         if (this.initialized) { | ||||
|             // Already initialized.
 | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // Get tracker URL and username.
 | ||||
|         const trackerData = await this.getTrackerData(); | ||||
| 
 | ||||
|         this.url = trackerData.url; | ||||
|         this.username = trackerData.username; | ||||
| 
 | ||||
|         const parsed = Url.parse(this.url); | ||||
|         this.ssl = parsed.protocol == 'https'; | ||||
|         this.host = parsed.domain; | ||||
|         this.uri = parsed.path; | ||||
| 
 | ||||
|         // Get the password.
 | ||||
|         this.password = await keytar.getPassword('mdk-jira-password', this.username); // Use same service name as mdk.
 | ||||
| 
 | ||||
|         if (!this.password) { | ||||
|             // Ask the user.
 | ||||
|             this.password = await this.askPassword(); | ||||
|         } | ||||
| 
 | ||||
|         while (!this.initialized) { | ||||
|             try { | ||||
|                 await this.getServerInfo(); | ||||
| 
 | ||||
|                 this.initialized = true; | ||||
|                 keytar.setPassword('mdk-jira-password', this.username, this.password); | ||||
|             } catch (error) { | ||||
|                 console.log('Error connecting to the server. Please make sure you entered the data correctly.', error); | ||||
|                 if (trackerData.fromInput) { | ||||
|                     // User entered the data manually, ask him again.
 | ||||
|                     trackerData = await this.askTrackerData(); | ||||
| 
 | ||||
|                     this.url = trackerData.url; | ||||
|                     this.username = trackerData.username; | ||||
|                 } | ||||
| 
 | ||||
|                 this.password = await this.askPassword(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Sends a request to the server and returns the data. | ||||
|      * | ||||
|      * @param uri URI to add the the Jira URL. | ||||
|      * @param method Method to use. Defaults to 'GET'. | ||||
|      * @param params Params to send as GET params (in the URL). | ||||
|      * @param data JSON string with the data to send as POST/PUT params. | ||||
|      * @param headers Headers to send. | ||||
|      * @return Promise resolved with the result. | ||||
|      */ | ||||
|     request(uri, method, params, data, headers) { | ||||
|         uri = uri || ''; | ||||
|         method = (method || 'GET').toUpperCase(); | ||||
|         data = data || ''; | ||||
|         params = params || {}; | ||||
|         headers = headers || {}; | ||||
|         headers['Content-Type'] = 'application/json'; | ||||
| 
 | ||||
|         return new Promise((resolve, reject) => { | ||||
| 
 | ||||
|             // Build the request URL.
 | ||||
|             let url = Utils.concatenatePaths([this.url, this.uri, '/rest/api/', apiVersion, uri]); | ||||
|             url = Url.addParamsToUrl(url, params); | ||||
| 
 | ||||
|             // Perform the request.
 | ||||
|             const options = { | ||||
|                 method: method, | ||||
|                 auth: `${this.username}:${this.password}`, | ||||
|                 headers: headers, | ||||
|             }; | ||||
|             const request = https.request(url, options, (response) => { | ||||
|                 // Read the result.
 | ||||
|                 let result = ''; | ||||
|                 response.on('data', (chunk) => { | ||||
|                     result += chunk; | ||||
|                 }); | ||||
|                 response.on('end', () => { | ||||
|                     try { | ||||
|                         result = JSON.parse(result); | ||||
|                     } catch (error) { | ||||
|                         // Leave it as text.
 | ||||
|                     } | ||||
| 
 | ||||
|                     resolve({ | ||||
|                         status: response.statusCode, | ||||
|                         data: result, | ||||
|                     }); | ||||
|                 }); | ||||
|             }); | ||||
| 
 | ||||
|             request.on('error', (e) => { | ||||
|                 reject(e); | ||||
|             }); | ||||
| 
 | ||||
|             // Send data.
 | ||||
|             if (data) { | ||||
|                 request.write(data); | ||||
|             } | ||||
| 
 | ||||
|             request.end(); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Sets a set of fields for a certain issue in Jira. | ||||
|      * | ||||
|      * @param key Key to identify the issue. E.g. MOBILE-1234. | ||||
|      * @param updates Object with the fields to update. | ||||
|      * @return Promise resolved when done. | ||||
|      */ | ||||
|     async setCustomFields(key, updates) { | ||||
|         const issue = await this.getIssue(key); | ||||
|         const update = {'fields': {}}; | ||||
| 
 | ||||
|         // Detect which fields have changed.
 | ||||
|         for (const updateName in updates) { | ||||
|             const updateValue = updates[updateName]; | ||||
|             const remoteValue = issue.named[updateName]; | ||||
| 
 | ||||
|             if (!remoteValue || remoteValue != updateValue) { | ||||
|                 // Map the label of the field with the field code.
 | ||||
|                 let fieldKey; | ||||
|                 for (const key in issue.names) { | ||||
|                     if (issue.names[key] == updateName) { | ||||
|                         fieldKey = key; | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 if (!fieldKey) { | ||||
|                     throw new Error(`Could not find the field named ${updateName}.`); | ||||
|                 } | ||||
| 
 | ||||
|                 update.fields[fieldKey] = updateValue; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (!Object.keys(update.fields).length) { | ||||
|             // No fields to update.
 | ||||
|             console.log('No updates required.') | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         const response = await this.request(`issue/${key}`, 'PUT', null, JSON.stringify(update)); | ||||
| 
 | ||||
|         if (response.status != 204) { | ||||
|             throw new Error(`Issue was not updated: ${response.status}`, response.data); | ||||
|         } | ||||
| 
 | ||||
|         console.log('Issue updated successfully.'); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| module.exports = new Jira(); | ||||
							
								
								
									
										125
									
								
								gulp/task-push.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								gulp/task-push.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,125 @@ | ||||
| // (C) Copyright 2015 Moodle Pty Ltd.
 | ||||
| //
 | ||||
| // Licensed under the Apache License, Version 2.0 (the "License");
 | ||||
| // you may not use this file except in compliance with the License.
 | ||||
| // You may obtain a copy of the License at
 | ||||
| //
 | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| //
 | ||||
| // Unless required by applicable law or agreed to in writing, software
 | ||||
| // distributed under the License is distributed on an "AS IS" BASIS,
 | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| const gulp = require('gulp'); | ||||
| const DevConfig = require('./dev-config'); | ||||
| const Git = require('./git'); | ||||
| const Jira = require('./jira'); | ||||
| const Utils = require('./utils'); | ||||
| 
 | ||||
| /** | ||||
|  * Task to push a git branch and update tracker issue. | ||||
|  */ | ||||
| class PushTask { | ||||
| 
 | ||||
|     /** | ||||
|      * Run the task. | ||||
|      * | ||||
|      * @param args Command line arguments. | ||||
|      * @param done Function to call when done. | ||||
|      */ | ||||
|     async run(args, done) { | ||||
|         try { | ||||
|             const remote = args.remote || DevConfig.get('upstreamRemote', 'origin'); | ||||
|             let branch = args.branch; | ||||
|             const force = !!args.force; | ||||
| 
 | ||||
|             if (!branch) { | ||||
|                 branch = await Git.getCurrentBranch(); | ||||
|             } | ||||
| 
 | ||||
|             if (!branch) { | ||||
|                 throw new Error('Cannot determine the current branch. Please make sure youu aren\'t in detached HEAD state'); | ||||
|             } else if (branch == 'HEAD') { | ||||
|                 throw new Error('Cannot push HEAD branch'); | ||||
|             } | ||||
| 
 | ||||
|             // Push the branch.
 | ||||
|             console.log(`Pushing branch ${branch} to remote ${remote}...`); | ||||
|             await Git.push(remote, branch, force); | ||||
| 
 | ||||
|             // Update tracker info.
 | ||||
|             console.log(`Branch pushed, update tracker info...`); | ||||
|             await this.updateTrackerGitInfo(branch, remote); | ||||
|         } catch (error) { | ||||
|             console.error(error); | ||||
|         } | ||||
| 
 | ||||
|         done(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Update git info in the tracker issue. | ||||
|      * | ||||
|      * @param branch Branch name. | ||||
|      * @param remote Remote used. | ||||
|      * @return Promise resolved when done. | ||||
|      */ | ||||
|     async updateTrackerGitInfo(branch, remote) { | ||||
|         // Parse the branch to get the project and issue number.
 | ||||
|         const branchData = Utils.parseBranch(branch); | ||||
| 
 | ||||
|         // Get the repository data for the project.
 | ||||
|         let repositoryUrl = DevConfig.get(branchData.project + '.repositoryUrl'); | ||||
|         let diffUrlTemplate = DevConfig.get(branchData.project + '.diffUrlTemplate', ''); | ||||
|         let remoteUrl; | ||||
| 
 | ||||
|         if (!repositoryUrl) { | ||||
|             // Calculate the repositoryUrl based on the remote URL.
 | ||||
|             remoteUrl = await Git.getRemoteUrl(remote); | ||||
| 
 | ||||
|             repositoryUrl = remoteUrl.replace(/^https?:\/\//, 'git://'); | ||||
|             if (!repositoryUrl.match(/\.git$/)) { | ||||
|                 repositoryUrl += '.git'; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (!diffUrlTemplate) { | ||||
|             // Calculate the diffUrlTemplate based on the remote URL.
 | ||||
|             if (!remoteUrl) { | ||||
|                 remoteUrl = await Git.getRemoteUrl(remoteUrl); | ||||
|             } | ||||
| 
 | ||||
|             diffUrlTemplate = remoteUrl + '/compare/%headcommit%...%branch%'; | ||||
|         } | ||||
| 
 | ||||
|         // Search HEAD commit to put in the diff URL.
 | ||||
|         console.log ('Searching for head commit...'); | ||||
|         let headCommit = await Git.getHeadCommit(branch, branchData); | ||||
| 
 | ||||
|         if (!headCommit) { | ||||
|             throw new Error('Head commit not resolved, aborting update of tracker fields'); | ||||
|         } | ||||
| 
 | ||||
|         headCommit = headCommit.substr(0, 10); | ||||
|         console.log(`Head commit resolved to ${headCommit}`); | ||||
| 
 | ||||
|         // Calculate last properties needed.
 | ||||
|         const diffUrl = diffUrlTemplate.replace('%branch%', branch).replace('%headcommit%', headCommit); | ||||
|         const fieldRepositoryUrl = DevConfig.get('tracker.fieldnames.repositoryurl', 'Pull  from Repository'); | ||||
|         const fieldBranch = DevConfig.get('tracker.fieldnames.branch', 'Pull Master Branch'); | ||||
|         const fieldDiffUrl = DevConfig.get('tracker.fieldnames.diffurl', 'Pull Master Diff URL'); | ||||
| 
 | ||||
|         // Update tracker fields.
 | ||||
|         const updates = {}; | ||||
|         updates[fieldRepositoryUrl] = repositoryUrl; | ||||
|         updates[fieldBranch] = branch; | ||||
|         updates[fieldDiffUrl] = diffUrl; | ||||
| 
 | ||||
|         console.log('Setting tracker fields...'); | ||||
|         await Jira.setCustomFields(branchData.issue, updates); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| module.exports = PushTask; | ||||
							
								
								
									
										79
									
								
								gulp/url.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								gulp/url.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,79 @@ | ||||
| // (C) Copyright 2015 Moodle Pty Ltd.
 | ||||
| //
 | ||||
| // Licensed under the Apache License, Version 2.0 (the "License");
 | ||||
| // you may not use this file except in compliance with the License.
 | ||||
| // You may obtain a copy of the License at
 | ||||
| //
 | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| //
 | ||||
| // Unless required by applicable law or agreed to in writing, software
 | ||||
| // distributed under the License is distributed on an "AS IS" BASIS,
 | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| /** | ||||
|  * Class with helper functions for urls. | ||||
|  */ | ||||
| class Url { | ||||
| 
 | ||||
|     /** | ||||
|      * Add params to a URL. | ||||
|      * | ||||
|      * @param url URL to add the params to. | ||||
|      * @param params Object with the params to add. | ||||
|      * @return URL with params. | ||||
|      */ | ||||
|     static addParamsToUrl(url, params) { | ||||
|         let separator = url.indexOf('?') != -1 ? '&' : '?'; | ||||
| 
 | ||||
|         for (const key in params) { | ||||
|             let value = params[key]; | ||||
| 
 | ||||
|             // Ignore objects.
 | ||||
|             if (typeof value != 'object') { | ||||
|                 url += separator + key + '=' + value; | ||||
|                 separator = '&'; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return url; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parse parts of a url, using an implicit protocol if it is missing from the url. | ||||
|      * | ||||
|      * @param url Url. | ||||
|      * @return Url parts. | ||||
|      */ | ||||
|     static parse(url) { | ||||
|         // Parse url with regular expression taken from RFC 3986: https://tools.ietf.org/html/rfc3986#appendix-B.
 | ||||
|         const match = url.trim().match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/); | ||||
| 
 | ||||
|         if (!match) { | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         const host = match[4] || ''; | ||||
| 
 | ||||
|         // Get the credentials and the port from the host.
 | ||||
|         const [domainAndPort, credentials] = host.split('@').reverse(); | ||||
|         const [domain, port] = domainAndPort.split(':'); | ||||
|         const [username, password] = credentials ? credentials.split(':') : []; | ||||
| 
 | ||||
|         // Prepare parts replacing empty strings with undefined.
 | ||||
|         return { | ||||
|             protocol: match[2] || undefined, | ||||
|             domain: domain || undefined, | ||||
|             port: port || undefined, | ||||
|             credentials: credentials || undefined, | ||||
|             username: username || undefined, | ||||
|             password: password || undefined, | ||||
|             path: match[5] || undefined, | ||||
|             query: match[7] || undefined, | ||||
|             fragment: match[9] || undefined, | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| module.exports = Url; | ||||
							
								
								
									
										119
									
								
								gulp/utils.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								gulp/utils.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,119 @@ | ||||
| // (C) Copyright 2015 Moodle Pty Ltd.
 | ||||
| //
 | ||||
| // Licensed under the Apache License, Version 2.0 (the "License");
 | ||||
| // you may not use this file except in compliance with the License.
 | ||||
| // You may obtain a copy of the License at
 | ||||
| //
 | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| //
 | ||||
| // Unless required by applicable law or agreed to in writing, software
 | ||||
| // distributed under the License is distributed on an "AS IS" BASIS,
 | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| const DevConfig = require('./dev-config'); | ||||
| const DEFAULT_ISSUE_REGEX = '(MOBILE)[-_]([0-9]+)'; | ||||
| 
 | ||||
| /** | ||||
|  * Class with some utility functions. | ||||
|  */ | ||||
| class Utils { | ||||
|     /** | ||||
|      * Concatenate several paths, adding a slash between them if needed. | ||||
|      * | ||||
|      * @param paths List of paths. | ||||
|      * @return Concatenated path. | ||||
|      */ | ||||
|     static concatenatePaths(paths) { | ||||
|         if (!paths.length) { | ||||
|             return ''; | ||||
|         } | ||||
| 
 | ||||
|         // Remove all slashes between paths.
 | ||||
|         for (let i = 0; i < paths.length; i++) { | ||||
|             if (!paths[i]) { | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             if (i === 0) { | ||||
|                 paths[i] = String(paths[i]).replace(/\/+$/g, ''); | ||||
|             } else if (i === paths.length - 1) { | ||||
|                 paths[i] = String(paths[i]).replace(/^\/+/g, ''); | ||||
|             } else { | ||||
|                 paths[i] = String(paths[i]).replace(/^\/+|\/+$/g, ''); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // Remove empty paths.
 | ||||
|         paths = paths.filter(path => !!path); | ||||
| 
 | ||||
|         return paths.join('/'); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get command line arguments. | ||||
|      * | ||||
|      * @return Object with command line arguments. | ||||
|      */ | ||||
|     static getCommandLineArguments() { | ||||
| 
 | ||||
|         let args = {}, opt, thisOpt, curOpt; | ||||
|         for (let a = 0; a < process.argv.length; a++) { | ||||
| 
 | ||||
|             thisOpt = process.argv[a].trim(); | ||||
|             opt = thisOpt.replace(/^\-+/, ''); | ||||
| 
 | ||||
|             if (opt === thisOpt) { | ||||
|                 // argument value
 | ||||
|                 if (curOpt) { | ||||
|                     args[curOpt] = opt; | ||||
|                 } | ||||
|                 curOpt = null; | ||||
|             } | ||||
|             else { | ||||
|                 // Argument name.
 | ||||
|                 curOpt = opt; | ||||
|                 args[curOpt] = true; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return args; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Given a commit message, return the issue name (e.g. MOBILE-1234). | ||||
|      * | ||||
|      * @param commit Commit message. | ||||
|      * @return Issue name. | ||||
|      */ | ||||
|     static getIssueFromCommitMessage(commit) { | ||||
|         const regex = new RegExp(DevConfig.get('wording.branchRegex', DEFAULT_ISSUE_REGEX), 'i'); | ||||
|         const matches = commit.match(regex); | ||||
| 
 | ||||
|         return matches && matches[0]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parse a branch name to extract some data. | ||||
|      * | ||||
|      * @param branch Branch name to parse. | ||||
|      * @return Data. | ||||
|      */ | ||||
|     static parseBranch(branch) { | ||||
|         const regex = new RegExp(DevConfig.get('wording.branchRegex', DEFAULT_ISSUE_REGEX), 'i'); | ||||
| 
 | ||||
|         const matches = branch.match(regex); | ||||
|         if (!matches || matches.length < 3) { | ||||
|             throw new Error(`Error parsing branch ${branch}`); | ||||
|         } | ||||
| 
 | ||||
|         return { | ||||
|             issue: matches[0], | ||||
|             project: matches[1], | ||||
|             issueNumber: matches[2], | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| module.exports = Utils; | ||||
| @ -16,7 +16,8 @@ const BuildConfigTask = require('./gulp/task-build-config'); | ||||
| const BuildLangTask = require('./gulp/task-build-lang'); | ||||
| const CombineScssTask = require('./gulp/task-combine-scss'); | ||||
| const CopyComponentTemplatesTask = require('./gulp/task-copy-component-templates'); | ||||
| 
 | ||||
| const PushTask = require('./gulp/task-push'); | ||||
| const Utils = require('./gulp/utils'); | ||||
| const gulp = require('gulp'); | ||||
| const pathLib = require('path'); | ||||
| 
 | ||||
| @ -31,6 +32,8 @@ const paths = { | ||||
|     config: './src/config.json', | ||||
| }; | ||||
| 
 | ||||
| const args = Utils.getCommandLineArguments(); | ||||
| 
 | ||||
| // Build the language files into a single file per language.
 | ||||
| gulp.task('lang', (done) => { | ||||
|     new BuildLangTask().run('en', paths.lang, done); | ||||
| @ -51,6 +54,10 @@ gulp.task('combine-scss', (done) => { | ||||
|     new CombineScssTask().run(done); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('push', (done) => { | ||||
|     new PushTask().run(args, done); | ||||
| }); | ||||
| 
 | ||||
| gulp.task('default', gulp.parallel('lang', 'config')); | ||||
| 
 | ||||
| gulp.task('watch', () => { | ||||
|  | ||||
							
								
								
									
										653
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										653
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "moodlemobile", | ||||
|   "version": "3.9.2", | ||||
|   "version": "3.9.3", | ||||
|   "lockfileVersion": 1, | ||||
|   "requires": true, | ||||
|   "dependencies": { | ||||
| @ -1627,8 +1627,7 @@ | ||||
|     "@types/color-name": { | ||||
|       "version": "1.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", | ||||
|       "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", | ||||
|       "dev": true | ||||
|       "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" | ||||
|     }, | ||||
|     "@types/cordova": { | ||||
|       "version": "0.0.34", | ||||
| @ -1864,9 +1863,12 @@ | ||||
|       } | ||||
|     }, | ||||
|     "ansi-escapes": { | ||||
|       "version": "3.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", | ||||
|       "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" | ||||
|       "version": "4.3.1", | ||||
|       "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", | ||||
|       "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", | ||||
|       "requires": { | ||||
|         "type-fest": "^0.11.0" | ||||
|       } | ||||
|     }, | ||||
|     "ansi-gray": { | ||||
|       "version": "0.1.1", | ||||
| @ -2425,6 +2427,46 @@ | ||||
|         "file-uri-to-path": "1.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "bl": { | ||||
|       "version": "4.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz", | ||||
|       "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "buffer": "^5.5.0", | ||||
|         "inherits": "^2.0.4", | ||||
|         "readable-stream": "^3.4.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "buffer": { | ||||
|           "version": "5.6.0", | ||||
|           "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", | ||||
|           "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "base64-js": "^1.0.2", | ||||
|             "ieee754": "^1.1.4" | ||||
|           } | ||||
|         }, | ||||
|         "inherits": { | ||||
|           "version": "2.0.4", | ||||
|           "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", | ||||
|           "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", | ||||
|           "dev": true | ||||
|         }, | ||||
|         "readable-stream": { | ||||
|           "version": "3.6.0", | ||||
|           "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", | ||||
|           "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "inherits": "^2.0.3", | ||||
|             "string_decoder": "^1.1.1", | ||||
|             "util-deprecate": "^1.0.1" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "block-stream": { | ||||
|       "version": "0.0.9", | ||||
|       "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", | ||||
| @ -3963,6 +4005,15 @@ | ||||
|       "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", | ||||
|       "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" | ||||
|     }, | ||||
|     "decompress-response": { | ||||
|       "version": "4.2.1", | ||||
|       "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", | ||||
|       "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "mimic-response": "^2.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "dedent": { | ||||
|       "version": "0.7.0", | ||||
|       "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", | ||||
| @ -5243,6 +5294,12 @@ | ||||
|         "fill-range": "^2.1.0" | ||||
|       } | ||||
|     }, | ||||
|     "expand-template": { | ||||
|       "version": "2.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", | ||||
|       "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "expand-tilde": { | ||||
|       "version": "2.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", | ||||
| @ -5701,9 +5758,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "figures": { | ||||
|       "version": "2.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", | ||||
|       "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", | ||||
|       "version": "3.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", | ||||
|       "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", | ||||
|       "requires": { | ||||
|         "escape-string-regexp": "^1.0.5" | ||||
|       } | ||||
| @ -6156,6 +6213,12 @@ | ||||
|       "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", | ||||
|       "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" | ||||
|     }, | ||||
|     "fs-constants": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", | ||||
|       "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "fs-extra": { | ||||
|       "version": "4.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", | ||||
| @ -6206,6 +6269,18 @@ | ||||
|       "requires": { | ||||
|         "graceful-fs": "^4.1.11", | ||||
|         "through2": "^2.0.3" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "through2": { | ||||
|           "version": "2.0.5", | ||||
|           "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", | ||||
|           "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "readable-stream": "~2.3.6", | ||||
|             "xtend": "~4.0.1" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "fs.realpath": { | ||||
| @ -6897,6 +6972,12 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "github-from-package": { | ||||
|       "version": "0.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", | ||||
|       "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "glob": { | ||||
|       "version": "7.1.2", | ||||
|       "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", | ||||
| @ -8140,6 +8221,18 @@ | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "through2": "~2.0.1" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "through2": { | ||||
|           "version": "2.0.5", | ||||
|           "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", | ||||
|           "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "readable-stream": "~2.3.6", | ||||
|             "xtend": "~4.0.1" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "gulp-concat": { | ||||
| @ -8151,6 +8244,18 @@ | ||||
|         "concat-with-sourcemaps": "^1.0.0", | ||||
|         "through2": "^2.0.0", | ||||
|         "vinyl": "^2.0.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "through2": { | ||||
|           "version": "2.0.5", | ||||
|           "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", | ||||
|           "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "readable-stream": "~2.3.6", | ||||
|             "xtend": "~4.0.1" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "gulp-flatten": { | ||||
| @ -8161,6 +8266,18 @@ | ||||
|       "requires": { | ||||
|         "plugin-error": "^0.1.2", | ||||
|         "through2": "^2.0.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "through2": { | ||||
|           "version": "2.0.5", | ||||
|           "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", | ||||
|           "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "readable-stream": "~2.3.6", | ||||
|             "xtend": "~4.0.1" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "gulp-htmlmin": { | ||||
| @ -8191,6 +8308,16 @@ | ||||
|             "arr-union": "^3.1.0", | ||||
|             "extend-shallow": "^3.0.2" | ||||
|           } | ||||
|         }, | ||||
|         "through2": { | ||||
|           "version": "2.0.5", | ||||
|           "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", | ||||
|           "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "readable-stream": "~2.3.6", | ||||
|             "xtend": "~4.0.1" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
| @ -8658,25 +8785,173 @@ | ||||
|       } | ||||
|     }, | ||||
|     "inquirer": { | ||||
|       "version": "6.5.2", | ||||
|       "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", | ||||
|       "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", | ||||
|       "version": "7.3.2", | ||||
|       "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.2.tgz", | ||||
|       "integrity": "sha512-DF4osh1FM6l0RJc5YWYhSDB6TawiBRlbV9Cox8MWlidU218Tb7fm3lQTULyUJDfJ0tjbzl0W4q651mrCCEM55w==", | ||||
|       "requires": { | ||||
|         "ansi-escapes": "^3.2.0", | ||||
|         "chalk": "^2.4.2", | ||||
|         "cli-cursor": "^2.1.0", | ||||
|         "cli-width": "^2.0.0", | ||||
|         "ansi-escapes": "^4.2.1", | ||||
|         "chalk": "^4.1.0", | ||||
|         "cli-cursor": "^3.1.0", | ||||
|         "cli-width": "^3.0.0", | ||||
|         "external-editor": "^3.0.3", | ||||
|         "figures": "^2.0.0", | ||||
|         "lodash": "^4.17.12", | ||||
|         "mute-stream": "0.0.7", | ||||
|         "run-async": "^2.2.0", | ||||
|         "rxjs": "^6.4.0", | ||||
|         "string-width": "^2.1.0", | ||||
|         "strip-ansi": "^5.1.0", | ||||
|         "figures": "^3.0.0", | ||||
|         "lodash": "^4.17.16", | ||||
|         "mute-stream": "0.0.8", | ||||
|         "run-async": "^2.4.0", | ||||
|         "rxjs": "^6.6.0", | ||||
|         "string-width": "^4.1.0", | ||||
|         "strip-ansi": "^6.0.0", | ||||
|         "through": "^2.3.6" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "ansi-regex": { | ||||
|           "version": "5.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", | ||||
|           "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" | ||||
|         }, | ||||
|         "ansi-styles": { | ||||
|           "version": "4.2.1", | ||||
|           "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", | ||||
|           "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", | ||||
|           "requires": { | ||||
|             "@types/color-name": "^1.1.1", | ||||
|             "color-convert": "^2.0.1" | ||||
|           } | ||||
|         }, | ||||
|         "chalk": { | ||||
|           "version": "4.1.0", | ||||
|           "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", | ||||
|           "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", | ||||
|           "requires": { | ||||
|             "ansi-styles": "^4.1.0", | ||||
|             "supports-color": "^7.1.0" | ||||
|           } | ||||
|         }, | ||||
|         "cli-cursor": { | ||||
|           "version": "3.1.0", | ||||
|           "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", | ||||
|           "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", | ||||
|           "requires": { | ||||
|             "restore-cursor": "^3.1.0" | ||||
|           } | ||||
|         }, | ||||
|         "cli-width": { | ||||
|           "version": "3.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", | ||||
|           "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==" | ||||
|         }, | ||||
|         "color-convert": { | ||||
|           "version": "2.0.1", | ||||
|           "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", | ||||
|           "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", | ||||
|           "requires": { | ||||
|             "color-name": "~1.1.4" | ||||
|           } | ||||
|         }, | ||||
|         "color-name": { | ||||
|           "version": "1.1.4", | ||||
|           "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", | ||||
|           "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" | ||||
|         }, | ||||
|         "emoji-regex": { | ||||
|           "version": "8.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", | ||||
|           "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" | ||||
|         }, | ||||
|         "has-flag": { | ||||
|           "version": "4.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", | ||||
|           "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" | ||||
|         }, | ||||
|         "is-fullwidth-code-point": { | ||||
|           "version": "3.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", | ||||
|           "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" | ||||
|         }, | ||||
|         "lodash": { | ||||
|           "version": "4.17.19", | ||||
|           "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", | ||||
|           "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" | ||||
|         }, | ||||
|         "mimic-fn": { | ||||
|           "version": "2.1.0", | ||||
|           "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", | ||||
|           "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" | ||||
|         }, | ||||
|         "onetime": { | ||||
|           "version": "5.1.0", | ||||
|           "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", | ||||
|           "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", | ||||
|           "requires": { | ||||
|             "mimic-fn": "^2.1.0" | ||||
|           } | ||||
|         }, | ||||
|         "restore-cursor": { | ||||
|           "version": "3.1.0", | ||||
|           "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", | ||||
|           "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", | ||||
|           "requires": { | ||||
|             "onetime": "^5.1.0", | ||||
|             "signal-exit": "^3.0.2" | ||||
|           } | ||||
|         }, | ||||
|         "rxjs": { | ||||
|           "version": "6.6.0", | ||||
|           "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz", | ||||
|           "integrity": "sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==", | ||||
|           "requires": { | ||||
|             "tslib": "^1.9.0" | ||||
|           } | ||||
|         }, | ||||
|         "string-width": { | ||||
|           "version": "4.2.0", | ||||
|           "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", | ||||
|           "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", | ||||
|           "requires": { | ||||
|             "emoji-regex": "^8.0.0", | ||||
|             "is-fullwidth-code-point": "^3.0.0", | ||||
|             "strip-ansi": "^6.0.0" | ||||
|           } | ||||
|         }, | ||||
|         "strip-ansi": { | ||||
|           "version": "6.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", | ||||
|           "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", | ||||
|           "requires": { | ||||
|             "ansi-regex": "^5.0.0" | ||||
|           } | ||||
|         }, | ||||
|         "supports-color": { | ||||
|           "version": "7.1.0", | ||||
|           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", | ||||
|           "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", | ||||
|           "requires": { | ||||
|             "has-flag": "^4.0.0" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "insight": { | ||||
|       "version": "0.10.3", | ||||
|       "resolved": "https://registry.npmjs.org/insight/-/insight-0.10.3.tgz", | ||||
|       "integrity": "sha512-YOncxSN6Omh+1Oqxt+OJAvJVMDKw7l6IEG0wT2cTMGxjsTcroOGW4IR926QDzxg/uZHcFZ2cZbckDWdZhc2pZw==", | ||||
|       "requires": { | ||||
|         "async": "^2.6.2", | ||||
|         "chalk": "^2.4.2", | ||||
|         "conf": "^1.4.0", | ||||
|         "inquirer": "^6.3.1", | ||||
|         "lodash.debounce": "^4.0.8", | ||||
|         "os-name": "^3.1.0", | ||||
|         "request": "^2.88.0", | ||||
|         "tough-cookie": "^3.0.1", | ||||
|         "uuid": "^3.3.2" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "ansi-escapes": { | ||||
|           "version": "3.2.0", | ||||
|           "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", | ||||
|           "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" | ||||
|         }, | ||||
|         "ansi-regex": { | ||||
|           "version": "3.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", | ||||
| @ -8692,20 +8967,67 @@ | ||||
|             "supports-color": "^5.3.0" | ||||
|           } | ||||
|         }, | ||||
|         "figures": { | ||||
|           "version": "2.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", | ||||
|           "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", | ||||
|           "requires": { | ||||
|             "escape-string-regexp": "^1.0.5" | ||||
|           } | ||||
|         }, | ||||
|         "inquirer": { | ||||
|           "version": "6.5.2", | ||||
|           "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", | ||||
|           "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", | ||||
|           "requires": { | ||||
|             "ansi-escapes": "^3.2.0", | ||||
|             "chalk": "^2.4.2", | ||||
|             "cli-cursor": "^2.1.0", | ||||
|             "cli-width": "^2.0.0", | ||||
|             "external-editor": "^3.0.3", | ||||
|             "figures": "^2.0.0", | ||||
|             "lodash": "^4.17.12", | ||||
|             "mute-stream": "0.0.7", | ||||
|             "run-async": "^2.2.0", | ||||
|             "rxjs": "^6.4.0", | ||||
|             "string-width": "^2.1.0", | ||||
|             "strip-ansi": "^5.1.0", | ||||
|             "through": "^2.3.6" | ||||
|           } | ||||
|         }, | ||||
|         "is-fullwidth-code-point": { | ||||
|           "version": "2.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", | ||||
|           "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" | ||||
|         }, | ||||
|         "macos-release": { | ||||
|           "version": "2.3.0", | ||||
|           "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", | ||||
|           "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" | ||||
|         }, | ||||
|         "mute-stream": { | ||||
|           "version": "0.0.7", | ||||
|           "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", | ||||
|           "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" | ||||
|         }, | ||||
|         "os-name": { | ||||
|           "version": "3.1.0", | ||||
|           "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", | ||||
|           "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", | ||||
|           "requires": { | ||||
|             "macos-release": "^2.2.0", | ||||
|             "windows-release": "^3.1.0" | ||||
|           } | ||||
|         }, | ||||
|         "punycode": { | ||||
|           "version": "2.1.1", | ||||
|           "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", | ||||
|           "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" | ||||
|         }, | ||||
|         "rxjs": { | ||||
|           "version": "6.5.3", | ||||
|           "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", | ||||
|           "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", | ||||
|           "version": "6.6.0", | ||||
|           "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz", | ||||
|           "integrity": "sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==", | ||||
|           "requires": { | ||||
|             "tslib": "^1.9.0" | ||||
|           } | ||||
| @ -8743,53 +9065,6 @@ | ||||
|               "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "insight": { | ||||
|       "version": "0.10.3", | ||||
|       "resolved": "https://registry.npmjs.org/insight/-/insight-0.10.3.tgz", | ||||
|       "integrity": "sha512-YOncxSN6Omh+1Oqxt+OJAvJVMDKw7l6IEG0wT2cTMGxjsTcroOGW4IR926QDzxg/uZHcFZ2cZbckDWdZhc2pZw==", | ||||
|       "requires": { | ||||
|         "async": "^2.6.2", | ||||
|         "chalk": "^2.4.2", | ||||
|         "conf": "^1.4.0", | ||||
|         "inquirer": "^6.3.1", | ||||
|         "lodash.debounce": "^4.0.8", | ||||
|         "os-name": "^3.1.0", | ||||
|         "request": "^2.88.0", | ||||
|         "tough-cookie": "^3.0.1", | ||||
|         "uuid": "^3.3.2" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "chalk": { | ||||
|           "version": "2.4.2", | ||||
|           "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", | ||||
|           "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", | ||||
|           "requires": { | ||||
|             "ansi-styles": "^3.2.1", | ||||
|             "escape-string-regexp": "^1.0.5", | ||||
|             "supports-color": "^5.3.0" | ||||
|           } | ||||
|         }, | ||||
|         "macos-release": { | ||||
|           "version": "2.3.0", | ||||
|           "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", | ||||
|           "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" | ||||
|         }, | ||||
|         "os-name": { | ||||
|           "version": "3.1.0", | ||||
|           "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", | ||||
|           "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", | ||||
|           "requires": { | ||||
|             "macos-release": "^2.2.0", | ||||
|             "windows-release": "^3.1.0" | ||||
|           } | ||||
|         }, | ||||
|         "punycode": { | ||||
|           "version": "2.1.1", | ||||
|           "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", | ||||
|           "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" | ||||
|         }, | ||||
|         "tough-cookie": { | ||||
|           "version": "3.0.1", | ||||
| @ -9129,11 +9404,6 @@ | ||||
|       "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", | ||||
|       "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" | ||||
|     }, | ||||
|     "is-promise": { | ||||
|       "version": "2.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", | ||||
|       "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" | ||||
|     }, | ||||
|     "is-redirect": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", | ||||
| @ -9382,6 +9652,16 @@ | ||||
|       "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "keytar": { | ||||
|       "version": "6.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/keytar/-/keytar-6.0.1.tgz", | ||||
|       "integrity": "sha512-1Ihpf2tdM3sLwGMkYHXYhVC/hx5BDR7CWFL4IrBA3IDZo0xHhS2nM+tU9Y+u/U7okNfbVkwmKsieLkcWRMh93g==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "node-addon-api": "^3.0.0", | ||||
|         "prebuild-install": "5.3.4" | ||||
|       } | ||||
|     }, | ||||
|     "kind-of": { | ||||
|       "version": "6.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", | ||||
| @ -10372,6 +10652,12 @@ | ||||
|       "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", | ||||
|       "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" | ||||
|     }, | ||||
|     "mimic-response": { | ||||
|       "version": "2.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", | ||||
|       "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "minimalistic-assert": { | ||||
|       "version": "1.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", | ||||
| @ -10448,6 +10734,12 @@ | ||||
|         "minimist": "^1.2.5" | ||||
|       } | ||||
|     }, | ||||
|     "mkdirp-classic": { | ||||
|       "version": "0.5.3", | ||||
|       "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", | ||||
|       "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "moment": { | ||||
|       "version": "2.24.0", | ||||
|       "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", | ||||
| @ -10511,6 +10803,12 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "napi-build-utils": { | ||||
|       "version": "1.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", | ||||
|       "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "native-run": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/native-run/-/native-run-1.0.0.tgz", | ||||
| @ -10602,6 +10900,21 @@ | ||||
|         "lower-case": "^1.1.1" | ||||
|       } | ||||
|     }, | ||||
|     "node-abi": { | ||||
|       "version": "2.18.0", | ||||
|       "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.18.0.tgz", | ||||
|       "integrity": "sha512-yi05ZoiuNNEbyT/xXfSySZE+yVnQW6fxPZuFbLyS1s6b5Kw3HzV2PHOM4XR+nsjzkHxByK+2Wg+yCQbe35l8dw==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "semver": "^5.4.1" | ||||
|       } | ||||
|     }, | ||||
|     "node-addon-api": { | ||||
|       "version": "3.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.0.tgz", | ||||
|       "integrity": "sha512-sSHCgWfJ+Lui/u+0msF3oyCgvdkhxDbkCS6Q8uiJquzOimkJBvX6hl5aSSA7DR1XbMpdM8r7phjcF63sF4rkKg==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "node-gyp": { | ||||
|       "version": "3.8.0", | ||||
|       "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", | ||||
| @ -10764,6 +11077,12 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "noop-logger": { | ||||
|       "version": "0.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", | ||||
|       "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "nopt": { | ||||
|       "version": "3.0.6", | ||||
|       "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", | ||||
| @ -11581,6 +11900,41 @@ | ||||
|       "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "prebuild-install": { | ||||
|       "version": "5.3.4", | ||||
|       "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.4.tgz", | ||||
|       "integrity": "sha512-AkKN+pf4fSEihjapLEEj8n85YIw/tN6BQqkhzbDc0RvEZGdkpJBGMUYx66AAMcPG2KzmPQS7Cm16an4HVBRRMA==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "detect-libc": "^1.0.3", | ||||
|         "expand-template": "^2.0.3", | ||||
|         "github-from-package": "0.0.0", | ||||
|         "minimist": "^1.2.3", | ||||
|         "mkdirp": "^0.5.1", | ||||
|         "napi-build-utils": "^1.0.1", | ||||
|         "node-abi": "^2.7.0", | ||||
|         "noop-logger": "^0.1.1", | ||||
|         "npmlog": "^4.0.1", | ||||
|         "pump": "^3.0.0", | ||||
|         "rc": "^1.2.7", | ||||
|         "simple-get": "^3.0.3", | ||||
|         "tar-fs": "^2.0.0", | ||||
|         "tunnel-agent": "^0.6.0", | ||||
|         "which-pm-runs": "^1.0.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "pump": { | ||||
|           "version": "3.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", | ||||
|           "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "end-of-stream": "^1.1.0", | ||||
|             "once": "^1.3.1" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "prelude-ls": { | ||||
|       "version": "1.1.2", | ||||
|       "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", | ||||
| @ -12090,6 +12444,18 @@ | ||||
|         "remove-bom-buffer": "^3.0.0", | ||||
|         "safe-buffer": "^5.1.0", | ||||
|         "through2": "^2.0.3" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "through2": { | ||||
|           "version": "2.0.5", | ||||
|           "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", | ||||
|           "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "readable-stream": "~2.3.6", | ||||
|             "xtend": "~4.0.1" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "remove-trailing-separator": { | ||||
| @ -12613,12 +12979,9 @@ | ||||
|       "dev": true | ||||
|     }, | ||||
|     "run-async": { | ||||
|       "version": "2.3.0", | ||||
|       "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", | ||||
|       "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", | ||||
|       "requires": { | ||||
|         "is-promise": "^2.1.0" | ||||
|       } | ||||
|       "version": "2.4.1", | ||||
|       "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", | ||||
|       "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" | ||||
|     }, | ||||
|     "rxjs": { | ||||
|       "version": "5.5.12", | ||||
| @ -13018,6 +13381,23 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "simple-concat": { | ||||
|       "version": "1.0.1", | ||||
|       "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", | ||||
|       "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "simple-get": { | ||||
|       "version": "3.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", | ||||
|       "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "decompress-response": "^4.2.0", | ||||
|         "once": "^1.3.1", | ||||
|         "simple-concat": "^1.0.0" | ||||
|       } | ||||
|     }, | ||||
|     "simple-plist": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.0.0.tgz", | ||||
| @ -13769,6 +14149,56 @@ | ||||
|         "inherits": "2" | ||||
|       } | ||||
|     }, | ||||
|     "tar-fs": { | ||||
|       "version": "2.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.0.tgz", | ||||
|       "integrity": "sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "chownr": "^1.1.1", | ||||
|         "mkdirp-classic": "^0.5.2", | ||||
|         "pump": "^3.0.0", | ||||
|         "tar-stream": "^2.0.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "pump": { | ||||
|           "version": "3.0.0", | ||||
|           "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", | ||||
|           "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "end-of-stream": "^1.1.0", | ||||
|             "once": "^1.3.1" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "tar-stream": { | ||||
|       "version": "2.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.3.tgz", | ||||
|       "integrity": "sha512-Z9yri56Dih8IaK8gncVPx4Wqt86NDmQTSh49XLZgjWpGZL9GK9HKParS2scqHCC4w6X9Gh2jwaU45V47XTKwVA==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "bl": "^4.0.1", | ||||
|         "end-of-stream": "^1.4.1", | ||||
|         "fs-constants": "^1.0.0", | ||||
|         "inherits": "^2.0.3", | ||||
|         "readable-stream": "^3.1.1" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "readable-stream": { | ||||
|           "version": "3.6.0", | ||||
|           "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", | ||||
|           "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "inherits": "^2.0.3", | ||||
|             "string_decoder": "^1.1.1", | ||||
|             "util-deprecate": "^1.0.1" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "temp-file": { | ||||
|       "version": "3.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.1.3.tgz", | ||||
| @ -13794,16 +14224,6 @@ | ||||
|       "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", | ||||
|       "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" | ||||
|     }, | ||||
|     "through2": { | ||||
|       "version": "2.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", | ||||
|       "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "readable-stream": "^2.1.5", | ||||
|         "xtend": "~4.0.1" | ||||
|       } | ||||
|     }, | ||||
|     "through2-filter": { | ||||
|       "version": "3.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", | ||||
| @ -13812,6 +14232,18 @@ | ||||
|       "requires": { | ||||
|         "through2": "~2.0.0", | ||||
|         "xtend": "~4.0.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "through2": { | ||||
|           "version": "2.0.5", | ||||
|           "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", | ||||
|           "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "readable-stream": "~2.3.6", | ||||
|             "xtend": "~4.0.1" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "thunkify": { | ||||
| @ -13960,6 +14392,18 @@ | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "through2": "^2.0.3" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "through2": { | ||||
|           "version": "2.0.5", | ||||
|           "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", | ||||
|           "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "readable-stream": "~2.3.6", | ||||
|             "xtend": "~4.0.1" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "tough-cookie": { | ||||
| @ -14102,8 +14546,7 @@ | ||||
|     "type-fest": { | ||||
|       "version": "0.11.0", | ||||
|       "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", | ||||
|       "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", | ||||
|       "dev": true | ||||
|       "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==" | ||||
|     }, | ||||
|     "type-is": { | ||||
|       "version": "1.6.16", | ||||
| @ -14587,6 +15030,18 @@ | ||||
|         "value-or-function": "^3.0.0", | ||||
|         "vinyl": "^2.0.0", | ||||
|         "vinyl-sourcemap": "^1.1.0" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "through2": { | ||||
|           "version": "2.0.5", | ||||
|           "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", | ||||
|           "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "readable-stream": "~2.3.6", | ||||
|             "xtend": "~4.0.1" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "vinyl-sourcemap": { | ||||
| @ -15469,6 +15924,12 @@ | ||||
|       "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "which-pm-runs": { | ||||
|       "version": "1.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", | ||||
|       "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "wide-align": { | ||||
|       "version": "1.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", | ||||
|  | ||||
| @ -119,6 +119,7 @@ | ||||
|     "cordova-support-google-services": "^1.3.2", | ||||
|     "es6-promise-plugin": "^4.2.2", | ||||
|     "font-awesome": "^4.7.0", | ||||
|     "inquirer": "^7.3.2", | ||||
|     "ionic-angular": "3.9.9", | ||||
|     "ionicons": "3.0.0", | ||||
|     "jszip": "^3.1.5", | ||||
| @ -153,6 +154,7 @@ | ||||
|     "gulp-htmlmin": "^5.0.1", | ||||
|     "gulp-rename": "^2.0.0", | ||||
|     "gulp-slash": "^1.1.3", | ||||
|     "keytar": "^6.0.1", | ||||
|     "lodash.template": "^4.5.0", | ||||
|     "minimist": "^1.2.5", | ||||
|     "native-run": "^1.0.0", | ||||
| @ -276,4 +278,4 @@ | ||||
|   "engines": { | ||||
|     "node": ">=11.x" | ||||
|   } | ||||
| } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user