瀏覽代碼

Removes dayjs & uses platform Intl formatting

main
Eric Amodio 2 年之前
父節點
當前提交
76e9abdceb
共有 11 個文件被更改,包括 267 次插入180 次删除
  1. +1
    -2
      package.json
  2. +6
    -5
      src/config.ts
  3. +3
    -3
      src/git/formatters/commitFormatter.ts
  4. +6
    -6
      src/git/models/commit.ts
  5. +2
    -2
      src/git/models/contributor.ts
  6. +7
    -3
      src/git/models/repository.ts
  7. +224
    -114
      src/system/date.ts
  8. +2
    -2
      src/webviews/apps/shared/appWithConfigBase.ts
  9. +1
    -15
      src/webviews/apps/shared/date.ts
  10. +1
    -1
      src/webviews/apps/tsconfig.json
  11. +14
    -27
      yarn.lock

+ 1
- 2
package.json 查看文件

@ -10135,7 +10135,6 @@
"@octokit/graphql": "4.8.0",
"@vscode/codicons": "0.0.27",
"chroma-js": "2.1.2",
"dayjs": "1.10.7",
"iconv-lite": "0.6.3",
"lodash-es": "4.17.21",
"md5.js": "1.3.5",
@ -10166,7 +10165,7 @@
"eslint-config-prettier": "8.3.0",
"eslint-import-resolver-typescript": "2.5.0",
"eslint-plugin-anti-trojan-source": "1.1.0",
"eslint-plugin-import": "2.25.3",
"eslint-plugin-import": "2.25.4",
"fork-ts-checker-webpack-plugin": "6.5.0",
"html-loader": "3.0.1",
"html-webpack-plugin": "5.5.0",

+ 6
- 5
src/config.ts 查看文件

@ -1,4 +1,5 @@
'use strict';
import { DateTimeFormat } from './system/date';
export const enum OutputLevel {
Silent = 'silent',
@ -12,7 +13,7 @@ export interface Config {
blame: {
avatars: boolean;
compact: boolean;
dateFormat: string | null;
dateFormat: DateTimeFormat | string | null;
format: string;
heatmap: {
enabled: boolean;
@ -41,12 +42,12 @@ export interface Config {
scrollable: boolean;
};
debug: boolean;
defaultDateFormat: string | null;
defaultDateShortFormat: string | null;
defaultDateFormat: DateTimeFormat | string | null;
defaultDateShortFormat: DateTimeFormat | string | null;
defaultDateSource: DateSource;
defaultDateStyle: DateStyle;
defaultGravatarsStyle: GravatarDefaultStyle;
defaultTimeFormat: string | null;
defaultTimeFormat: DateTimeFormat | string | null;
fileAnnotations: {
command: string | null;
};
@ -127,7 +128,7 @@ export interface Config {
statusBar: {
alignment: 'left' | 'right';
command: StatusBarCommand;
dateFormat: string | null;
dateFormat: DateTimeFormat | string | null;
enabled: boolean;
format: string;
reduceFlicker: boolean;

+ 3
- 3
src/git/formatters/commitFormatter.ts 查看文件

@ -87,7 +87,7 @@ export class CommitFormatter extends Formatter {
}
private get _authorDateAgoShort() {
return this._item.formatCommitterDateFromNow('en-short');
return this._item.formatCommitterDateFromNow(true);
}
private get _committerDate() {
@ -99,7 +99,7 @@ export class CommitFormatter extends Formatter {
}
private get _committerDateAgoShort() {
return this._item.formatCommitterDateFromNow('en-short');
return this._item.formatCommitterDateFromNow(true);
}
private get _date() {
@ -111,7 +111,7 @@ export class CommitFormatter extends Formatter {
}
private get _dateAgoShort() {
return this._item.formatDateFromNow('en-short');
return this._item.formatDateFromNow(true);
}
private get _pullRequestDate() {

+ 6
- 6
src/git/models/commit.ts 查看文件

@ -195,8 +195,8 @@ export abstract class GitCommit implements GitRevisionReference {
return this.authorDateFormatter.format(format);
}
formatAuthorDateFromNow(locale?: string) {
return this.authorDateFormatter.fromNow(locale);
formatAuthorDateFromNow(short?: boolean) {
return this.authorDateFormatter.fromNow(short);
}
@memoize<GitCommit['formatCommitterDate']>(format => (format == null ? 'MMMM Do, YYYY h:mma' : format))
@ -208,8 +208,8 @@ export abstract class GitCommit implements GitRevisionReference {
return this.committerDateFormatter.format(format);
}
formatCommitterDateFromNow(locale?: string) {
return this.committerDateFormatter.fromNow(locale);
formatCommitterDateFromNow(short?: boolean) {
return this.committerDateFormatter.fromNow(short);
}
@memoize<GitCommit['formatDate']>(format => (format == null ? 'MMMM Do, YYYY h:mma' : format))
@ -221,8 +221,8 @@ export abstract class GitCommit implements GitRevisionReference {
return this.dateFormatter.format(format);
}
formatDateFromNow(locale?: string) {
return this.dateFormatter.fromNow(locale);
formatDateFromNow(short?: boolean) {
return this.dateFormatter.fromNow(short);
}
getFormattedPath(options: { relativeTo?: string; suffix?: string; truncateTo?: number } = {}): string {

+ 2
- 2
src/git/models/contributor.ts 查看文件

@ -86,8 +86,8 @@ export class GitContributor {
return this.dateFormatter.format(format);
}
formatDateFromNow(locale?: string) {
return this.dateFormatter.fromNow(locale);
formatDateFromNow(short?: boolean) {
return this.dateFormatter.fromNow(short);
}
getAvatarUri(options?: { defaultStyle?: GravatarDefaultStyle; size?: number }): Uri | Promise<Uri> {

+ 7
- 3
src/git/models/repository.ts 查看文件

@ -40,6 +40,10 @@ import { GitStash } from './stash';
import { GitStatus } from './status';
import { GitTag, TagSortOptions } from './tag';
const millisecondsPerMinute = 60 * 1000;
const millisecondsPerHour = 60 * 60 * 1000;
const millisecondsPerDay = 24 * 60 * 60 * 1000;
export const enum RepositoryChange {
// FileSystem = 'filesystem',
Unknown = 'unknown',
@ -145,7 +149,7 @@ export interface RepositoryFileSystemChangeEvent {
export class Repository implements Disposable {
static formatLastFetched(lastFetched: number, short: boolean = true): string {
const formatter = Dates.getFormatter(new Date(lastFetched));
if (Date.now() - lastFetched < Dates.MillisecondsPerDay) {
if (Date.now() - lastFetched < millisecondsPerDay) {
return formatter.fromNow();
}
@ -164,8 +168,8 @@ export class Repository implements Disposable {
static getLastFetchedUpdateInterval(lastFetched: number): number {
const timeDiff = Date.now() - lastFetched;
return timeDiff < Dates.MillisecondsPerDay
? (timeDiff < Dates.MillisecondsPerHour ? Dates.MillisecondsPerMinute : Dates.MillisecondsPerHour) / 2
return timeDiff < millisecondsPerDay
? (timeDiff < millisecondsPerHour ? millisecondsPerMinute : millisecondsPerHour) / 2
: 0;
}

+ 224
- 114
src/system/date.ts 查看文件

@ -1,125 +1,235 @@
'use strict';
import * as dayjs from 'dayjs';
import * as advancedFormat from 'dayjs/plugin/advancedFormat';
import * as relativeTime from 'dayjs/plugin/relativeTime';
import * as updateLocale from 'dayjs/plugin/updateLocale';
dayjs.default.extend(advancedFormat.default);
dayjs.default.extend(relativeTime.default, {
thresholds: [
{ l: 's', r: 44, d: 'second' },
{ l: 'm', r: 89 },
{ l: 'mm', r: 44, d: 'minute' },
{ l: 'h', r: 89 },
{ l: 'hh', r: 21, d: 'hour' },
{ l: 'd', r: 35 },
{ l: 'dd', r: 6, d: 'day' },
{ l: 'w', r: 7 },
{ l: 'ww', r: 3, d: 'week' },
{ l: 'M', r: 4 },
{ l: 'MM', r: 10, d: 'month' },
{ l: 'y', r: 17 },
{ l: 'yy', d: 'year' },
],
});
dayjs.default.extend(updateLocale.default);
dayjs.default.updateLocale('en', {
relativeTime: {
future: 'in %s',
past: '%s ago',
s: 'seconds',
m: 'a minute',
mm: '%d minutes',
h: 'an hour',
hh: '%d hours',
d: 'a day',
dd: '%d days',
w: 'a week',
ww: '%d weeks',
M: 'a month',
MM: '%d months',
y: 'a year',
yy: '%d years',
},
});
const shortLocale = {
name: 'en-short',
weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
weekStart: 1,
weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
// relativeTime: {
// future: 'in %s',
// past: '%s',
// s: 'now',
// m: '1 min',
// mm: '%d mins',
// h: '1 hr',
// hh: '%d hrs',
// d: '1 day',
// dd: '%d days',
// w: '1 wk',
// ww: '%d wks',
// M: '1 mo',
// MM: '%d mos',
// y: '1 yr',
// yy: '%d yrs',
// },
relativeTime: {
future: 'in %s',
past: '%s',
s: 'now',
m: '1m',
mm: '%dm',
h: '1h',
hh: '%dh',
d: '1d',
dd: '%dd',
w: '1wk',
ww: '%dwk',
M: '1mo',
MM: '%dmo',
y: '1yr',
yy: '%dyr',
},
formats: {
LTS: 'h:mm:ss A',
LT: 'h:mm A',
L: 'MM/DD/YYYY',
LL: 'MMMM D, YYYY',
LLL: 'MMMM D, YYYY h:mm A',
LLLL: 'dddd, MMMM D, YYYY h:mm A',
},
ordinal: (n: number) => {
const s = ['th', 'st', 'nd', 'rd'];
const v = n % 100;
return `[${n}${s[(v - 20) % 10] || s[v] || s[0]}]`;
},
};
dayjs.default.locale('en-short', shortLocale, true);
export const MillisecondsPerMinute = 60000; // 60 * 1000
export const MillisecondsPerHour = 3600000; // 60 * 60 * 1000
export const MillisecondsPerDay = 86400000; // 24 * 60 * 60 * 1000
// NOTE@eamodio If this changes we need to update the replacement function too (since its parameter number/order relies on the matching)
const customDateTimeFormatParserRegex =
/(?<literal>\[.*?\])|(?<year>YYYY|YY)|(?<month>M{1,4})|(?<day>Do|DD?)|(?<weekday>d{2,4})|(?<hour>HH?|hh?)|(?<minute>mm?)|(?<second>ss?)|(?<fractionalSecond>SSS)|(?<dayPeriod>A|a)|(?<timeZoneName>ZZ?)/g;
const dateTimeFormatCache = new Map<string | undefined, Intl.DateTimeFormat>();
const dateTimeFormatRegex = /(?<dateStyle>full|long|medium|short)(?:\+(?<timeStyle>full|long|medium|short))?/;
let defaultRelativeTimeFormat: InstanceType<typeof Intl.RelativeTimeFormat> | undefined;
let defaultShortRelativeTimeFormat: InstanceType<typeof Intl.RelativeTimeFormat> | undefined;
let locale: string | undefined;
const relativeUnitThresholds: [Intl.RelativeTimeFormatUnit, number, string][] = [
['year', 24 * 60 * 60 * 1000 * 365, 'yr'],
['month', (24 * 60 * 60 * 1000 * 365) / 12, 'mo'],
['week', 24 * 60 * 60 * 1000 * 7, 'wk'],
['day', 24 * 60 * 60 * 1000, 'd'],
['hour', 60 * 60 * 1000, 'h'],
['minute', 60 * 1000, 'm'],
['second', 1000, 's'],
];
type DateStyle = 'full' | 'long' | 'medium' | 'short';
type TimeStyle = 'full' | 'long' | 'medium' | 'short';
export type DateTimeFormat = DateStyle | `${DateStyle}+${TimeStyle}`;
export interface DateFormatter {
fromNow(locale?: string): string;
format(format: string): string;
fromNow(short?: boolean): string;
format(format: DateTimeFormat | string | null | undefined): string;
}
export function getFormatter(date: Date): DateFormatter {
const formatter = dayjs.default(date);
return {
fromNow: function (locale?: string) {
return (locale ? formatter.locale(locale) : formatter).fromNow();
fromNow: function (short?: boolean) {
const elapsed = date.getTime() - new Date().getTime();
for (const [unit, threshold, shortUnit] of relativeUnitThresholds) {
const elapsedABS = Math.abs(elapsed);
if (elapsedABS >= threshold || threshold === 1000 /* second */) {
if (short) {
if (locale == null) {
if (defaultShortRelativeTimeFormat != null) {
locale = defaultShortRelativeTimeFormat.resolvedOptions().locale;
} else if (defaultRelativeTimeFormat != null) {
locale = defaultRelativeTimeFormat.resolvedOptions().locale;
} else {
defaultShortRelativeTimeFormat = new Intl.RelativeTimeFormat(undefined, {
localeMatcher: 'best fit',
numeric: 'always',
style: 'narrow',
});
locale = defaultShortRelativeTimeFormat.resolvedOptions().locale;
}
}
if (locale === 'en' || locale?.startsWith('en-')) {
const value = Math.round(elapsedABS / threshold);
return `${value}${shortUnit}`;
}
if (defaultShortRelativeTimeFormat == null) {
defaultShortRelativeTimeFormat = new Intl.RelativeTimeFormat(undefined, {
localeMatcher: 'best fit',
numeric: 'always',
style: 'narrow',
});
}
return defaultShortRelativeTimeFormat.format(Math.round(elapsed / threshold), unit);
}
if (defaultRelativeTimeFormat == null) {
defaultRelativeTimeFormat = new Intl.RelativeTimeFormat(undefined, {
localeMatcher: 'best fit',
numeric: 'auto',
style: 'long',
});
}
return defaultRelativeTimeFormat.format(Math.round(elapsed / threshold), unit);
}
}
return '';
},
format: function (format: string) {
return formatter.format(format);
format: function (format: 'full' | 'long' | 'medium' | 'short' | string | null | undefined) {
format = format ?? undefined;
let formatter = dateTimeFormatCache.get(format);
if (formatter == null) {
const options = getDateTimeFormatOptionsFromFormatString(format);
formatter = new Intl.DateTimeFormat(undefined, options);
dateTimeFormatCache.set(format, formatter);
}
if (format == null || dateTimeFormatRegex.test(format)) {
return formatter.format(date);
}
const parts = formatter.formatToParts(date);
return format.replace(
customDateTimeFormatParserRegex,
(
_match,
literal,
_year,
_month,
_day,
_weekday,
_hour,
_minute,
_second,
_fractionalSecond,
_dayPeriod,
_timeZoneName,
_offset,
_s,
groups,
) => {
if (literal != null) return (literal as string).substring(1, literal.length - 1);
for (const key in groups) {
const value = groups[key];
if (value == null) continue;
const part = parts.find(p => p.type === key);
if (value === 'Do' && part?.type === 'day') {
return formatWithOrdinal(Number(part.value));
} else if (value === 'a' && part?.type === 'dayPeriod') {
return part.value.toLocaleLowerCase();
}
return part?.value ?? '';
}
return '';
},
);
},
};
}
function getDateTimeFormatOptionsFromFormatString(
format: DateTimeFormat | string | undefined,
): Intl.DateTimeFormatOptions {
if (format == null) return { localeMatcher: 'best fit', dateStyle: 'full', timeStyle: 'short' };
const match = dateTimeFormatRegex.exec(format);
if (match?.groups != null) {
const { dateStyle, timeStyle } = match.groups;
return {
localeMatcher: 'best fit',
dateStyle: (dateStyle as Intl.DateTimeFormatOptions['dateStyle']) || 'full',
timeStyle: (timeStyle as Intl.DateTimeFormatOptions['timeStyle']) || undefined,
};
}
const options: Intl.DateTimeFormatOptions = { localeMatcher: 'best fit' };
for (const { groups } of format.matchAll(customDateTimeFormatParserRegex)) {
if (groups == null) continue;
for (const key in groups) {
const value = groups[key];
if (value == null) continue;
switch (key) {
case 'year':
options.year = value.length === 4 ? 'numeric' : '2-digit';
break;
case 'month':
switch (value.length) {
case 4:
options.month = 'long';
break;
case 3:
options.month = 'short';
break;
case 2:
options.month = '2-digit';
break;
case 1:
options.month = 'numeric';
break;
}
break;
case 'day':
if (value === 'DD') {
options.day = '2-digit';
} else {
options.day = 'numeric';
}
break;
case 'weekday':
switch (value.length) {
case 4:
options.weekday = 'long';
break;
case 3:
options.weekday = 'short';
break;
case 2:
options.weekday = 'narrow';
break;
}
break;
case 'hour':
options.hour = value.length === 2 ? '2-digit' : 'numeric';
options.hour12 = value === 'hh' || value === 'h';
break;
case 'minute':
options.minute = value.length === 2 ? '2-digit' : 'numeric';
break;
case 'second':
options.second = value.length === 2 ? '2-digit' : 'numeric';
break;
case 'fractionalSecond':
(options as any).fractionalSecondDigits = 3;
break;
case 'dayPeriod':
options.dayPeriod = 'narrow';
options.hour12 = true;
break;
case 'timeZoneName':
options.timeZoneName = (value.length === 2 ? 'longOffset' : 'shortOffset') as any;
break;
}
}
}
return options;
}
const ordinals = ['th', 'st', 'nd', 'rd'];
function formatWithOrdinal(n: number): string {
const v = n % 100;
return `${n}${ordinals[(v - 20) % 10] ?? ordinals[v] ?? ordinals[0]}`;
}

+ 2
- 2
src/webviews/apps/shared/appWithConfigBase.ts 查看文件

@ -9,12 +9,12 @@ import {
PreviewConfigurationCommandType,
UpdateConfigurationCommandType,
} from '../../protocol';
import { getDateFormatter } from '../shared/date';
import { getFormatter } from '../shared/date';
import { App } from './appBase';
import { DOM } from './dom';
const offset = (new Date().getTimezoneOffset() / 60) * 100;
const dateFormatter = getDateFormatter(
const dateFormatter = getFormatter(
new Date(`Wed Jul 25 2018 19:18:00 GMT${offset >= 0 ? '-' : '+'}${String(Math.abs(offset)).padStart(4, '0')}`),
);

+ 1
- 15
src/webviews/apps/shared/date.ts 查看文件

@ -1,16 +1,2 @@
'use strict';
import * as dayjs from 'dayjs';
import advancedFormat from 'dayjs/plugin/advancedFormat';
import relativeTime from 'dayjs/plugin/relativeTime';
dayjs.extend(advancedFormat);
dayjs.extend(relativeTime);
export interface DateFormatter {
fromNow(): string;
format(format: string): string;
}
export function getDateFormatter(date: Date): DateFormatter {
return dayjs.default(date);
}
export * from '../../../system/date';

+ 1
- 1
src/webviews/apps/tsconfig.json 查看文件

@ -5,6 +5,6 @@
"lib": ["dom", "dom.iterable", "es2020"],
"outDir": "../../"
},
"include": ["**/*", "../../config.ts", "../protocol.ts"],
"include": ["**/*", "../../../system/date.ts", "../../config.ts", "../protocol.ts"],
"exclude": ["node_modules", "test"]
}

+ 14
- 27
yarn.lock 查看文件

@ -1212,11 +1212,6 @@ data-uri-to-buffer@^3.0.1:
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636"
integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==
dayjs@1.10.7:
version "1.10.7"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.7.tgz#2cf5f91add28116748440866a0a1d26f3a6ce468"
integrity sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==
debug@^2.6.8, debug@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@ -1762,14 +1757,13 @@ eslint-import-resolver-typescript@2.5.0:
resolve "^1.20.0"
tsconfig-paths "^3.9.0"
eslint-module-utils@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz#b435001c9f8dd4ab7f6d0efcae4b9696d4c24b7c"
integrity sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==
eslint-module-utils@^2.7.2:
version "2.7.2"
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz#1d0aa455dcf41052339b63cada8ab5fd57577129"
integrity sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg==
dependencies:
debug "^3.2.7"
find-up "^2.1.0"
pkg-dir "^2.0.0"
eslint-plugin-anti-trojan-source@1.1.0:
version "1.1.0"
@ -1778,24 +1772,24 @@ eslint-plugin-anti-trojan-source@1.1.0:
dependencies:
anti-trojan-source "^1.3.1"
eslint-plugin-import@2.25.3:
version "2.25.3"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz#a554b5f66e08fb4f6dc99221866e57cfff824766"
integrity sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg==
eslint-plugin-import@2.25.4:
version "2.25.4"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz#322f3f916a4e9e991ac7af32032c25ce313209f1"
integrity sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==
dependencies:
array-includes "^3.1.4"
array.prototype.flat "^1.2.5"
debug "^2.6.9"
doctrine "^2.1.0"
eslint-import-resolver-node "^0.3.6"
eslint-module-utils "^2.7.1"
eslint-module-utils "^2.7.2"
has "^1.0.3"
is-core-module "^2.8.0"
is-glob "^4.0.3"
minimatch "^3.0.4"
object.values "^1.1.5"
resolve "^1.20.0"
tsconfig-paths "^3.11.0"
tsconfig-paths "^3.12.0"
eslint-scope@5.1.1, eslint-scope@^5.1.1:
version "5.1.1"
@ -3730,9 +3724,9 @@ picocolors@^1.0.0:
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3:
version "2.3.0"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
pify@^2.0.0, pify@^2.2.0, pify@^2.3.0:
version "2.3.0"
@ -3761,13 +3755,6 @@ pinkie@^2.0.0:
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
pkg-dir@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b"
integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=
dependencies:
find-up "^2.1.0"
pkg-dir@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
@ -4673,7 +4660,7 @@ ts-loader@9.2.6:
micromatch "^4.0.0"
semver "^7.3.4"
tsconfig-paths@^3.11.0, tsconfig-paths@^3.9.0:
tsconfig-paths@^3.12.0, tsconfig-paths@^3.9.0:
version "3.12.0"
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz#19769aca6ee8f6a1a341e38c8fa45dd9fb18899b"
integrity sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==

Loading…
取消
儲存