From a79dd578ab6fd1146eeeda10f339526da7839ffb Mon Sep 17 00:00:00 2001 From: yasmanets <34303875+yasmanets@users.noreply.github.com> Date: Tue, 31 Mar 2020 17:42:51 +0200 Subject: [PATCH 01/25] Create nodejs.yml --- .github/workflows/nodejs.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/nodejs.yml diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml new file mode 100644 index 0000000..515d525 --- /dev/null +++ b/.github/workflows/nodejs.yml @@ -0,0 +1,30 @@ +# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: Node.js CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [12.15.0] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: npm ci + - run: npm test + env: + CI: true From d3fb40e0fb6ffac6486adcfeb2da1f6888881ac2 Mon Sep 17 00:00:00 2001 From: yasmanets <34303875+yasmanets@users.noreply.github.com> Date: Tue, 31 Mar 2020 17:44:59 +0200 Subject: [PATCH 02/25] Update vCardFormatter.js --- lib/vCardFormatter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/vCardFormatter.js b/lib/vCardFormatter.js index 903eb8b..2d0d33e 100644 --- a/lib/vCardFormatter.js +++ b/lib/vCardFormatter.js @@ -375,7 +375,7 @@ for (var key in vCard.socialUrls) { if (vCard.socialUrls.hasOwnProperty(key) && vCard.socialUrls[key]) { - formattedVCardString += 'X-SOCIALPROFILE;TYPE=' + key + ':' + e(vCard.socialUrls[key]) + nl(); + formattedVCardString += 'X-SOCIALPROFILE:TYPE=' + key + ':' + e(vCard.socialUrls[key]) + nl(); } } } @@ -394,4 +394,4 @@ return formattedVCardString; } }; -})(); \ No newline at end of file +})(); From c4e05e3473ae4c66613a5d1e8c394e6f2bb836cb Mon Sep 17 00:00:00 2001 From: yasmanets <34303875+yasmanets@users.noreply.github.com> Date: Tue, 31 Mar 2020 17:48:22 +0200 Subject: [PATCH 03/25] multiple url for Android devices --- lib/vCardFormatter.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/vCardFormatter.js b/lib/vCardFormatter.js index 2d0d33e..bd701dd 100644 --- a/lib/vCardFormatter.js +++ b/lib/vCardFormatter.js @@ -360,7 +360,9 @@ } if (vCard.url) { - formattedVCardString += 'URL' + encodingPrefix + ':' + e(vCard.url) + nl(); + vCard.url.forEach((number) => { + formattedVCardString += 'URL' + encodingPrefix + ':' + e(number) + nl(); + }); } if (vCard.workUrl) { From 558b8440bc6988fc96bc23a2273e44937c43df38 Mon Sep 17 00:00:00 2001 From: Yaser Date: Sun, 5 Apr 2020 17:15:45 +0200 Subject: [PATCH 04/25] linter --- lib/vCardFormatter.js | 637 ++++++++++++++------------- package-lock.json | 998 +++++++++++++++++++++++++++++++++++++++++- package.json | 7 +- test/testCard.vcf | 12 +- 4 files changed, 1329 insertions(+), 325 deletions(-) diff --git a/lib/vCardFormatter.js b/lib/vCardFormatter.js index bd701dd..3e9770e 100644 --- a/lib/vCardFormatter.js +++ b/lib/vCardFormatter.js @@ -8,392 +8,397 @@ * vCard formatter for formatting vCards in VCF format */ (function vCardFormatter() { - var majorVersion = '3'; + var majorVersion = '3'; - /** + /** * Encode string * @param {String} value to encode * @return {String} encoded string */ - function e(value) { - if (value) { - if (typeof(value) !== 'string') { - value = '' + value; - } - return value.replace(/\n/g, '\\n').replace(/,/g, '\\,').replace(/;/g, '\\;'); - } - return ''; - } - - /** + function e(value) { + if (value) { + if (typeof(value) !== 'string') { + value = '' + value; + } + return value.replace(/\n/g, '\\n').replace(/,/g, '\\,').replace(/;/g, '\\;'); + } + return ''; + } + + /** * Return new line characters * @return {String} new line characters */ - function nl() { - return '\r\n'; - } + function nl() { + return '\r\n'; + } - /** + /** * Get formatted photo * @param {String} photoType Photo type (PHOTO, LOGO) * @param {String} url URL to attach photo from * @param {String} mediaType Media-type of photo (JPEG, PNG, GIF) * @return {String} Formatted photo */ - function getFormattedPhoto(photoType, url, mediaType, base64) { + function getFormattedPhoto(photoType, url, mediaType, base64) { - var params; + var params; - if (majorVersion >= 4) { - params = base64 ? ';ENCODING=b;MEDIATYPE=image/' : ';MEDIATYPE=image/'; - } else if (majorVersion === 3) { - params = base64 ? ';ENCODING=b;TYPE=' : ';TYPE='; - } else { - params = base64 ? ';ENCODING=BASE64;' : ';'; - } + if (majorVersion >= 4) { + params = base64 ? ';ENCODING=b;MEDIATYPE=image/' : ';MEDIATYPE=image/'; + } else if (majorVersion === 3) { + params = base64 ? ';ENCODING=b;TYPE=' : ';TYPE='; + } else { + params = base64 ? ';ENCODING=BASE64;' : ';'; + } - var formattedPhoto = photoType + params + mediaType + ':' + e(url) + nl(); - return formattedPhoto; - } + var formattedPhoto = photoType + params + mediaType + ':' + e(url) + nl(); + return formattedPhoto; + } - /** + /** * Get formatted address * @param {object} address * @param {object} encoding prefix * @return {String} Formatted address */ - function getFormattedAddress(encodingPrefix, address) { + function getFormattedAddress(encodingPrefix, address) { - var formattedAddress = ''; + var formattedAddress = ''; - if (address.details.label || + if (address.details.label || address.details.street || address.details.city || address.details.stateProvince || address.details.postalCode || address.details.countryRegion) { - if (majorVersion >= 4) { - formattedAddress = 'ADR' + encodingPrefix + ';TYPE=' + address.type + + if (majorVersion >= 4) { + formattedAddress = 'ADR' + encodingPrefix + ';TYPE=' + address.type + (address.details.label ? ';LABEL="' + e(address.details.label) + '"' : '') + ':;;' + e(address.details.street) + ';' + e(address.details.city) + ';' + e(address.details.stateProvince) + ';' + e(address.details.postalCode) + ';' + e(address.details.countryRegion) + nl(); - } else { - if (address.details.label) { - formattedAddress = 'LABEL' + encodingPrefix + ';TYPE=' + address.type + ':' + e(address.details.label) + nl(); - } - formattedAddress += 'ADR' + encodingPrefix + ';TYPE=' + address.type + ':;;' + + } else { + if (address.details.label) { + formattedAddress = 'LABEL' + encodingPrefix + ';TYPE=' + address.type + ':' + e(address.details.label) + nl(); + } + formattedAddress += 'ADR' + encodingPrefix + ';TYPE=' + address.type + ':;;' + e(address.details.street) + ';' + e(address.details.city) + ';' + e(address.details.stateProvince) + ';' + e(address.details.postalCode) + ';' + e(address.details.countryRegion) + nl(); - } - } + } + } - return formattedAddress; - } + return formattedAddress; + } - /** + /** * Convert date to YYYYMMDD format * @param {Date} date to encode * @return {String} encoded date */ - function YYYYMMDD(date) { - return date.getFullYear() + ('0' + (date.getMonth()+1)).slice(-2) + ('0' + date.getDate()).slice(-2); - } + function YYYYMMDD(date) { + return date.getFullYear() + ('0' + (date.getMonth()+1)).slice(-2) + ('0' + date.getDate()).slice(-2); + } - module.exports = { + module.exports = { - /** + /** * Get formatted vCard in VCF format * @param {object} vCard object * @return {String} Formatted vCard in VCF format */ - getFormattedString: function(vCard) { + getFormattedString: function(vCard) { - majorVersion = vCard.getMajorVersion(); + majorVersion = vCard.getMajorVersion(); - var formattedVCardString = ''; - formattedVCardString += 'BEGIN:VCARD' + nl(); - formattedVCardString += 'VERSION:' + vCard.version + nl(); + var formattedVCardString = ''; + formattedVCardString += 'BEGIN:VCARD' + nl(); + formattedVCardString += 'VERSION:' + vCard.version + nl(); - var encodingPrefix = majorVersion >= 4 ? '' : ';CHARSET=UTF-8'; - var formattedName = vCard.formattedName; + var encodingPrefix = majorVersion >= 4 ? '' : ';CHARSET=UTF-8'; + var formattedName = vCard.formattedName; - if (!formattedName) { - formattedName = ''; + if (!formattedName) { + formattedName = ''; - [vCard.firstName, vCard.middleName, vCard.lastName] - .forEach(function(name) { - if (name) { - if (formattedName) { - formattedName += ' '; - } - } - formattedName += name; - }); - } + [vCard.firstName, vCard.middleName, vCard.lastName] + .forEach(function(name) { + if (name) { + if (formattedName) { + formattedName += ' '; + } + } + formattedName += name; + }); + } - formattedVCardString += 'FN' + encodingPrefix + ':' + e(formattedName) + nl(); - formattedVCardString += 'N' + encodingPrefix + ':' + + formattedVCardString += 'FN' + encodingPrefix + ':' + e(formattedName) + nl(); + formattedVCardString += 'N' + encodingPrefix + ':' + e(vCard.lastName) + ';' + e(vCard.firstName) + ';' + e(vCard.middleName) + ';' + e(vCard.namePrefix) + ';' + e(vCard.nameSuffix) + nl(); - if (vCard.nickname && majorVersion >= 3) { - formattedVCardString += 'NICKNAME' + encodingPrefix + ':' + e(vCard.nickname) + nl(); - } - - if (vCard.gender) { - formattedVCardString += 'GENDER:' + e(vCard.gender) + nl(); - } - - if (vCard.uid) { - formattedVCardString += 'UID' + encodingPrefix + ':' + e(vCard.uid) + nl(); - } - - if (vCard.birthday) { - formattedVCardString += 'BDAY:' + YYYYMMDD(vCard.birthday) + nl(); - } - - if (vCard.anniversary) { - formattedVCardString += 'ANNIVERSARY:' + YYYYMMDD(vCard.anniversary) + nl(); - } - - if (vCard.email) { - if(!Array.isArray(vCard.email)){ - vCard.email = [vCard.email]; - } - vCard.email.forEach( - function(address) { - if (majorVersion >= 4) { - formattedVCardString += 'EMAIL' + encodingPrefix + ';type=HOME:' + e(address) + nl(); - } else if (majorVersion >= 3 && majorVersion < 4) { - formattedVCardString += 'EMAIL' + encodingPrefix + ';type=HOME,INTERNET:' + e(address) + nl(); - } else { - formattedVCardString += 'EMAIL' + encodingPrefix + ';HOME;INTERNET:' + e(address) + nl(); - } - } - ); - } - - if (vCard.workEmail) { - if(!Array.isArray(vCard.workEmail)){ - vCard.workEmail = [vCard.workEmail]; - } - vCard.workEmail.forEach( - function(address) { - if (majorVersion >= 4) { - formattedVCardString += 'EMAIL' + encodingPrefix + ';type=WORK:' + e(address) + nl(); - } else if (majorVersion >= 3 && majorVersion < 4) { - formattedVCardString += 'EMAIL' + encodingPrefix + ';type=WORK,INTERNET:' + e(address) + nl(); - } else { - formattedVCardString += 'EMAIL' + encodingPrefix + ';WORK;INTERNET:' + e(address) + nl(); - } - } - ); - } - - if (vCard.otherEmail) { - if(!Array.isArray(vCard.otherEmail)){ - vCard.otherEmail = [vCard.otherEmail]; - } - vCard.otherEmail.forEach( - function(address) { - if (majorVersion >= 4) { - formattedVCardString += 'EMAIL' + encodingPrefix + ';type=OTHER:' + e(address) + nl(); - } else if (majorVersion >= 3 && majorVersion < 4) { - formattedVCardString += 'EMAIL' + encodingPrefix + ';type=OTHER,INTERNET:' + e(address) + nl(); - } else { - formattedVCardString += 'EMAIL' + encodingPrefix + ';OTHER;INTERNET:' + e(address) + nl(); - } - } - ); - } - - if (vCard.logo.url) { - formattedVCardString += getFormattedPhoto('LOGO', vCard.logo.url, vCard.logo.mediaType, vCard.logo.base64); - } - - if (vCard.photo.url) { - formattedVCardString += getFormattedPhoto('PHOTO', vCard.photo.url, vCard.photo.mediaType, vCard.photo.base64); - } - - if (vCard.cellPhone) { - if(!Array.isArray(vCard.cellPhone)){ - vCard.cellPhone = [vCard.cellPhone]; - } - vCard.cellPhone.forEach( - function(number){ - if (majorVersion >= 4) { - formattedVCardString += 'TEL;VALUE=uri;TYPE="voice,cell":tel:' + e(number) + nl(); - } else { - formattedVCardString += 'TEL;TYPE=CELL:' + e(number) + nl(); - } - } - ); - } - - if (vCard.pagerPhone) { - if(!Array.isArray(vCard.pagerPhone)){ - vCard.pagerPhone = [vCard.pagerPhone]; - } - vCard.pagerPhone.forEach( - function(number) { - if (majorVersion >= 4) { - formattedVCardString += 'TEL;VALUE=uri;TYPE="pager,cell":tel:' + e(number) + nl(); - } else { - formattedVCardString += 'TEL;TYPE=PAGER:' + e(number) + nl(); - } - } - ); - } - - if (vCard.homePhone) { - if(!Array.isArray(vCard.homePhone)){ - vCard.homePhone = [vCard.homePhone]; - } - vCard.homePhone.forEach( - function(number) { - if (majorVersion >= 4) { - formattedVCardString += 'TEL;VALUE=uri;TYPE="voice,home":tel:' + e(number) + nl(); - } else { - formattedVCardString += 'TEL;TYPE=HOME,VOICE:' + e(number) + nl(); - } - } - ); - } - - if (vCard.workPhone) { - if(!Array.isArray(vCard.workPhone)){ - vCard.workPhone = [vCard.workPhone]; - } - vCard.workPhone.forEach( - function(number) { - if (majorVersion >= 4) { - formattedVCardString += 'TEL;VALUE=uri;TYPE="voice,work":tel:' + e(number) + nl(); - - } else { - formattedVCardString += 'TEL;TYPE=WORK,VOICE:' + e(number) + nl(); - } - } - ); - } - - if (vCard.homeFax) { - if(!Array.isArray(vCard.homeFax)){ - vCard.homeFax = [vCard.homeFax]; - } - vCard.homeFax.forEach( - function(number) { - if (majorVersion >= 4) { - formattedVCardString += 'TEL;VALUE=uri;TYPE="fax,home":tel:' + e(number) + nl(); - - } else { - formattedVCardString += 'TEL;TYPE=HOME,FAX:' + e(number) + nl(); - } - } - ); - } - - if (vCard.workFax) { - if(!Array.isArray(vCard.workFax)){ - vCard.workFax = [vCard.workFax]; - } - vCard.workFax.forEach( - function(number) { - if (majorVersion >= 4) { - formattedVCardString += 'TEL;VALUE=uri;TYPE="fax,work":tel:' + e(number) + nl(); - - } else { - formattedVCardString += 'TEL;TYPE=WORK,FAX:' + e(number) + nl(); - } - } - ); - } - - if (vCard.otherPhone) { - if(!Array.isArray(vCard.otherPhone)){ - vCard.otherPhone = [vCard.otherPhone]; - } - vCard.otherPhone.forEach( - function(number) { - if (majorVersion >= 4) { - formattedVCardString += 'TEL;VALUE=uri;TYPE="voice,other":tel:' + e(number) + nl(); - - } else { - formattedVCardString += 'TEL;TYPE=OTHER:' + e(number) + nl(); - } - } - ); - } - - [{ - details: vCard.homeAddress, - type: 'HOME' - }, { - details: vCard.workAddress, - type: 'WORK' - }].forEach( - function(address) { - formattedVCardString += getFormattedAddress(encodingPrefix, address); - } - ); - - if (vCard.title) { - formattedVCardString += 'TITLE' + encodingPrefix + ':' + e(vCard.title) + nl(); - } - - if (vCard.role) { - formattedVCardString += 'ROLE' + encodingPrefix + ':' + e(vCard.role) + nl(); - } - - if (vCard.organization) { - formattedVCardString += 'ORG' + encodingPrefix + ':' + e(vCard.organization) + nl(); - } - - if (vCard.url) { - vCard.url.forEach((number) => { - formattedVCardString += 'URL' + encodingPrefix + ':' + e(number) + nl(); - }); - } - - if (vCard.workUrl) { - formattedVCardString += 'URL;type=WORK' + encodingPrefix + ':' + e(vCard.workUrl) + nl(); - } - - if (vCard.note) { - formattedVCardString += 'NOTE' + encodingPrefix + ':' + e(vCard.note) + nl(); - } - - if (vCard.socialUrls) { - for (var key in vCard.socialUrls) { - if (vCard.socialUrls.hasOwnProperty(key) && + if (vCard.nickname && majorVersion >= 3) { + formattedVCardString += 'NICKNAME' + encodingPrefix + ':' + e(vCard.nickname) + nl(); + } + + if (vCard.gender) { + formattedVCardString += 'GENDER:' + e(vCard.gender) + nl(); + } + + if (vCard.uid) { + formattedVCardString += 'UID' + encodingPrefix + ':' + e(vCard.uid) + nl(); + } + + if (vCard.birthday) { + formattedVCardString += 'BDAY:' + YYYYMMDD(vCard.birthday) + nl(); + } + + if (vCard.anniversary) { + formattedVCardString += 'ANNIVERSARY:' + YYYYMMDD(vCard.anniversary) + nl(); + } + + if (vCard.email) { + if(!Array.isArray(vCard.email)){ + vCard.email = [vCard.email]; + } + vCard.email.forEach( + function(address) { + if (majorVersion >= 4) { + formattedVCardString += 'EMAIL' + encodingPrefix + ';type=HOME:' + e(address) + nl(); + } else if (majorVersion >= 3 && majorVersion < 4) { + formattedVCardString += 'EMAIL' + encodingPrefix + ';type=HOME,INTERNET:' + e(address) + nl(); + } else { + formattedVCardString += 'EMAIL' + encodingPrefix + ';HOME;INTERNET:' + e(address) + nl(); + } + } + ); + } + + if (vCard.workEmail) { + if(!Array.isArray(vCard.workEmail)){ + vCard.workEmail = [vCard.workEmail]; + } + vCard.workEmail.forEach( + function(address) { + if (majorVersion >= 4) { + formattedVCardString += 'EMAIL' + encodingPrefix + ';type=WORK:' + e(address) + nl(); + } else if (majorVersion >= 3 && majorVersion < 4) { + formattedVCardString += 'EMAIL' + encodingPrefix + ';type=WORK,INTERNET:' + e(address) + nl(); + } else { + formattedVCardString += 'EMAIL' + encodingPrefix + ';WORK;INTERNET:' + e(address) + nl(); + } + } + ); + } + + if (vCard.otherEmail) { + if(!Array.isArray(vCard.otherEmail)){ + vCard.otherEmail = [vCard.otherEmail]; + } + vCard.otherEmail.forEach( + function(address) { + if (majorVersion >= 4) { + formattedVCardString += 'EMAIL' + encodingPrefix + ';type=OTHER:' + e(address) + nl(); + } else if (majorVersion >= 3 && majorVersion < 4) { + formattedVCardString += 'EMAIL' + encodingPrefix + ';type=OTHER,INTERNET:' + e(address) + nl(); + } else { + formattedVCardString += 'EMAIL' + encodingPrefix + ';OTHER;INTERNET:' + e(address) + nl(); + } + } + ); + } + + if (vCard.logo.url) { + formattedVCardString += getFormattedPhoto('LOGO', vCard.logo.url, vCard.logo.mediaType, vCard.logo.base64); + } + + if (vCard.photo.url) { + formattedVCardString += getFormattedPhoto('PHOTO', vCard.photo.url, vCard.photo.mediaType, vCard.photo.base64); + } + + if (vCard.cellPhone) { + if(!Array.isArray(vCard.cellPhone)){ + vCard.cellPhone = [vCard.cellPhone]; + } + vCard.cellPhone.forEach( + function(number){ + if (majorVersion >= 4) { + formattedVCardString += 'TEL;VALUE=uri;TYPE="voice,cell":tel:' + e(number) + nl(); + } else { + formattedVCardString += 'TEL;TYPE=CELL:' + e(number) + nl(); + } + } + ); + } + + if (vCard.pagerPhone) { + if(!Array.isArray(vCard.pagerPhone)){ + vCard.pagerPhone = [vCard.pagerPhone]; + } + vCard.pagerPhone.forEach( + function(number) { + if (majorVersion >= 4) { + formattedVCardString += 'TEL;VALUE=uri;TYPE="pager,cell":tel:' + e(number) + nl(); + } else { + formattedVCardString += 'TEL;TYPE=PAGER:' + e(number) + nl(); + } + } + ); + } + + if (vCard.homePhone) { + if(!Array.isArray(vCard.homePhone)){ + vCard.homePhone = [vCard.homePhone]; + } + vCard.homePhone.forEach( + function(number) { + if (majorVersion >= 4) { + formattedVCardString += 'TEL;VALUE=uri;TYPE="voice,home":tel:' + e(number) + nl(); + } else { + formattedVCardString += 'TEL;TYPE=HOME,VOICE:' + e(number) + nl(); + } + } + ); + } + + if (vCard.workPhone) { + if(!Array.isArray(vCard.workPhone)){ + vCard.workPhone = [vCard.workPhone]; + } + vCard.workPhone.forEach( + function(number) { + if (majorVersion >= 4) { + formattedVCardString += 'TEL;VALUE=uri;TYPE="voice,work":tel:' + e(number) + nl(); + + } else { + formattedVCardString += 'TEL;TYPE=WORK,VOICE:' + e(number) + nl(); + } + } + ); + } + + if (vCard.homeFax) { + if(!Array.isArray(vCard.homeFax)){ + vCard.homeFax = [vCard.homeFax]; + } + vCard.homeFax.forEach( + function(number) { + if (majorVersion >= 4) { + formattedVCardString += 'TEL;VALUE=uri;TYPE="fax,home":tel:' + e(number) + nl(); + + } else { + formattedVCardString += 'TEL;TYPE=HOME,FAX:' + e(number) + nl(); + } + } + ); + } + + if (vCard.workFax) { + if(!Array.isArray(vCard.workFax)){ + vCard.workFax = [vCard.workFax]; + } + vCard.workFax.forEach( + function(number) { + if (majorVersion >= 4) { + formattedVCardString += 'TEL;VALUE=uri;TYPE="fax,work":tel:' + e(number) + nl(); + + } else { + formattedVCardString += 'TEL;TYPE=WORK,FAX:' + e(number) + nl(); + } + } + ); + } + + if (vCard.otherPhone) { + if(!Array.isArray(vCard.otherPhone)){ + vCard.otherPhone = [vCard.otherPhone]; + } + vCard.otherPhone.forEach( + function(number) { + if (majorVersion >= 4) { + formattedVCardString += 'TEL;VALUE=uri;TYPE="voice,other":tel:' + e(number) + nl(); + + } else { + formattedVCardString += 'TEL;TYPE=OTHER:' + e(number) + nl(); + } + } + ); + } + + [{ + details: vCard.homeAddress, + type: 'HOME' + }, { + details: vCard.workAddress, + type: 'WORK' + }].forEach( + function(address) { + formattedVCardString += getFormattedAddress(encodingPrefix, address); + } + ); + + if (vCard.title) { + formattedVCardString += 'TITLE' + encodingPrefix + ':' + e(vCard.title) + nl(); + } + + if (vCard.role) { + formattedVCardString += 'ROLE' + encodingPrefix + ':' + e(vCard.role) + nl(); + } + + if (vCard.organization) { + formattedVCardString += 'ORG' + encodingPrefix + ':' + e(vCard.organization) + nl(); + } + + if (vCard.url) { + if (!Array.isArray(vCard.url)) { + formattedVCardString += 'URL' + encodingPrefix + ':' + e(vCard.url) + nl(); + } + else { + vCard.url.forEach((number) => { + formattedVCardString += 'URL' + encodingPrefix + ':' + e(number) + nl(); + }); + } + } + + if (vCard.workUrl) { + formattedVCardString += 'URL;type=WORK' + encodingPrefix + ':' + e(vCard.workUrl) + nl(); + } + + if (vCard.note) { + formattedVCardString += 'NOTE' + encodingPrefix + ':' + e(vCard.note) + nl(); + } + + if (vCard.socialUrls) { + for (var key in vCard.socialUrls) { + if (vCard.socialUrls.hasOwnProperty(key) && vCard.socialUrls[key]) { - formattedVCardString += 'X-SOCIALPROFILE:TYPE=' + key + ':' + e(vCard.socialUrls[key]) + nl(); - } - } - } + formattedVCardString += 'X-SOCIALPROFILE:TYPE=' + key + ':' + e(vCard.socialUrls[key]) + nl(); + } + } + } - if (vCard.source) { - formattedVCardString += 'SOURCE' + encodingPrefix + ':' + e(vCard.source) + nl(); - } + if (vCard.source) { + formattedVCardString += 'SOURCE' + encodingPrefix + ':' + e(vCard.source) + nl(); + } - formattedVCardString += 'REV:' + (new Date()).toISOString() + nl(); + formattedVCardString += 'REV:' + (new Date()).toISOString() + nl(); - if (vCard.isOrganization) { - formattedVCardString += 'X-ABShowAs:COMPANY' + nl(); - } + if (vCard.isOrganization) { + formattedVCardString += 'X-ABShowAs:COMPANY' + nl(); + } - formattedVCardString += 'END:VCARD' + nl(); - return formattedVCardString; - } - }; -})(); + formattedVCardString += 'END:VCARD' + nl(); + return formattedVCardString; + } + }; +}()); diff --git a/package-lock.json b/package-lock.json index 98fe143..7e43301 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9 +1,112 @@ { "name": "vcards-js", - "version": "2.9.0", + "version": "2.10.0", "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz", + "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@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 + }, + "acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "dev": true + }, + "acorn-jsx": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", + "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "dev": true + }, + "ajv": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "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==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "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 + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -26,6 +129,59 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, "commander": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", @@ -38,6 +194,27 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", @@ -47,24 +224,263 @@ "ms": "2.0.0" } }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "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==", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "eslint": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", + "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.3", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.2", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.3", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "eslint-config-google": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", + "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", + "dev": true + }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true + }, + "espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.2.0.tgz", + "integrity": "sha512-weltsSqdeWIX9G2qQZz7KlTRJdkkOCTPgLYJUz1Hacf48R4YOwGPHO3+ORfWedqJKbq5WQmsgK90n+pFLIKt/Q==", + "dev": true, + "requires": { + "estraverse": "^5.0.0" + }, + "dependencies": { + "estraverse": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.0.0.tgz", + "integrity": "sha512-j3acdrMzqrxmJTNj5dbr1YbjacrYgAxVMeF0gK16E3j494mOe7xygM/ZLIguEQ0ETwAg2hlJCtHRGav+y0Ny5A==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", @@ -79,6 +495,24 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -97,6 +531,37 @@ "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -113,6 +578,171 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, + "inquirer": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", + "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "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==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "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==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -162,6 +792,24 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -171,12 +819,242 @@ "wrappy": "1" } }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "run-async": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", + "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", + "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "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=", + "dev": true + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } + } + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + }, "supports-color": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", @@ -186,11 +1064,129 @@ "has-flag": "^3.0.0" } }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "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=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tslib": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", + "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } } } } diff --git a/package.json b/package.json index 5d04291..b5e25cf 100644 --- a/package.json +++ b/package.json @@ -5,10 +5,13 @@ "main": "index.js", "dependencies": {}, "devDependencies": { + "eslint": "^6.8.0", + "eslint-config-google": "^0.14.0", "mocha": "~5.2.0" }, "scripts": { - "test": "mocha ./test/tests" + "test": "mocha ./test/tests", + "lint-test": "npm run lint" }, "repository": { "type": "git", @@ -35,4 +38,4 @@ "sensotix (https://github.com/sensotix)", "Randy Stevens (https://github.com/RandyStevens)" ] -} \ No newline at end of file +} diff --git a/test/testCard.vcf b/test/testCard.vcf index 0769ff0..4ea99fa 100644 --- a/test/testCard.vcf +++ b/test/testCard.vcf @@ -27,11 +27,11 @@ ORG;CHARSET=UTF-8:ACME Corporation URL;CHARSET=UTF-8:http://johndoe URL;type=WORK;CHARSET=UTF-8:http://acemecompany/johndoe NOTE;CHARSET=UTF-8:John Doe's \nnotes\;\, -X-SOCIALPROFILE;TYPE=facebook:https://facebook/johndoe -X-SOCIALPROFILE;TYPE=linkedIn:https://linkedin/johndoe -X-SOCIALPROFILE;TYPE=twitter:https://twitter/johndoe -X-SOCIALPROFILE;TYPE=flickr:https://flickr/johndoe -X-SOCIALPROFILE;TYPE=custom:https://custom/johndoe +X-SOCIALPROFILE:TYPE=facebook:https://facebook/johndoe +X-SOCIALPROFILE:TYPE=linkedIn:https://linkedin/johndoe +X-SOCIALPROFILE:TYPE=twitter:https://twitter/johndoe +X-SOCIALPROFILE:TYPE=flickr:https://flickr/johndoe +X-SOCIALPROFILE:TYPE=custom:https://custom/johndoe SOURCE;CHARSET=UTF-8:http://sourceurl -REV:2019-01-04T20:18:50.127Z +REV:2020-04-05T15:14:37.180Z END:VCARD From de130b0538b9ccb47bb27e801b568fa89fe41872 Mon Sep 17 00:00:00 2001 From: Yaser Date: Sun, 5 Apr 2020 17:40:01 +0200 Subject: [PATCH 05/25] Allows you to set custom URLs for ios devices --- lib/vCardFormatter.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/vCardFormatter.js b/lib/vCardFormatter.js index 3e9770e..4886536 100644 --- a/lib/vCardFormatter.js +++ b/lib/vCardFormatter.js @@ -364,12 +364,25 @@ formattedVCardString += 'URL' + encodingPrefix + ':' + e(vCard.url) + nl(); } else { - vCard.url.forEach((number) => { - formattedVCardString += 'URL' + encodingPrefix + ':' + e(number) + nl(); + vCard.url.forEach((url) => { + formattedVCardString += 'URL' + encodingPrefix + ':' + e(url) + nl(); }); } } - + + if (vCard.iosURL) { + if (!Array.isArray(vCard.iosURL)) { + formattedVCardString += 'item1.URL' + encodingPrefix + ':' + e(vCard.iosURL) + nl(); + formattedVCardString += 'item1.X-ABLABEL' + encodingPrefix + ':' + e(vCard.label) + nl(); + } + else { + vCard.iosURL.forEach((url, index) => { + formattedVCardString += 'item' + (index + 1) + '.URL' + encodingPrefix + ':' + e(url) + nl(); + formattedVCardString += 'item' + (index + 1) + '.X-ABLABEL' + encodingPrefix + ':' + e(vCard.label[index]) + nl(); + }); + } + } + if (vCard.workUrl) { formattedVCardString += 'URL;type=WORK' + encodingPrefix + ':' + e(vCard.workUrl) + nl(); } From f08c4fa1f707d490da0e0e5735c3494d7d37304d Mon Sep 17 00:00:00 2001 From: Yaser Date: Sun, 5 Apr 2020 17:40:38 +0200 Subject: [PATCH 06/25] tests --- test/testCard.vcf | 11 +++++++++-- test/tests.js | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/test/testCard.vcf b/test/testCard.vcf index 4ea99fa..411a020 100644 --- a/test/testCard.vcf +++ b/test/testCard.vcf @@ -24,7 +24,14 @@ ADR;CHARSET=UTF-8;TYPE=WORK:;;123 Corporate Loop\nSuite 500;Los Angeles;CA;12345 TITLE;CHARSET=UTF-8:Crash Test Dummy ROLE;CHARSET=UTF-8:Crash Testing ORG;CHARSET=UTF-8:ACME Corporation -URL;CHARSET=UTF-8:http://johndoe +item1.URL;CHARSET=UTF-8:https://www.treeala.com +item1.X-ABLABEL;CHARSET=UTF-8:Web page +item2.URL;CHARSET=UTF-8:https://www.twitter.com/yasmaniaco +item2.X-ABLABEL;CHARSET=UTF-8:Twitter +item3.URL;CHARSET=UTF-8:https://www.instagram.com/yasmanets +item3.X-ABLABEL;CHARSET=UTF-8:Instagram +item4.URL;CHARSET=UTF-8:https://github.com/yasmanets +item4.X-ABLABEL;CHARSET=UTF-8:Github URL;type=WORK;CHARSET=UTF-8:http://acemecompany/johndoe NOTE;CHARSET=UTF-8:John Doe's \nnotes\;\, X-SOCIALPROFILE:TYPE=facebook:https://facebook/johndoe @@ -33,5 +40,5 @@ X-SOCIALPROFILE:TYPE=twitter:https://twitter/johndoe X-SOCIALPROFILE:TYPE=flickr:https://flickr/johndoe X-SOCIALPROFILE:TYPE=custom:https://custom/johndoe SOURCE;CHARSET=UTF-8:http://sourceurl -REV:2020-04-05T15:14:37.180Z +REV:2020-04-05T15:37:26.471Z END:VCARD diff --git a/test/tests.js b/test/tests.js index 9e1f1d5..0c7f5f4 100644 --- a/test/tests.js +++ b/test/tests.js @@ -1,5 +1,6 @@ 'use strict'; +// eslint-disable-next-line no-redeclare /* global require, describe, it: true */ const vCard = require('../index'); @@ -36,6 +37,10 @@ let getValueByFieldName = (fieldName, lines) => { describe('vCard', function() { let testCard = vCard(); + + testCard.iosURL = []; + testCard.label = []; + testCard.version = '3.0'; testCard.uid = TEST_VALUE_UID; testCard.lastName = 'Doe'; @@ -60,8 +65,17 @@ describe('vCard', function() { testCard.role = 'Crash Testing'; testCard.email = 'john.doe@testmail'; testCard.workEmail = 'john.doe@workmail'; - testCard.url = 'http://johndoe'; testCard.workUrl = 'http://acemecompany/johndoe'; + + testCard.iosURL.push('https://www.treeala.com'); + testCard.iosURL.push('https://www.twitter.com/yasmaniaco'); + testCard.iosURL.push('https://www.instagram.com/yasmanets'); + testCard.iosURL.push('https://github.com/yasmanets'); + + testCard.label.push('Web page'); + testCard.label.push('Twitter'); + testCard.label.push('Instagram'); + testCard.label.push('Github'); testCard.homeAddress.label = 'Home Address'; testCard.homeAddress.street = '123 Main Street'; From 8ffc617cbf11f89195f206fce693de5b35f629d0 Mon Sep 17 00:00:00 2001 From: yasmanets <34303875+yasmanets@users.noreply.github.com> Date: Sun, 5 Apr 2020 17:56:56 +0200 Subject: [PATCH 07/25] Update README.md --- README.md | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 10570cc..6227f26 100644 --- a/README.md +++ b/README.md @@ -231,6 +231,28 @@ You can mark as a contact as an organization with the following Apple AddressBoo vCard.isOrganization = true; ``` +### Custom url's for iOS devices + +You can set custom url's for iOs devices initializing the properties `vCard.iosURL` and `vCard.label` as an empty array and putting in each position of the array a url and its label respectively. As in the following example: + +``` +vCard.iosURL = [ ]; +vCard.label = [ ]; + +testCard.iosURL.push('https://www.treeala.com'); +testCard.iosURL.push('https://www.twitter.com/yasmaniaco'); +testCard.iosURL.push('https://www.instagram.com/yasmanets'); +testCard.iosURL.push('https://github.com/yasmanets'); + +testCard.label.push('Web page'); +testCard.label.push('Twitter'); +testCard.label.push('Instagram'); +testCard.label.push('Github');` +``` + +You will get the following result: +![Captura de pantalla de 2020-04-05 17-50-06](https://user-images.githubusercontent.com/34303875/78503274-f2f89100-7765-11ea-8610-f96e1f4bfc36.png) + ## React Native A React Native version exists here at this repository -- @@ -261,4 +283,4 @@ Additional thanks to -- BTC 18N1g2o1b9u2jNPbSpGHhV6x5xs6Qou3EV ## License -Copyright (c) 2014-2019 Eric J Nesser MIT \ No newline at end of file +Copyright (c) 2014-2019 Eric J Nesser MIT From a99c3da3f876a5b5a315ff907f8e146e88df72a4 Mon Sep 17 00:00:00 2001 From: yasmanets <34303875+yasmanets@users.noreply.github.com> Date: Sun, 5 Apr 2020 17:57:47 +0200 Subject: [PATCH 08/25] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6227f26..d7c921c 100644 --- a/README.md +++ b/README.md @@ -235,7 +235,7 @@ You can mark as a contact as an organization with the following Apple AddressBoo You can set custom url's for iOs devices initializing the properties `vCard.iosURL` and `vCard.label` as an empty array and putting in each position of the array a url and its label respectively. As in the following example: -``` +```js vCard.iosURL = [ ]; vCard.label = [ ]; From 88192c96a2e35afb33edf847b35c5f71ddf3efeb Mon Sep 17 00:00:00 2001 From: yasmanets <34303875+yasmanets@users.noreply.github.com> Date: Sun, 5 Apr 2020 17:59:06 +0200 Subject: [PATCH 09/25] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d7c921c..9cb0b4e 100644 --- a/README.md +++ b/README.md @@ -251,6 +251,7 @@ testCard.label.push('Github');` ``` You will get the following result: + ![Captura de pantalla de 2020-04-05 17-50-06](https://user-images.githubusercontent.com/34303875/78503274-f2f89100-7765-11ea-8610-f96e1f4bfc36.png) ## React Native From 7e84a0e0834a8ea49938a33ea62c259f19630d1e Mon Sep 17 00:00:00 2001 From: Yaser Date: Sun, 5 Apr 2020 18:44:18 +0200 Subject: [PATCH 10/25] new type of variables --- index.js | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/index.js b/index.js index 032aece..a1d64c8 100644 --- a/index.js +++ b/index.js @@ -33,12 +33,12 @@ var vCard = (function () { * @param {string} filename */ embedFromFile: function(fileLocation) { - var fs = require('fs'); - var path = require('path'); - this.mediaType = path.extname(fileLocation).toUpperCase().replace(/\./g, ""); - var imgData = fs.readFileSync(fileLocation); - this.url = imgData.toString('base64'); - this.base64 = true; + var fs = require('fs'); + var path = require('path'); + this.mediaType = path.extname(fileLocation).toUpperCase().replace(/\./g, ""); + var imgData = fs.readFileSync(fileLocation); + this.url = imgData.toString('base64'); + this.base64 = true; }, /** @@ -46,9 +46,9 @@ var vCard = (function () { * @param {string} base64String */ embedFromString: function(base64String, mediaType) { - this.mediaType = mediaType; - this.url = base64String; - this.base64 = true; + this.mediaType = mediaType; + this.url = base64String; + this.base64 = true; } }; } @@ -270,6 +270,18 @@ var vCard = (function () { */ url: '', + /** + * URL pointing to a website that represents the person in some way + * @type {Array} + */ + iosURL: [], + + /** + * URL pointing to a website that represents the person in some way + * @type {Array} + */ + label: [], + /** * URL pointing to a website that represents the person's work in some way * @type {String} From 2b6dc652485cdf1d72684c1fda71b0c6a22abf39 Mon Sep 17 00:00:00 2001 From: Yaser Date: Sun, 5 Apr 2020 18:47:47 +0200 Subject: [PATCH 11/25] new type of variables --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index a1d64c8..1c7e573 100644 --- a/index.js +++ b/index.js @@ -271,13 +271,13 @@ var vCard = (function () { url: '', /** - * URL pointing to a website that represents the person in some way + * URL pointing to a custom url that represents the person in some way * @type {Array} */ iosURL: [], /** - * URL pointing to a website that represents the person in some way + * URL pointing to a url custom label that represents the person in some way * @type {Array} */ label: [], From 8e1ce512efbc604e2831b75166786f5a2b8f0df0 Mon Sep 17 00:00:00 2001 From: Yaser Date: Fri, 10 Apr 2020 19:01:13 +0200 Subject: [PATCH 12/25] custom social profiles --- index.js | 12 ++++++++++++ lib/vCardFormatter.js | 7 +++++++ 2 files changed, 19 insertions(+) diff --git a/index.js b/index.js index 1c7e573..86bc1eb 100644 --- a/index.js +++ b/index.js @@ -252,6 +252,18 @@ var vCard = (function () { */ socialUrls: getSocialUrls(), + /** + * Custom social URLs attached to the vCard object (ex: Facebook, Twitter, LinkedIn) + * @type {Array} + */ + customSocialUrls: [], + + /** + * URL pointing to a url custom label that represents the person in some way + * @type {Array} + */ + socualUrlsLabel: [], + /** * A URL that can be used to get the latest version of this vCard * @type {String} diff --git a/lib/vCardFormatter.js b/lib/vCardFormatter.js index 4886536..c4f6128 100644 --- a/lib/vCardFormatter.js +++ b/lib/vCardFormatter.js @@ -400,6 +400,13 @@ } } + if (vCard.customSocialUrls) { + vCard.customSocialUrls.forEach((socialProfile, index) => { + formattedVCardString += 'item' + (index + 1) + '.SOCIALPROFILE' + encodingPrefix + ':' + e(socialProfile) + nl(); + formattedVCardString += 'item' + (index + 1) + '.X-ABLABEL' + encodingPrefix + ':' + e(vCard.socualUrlsLabel[index]) +nl(); + }) + } + if (vCard.source) { formattedVCardString += 'SOURCE' + encodingPrefix + ':' + e(vCard.source) + nl(); } From 7b87cc0aaf96827e5b15bfd33b7b6ef683d36b13 Mon Sep 17 00:00:00 2001 From: Yaser Date: Fri, 10 Apr 2020 19:01:27 +0200 Subject: [PATCH 13/25] update tests --- test/testCard.vcf | 2 +- test/tests.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/test/testCard.vcf b/test/testCard.vcf index 411a020..7200afa 100644 --- a/test/testCard.vcf +++ b/test/testCard.vcf @@ -40,5 +40,5 @@ X-SOCIALPROFILE:TYPE=twitter:https://twitter/johndoe X-SOCIALPROFILE:TYPE=flickr:https://flickr/johndoe X-SOCIALPROFILE:TYPE=custom:https://custom/johndoe SOURCE;CHARSET=UTF-8:http://sourceurl -REV:2020-04-05T15:37:26.471Z +REV:2020-04-10T16:58:32.713Z END:VCARD diff --git a/test/tests.js b/test/tests.js index 0c7f5f4..b6f95f0 100644 --- a/test/tests.js +++ b/test/tests.js @@ -40,6 +40,8 @@ describe('vCard', function() { testCard.iosURL = []; testCard.label = []; + testCard.customSocialUrls = []; + testCard.socualUrlsLabel = []; testCard.version = '3.0'; testCard.uid = TEST_VALUE_UID; @@ -77,6 +79,9 @@ describe('vCard', function() { testCard.label.push('Instagram'); testCard.label.push('Github'); + testCard.customSocialUrls.push('yaser'); + testCard.socualUrlsLabel.push('Skype'); + testCard.homeAddress.label = 'Home Address'; testCard.homeAddress.street = '123 Main Street'; testCard.homeAddress.city = 'Chicago'; From 7f198bd945de46e901742fed1504a82e1d7d5eee Mon Sep 17 00:00:00 2001 From: Yaser Date: Fri, 10 Apr 2020 19:19:29 +0200 Subject: [PATCH 14/25] var names --- index.js | 2 +- lib/vCardFormatter.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 86bc1eb..e731814 100644 --- a/index.js +++ b/index.js @@ -262,7 +262,7 @@ var vCard = (function () { * URL pointing to a url custom label that represents the person in some way * @type {Array} */ - socualUrlsLabel: [], + socialUrlsLabel: [], /** * A URL that can be used to get the latest version of this vCard diff --git a/lib/vCardFormatter.js b/lib/vCardFormatter.js index c4f6128..4f8e44a 100644 --- a/lib/vCardFormatter.js +++ b/lib/vCardFormatter.js @@ -403,7 +403,7 @@ if (vCard.customSocialUrls) { vCard.customSocialUrls.forEach((socialProfile, index) => { formattedVCardString += 'item' + (index + 1) + '.SOCIALPROFILE' + encodingPrefix + ':' + e(socialProfile) + nl(); - formattedVCardString += 'item' + (index + 1) + '.X-ABLABEL' + encodingPrefix + ':' + e(vCard.socualUrlsLabel[index]) +nl(); + formattedVCardString += 'item' + (index + 1) + '.X-ABLABEL' + encodingPrefix + ':' + e(vCard.socialUrlsLabel[index]) +nl(); }) } From 38e92c13bb63ef1045ca4d5b1f2f0a62bb752bd0 Mon Sep 17 00:00:00 2001 From: Yaser Date: Fri, 10 Apr 2020 19:20:36 +0200 Subject: [PATCH 15/25] formatter --- lib/vCardFormatter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vCardFormatter.js b/lib/vCardFormatter.js index 4f8e44a..d1a5637 100644 --- a/lib/vCardFormatter.js +++ b/lib/vCardFormatter.js @@ -402,7 +402,7 @@ if (vCard.customSocialUrls) { vCard.customSocialUrls.forEach((socialProfile, index) => { - formattedVCardString += 'item' + (index + 1) + '.SOCIALPROFILE' + encodingPrefix + ':' + e(socialProfile) + nl(); + formattedVCardString += 'item' + (index + 1) + '.X-SOCIALPROFILE' + encodingPrefix + ':' + e(socialProfile) + nl(); formattedVCardString += 'item' + (index + 1) + '.X-ABLABEL' + encodingPrefix + ':' + e(vCard.socialUrlsLabel[index]) +nl(); }) } From 38a5d9304badb6637b5d9588075ee41280c6e5d1 Mon Sep 17 00:00:00 2001 From: Yaser Date: Fri, 10 Apr 2020 19:38:59 +0200 Subject: [PATCH 16/25] etiquetas --- index.js | 6 ------ lib/vCardFormatter.js | 4 ++-- test/testCard.vcf | 4 +++- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/index.js b/index.js index e731814..5cfe3b1 100644 --- a/index.js +++ b/index.js @@ -258,12 +258,6 @@ var vCard = (function () { */ customSocialUrls: [], - /** - * URL pointing to a url custom label that represents the person in some way - * @type {Array} - */ - socialUrlsLabel: [], - /** * A URL that can be used to get the latest version of this vCard * @type {String} diff --git a/lib/vCardFormatter.js b/lib/vCardFormatter.js index d1a5637..4f5b8d5 100644 --- a/lib/vCardFormatter.js +++ b/lib/vCardFormatter.js @@ -402,8 +402,8 @@ if (vCard.customSocialUrls) { vCard.customSocialUrls.forEach((socialProfile, index) => { - formattedVCardString += 'item' + (index + 1) + '.X-SOCIALPROFILE' + encodingPrefix + ':' + e(socialProfile) + nl(); - formattedVCardString += 'item' + (index + 1) + '.X-ABLABEL' + encodingPrefix + ':' + e(vCard.socialUrlsLabel[index]) +nl(); + formattedVCardString += 'item' + (index + vCard.label.length) + '.X-SOCIALPROFILE' + encodingPrefix + ':' + e(socialProfile) + nl(); + formattedVCardString += 'item' + (index + vCard.label.length) + '.X-ABLABEL' + encodingPrefix + ':' + e(vCard.label[index + vCard.label.length - 1]) +nl(); }) } diff --git a/test/testCard.vcf b/test/testCard.vcf index 7200afa..c394949 100644 --- a/test/testCard.vcf +++ b/test/testCard.vcf @@ -39,6 +39,8 @@ X-SOCIALPROFILE:TYPE=linkedIn:https://linkedin/johndoe X-SOCIALPROFILE:TYPE=twitter:https://twitter/johndoe X-SOCIALPROFILE:TYPE=flickr:https://flickr/johndoe X-SOCIALPROFILE:TYPE=custom:https://custom/johndoe +item4.X-SOCIALPROFILE;CHARSET=UTF-8:yaser +item4.X-ABLABEL;CHARSET=UTF-8:Github SOURCE;CHARSET=UTF-8:http://sourceurl -REV:2020-04-10T16:58:32.713Z +REV:2020-04-10T17:38:34.308Z END:VCARD From da76ccd2473c767ee3f82864f933b47923f6ec21 Mon Sep 17 00:00:00 2001 From: Yaser Date: Wed, 2 Dec 2020 16:54:31 +0100 Subject: [PATCH 17/25] outlook format --- index.js | 3 ++- lib/vCardFormatter.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 5cfe3b1..36c1efa 100644 --- a/index.js +++ b/index.js @@ -348,7 +348,8 @@ var vCard = (function () { var contents = vCardFormatter.getFormattedString(this); var fs = require('fs'); - fs.writeFileSync(filename, contents, { encoding: 'utf8' }); + fs.writeFileSync(filename, contents, { encoding: 'binary'}); + //fs.writeFileSync(filename, contents, { encoding: 'utf8' }); } }; }); diff --git a/lib/vCardFormatter.js b/lib/vCardFormatter.js index 4f5b8d5..2ba730f 100644 --- a/lib/vCardFormatter.js +++ b/lib/vCardFormatter.js @@ -122,7 +122,8 @@ formattedVCardString += 'BEGIN:VCARD' + nl(); formattedVCardString += 'VERSION:' + vCard.version + nl(); - var encodingPrefix = majorVersion >= 4 ? '' : ';CHARSET=UTF-8'; + var encodingPrefix = majorVersion >= 4 ? '' : ';CHARSET=ISO-8859-1'; + //var encodingPrefix = majorVersion >= 4 ? '' : ';CHARSET=UTF-8'; var formattedName = vCard.formattedName; if (!formattedName) { From 44920ee06ee5eacf706d39d41771208373ae2656 Mon Sep 17 00:00:00 2001 From: Yaser Date: Wed, 2 Dec 2020 16:54:42 +0100 Subject: [PATCH 18/25] . --- .eslintignore | 1 + .eslintrc.json | 267 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 268 insertions(+) create mode 100644 .eslintignore create mode 100644 .eslintrc.json diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +node_modules/ diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..32b6a8a --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,267 @@ +{ + "env": { + "es6": true, + "node": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "sourceType": "module", + "ecmaVersion": 2017 + }, + "rules": { + "accessor-pairs": "error", + "array-bracket-newline": "off", + "array-bracket-spacing": "off", + "array-callback-return": "off", + "array-element-newline": "off", + "arrow-body-style": "off", + "arrow-parens": "off", + "arrow-spacing": "off", + "block-scoped-var": "off", + "block-spacing": "off", + "brace-style": "off", + "callback-return": "off", + "camelcase": "off", + "capitalized-comments": "off", + "class-methods-use-this": "error", + "comma-dangle": "off", + "comma-spacing": "off", + "comma-style": [ + "error", + "last" + ], + "complexity": "off", + "computed-property-spacing": [ + "error", + "never" + ], + "consistent-return": "off", + "consistent-this": "error", + "curly": "off", + "default-case": "off", + "dot-location": [ + "error", + "property" + ], + "dot-notation": [ + "error", + { + "allowKeywords": true + } + ], + "eol-last": "error", + "eqeqeq": "off", + "for-direction": "error", + "func-call-spacing": "off", + "func-name-matching": "error", + "func-names": "off", + "func-style": "off", + "function-paren-newline": "off", + "generator-star-spacing": "error", + "getter-return": "error", + "global-require": "off", + "guard-for-in": "off", + "handle-callback-err": "off", + "id-blacklist": "error", + "id-length": "off", + "id-match": "error", + "indent": [ + "error", + 4 + ], + "indent-legacy": "off", + "init-declarations": "off", + "jsx-quotes": "error", + "key-spacing": "off", + "keyword-spacing": "off", + "line-comment-position": "off", + "linebreak-style": [ + "error", + "unix" + ], + "lines-around-comment": "off", + "lines-around-directive": "off", + "lines-between-class-members": "error", + "max-depth": "off", + "max-len": "off", + "max-lines": "off", + "max-nested-callbacks": "error", + "max-params": "off", + "max-statements": "off", + "max-statements-per-line": "off", + "multiline-comment-style": "off", + "new-cap": "off", + "new-parens": "error", + "newline-after-var": "off", + "newline-before-return": "off", + "no-alert": "error", + "no-array-constructor": "error", + "no-await-in-loop": "off", + "no-bitwise": "off", + "no-buffer-constructor": "off", + "no-caller": "error", + "no-catch-shadow": "off", + "no-confusing-arrow": "off", + "no-continue": "off", + "no-console": "off", + "no-constant-condition": "off", + "no-div-regex": "error", + "no-duplicate-imports": "error", + "no-else-return": "off", + "no-empty": "off", + "no-empty-function": "off", + "no-eq-null": "error", + "no-eval": "error", + "no-extend-native": "error", + "no-extra-bind": "error", + "no-extra-label": "error", + "no-extra-parens": "off", + "no-floating-decimal": "error", + "no-implicit-globals": "error", + "no-implied-eval": "error", + "no-inline-comments": "off", + "no-inner-declarations": [ + "error", + "functions" + ], + "no-invalid-this": "off", + "no-irregular-whitespace": "off", + "no-iterator": "error", + "no-label-var": "error", + "no-labels": "error", + "no-lone-blocks": "error", + "no-lonely-if": "off", + "no-loop-func": "off", + "no-magic-numbers": "off", + "no-mixed-operators": "off", + "no-mixed-requires": "error", + "no-multi-assign": "off", + "no-multi-spaces": "error", + "no-multi-str": "error", + "no-multiple-empty-lines": "off", + "no-native-reassign": "error", + "no-negated-condition": "off", + "no-negated-in-lhs": "error", + "no-nested-ternary": "off", + "no-new": "off", + "no-new-func": "error", + "no-new-object": "error", + "no-new-require": "error", + "no-new-wrappers": "error", + "no-octal-escape": "error", + "no-param-reassign": "off", + "no-path-concat": "off", + "no-plusplus": "off", + "no-process-env": "off", + "no-process-exit": "off", + "no-proto": "error", + "no-prototype-builtins": "off", + "no-restricted-globals": "error", + "no-restricted-imports": "error", + "no-restricted-modules": "error", + "no-restricted-properties": "error", + "no-restricted-syntax": "error", + "no-return-assign": [ + "off", + "except-parens" + ], + "no-return-await": "error", + "no-script-url": "error", + "no-self-compare": "off", + "no-sequences": "error", + "no-shadow": "off", + "no-shadow-restricted-names": "error", + "no-spaced-func": "off", + "no-sync": "off", + "no-tabs": "off", + "no-template-curly-in-string": "off", + "no-ternary": "off", + "no-throw-literal": "error", + "no-trailing-spaces": "off", + "no-undef": "error", + "no-undef-init": "error", + "no-undefined": "off", + "no-underscore-dangle": "off", + "no-unexpected-multiline": "off", + "no-unmodified-loop-condition": "error", + "no-unneeded-ternary": "off", + "no-unused-expressions": "error", + "no-use-before-define": "off", + "no-useless-call": "error", + "no-useless-computed-key": "error", + "no-useless-concat": "off", + "no-useless-constructor": "error", + "no-useless-escape": "off", + "no-useless-rename": "error", + "no-useless-return": "off", + "no-var": "off", + "no-void": "error", + "no-warning-comments": "off", + "no-whitespace-before-property": "error", + "no-with": "error", + "nonblock-statement-body-position": "error", + "object-curly-newline": "off", + "object-curly-spacing": "off", + "object-property-newline": "off", + "object-shorthand": "off", + "one-var": "off", + "one-var-declaration-per-line": "off", + "operator-assignment": "off", + "operator-linebreak": "error", + "padded-blocks": "off", + "padding-line-between-statements": "error", + "prefer-arrow-callback": "off", + "prefer-const": "off", + "prefer-destructuring": "off", + "prefer-numeric-literals": "error", + "prefer-promise-reject-errors": "error", + "prefer-reflect": "off", + "prefer-rest-params": "off", + "prefer-spread": "off", + "prefer-template": "off", + "quote-props": "off", + "quotes": "off", + "radix": "off", + "require-await": "error", + "require-jsdoc": "off", + "rest-spread-spacing": "error", + "semi": "off", + "semi-spacing": "off", + "semi-style": [ + "error", + "last" + ], + "sort-imports": "error", + "sort-keys": "off", + "sort-vars": "off", + "space-before-blocks": "off", + "space-before-function-paren": "off", + "space-in-parens": "off", + "space-infix-ops": "off", + "space-unary-ops": "off", + "spaced-comment": "off", + "strict": "off", + "switch-colon-spacing": [ + "error", + { + "after": true, + "before": false + } + ], + "symbol-description": "error", + "template-curly-spacing": [ + "error", + "never" + ], + "template-tag-spacing": "error", + "unicode-bom": [ + "error", + "never" + ], + "valid-jsdoc": "off", + "vars-on-top": "off", + "wrap-iife": "error", + "wrap-regex": "off", + "yield-star-spacing": "error" + } +} From 86d3ea4d41e79b9b5ec2c68e3d5b624cb5ac902e Mon Sep 17 00:00:00 2001 From: Yaser Date: Wed, 2 Dec 2020 17:19:11 +0100 Subject: [PATCH 19/25] version updated --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b5e25cf..393f131 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vcards-js", - "version": "2.10.0", + "version": "2.11.0", "description": "Create vCards to import contacts into Outlook, iOS, Mac OS, Android devices, and more.", "main": "index.js", "dependencies": {}, From a67589bd62af5f143f35cc12fcc08fdc0bdee0a8 Mon Sep 17 00:00:00 2001 From: Yaser Date: Wed, 2 Dec 2020 18:46:13 +0100 Subject: [PATCH 20/25] the web page must be the first url --- lib/vCardFormatter.js | 8 +++---- test/testCard.vcf | 54 +++++++++++++++++++++---------------------- test/tests.js | 4 ++-- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lib/vCardFormatter.js b/lib/vCardFormatter.js index 2ba730f..cb5bd7a 100644 --- a/lib/vCardFormatter.js +++ b/lib/vCardFormatter.js @@ -360,6 +360,10 @@ formattedVCardString += 'ORG' + encodingPrefix + ':' + e(vCard.organization) + nl(); } + if (vCard.workUrl) { + formattedVCardString += 'URL;type=WORK' + encodingPrefix + ':' + e(vCard.workUrl) + nl(); + } + if (vCard.url) { if (!Array.isArray(vCard.url)) { formattedVCardString += 'URL' + encodingPrefix + ':' + e(vCard.url) + nl(); @@ -383,10 +387,6 @@ }); } } - - if (vCard.workUrl) { - formattedVCardString += 'URL;type=WORK' + encodingPrefix + ':' + e(vCard.workUrl) + nl(); - } if (vCard.note) { formattedVCardString += 'NOTE' + encodingPrefix + ':' + e(vCard.note) + nl(); diff --git a/test/testCard.vcf b/test/testCard.vcf index c394949..bd7d48e 100644 --- a/test/testCard.vcf +++ b/test/testCard.vcf @@ -1,14 +1,14 @@ BEGIN:VCARD VERSION:3.0 -FN;CHARSET=UTF-8:John D Doe -N;CHARSET=UTF-8:Doe;John;D;MR;JR -NICKNAME;CHARSET=UTF-8:Test User +FN;CHARSET=ISO-8859-1:John D Doe +N;CHARSET=ISO-8859-1:Doe;John;D;MR;JR +NICKNAME;CHARSET=ISO-8859-1:Test User GENDER:M -UID;CHARSET=UTF-8:69531f4a-c34d-4a1e-8922-bd38a9476a53 +UID;CHARSET=ISO-8859-1:69531f4a-c34d-4a1e-8922-bd38a9476a53 BDAY:20181201 ANNIVERSARY:20181201 -EMAIL;CHARSET=UTF-8;type=HOME,INTERNET:john.doe@testmail -EMAIL;CHARSET=UTF-8;type=WORK,INTERNET:john.doe@workmail +EMAIL;CHARSET=ISO-8859-1;type=HOME,INTERNET:john.doe@testmail +EMAIL;CHARSET=ISO-8859-1;type=WORK,INTERNET:john.doe@workmail LOGO;TYPE=png:https://testurl PHOTO;TYPE=png:https://testurl TEL;TYPE=CELL:12345678900 @@ -17,30 +17,30 @@ TEL;TYPE=HOME,VOICE:312-555-1313 TEL;TYPE=WORK,VOICE:312-555-1212 TEL;TYPE=HOME,FAX:312-555-1616 TEL;TYPE=WORK,FAX:312-555-1717 -LABEL;CHARSET=UTF-8;TYPE=HOME:Home Address -ADR;CHARSET=UTF-8;TYPE=HOME:;;123 Main Street;Chicago;IL;12345;United States of America -LABEL;CHARSET=UTF-8;TYPE=WORK:Work Address -ADR;CHARSET=UTF-8;TYPE=WORK:;;123 Corporate Loop\nSuite 500;Los Angeles;CA;12345;California Republic -TITLE;CHARSET=UTF-8:Crash Test Dummy -ROLE;CHARSET=UTF-8:Crash Testing -ORG;CHARSET=UTF-8:ACME Corporation -item1.URL;CHARSET=UTF-8:https://www.treeala.com -item1.X-ABLABEL;CHARSET=UTF-8:Web page -item2.URL;CHARSET=UTF-8:https://www.twitter.com/yasmaniaco -item2.X-ABLABEL;CHARSET=UTF-8:Twitter -item3.URL;CHARSET=UTF-8:https://www.instagram.com/yasmanets -item3.X-ABLABEL;CHARSET=UTF-8:Instagram -item4.URL;CHARSET=UTF-8:https://github.com/yasmanets -item4.X-ABLABEL;CHARSET=UTF-8:Github -URL;type=WORK;CHARSET=UTF-8:http://acemecompany/johndoe -NOTE;CHARSET=UTF-8:John Doe's \nnotes\;\, +LABEL;CHARSET=ISO-8859-1;TYPE=HOME:Home Address +ADR;CHARSET=ISO-8859-1;TYPE=HOME:;;123 Main Street;Chicago;IL;12345;United States of America +LABEL;CHARSET=ISO-8859-1;TYPE=WORK:Work Address +ADR;CHARSET=ISO-8859-1;TYPE=WORK:;;123 Corporate Loop\nSuite 500;Los Angeles;CA;12345;California Republic +TITLE;CHARSET=ISO-8859-1:Crash Test Dummy +ROLE;CHARSET=ISO-8859-1:Crash Testing +ORG;CHARSET=ISO-8859-1:ACME Corporation +URL;type=WORK;CHARSET=ISO-8859-1:https://ulompi.cards +item1.URL;CHARSET=ISO-8859-1:https://www.ulompi.com +item1.X-ABLABEL;CHARSET=ISO-8859-1:Web page +item2.URL;CHARSET=ISO-8859-1:https://www.twitter.com/yasmaniaco +item2.X-ABLABEL;CHARSET=ISO-8859-1:Twitter +item3.URL;CHARSET=ISO-8859-1:https://www.instagram.com/yasmanets +item3.X-ABLABEL;CHARSET=ISO-8859-1:Instagram +item4.URL;CHARSET=ISO-8859-1:https://github.com/yasmanets +item4.X-ABLABEL;CHARSET=ISO-8859-1:Github +NOTE;CHARSET=ISO-8859-1:John Doe's \nnotes\;\, X-SOCIALPROFILE:TYPE=facebook:https://facebook/johndoe X-SOCIALPROFILE:TYPE=linkedIn:https://linkedin/johndoe X-SOCIALPROFILE:TYPE=twitter:https://twitter/johndoe X-SOCIALPROFILE:TYPE=flickr:https://flickr/johndoe X-SOCIALPROFILE:TYPE=custom:https://custom/johndoe -item4.X-SOCIALPROFILE;CHARSET=UTF-8:yaser -item4.X-ABLABEL;CHARSET=UTF-8:Github -SOURCE;CHARSET=UTF-8:http://sourceurl -REV:2020-04-10T17:38:34.308Z +item4.X-SOCIALPROFILE;CHARSET=ISO-8859-1:yaser +item4.X-ABLABEL;CHARSET=ISO-8859-1:Github +SOURCE;CHARSET=ISO-8859-1:http://sourceurl +REV:2020-12-02T17:39:10.037Z END:VCARD diff --git a/test/tests.js b/test/tests.js index b6f95f0..614353b 100644 --- a/test/tests.js +++ b/test/tests.js @@ -67,9 +67,9 @@ describe('vCard', function() { testCard.role = 'Crash Testing'; testCard.email = 'john.doe@testmail'; testCard.workEmail = 'john.doe@workmail'; - testCard.workUrl = 'http://acemecompany/johndoe'; + testCard.workUrl = 'https://ulompi.cards'; - testCard.iosURL.push('https://www.treeala.com'); + testCard.iosURL.push('https://www.ulompi.com'); testCard.iosURL.push('https://www.twitter.com/yasmaniaco'); testCard.iosURL.push('https://www.instagram.com/yasmanets'); testCard.iosURL.push('https://github.com/yasmanets'); From 1acc0f2728f17412c3010d222fb2f364d79eee1f Mon Sep 17 00:00:00 2001 From: yaser Date: Sat, 16 Jan 2021 18:30:20 +0100 Subject: [PATCH 21/25] =?UTF-8?q?versi=C3=B3n=20updated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- test/testCard.vcf | 13 ++++++------- test/tests.js | 19 +++++++++++++------ 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 393f131..5caedee 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vcards-js", - "version": "2.11.0", + "version": "2.11.1", "description": "Create vCards to import contacts into Outlook, iOS, Mac OS, Android devices, and more.", "main": "index.js", "dependencies": {}, diff --git a/test/testCard.vcf b/test/testCard.vcf index bd7d48e..14791d2 100644 --- a/test/testCard.vcf +++ b/test/testCard.vcf @@ -24,7 +24,11 @@ ADR;CHARSET=ISO-8859-1;TYPE=WORK:;;123 Corporate Loop\nSuite 500;Los Angeles;CA; TITLE;CHARSET=ISO-8859-1:Crash Test Dummy ROLE;CHARSET=ISO-8859-1:Crash Testing ORG;CHARSET=ISO-8859-1:ACME Corporation -URL;type=WORK;CHARSET=ISO-8859-1:https://ulompi.cards +URL;type=WORK;CHARSET=ISO-8859-1:https://www.ulompi.cards +URL;CHARSET=ISO-8859-1:https://www.twitter.com/yasmaniaco +URL;CHARSET=ISO-8859-1:https://www.facebook.com/yasmaniaco +URL;CHARSET=ISO-8859-1:https://www.linkedin.com/in/yasmaniaco +URL;CHARSET=ISO-8859-1:https://www.youtube.com/ulompi item1.URL;CHARSET=ISO-8859-1:https://www.ulompi.com item1.X-ABLABEL;CHARSET=ISO-8859-1:Web page item2.URL;CHARSET=ISO-8859-1:https://www.twitter.com/yasmaniaco @@ -34,13 +38,8 @@ item3.X-ABLABEL;CHARSET=ISO-8859-1:Instagram item4.URL;CHARSET=ISO-8859-1:https://github.com/yasmanets item4.X-ABLABEL;CHARSET=ISO-8859-1:Github NOTE;CHARSET=ISO-8859-1:John Doe's \nnotes\;\, -X-SOCIALPROFILE:TYPE=facebook:https://facebook/johndoe -X-SOCIALPROFILE:TYPE=linkedIn:https://linkedin/johndoe -X-SOCIALPROFILE:TYPE=twitter:https://twitter/johndoe -X-SOCIALPROFILE:TYPE=flickr:https://flickr/johndoe -X-SOCIALPROFILE:TYPE=custom:https://custom/johndoe item4.X-SOCIALPROFILE;CHARSET=ISO-8859-1:yaser item4.X-ABLABEL;CHARSET=ISO-8859-1:Github SOURCE;CHARSET=ISO-8859-1:http://sourceurl -REV:2020-12-02T17:39:10.037Z +REV:2021-01-16T17:17:52.246Z END:VCARD diff --git a/test/tests.js b/test/tests.js index 614353b..1316e6a 100644 --- a/test/tests.js +++ b/test/tests.js @@ -67,7 +67,7 @@ describe('vCard', function() { testCard.role = 'Crash Testing'; testCard.email = 'john.doe@testmail'; testCard.workEmail = 'john.doe@workmail'; - testCard.workUrl = 'https://ulompi.cards'; + testCard.workUrl = 'https://www.ulompi.cards'; testCard.iosURL.push('https://www.ulompi.com'); testCard.iosURL.push('https://www.twitter.com/yasmaniaco'); @@ -99,11 +99,18 @@ describe('vCard', function() { testCard.source = 'http://sourceurl'; testCard.note = 'John Doe\'s \nnotes;,'; - testCard.socialUrls.facebook = 'https://facebook/johndoe'; - testCard.socialUrls.linkedIn = 'https://linkedin/johndoe'; - testCard.socialUrls.twitter = 'https://twitter/johndoe'; - testCard.socialUrls.flickr = 'https://flickr/johndoe'; - testCard.socialUrls.custom = 'https://custom/johndoe'; + // testCard.socialUrls.facebook = 'https://facebook/johndoe'; + // testCard.socialUrls.linkedIn = 'https://linkedin/johndoe'; + // testCard.socialUrls.twitter = 'https://twitter/johndoe'; + // testCard.socialUrls.flickr = 'https://flickr/johndoe'; + // testCard.socialUrls.custom = 'https://custom/johndoe'; + + testCard.url = []; + testCard.url.push('https://www.twitter.com/yasmaniaco'); + testCard.url.push('https://www.facebook.com/yasmaniaco'); + testCard.url.push('https://www.linkedin.com/in/yasmaniaco'); + testCard.url.push('https://www.youtube.com/ulompi'); + var vCardString = testCard.getFormattedString(); var lines = vCardString.split(/[\n\r]+/); From 99a2948d6380c0599488c7b548083fda7b8cf1d8 Mon Sep 17 00:00:00 2001 From: yaser Date: Sat, 16 Jan 2021 19:11:19 +0100 Subject: [PATCH 22/25] majorVersion conditional --- lib/vCardFormatter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vCardFormatter.js b/lib/vCardFormatter.js index cb5bd7a..86ed772 100644 --- a/lib/vCardFormatter.js +++ b/lib/vCardFormatter.js @@ -122,7 +122,7 @@ formattedVCardString += 'BEGIN:VCARD' + nl(); formattedVCardString += 'VERSION:' + vCard.version + nl(); - var encodingPrefix = majorVersion >= 4 ? '' : ';CHARSET=ISO-8859-1'; + var encodingPrefix = majorVersion >= 3 ? '' : ';CHARSET=ISO-8859-1'; //var encodingPrefix = majorVersion >= 4 ? '' : ';CHARSET=UTF-8'; var formattedName = vCard.formattedName; From 06ca0cbf04df5eadaf8a73e68044363406d9cbc4 Mon Sep 17 00:00:00 2001 From: yaser-eda-teamswipe Date: Sun, 15 Jan 2023 13:16:48 +0100 Subject: [PATCH 23/25] more than one address can be added per type --- lib/vCardFormatter.js | 64 ++++++++++++++++++++++++------------------- test/testCard.vcf | 64 ++++++++++++++++++++++--------------------- test/tests.js | 30 ++++++++++++-------- 3 files changed, 87 insertions(+), 71 deletions(-) diff --git a/lib/vCardFormatter.js b/lib/vCardFormatter.js index 86ed772..4c36670 100644 --- a/lib/vCardFormatter.js +++ b/lib/vCardFormatter.js @@ -66,31 +66,31 @@ var formattedAddress = ''; - if (address.details.label || - address.details.street || - address.details.city || - address.details.stateProvince || - address.details.postalCode || - address.details.countryRegion) { + if (address.label || + address.street || + address.city || + address.stateProvince || + address.postalCode || + address.countryRegion) { if (majorVersion >= 4) { formattedAddress = 'ADR' + encodingPrefix + ';TYPE=' + address.type + - (address.details.label ? ';LABEL="' + e(address.details.label) + '"' : '') + ':;;' + - e(address.details.street) + ';' + - e(address.details.city) + ';' + - e(address.details.stateProvince) + ';' + - e(address.details.postalCode) + ';' + - e(address.details.countryRegion) + nl(); + (address.label ? ';LABEL="' + e(address.label) + '"' : '') + ':;;' + + e(address.street) + ';' + + e(address.city) + ';' + + e(address.stateProvince) + ';' + + e(address.postalCode) + ';' + + e(address.countryRegion) + nl(); } else { - if (address.details.label) { - formattedAddress = 'LABEL' + encodingPrefix + ';TYPE=' + address.type + ':' + e(address.details.label) + nl(); + if (address.label) { + formattedAddress = 'LABEL' + encodingPrefix + ';TYPE=' + address.type + ':' + e(address.label) + nl(); } formattedAddress += 'ADR' + encodingPrefix + ';TYPE=' + address.type + ':;;' + - e(address.details.street) + ';' + - e(address.details.city) + ';' + - e(address.details.stateProvince) + ';' + - e(address.details.postalCode) + ';' + - e(address.details.countryRegion) + nl(); + e(address.street) + ';' + + e(address.city) + ';' + + e(address.stateProvince) + ';' + + e(address.postalCode) + ';' + + e(address.countryRegion) + nl(); } } @@ -336,17 +336,25 @@ ); } - [{ - details: vCard.homeAddress, - type: 'HOME' - }, { - details: vCard.workAddress, - type: 'WORK' - }].forEach( - function(address) { + if (vCard.homeAddress) { + if(!Array.isArray(vCard.homeAddress)){ + vCard.homeAddress = [vCard.homeAddress]; + } + vCard.homeAddress.map(address => { + address.type = 'HOME'; formattedVCardString += getFormattedAddress(encodingPrefix, address); + }); + } + + if (vCard.workAddress) { + if(!Array.isArray(vCard.workAddress)){ + vCard.workAddress = [vCard.workAddress]; } - ); + vCard.workAddress.map(address => { + address.type = 'WORK'; + formattedVCardString += getFormattedAddress(encodingPrefix, address); + }); + } if (vCard.title) { formattedVCardString += 'TITLE' + encodingPrefix + ':' + e(vCard.title) + nl(); diff --git a/test/testCard.vcf b/test/testCard.vcf index 14791d2..80f7b70 100644 --- a/test/testCard.vcf +++ b/test/testCard.vcf @@ -1,14 +1,14 @@ BEGIN:VCARD VERSION:3.0 -FN;CHARSET=ISO-8859-1:John D Doe -N;CHARSET=ISO-8859-1:Doe;John;D;MR;JR -NICKNAME;CHARSET=ISO-8859-1:Test User +FN:John D Doe +N:Doe;John;D;MR;JR +NICKNAME:Test User GENDER:M -UID;CHARSET=ISO-8859-1:69531f4a-c34d-4a1e-8922-bd38a9476a53 +UID:69531f4a-c34d-4a1e-8922-bd38a9476a53 BDAY:20181201 ANNIVERSARY:20181201 -EMAIL;CHARSET=ISO-8859-1;type=HOME,INTERNET:john.doe@testmail -EMAIL;CHARSET=ISO-8859-1;type=WORK,INTERNET:john.doe@workmail +EMAIL;type=HOME,INTERNET:john.doe@testmail +EMAIL;type=WORK,INTERNET:john.doe@workmail LOGO;TYPE=png:https://testurl PHOTO;TYPE=png:https://testurl TEL;TYPE=CELL:12345678900 @@ -17,29 +17,31 @@ TEL;TYPE=HOME,VOICE:312-555-1313 TEL;TYPE=WORK,VOICE:312-555-1212 TEL;TYPE=HOME,FAX:312-555-1616 TEL;TYPE=WORK,FAX:312-555-1717 -LABEL;CHARSET=ISO-8859-1;TYPE=HOME:Home Address -ADR;CHARSET=ISO-8859-1;TYPE=HOME:;;123 Main Street;Chicago;IL;12345;United States of America -LABEL;CHARSET=ISO-8859-1;TYPE=WORK:Work Address -ADR;CHARSET=ISO-8859-1;TYPE=WORK:;;123 Corporate Loop\nSuite 500;Los Angeles;CA;12345;California Republic -TITLE;CHARSET=ISO-8859-1:Crash Test Dummy -ROLE;CHARSET=ISO-8859-1:Crash Testing -ORG;CHARSET=ISO-8859-1:ACME Corporation -URL;type=WORK;CHARSET=ISO-8859-1:https://www.ulompi.cards -URL;CHARSET=ISO-8859-1:https://www.twitter.com/yasmaniaco -URL;CHARSET=ISO-8859-1:https://www.facebook.com/yasmaniaco -URL;CHARSET=ISO-8859-1:https://www.linkedin.com/in/yasmaniaco -URL;CHARSET=ISO-8859-1:https://www.youtube.com/ulompi -item1.URL;CHARSET=ISO-8859-1:https://www.ulompi.com -item1.X-ABLABEL;CHARSET=ISO-8859-1:Web page -item2.URL;CHARSET=ISO-8859-1:https://www.twitter.com/yasmaniaco -item2.X-ABLABEL;CHARSET=ISO-8859-1:Twitter -item3.URL;CHARSET=ISO-8859-1:https://www.instagram.com/yasmanets -item3.X-ABLABEL;CHARSET=ISO-8859-1:Instagram -item4.URL;CHARSET=ISO-8859-1:https://github.com/yasmanets -item4.X-ABLABEL;CHARSET=ISO-8859-1:Github -NOTE;CHARSET=ISO-8859-1:John Doe's \nnotes\;\, -item4.X-SOCIALPROFILE;CHARSET=ISO-8859-1:yaser -item4.X-ABLABEL;CHARSET=ISO-8859-1:Github -SOURCE;CHARSET=ISO-8859-1:http://sourceurl -REV:2021-01-16T17:17:52.246Z +LABEL;TYPE=HOME:Home Address +ADR;TYPE=HOME:;;123 Main Street;Chicago;IL;12345;United States of America +LABEL;TYPE=WORK:Work Address +ADR;TYPE=WORK:;;Avenida de Maisonnave\, 41;Alicante;Alicante;03003;Spain +LABEL;TYPE=WORK:Work Address +ADR;TYPE=WORK:;;123 Corporate Loop\nSuite 500;Los Angeles;CA;54321;California Republic +TITLE:Crash Test Dummy +ROLE:Crash Testing +ORG:ACME Corporation +URL;type=WORK:https://www.ulompi.cards +URL:https://www.twitter.com/yasmaniaco +URL:https://www.facebook.com/yasmaniaco +URL:https://www.linkedin.com/in/yasmaniaco +URL:https://www.youtube.com/ulompi +item1.URL:https://www.ulompi.com +item1.X-ABLABEL:Web page +item2.URL:https://www.twitter.com/yasmaniaco +item2.X-ABLABEL:Twitter +item3.URL:https://www.instagram.com/yasmanets +item3.X-ABLABEL:Instagram +item4.URL:https://github.com/yasmanets +item4.X-ABLABEL:Github +NOTE:John Doe's \nnotes\;\, +item4.X-SOCIALPROFILE:yaser +item4.X-ABLABEL:Github +SOURCE:http://sourceurl +REV:2023-01-15T11:44:56.912Z END:VCARD diff --git a/test/tests.js b/test/tests.js index 1316e6a..b46fe88 100644 --- a/test/tests.js +++ b/test/tests.js @@ -89,22 +89,28 @@ describe('vCard', function() { testCard.homeAddress.postalCode = '12345'; testCard.homeAddress.countryRegion = 'United States of America'; - testCard.workAddress.label = 'Work Address'; - testCard.workAddress.street = '123 Corporate Loop\nSuite 500'; - testCard.workAddress.city = 'Los Angeles'; - testCard.workAddress.stateProvince = 'CA'; - testCard.workAddress.postalCode = '54321'; - testCard.workAddress.countryRegion = 'California Republic'; + testCard.workAddress = [ + { + label: 'Work Address', + street: 'Avenida de Maisonnave, 41', + city: 'Alicante', + stateProvince: 'Alicante', + postalCode: '03003', + countryRegion: 'Spain', + }, + { + label: 'Work Address', + street: '123 Corporate Loop\nSuite 500', + city: 'Los Angeles', + stateProvince: 'CA', + postalCode: '54321', + countryRegion: 'California Republic', + }, + ]; testCard.source = 'http://sourceurl'; testCard.note = 'John Doe\'s \nnotes;,'; - // testCard.socialUrls.facebook = 'https://facebook/johndoe'; - // testCard.socialUrls.linkedIn = 'https://linkedin/johndoe'; - // testCard.socialUrls.twitter = 'https://twitter/johndoe'; - // testCard.socialUrls.flickr = 'https://flickr/johndoe'; - // testCard.socialUrls.custom = 'https://custom/johndoe'; - testCard.url = []; testCard.url.push('https://www.twitter.com/yasmaniaco'); testCard.url.push('https://www.facebook.com/yasmaniaco'); From 8a3540ff2203bfe0e7a75a7042151a05d2db97b1 Mon Sep 17 00:00:00 2001 From: yaser-eda-teamswipe Date: Sun, 15 Jan 2023 13:17:03 +0100 Subject: [PATCH 24/25] README updated --- README.md | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 9cb0b4e..10a3a01 100644 --- a/README.md +++ b/README.md @@ -159,19 +159,27 @@ vCard.logo.attachFromUrl('https://avatars2.githubusercontent.com/u/5659221?v=3&s vCard.source = 'http://mywebpage/myvcard.vcf'; //set address information -vCard.homeAddress.label = 'Home Address'; -vCard.homeAddress.street = '123 Main Street'; -vCard.homeAddress.city = 'Chicago'; -vCard.homeAddress.stateProvince = 'IL'; -vCard.homeAddress.postalCode = '12345'; -vCard.homeAddress.countryRegion = 'United States of America'; - -vCard.workAddress.label = 'Work Address'; -vCard.workAddress.street = '123 Corporate Loop\nSuite 500'; -vCard.workAddress.city = 'Los Angeles'; -vCard.workAddress.stateProvince = 'CA'; -vCard.workAddress.postalCode = '54321'; -vCard.workAddress.countryRegion = 'United States of America'; +vCard.homeAddress = [ + { + label: 'Home Address', + street: '123 Main Street', + city: 'Chicago', + stateProvince: 'IL', + postalCode: '12345', + countryRegion: 'United States of America', + }, +]; + +vCard.workAddress = [ + { + label: 'Work Address', + street: '123 Corporate Loop\nSuite 500', + city: 'Los Angeles', + stateProvince: 'CA', + postalCode: '54321', + countryRegion: 'United States of America', + } +] //set social media URLs vCard.socialUrls['facebook'] = 'https://...'; From 551d09d14b3b12d377420b5ae21b08e28939d64c Mon Sep 17 00:00:00 2001 From: yaser-eda-teamswipe Date: Sun, 15 Jan 2023 13:17:48 +0100 Subject: [PATCH 25/25] version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5caedee..ede612f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vcards-js", - "version": "2.11.1", + "version": "2.11.2", "description": "Create vCards to import contacts into Outlook, iOS, Mac OS, Android devices, and more.", "main": "index.js", "dependencies": {},