pull/737/merge
connor trotter 1 year ago committed by GitHub
commit b1fecad293
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -118,13 +118,11 @@
"@postlight/ci-failed-test-reporter": "^1.0",
"browser-request": "github:postlight/browser-request#feat-add-headers-to-response",
"cheerio": "^0.22.0",
"dayjs": "^1.11.7",
"difflib": "github:postlight/difflib.js",
"ellipsize": "0.1.0",
"iconv-lite": "0.5.0",
"jquery": "^3.5.0",
"moment": "^2.23.0",
"moment-parseformat": "3.0.0",
"moment-timezone": "0.5.37",
"postman-request": "^2.88.1-postman.31",
"string-direction": "^0.1.2",
"turndown": "^7.1.1",
@ -134,7 +132,6 @@
},
"bundleDependencies": [
"jquery",
"moment-timezone",
"browser-request"
],
"browser": {
@ -142,8 +139,7 @@
"cheerio": "./src/shims/cheerio-query",
"jquery": "./node_modules/jquery/dist/jquery.min.js",
"postman-request": "browser-request",
"iconv-lite": "./src/shims/iconv-lite",
"moment-timezone": "./node_modules/moment-timezone/builds/moment-timezone-with-data-2012-2022.min.js"
"iconv-lite": "./src/shims/iconv-lite"
},
"husky": {
"hooks": {

@ -1,8 +1,8 @@
import moment from 'moment-timezone';
import parseFormat from 'moment-parseformat';
// Is there a compelling reason to use moment here?
// Mostly only being used for the isValid() method,
// but could just check for 'Invalid Date' string.
import dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import utc from 'dayjs/plugin/utc';
import timezonePlugin from 'dayjs/plugin/timezone';
import advancedFormat from 'dayjs/plugin/advancedFormat';
import {
MS_DATE_STRING,
@ -16,6 +16,11 @@ import {
TIME_WITH_OFFSET_RE,
} from './constants';
dayjs.extend(customParseFormat);
dayjs.extend(utc);
dayjs.extend(timezonePlugin);
dayjs.extend(advancedFormat);
export function cleanDateString(dateString) {
return (dateString.match(SPLIT_DATE_STRING) || [])
.join(' ')
@ -27,21 +32,30 @@ export function cleanDateString(dateString) {
export function createDate(dateString, timezone, format) {
if (TIME_WITH_OFFSET_RE.test(dateString)) {
return moment(new Date(dateString));
return dayjs(new Date(dateString));
}
if (TIME_AGO_STRING.test(dateString)) {
const fragments = TIME_AGO_STRING.exec(dateString);
return moment().subtract(fragments[1], fragments[2]);
return dayjs().subtract(fragments[1], fragments[2]);
}
if (TIME_NOW_STRING.test(dateString)) {
return moment();
return dayjs();
}
return timezone
? moment.tz(dateString, format || parseFormat(dateString), timezone)
: moment(dateString, format || parseFormat(dateString));
if (timezone) {
try {
return format
? dayjs.tz(dateString, format, timezone)
: dayjs.tz(dayjs(dateString).format('YYYY-MM-DD HH:mm:ss'), timezone);
} catch (error) {
// return an intentionally invalid dayjs object,
// in case the input needs to be cleaned first
return dayjs('');
}
}
return format ? dayjs(dateString, format) : dayjs(dateString);
}
// Take a date published string, and hopefully return a date out of
@ -62,7 +76,7 @@ export default function cleanDatePublished(
if (!date.isValid()) {
dateString = cleanDateString(dateString);
date = createDate(dateString, timezone, format);
date = createDate(dateString, timezone);
}
return date.isValid() ? date.toISOString() : null;

@ -1,5 +1,5 @@
import assert from 'assert';
import moment from 'moment-timezone';
import dayjs from 'dayjs';
import cleanDatePublished, { cleanDateString } from './date-published';
@ -7,7 +7,7 @@ describe('cleanDatePublished(dateString)', () => {
it('returns a date', () => {
const datePublished = cleanDatePublished('published: 1/1/2020');
assert.equal(datePublished, moment('1/1/2020', 'MM/DD/YYYY').toISOString());
assert.equal(datePublished, dayjs('1/1/2020', 'M/D/YYYY').toISOString());
});
it('returns null if date is invalid', () => {
@ -28,37 +28,37 @@ describe('cleanDatePublished(dateString)', () => {
it('accepts a custom date format', () => {
// The JS date parser is forgiving, but
// it needs am/pm separated from a time
const datePublished = cleanDatePublished('Mon Aug 03 12:45:00 EDT 2015', {
const datePublished = cleanDatePublished('Aug 03 12:45:00 EDT 2015', {
timezone: 'America/New_York',
format: 'ddd MMM DD HH:mm:ss zz YYYY',
format: 'MMM DD HH:mm:ss z YYYY',
});
assert.equal(datePublished, '2015-08-03T16:45:00.000Z');
});
it('can handle dates formatted as "[just|right] now"', () => {
const date1 = cleanDatePublished('now');
const newDate1 = moment(date1)
const newDate1 = dayjs(date1)
.format()
.split('T')[0];
const expectedDate1 = moment()
const expectedDate1 = dayjs()
.format()
.split('T')[0];
assert.equal(newDate1, expectedDate1);
const date2 = cleanDatePublished('just now');
const newDate2 = moment(date2)
const newDate2 = dayjs(date2)
.format()
.split('T')[0];
const expectedDate2 = moment()
const expectedDate2 = dayjs()
.format()
.split('T')[0];
assert.equal(newDate2, expectedDate2);
const date3 = cleanDatePublished('right now');
const newDate3 = moment(date3)
const newDate3 = dayjs(date3)
.format()
.split('T')[0];
const expectedDate3 = moment()
const expectedDate3 = dayjs()
.format()
.split('T')[0];
assert.equal(newDate3, expectedDate3);
@ -69,30 +69,30 @@ describe('cleanDatePublished(dateString)', () => {
// "X days ago" will not be accurate down to the exact time
// "X months ago" will not be accurate down to the exact day
const date1 = cleanDatePublished('1 hour ago');
const newDate1 = moment(date1)
const newDate1 = dayjs(date1)
.format()
.split('T')[0];
const expectedDate1 = moment()
const expectedDate1 = dayjs()
.subtract(1, 'hour')
.format()
.split('T')[0];
assert.equal(newDate1, expectedDate1);
const date2 = cleanDatePublished('5 days ago');
const newDate2 = moment(date2)
const newDate2 = dayjs(date2)
.format()
.split('T')[0];
const expectedDate2 = moment()
const expectedDate2 = dayjs()
.subtract(5, 'days')
.format()
.split('T')[0];
assert.equal(newDate2, expectedDate2);
const date3 = cleanDatePublished('10 months ago');
const newDate3 = moment(date3)
const newDate3 = dayjs(date3)
.format()
.split('T')[0];
const expectedDate3 = moment()
const expectedDate3 = dayjs()
.subtract(10, 'months')
.format()
.split('T')[0];

@ -12,6 +12,7 @@ export const ClinicaltrialsGovExtractor = {
date_published: {
// selectors: ['span.term[data-term="Last Update Posted"]'],
selectors: ['div:has(> span.term[data-term="Last Update Posted"])'],
timezone: 'UTC',
},
content: {

@ -1,7 +1,6 @@
import assert from 'assert';
import URL from 'url';
import cheerio from 'cheerio';
import moment from 'moment-timezone';
import Mercury from 'mercury';
import getExtractor from 'extractors/get-extractor';
@ -59,7 +58,7 @@ describe('ClinicaltrialsGovExtractor', () => {
// Update these values with the expected values from
// the article.
assert.equal(moment(date_published).format('YYYY-MM-DD'), '2018-11-21');
assert.equal(date_published, '2018-11-21T00:00:00.000Z');
});
it('returns the content', async () => {

@ -11,8 +11,6 @@ export const FortuneComExtractor = {
date_published: {
selectors: ['.MblGHNMJ'],
timezone: 'UTC',
},
lead_image_url: {

@ -20,6 +20,7 @@ export const GeniusComExtractor = {
},
],
],
timezone: 'UTC',
},
dek: {

@ -1,7 +1,6 @@
import assert from 'assert';
import URL from 'url';
import cheerio from 'cheerio';
import moment from 'moment';
import Mercury from 'mercury';
import getExtractor from 'extractors/get-extractor';
@ -51,11 +50,10 @@ describe('GeniusComExtractor', () => {
// To pass this test, fill out the date_published selector
// in ./src/extractors/custom/genius.com/index.js.
const { date_published } = await result;
const newDatePublished = moment(date_published).format();
// Update these values with the expected values from
// the article.
assert.equal(newDatePublished.split('T')[0], '1984-06-25');
assert.equal(date_published, '1984-06-25T00:00:00.000Z');
});
it('returns the lead_image_url', async () => {

@ -24,8 +24,6 @@ export const GothamistComExtractor = {
'abbr',
'abbr.published',
],
timezone: 'America/New_York',
},
dek: {

@ -11,8 +11,6 @@ export const NewsNationalgeographicComExtractor = {
date_published: {
selectors: [['meta[name="article:published_time"]', 'value']],
format: 'ddd MMM DD HH:mm:ss zz YYYY',
timezone: 'EST',
},
dek: {

@ -49,7 +49,7 @@ describe('NewsNationalgeographicComExtractor', () => {
// Update these values with the expected values from
// the article.
assert.equal(date_published, '2015-08-03T17:45:00.000Z');
assert.equal(date_published, '2015-08-03T16:45:00.000Z');
});
it('returns the dek', async () => {

@ -14,6 +14,7 @@ export const PeopleComExtractor = {
'.mntl-attribution__item-date',
['meta[name="article:published_time"]', 'value'],
],
timezone: 'UTC',
},
lead_image_url: {

@ -1,7 +1,6 @@
import assert from 'assert';
import URL from 'url';
import cheerio from 'cheerio';
import moment from 'moment-timezone';
import Mercury from 'mercury';
import getExtractor from 'extractors/get-extractor';
@ -55,13 +54,9 @@ describe('PeopleComExtractor', () => {
// in ./src/extractors/custom/people.com/index.js.
const { date_published } = await result;
const new_date_published = moment(date_published)
.format()
.split('T')[0];
// Update these values with the expected values from
// the article.
assert.equal(new_date_published, '2016-12-12');
assert.equal(date_published, '2016-12-12T09:22:00.000Z');
});
it('returns the lead_image_url', async () => {

@ -14,6 +14,7 @@ export const PitchforkComExtractor = {
date_published: {
selectors: ['div[class^="InfoSliceWrapper-"]', ['.pub-date', 'datetime']],
timezone: 'UTC',
},
dek: {

@ -1,7 +1,6 @@
import assert from 'assert';
import URL from 'url';
import cheerio from 'cheerio';
import moment from 'moment-timezone';
import Mercury from 'mercury';
import getExtractor from 'extractors/get-extractor';
@ -41,11 +40,8 @@ describe('PitchforkComExtractor', () => {
it('returns the date_published', async () => {
const { date_published } = await result;
const new_date_published = moment(date_published)
.format()
.split('T')[0];
assert.equal(new_date_published, '2019-06-07');
assert.equal(date_published, '2019-06-07T00:00:00.000Z');
});
it('returns the dek', async () => {

@ -1,7 +1,6 @@
import assert from 'assert';
import URL from 'url';
import cheerio from 'cheerio';
import moment from 'moment';
import Mercury from 'mercury';
import getExtractor from 'extractors/get-extractor';
@ -57,11 +56,10 @@ describe('TakagihiromitsuJpExtractor', () => {
// To pass this test, fill out the date_published selector
// in ./src/extractors/custom/takagi-hiromitsu.jp/index.js.
const { date_published } = await result;
const newDatePublished = moment(date_published).format();
// Update these values with the expected values from
// the article.
assert.equal(newDatePublished.split('T')[0], '2019-02-17');
assert.equal(date_published, '2019-02-17T14:34:06.000Z');
});
it('returns the dek', async () => {

@ -11,7 +11,7 @@ export const WwwAlComExtractor = {
date_published: {
selectors: [['meta[name="article_date_original"]', 'value']],
timezone: 'EST',
timezone: 'America/Chicago',
},
lead_image_url: {

@ -57,7 +57,7 @@ describe('WwwAlComExtractor', () => {
// Update these values with the expected values from
// the article.
assert.equal(date_published, '2016-12-22T23:47:00.000Z');
assert.equal(date_published, '2016-12-23T00:47:00.000Z');
});
it('returns the lead_image_url', async () => {

@ -11,6 +11,7 @@ export const WwwChicagotribuneComExtractor = {
date_published: {
selectors: ['time'],
timezone: 'America/Chicago',
},
lead_image_url: {

@ -1,7 +1,6 @@
import assert from 'assert';
import URL from 'url';
import cheerio from 'cheerio';
import moment from 'moment-timezone';
import Mercury from 'mercury';
import getExtractor from 'extractors/get-extractor';
@ -55,13 +54,10 @@ describe('WwwChicagotribuneComExtractor', () => {
// To pass this test, fill out the date_published selector
// in ./src/extractors/custom/www.chicagotribune.com/index.js.
const { date_published } = await result;
const new_date_published = moment(date_published)
.format()
.split('T')[0];
// Update these values with the expected values from
// the article.
assert.equal(new_date_published, '2016-12-13');
assert.equal(date_published, '2016-12-13T21:45:00.000Z');
});
it('returns the lead_image_url', async () => {

@ -11,7 +11,7 @@ export const WwwInfoqComExtractor = {
date_published: {
selectors: ['.article__readTime.date'],
format: 'YYYY年MM月DD日',
format: 'YYYY[年]M[月]D[日]',
timezone: 'Asia/Tokyo',
},

@ -11,8 +11,7 @@ export const WwwMacrumorsComExtractor = {
date_published: {
selectors: [['time', 'datetime']],
timezone: 'America/Los_Angeles',
// timezone: 'America/Los_Angeles',
},
dek: {

@ -22,7 +22,7 @@ export const WwwMentalflossComExtractor = {
['meta[name="article:published_time"]', 'value'],
'.date-display-single',
],
timezone: 'America/New_York',
// timezone: 'America/New_York',
},
lead_image_url: {

@ -1,7 +1,6 @@
import assert from 'assert';
import URL from 'url';
import cheerio from 'cheerio';
import moment from 'moment';
import Mercury from 'mercury';
import getExtractor from 'extractors/get-extractor';
@ -58,11 +57,10 @@ describe('MSNExtractor', () => {
// To pass this test, fill out the date_published selector
// in ./src/extractors/custom/www.msn.com/index.js.
const { date_published } = await result;
const newDatePublished = moment(date_published).format();
// Update these values with the expected values from
// the article.
assert.equal(newDatePublished.split('T')[0], '2016-09-21');
assert.equal(date_published.split('T')[0], '2016-09-21');
});
it('returns the lead_image_url', async () => {

@ -1,7 +1,6 @@
import assert from 'assert';
import URL from 'url';
import cheerio from 'cheerio';
import moment from 'moment-timezone';
import Mercury from 'mercury';
import getExtractor from 'extractors/get-extractor';
@ -44,13 +43,10 @@ describe('WwwNationalgeographicComExtractor', () => {
// To pass this test, fill out the date_published selector
// in ./src/extractors/custom/www.nationalgeographic.com/index.js.
const { date_published } = await result;
const new_date_published = moment(date_published)
.format()
.split('T')[0];
// Update these values with the expected values from
// the article.
assert.equal(new_date_published, '2016-12-15');
assert.equal(date_published.split('T')[0], '2016-12-15');
});
it('returns the dek', async () => {

@ -19,7 +19,7 @@ export const WwwNbcnewsComExtractor = {
'.flag_article-wrapper time',
],
timezone: 'America/New_York',
// timezone: 'America/New_York',
},
lead_image_url: {

@ -53,7 +53,7 @@ describe('WwwNbcnewsComExtractor', () => {
// Update these values with the expected values from
// the article.
assert.equal(date_published, '2016-12-13T23:06:00.000Z');
assert.equal(date_published, '2016-12-13T18:06:00.000Z');
});
it('returns the lead_image_url', async () => {

@ -47,7 +47,7 @@ export const NewYorkerExtractor = {
'time.content-header__publish-date',
['meta[name="pubdate"]', 'value'],
],
timezone: 'America/New_York',
// timezone: 'America/New_York',
},
lead_image_url: {

@ -1,7 +1,6 @@
import assert from 'assert';
import URL from 'url';
import cheerio from 'cheerio';
import moment from 'moment-timezone';
import Mercury from 'mercury';
import getExtractor from 'extractors/get-extractor';
@ -55,14 +54,11 @@ describe('WwwNydailynewsComExtractor', () => {
// To pass this test, fill out the date_published selector
// in ./src/extractors/custom/www.nydailynews.com/index.js.
const { date_published } = await result;
const new_date_published = moment(date_published)
.format()
.split('T')[0];
// Update these values with the expected values from
// the article.
assert.equal(new_date_published, '2016-12-16');
assert.equal(date_published.split('T')[0], '2016-12-16');
});
it('returns the lead_image_url', async () => {

@ -9,7 +9,7 @@ export const WwwOssnewsJpExtractor = {
date_published: {
selectors: ['p.fs12'],
format: 'YYYY年MM月DD日 HH:mm',
format: 'YYYY[年]M[月]D[日] HH:mm',
timezone: 'Asia/Tokyo',
},

@ -12,7 +12,7 @@ export const WwwPhoronixComExtractor = {
date_published: {
selectors: ['.author'],
// 1 June 2019 at 08:34 PM EDT
format: 'D MMMM YYYY at hh:mm',
format: 'D MMMM YYYY [at] hh:mm A',
timezone: 'America/New_York',
},

@ -57,7 +57,7 @@ describe('WwwPhoronixComExtractor', () => {
// Update these values with the expected values from
// the article.
assert.equal(date_published, '2019-06-01T12:34:00.000Z');
assert.equal(date_published, '2019-06-02T00:34:00.000Z');
});
it('returns the dek', async () => {

@ -1,7 +1,6 @@
import assert from 'assert';
import URL from 'url';
import cheerio from 'cheerio';
import moment from 'moment-timezone';
import Mercury from 'mercury';
import getExtractor from 'extractors/get-extractor';
@ -55,13 +54,10 @@ describe('PoliticoExtractor', () => {
// To pass this test, fill out the date_published selector
// in ./src/extractors/custom/www.politico.com/index.js.
const { date_published } = await result;
const new_date_published = moment(date_published)
.format()
.split('T')[0];
// Update these values with the expected values from
// the article.
assert.equal(new_date_published, '2016-10-04');
assert.equal(date_published.split('T')[0], '2016-10-04');
});
it('returns the lead_image_url', async () => {

@ -11,8 +11,6 @@ export const WwwProspectmagazineCoUkExtractor = {
date_published: {
selectors: [['meta[name="article:published_time"]', 'value'], '.post-info'],
timezone: 'Europe/London',
},
dek: {

@ -18,7 +18,7 @@ export const WwwRawstoryComExtractor = {
'.blog-author a:last-of-type',
],
timezone: 'EST',
// timezone: 'EST',
},
lead_image_url: {

@ -1,7 +1,7 @@
import assert from 'assert';
import URL from 'url';
import cheerio from 'cheerio';
import moment from 'moment-timezone';
import dayjs from 'dayjs';
import Mercury from 'mercury';
import getExtractor from 'extractors/get-extractor';
@ -55,17 +55,15 @@ describe('WwwRedditComExtractor', () => {
// To pass this test, fill out the date_published selector
// in ./src/extractors/custom/www.reddit.com/index.js.
const { date_published } = await result;
const newDatePublished = moment(date_published)
.format()
.split('T')[0];
const expectedDate = moment()
const expectedDate = dayjs()
.subtract(4, 'years')
.format()
.split('T')[0];
// Update these values with the expected values from
// the article.
assert.equal(newDatePublished, expectedDate);
assert.equal(date_published.split('T')[0], expectedDate);
});
it('returns the lead_image_url', async () => {

@ -15,7 +15,7 @@ export const WwwRollingstoneComExtractor = {
'time.content-published-date',
],
timezone: 'America/New_York',
// timezone: 'America/New_York',
},
dek: {

@ -12,7 +12,7 @@ export const WwwSiComExtractor = {
date_published: {
selectors: [['meta[name="published"]', 'value']],
timezone: 'America/New_York',
// timezone: 'America/New_York',
},
dek: {

@ -11,6 +11,7 @@ export const SpektrumExtractor = {
date_published: {
selectors: ['.content__meta__date'],
format: 'DD[.]MM[.]YYYY',
timezone: 'Europe/Berlin',
},

@ -1,7 +1,6 @@
import assert from 'assert';
import URL from 'url';
import cheerio from 'cheerio';
import moment from 'moment-timezone';
import Mercury from 'mercury';
import getExtractor from 'extractors/get-extractor';
@ -55,13 +54,10 @@ describe('WwwTodayComExtractor', () => {
// To pass this test, fill out the date_published selector
// in ./src/extractors/custom/www.today.com/index.js.
const { date_published } = await result;
const new_date_published = moment(date_published)
.format()
.split('T')[0];
// Update these values with the expected values from
// the article.
assert.equal(new_date_published, '2016-12-22');
assert.equal(date_published.split('T')[0], '2016-12-22');
});
it('returns the lead_image_url', async () => {

@ -10,7 +10,7 @@ export const WwwUsmagazineComExtractor = {
},
date_published: {
timezone: 'America/New_York',
// timezone: 'America/New_York',
selectors: [['meta[name="article:published_time"]', 'value']],
},

@ -1,6 +1,6 @@
import assert from 'assert';
import cheerio from 'cheerio';
import moment from 'moment-timezone';
import dayjs from 'dayjs';
import GenericDatePublishedExtractor from './extractor';
@ -67,7 +67,7 @@ describe('GenericDatePublishedExtractor', () => {
metaCache,
});
assert.equal(result, moment('2020-01-01', 'YYYY-MM-DD').toISOString());
assert.equal(result, dayjs('2020-01-01', 'YYYY-MM-DD').toISOString());
});
it('extracts from url formatted /2020/jan/01', () => {
@ -83,7 +83,7 @@ describe('GenericDatePublishedExtractor', () => {
metaCache,
});
assert.equal(result, moment(new Date('2020 jan 01')).toISOString());
assert.equal(result, dayjs(new Date('2020 jan 01')).toISOString());
}
});

@ -1,5 +1,5 @@
import assert from 'assert';
import moment from 'moment';
import dayjs from 'dayjs';
import GenericExtractor from './index';
@ -18,7 +18,7 @@ describe('GenericExtractor', () => {
html,
metaCache: [],
});
const newDatePublished = moment(date_published).format();
const newDatePublished = dayjs(date_published).format();
assert.equal(author, null);
assert.equal(

@ -2577,6 +2577,11 @@ date-now@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
dayjs@^1.11.7:
version "1.11.7"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2"
integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==
debug@2.6.9, debug@^2.1.2, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@ -6132,22 +6137,6 @@ module-deps@^6.0.0:
through2 "^2.0.0"
xtend "^4.0.0"
moment-parseformat@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/moment-parseformat/-/moment-parseformat-3.0.0.tgz#3a1dc438b4bc073b7e93cc298cfb6c5daac26dba"
moment-timezone@0.5.37:
version "0.5.37"
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.37.tgz#adf97f719c4e458fdb12e2b4e87b8bec9f4eef1e"
integrity sha512-uEDzDNFhfaywRl+vwXxffjjq1q0Vzr+fcQpQ1bU0kbzorfS7zVtZnCnGc8mhWmF39d4g4YriF6kwA75mJKE/Zg==
dependencies:
moment ">= 2.9.0"
"moment@>= 2.9.0", moment@^2.23.0:
version "2.29.4"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
ms@0.7.2:
version "0.7.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765"

Loading…
Cancel
Save