chore: add eslint package standard-with-typescript and apply rules
This commit is contained in:
parent
668e7dac73
commit
adf3aefcc5
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"root": true,
|
||||
"parser": "vue-eslint-parser",
|
||||
"parserOptions": {
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"project": "./tsconfig.json",
|
||||
"sourceType": "module",
|
||||
"extraFileExtensions": [
|
||||
".vue",
|
||||
".d.ts"
|
||||
]
|
||||
},
|
||||
"extends": [
|
||||
"standard",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"standard-with-typescript",
|
||||
"plugin:vue/vue3-recommended"
|
||||
],
|
||||
"rules": {
|
||||
"no-undef": "off",
|
||||
"comma-dangle": [
|
||||
"warn",
|
||||
"always-multiline"
|
||||
],
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/promise-function-async": "off"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"root": true,
|
||||
"env": {
|
||||
"cypress/globals": true
|
||||
},
|
||||
"extends": [
|
||||
"standard",
|
||||
"plugin:cypress/recommended"
|
||||
],
|
||||
"rules": {
|
||||
"comma-dangle": [
|
||||
"warn",
|
||||
"always-multiline"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
|
||||
/// <reference types="cypress" />
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
|
|
|
|||
35
package.json
35
package.json
|
|
@ -6,7 +6,7 @@
|
|||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"check-ts-errors": "yarn tsc && yarn vti diagnostics",
|
||||
"lint": "eslint \"{src,cypress/integration}/**/*.{js,ts,vue}\"",
|
||||
"lint": "eslint \"{src,cypress}/**/*.{js,ts,vue}\"",
|
||||
"test:unit": "jest --coverage",
|
||||
"test:e2e": "cypress run",
|
||||
"test": "yarn check-ts-errors && yarn lint && yarn test:unit && yarn test:e2e"
|
||||
|
|
@ -26,19 +26,20 @@
|
|||
"@types/dompurify": "^2.0.4",
|
||||
"@types/jest": "^24.9.1",
|
||||
"@types/marked": "^1.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.6.1",
|
||||
"@typescript-eslint/parser": "^4.6.1",
|
||||
"@typescript-eslint/eslint-plugin": "^4.7.0",
|
||||
"@typescript-eslint/parser": "^4.7.0",
|
||||
"@vue/compiler-sfc": "^3.0.2",
|
||||
"@vue/test-utils": "^2.0.0-beta.8",
|
||||
"babel-jest": "^24.9.0",
|
||||
"cypress": "^5.3.0",
|
||||
"eslint": "^7.12.1",
|
||||
"eslint": "^7.13.0",
|
||||
"eslint-config-standard": "^16.0.1",
|
||||
"eslint-config-standard-with-typescript": "^19.0.1",
|
||||
"eslint-plugin-cypress": "^2.11.2",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.2",
|
||||
"eslint-plugin-standard": "^4.1.0",
|
||||
"eslint-plugin-vue": "^7.1.0",
|
||||
"husky": "^4.3.0",
|
||||
"jest": "^24.9.0",
|
||||
|
|
@ -60,30 +61,6 @@
|
|||
"src/**/*.{ts,vue}": "eslint --fix",
|
||||
"cypress/**/*.js": "eslint --fix"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"parser": "vue-eslint-parser",
|
||||
"parserOptions": {
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"project": "./tsconfig.json"
|
||||
},
|
||||
"sourceType": "module"
|
||||
},
|
||||
"extends": [
|
||||
"standard",
|
||||
"plugin:cypress/recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:vue/vue3-recommended"
|
||||
],
|
||||
"rules": {
|
||||
"no-undef": "off",
|
||||
"comma-dangle": [
|
||||
"warn",
|
||||
"always-multiline"
|
||||
]
|
||||
}
|
||||
},
|
||||
"jest": {
|
||||
"preset": "ts-jest",
|
||||
"globals": {
|
||||
|
|
|
|||
|
|
@ -59,9 +59,9 @@ export function useArticles () {
|
|||
|
||||
const { active: articlesDownloading, run: runWrappedFetchArticles } = createAsyncProcess(fetchArticles)
|
||||
|
||||
watch(metaChanged, () => {
|
||||
watch(metaChanged, async () => {
|
||||
if (page.value !== 1) changePage(1)
|
||||
else runWrappedFetchArticles()
|
||||
else await runWrappedFetchArticles()
|
||||
})
|
||||
|
||||
watch(page, runWrappedFetchArticles)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export function useFollow ({ username, following, onUpdate }: UseFollowProps) {
|
|||
async function toggleFollow () {
|
||||
let response: Either<AuthorizationError, Profile>
|
||||
|
||||
if (following.value === true) {
|
||||
if (following.value) {
|
||||
response = await deleteFollowProfile(username.value)
|
||||
} else {
|
||||
response = await postFollowProfile(username.value)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export function useProfile ({ username }: UseProfileProps) {
|
|||
updateProfile(profileData)
|
||||
}
|
||||
|
||||
async function updateProfile (profileData: Profile | null) {
|
||||
function updateProfile (profileData: Profile | null) {
|
||||
profile.value = profileData
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
export const CONFIG = {
|
||||
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
||||
API_HOST: import.meta.env.VITE_API_HOST || '',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,5 +3,5 @@ import storage from '../utils/storage'
|
|||
|
||||
export default function (): void {
|
||||
const token = storage.get<User>('user')?.token
|
||||
if (token) request.setAuthorizationHeader(token)
|
||||
if (token !== undefined) request.setAuthorizationHeader(token)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,6 @@ export const router = createRouter({
|
|||
})
|
||||
|
||||
export function routerPush (name: AppRouteNames, params?: RouteParams): ReturnType<typeof router.push> {
|
||||
if (params) return router.push({ name, params })
|
||||
if (params !== undefined) return router.push({ name, params })
|
||||
else return router.push({ name })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { request } from '../index'
|
||||
|
||||
export async function deleteArticle (slug: string): Promise<void> {
|
||||
export function deleteArticle (slug: string): Promise<void> {
|
||||
return request.delete(`/articles/${slug}`)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { request } from '../index'
|
||||
|
||||
export async function getArticle (slug: string): Promise<Article> {
|
||||
export function getArticle (slug: string): Promise<Article> {
|
||||
return request.get<ArticleResponse>(`/articles/${slug}`).then(res => res.article)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,26 @@
|
|||
import { limit, request } from '../index'
|
||||
|
||||
export async function getArticles (page = 1): Promise<ArticlesResponse> {
|
||||
export function getArticles (page = 1): Promise<ArticlesResponse> {
|
||||
const params = { limit, offset: (page - 1) * limit }
|
||||
return request.get<ArticlesResponse>('/articles', { params })
|
||||
}
|
||||
|
||||
export async function getFavoritedArticles (username: string, page = 1): Promise<ArticlesResponse> {
|
||||
export function getFavoritedArticles (username: string, page = 1): Promise<ArticlesResponse> {
|
||||
const params = { limit, offset: (page - 1) * limit, favorited: username }
|
||||
return request.get<ArticlesResponse>('/articles', { params })
|
||||
}
|
||||
|
||||
export async function getProfileArticles (username: string, page = 1): Promise<ArticlesResponse> {
|
||||
export function getProfileArticles (username: string, page = 1): Promise<ArticlesResponse> {
|
||||
const params = { limit, offset: (page - 1) * limit, author: username }
|
||||
return request.get<ArticlesResponse>('/articles', { params })
|
||||
}
|
||||
|
||||
export async function getFeeds (page = 1): Promise<ArticlesResponse> {
|
||||
export function getFeeds (page = 1): Promise<ArticlesResponse> {
|
||||
const params = { limit, offset: (page - 1) * limit }
|
||||
return request.get<ArticlesResponse>('/articles/feed', { params })
|
||||
}
|
||||
|
||||
export async function getArticlesByTag (tagName: string, page = 1): Promise<ArticlesResponse> {
|
||||
export function getArticlesByTag (tagName: string, page = 1): Promise<ArticlesResponse> {
|
||||
const params = { tag: tagName, limit, offset: (page - 1) * limit }
|
||||
return request.get<ArticlesResponse>('/articles', { params })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
import { request } from '../index'
|
||||
|
||||
interface PostArticleForm {
|
||||
title: string;
|
||||
description: string;
|
||||
body: string;
|
||||
tagList: string[];
|
||||
title: string
|
||||
description: string
|
||||
body: string
|
||||
tagList: string[]
|
||||
}
|
||||
|
||||
export async function postArticle (form: PostArticleForm): Promise<Article> {
|
||||
export function postArticle (form: PostArticleForm): Promise<Article> {
|
||||
return request.post<ArticleResponse>('/articles', { article: form })
|
||||
.then(res => res.article)
|
||||
}
|
||||
|
||||
export async function putArticle (slug: string, form: PostArticleForm): Promise<Article> {
|
||||
export function putArticle (slug: string, form: PostArticleForm): Promise<Article> {
|
||||
return request.put<ArticleResponse>(`/articles/${slug}`, { article: form })
|
||||
.then(res => res.article)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import { mapValidationResponse } from '../../utils/map-checkable-response'
|
|||
import { Either, fail, success } from '../../utils/either'
|
||||
|
||||
export interface PostLoginForm {
|
||||
email: string;
|
||||
password: string;
|
||||
email: string
|
||||
password: string
|
||||
}
|
||||
|
||||
export type PostLoginErrors = Partial<Record<keyof PostLoginForm, string[]>>
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ import { mapValidationResponse } from '../../utils/map-checkable-response'
|
|||
import { Either, fail, success } from '../../utils/either'
|
||||
|
||||
export interface PostRegisterForm {
|
||||
email: string;
|
||||
password: string;
|
||||
username: string;
|
||||
email: string
|
||||
password: string
|
||||
username: string
|
||||
}
|
||||
|
||||
export type PostRegisterErrors = Partial<Record<keyof PostRegisterForm, string[]>>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { request } from '../index'
|
||||
|
||||
export async function getCommentsByArticle (slug: string): Promise<ArticleComment[]> {
|
||||
export function getCommentsByArticle (slug: string): Promise<ArticleComment[]> {
|
||||
return request.get<CommentsResponse>(`/articles/${slug}/comments`).then(res => res.comments)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { request } from '../index'
|
||||
|
||||
export async function deleteComment (slug: string, commentId: number): Promise<Record<string, unknown>> {
|
||||
export function deleteComment (slug: string, commentId: number): Promise<Record<string, unknown>> {
|
||||
return request.delete(`/articles/${slug}/comments/${commentId}`)
|
||||
}
|
||||
|
||||
export async function postComment (slug: string, body: string): Promise<ArticleComment> {
|
||||
export function postComment (slug: string, body: string): Promise<ArticleComment> {
|
||||
return request.post<CommentResponse>(`/articles/${slug}/comments`, { comment: { body } })
|
||||
.then(res => res.comment)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { request } from '../index'
|
||||
|
||||
export async function getProfile (username: string): Promise<Profile> {
|
||||
export function getProfile (username: string): Promise<Profile> {
|
||||
return request.get<ProfileResponse>(`/profiles/${username}`).then(res => res.profile)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import { request } from '../index'
|
||||
|
||||
export interface PutProfileForm {
|
||||
username?: string;
|
||||
bio?: string;
|
||||
image?: string;
|
||||
email?: string;
|
||||
password?: string;
|
||||
username?: string
|
||||
bio?: string
|
||||
image?: string
|
||||
email?: string
|
||||
password?: string
|
||||
}
|
||||
|
||||
export async function putProfile (form: PutProfileForm): Promise<User> {
|
||||
export function putProfile (form: PutProfileForm): Promise<User> {
|
||||
return request.put<UserResponse>('/user', form).then(res => res.user)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { request } from '../index'
|
||||
|
||||
export async function getAllTags (): Promise<string[]> {
|
||||
export function getAllTags (): Promise<string[]> {
|
||||
return request.get<TagsResponse>('/tags').then(res => res.tags)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export const checkAuthorization = (user: ComputedRef<User | null>): user is Comp
|
|||
}
|
||||
|
||||
export const updateUser = mutation<User | null>('updateUser', (state, userData) => {
|
||||
if (!userData) {
|
||||
if (userData === undefined || userData === null) {
|
||||
storage.remove('user')
|
||||
request.deleteAuthorizationHeader()
|
||||
state.user = null
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
declare interface Article {
|
||||
title: string;
|
||||
slug: string;
|
||||
body: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
tagList: string[];
|
||||
description: string;
|
||||
author: Profile;
|
||||
favorited: boolean;
|
||||
favoritesCount: number;
|
||||
title: string
|
||||
slug: string
|
||||
body: string
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
tagList: string[]
|
||||
description: string
|
||||
author: Profile
|
||||
favorited: boolean
|
||||
favoritesCount: number
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
declare interface ArticleComment {
|
||||
id: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
body: string;
|
||||
author: Profile;
|
||||
id: number
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
body: string
|
||||
author: Profile
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
declare interface UserResponse {
|
||||
user: User;
|
||||
user: User
|
||||
}
|
||||
|
||||
declare interface TagsResponse {
|
||||
tags: string[];
|
||||
tags: string[]
|
||||
}
|
||||
|
||||
declare interface ProfileResponse {
|
||||
profile: Profile;
|
||||
profile: Profile
|
||||
}
|
||||
|
||||
declare interface ArticleResponse {
|
||||
article: Article;
|
||||
article: Article
|
||||
}
|
||||
|
||||
declare interface ArticlesResponse {
|
||||
articles: Article[];
|
||||
articlesCount: number;
|
||||
articles: Article[]
|
||||
articlesCount: number
|
||||
}
|
||||
|
||||
declare interface CommentResponse {
|
||||
comment: ArticleComment;
|
||||
comment: ArticleComment
|
||||
}
|
||||
|
||||
declare interface CommentsResponse {
|
||||
comments: ArticleComment[];
|
||||
comments: ArticleComment[]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
declare interface Profile {
|
||||
username: string;
|
||||
bio: string;
|
||||
image: string;
|
||||
following: boolean;
|
||||
username: string
|
||||
bio: string
|
||||
image: string
|
||||
following: boolean
|
||||
}
|
||||
|
||||
declare interface User {
|
||||
id: number;
|
||||
email: string;
|
||||
username: string;
|
||||
bio: string | undefined;
|
||||
image: string | undefined;
|
||||
token: string;
|
||||
id: number
|
||||
email: string
|
||||
username: string
|
||||
bio: string | undefined
|
||||
image: string | undefined
|
||||
token: string
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { isRef } from 'vue'
|
|||
import createAsyncProcess from './create-async-process'
|
||||
|
||||
describe('# Create async process', function () {
|
||||
const someProcess = async () => Promise.resolve(null)
|
||||
const someProcess = () => Promise.resolve(null)
|
||||
|
||||
it('should expect active as Vue Ref type', function () {
|
||||
const { active } = createAsyncProcess(someProcess)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { ValidationError, AuthorizationError, NetworkError } from 'src/types/err
|
|||
import { Either, fail, isEither, success } from './either'
|
||||
import { mapAuthorizationResponse, mapValidationResponse } from './map-checkable-response'
|
||||
|
||||
const createCheckableResponse = (response: Partial<Response>): Either<NetworkError, Partial<Response>> => response.ok
|
||||
const createCheckableResponse = (response: Partial<Response>): Either<NetworkError, Partial<Response>> => response.ok === true
|
||||
? success(response)
|
||||
: fail(new NetworkError(response as Response))
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ async function triggerMethod<T = unknown> (request: FetchRequest, method: Method
|
|||
}
|
||||
}
|
||||
|
||||
function forCorrectMethods (task: string, fn: (method: Method) => void): void {
|
||||
function forCorrectMethods (task: string, fn: (method: Method) => Promise<void>): void {
|
||||
wrapTests<Method>({
|
||||
task,
|
||||
fn,
|
||||
|
|
@ -61,7 +61,7 @@ function forCorrectMethods (task: string, fn: (method: Method) => void): void {
|
|||
})
|
||||
}
|
||||
|
||||
function forCheckableMethods (task: string, fn: (method: CheckableMethod) => void): void {
|
||||
function forCheckableMethods (task: string, fn: (method: CheckableMethod) => Promise<void>): void {
|
||||
wrapTests<CheckableMethod>({
|
||||
task,
|
||||
fn,
|
||||
|
|
@ -70,7 +70,7 @@ function forCheckableMethods (task: string, fn: (method: CheckableMethod) => voi
|
|||
})
|
||||
}
|
||||
|
||||
function forAllMethods (task: string, fn: (method: Method | CheckableMethod) => void): void {
|
||||
function forAllMethods (task: string, fn: (method: Method | CheckableMethod) => Promise<void>): void {
|
||||
forCheckableMethods(task, fn)
|
||||
forCorrectMethods(task, fn)
|
||||
}
|
||||
|
|
@ -78,7 +78,7 @@ function forAllMethods (task: string, fn: (method: Method | CheckableMethod) =>
|
|||
forAllMethods('# Should be implemented', async (method) => {
|
||||
const request = new FetchRequest()
|
||||
|
||||
triggerMethod(request, method)
|
||||
await triggerMethod(request, method)
|
||||
|
||||
expect(global.fetch).toBeCalledWith(PATH, expect.objectContaining({
|
||||
method: method.replace('checkable', '').toUpperCase(),
|
||||
|
|
@ -89,7 +89,7 @@ describe('# Should implement prefix', () => {
|
|||
forAllMethods('should implement global prefix', async (method) => {
|
||||
const request = new FetchRequest({ prefix: PREFIX })
|
||||
|
||||
triggerMethod(request, method)
|
||||
await triggerMethod(request, method)
|
||||
|
||||
expect(global.fetch).toBeCalledWith(`${PREFIX}${PATH}`, expect.any(Object))
|
||||
})
|
||||
|
|
@ -97,7 +97,7 @@ describe('# Should implement prefix', () => {
|
|||
forAllMethods('should implement local prefix', async (method) => {
|
||||
const request = new FetchRequest()
|
||||
|
||||
triggerMethod(request, method, { prefix: SUB_PREFIX })
|
||||
await triggerMethod(request, method, { prefix: SUB_PREFIX })
|
||||
|
||||
expect(global.fetch).toBeCalledWith(`${SUB_PREFIX}${PATH}`, expect.any(Object))
|
||||
})
|
||||
|
|
@ -105,7 +105,7 @@ describe('# Should implement prefix', () => {
|
|||
forAllMethods('should implement global + local prefix', async (method) => {
|
||||
const request = new FetchRequest({ prefix: PREFIX })
|
||||
|
||||
triggerMethod(request, method, { prefix: SUB_PREFIX })
|
||||
await triggerMethod(request, method, { prefix: SUB_PREFIX })
|
||||
|
||||
expect(global.fetch).toBeCalledWith(`${SUB_PREFIX}${PATH}`, expect.any(Object))
|
||||
})
|
||||
|
|
@ -115,7 +115,7 @@ describe('# Should convert query object to query string in request url', () => {
|
|||
forAllMethods('should implement global query', async (method) => {
|
||||
const request = new FetchRequest({ params: PARAMS })
|
||||
|
||||
triggerMethod(request, method)
|
||||
await triggerMethod(request, method)
|
||||
|
||||
expect(global.fetch).toBeCalledWith(`${PATH}?${params2query(PARAMS)}`, expect.any(Object))
|
||||
})
|
||||
|
|
@ -123,7 +123,7 @@ describe('# Should convert query object to query string in request url', () => {
|
|||
forAllMethods('should implement local query', async (method) => {
|
||||
const request = new FetchRequest()
|
||||
|
||||
triggerMethod(request, method, { params: PARAMS })
|
||||
await triggerMethod(request, method, { params: PARAMS })
|
||||
|
||||
expect(global.fetch).toBeCalledWith(`${PATH}?${params2query(PARAMS)}`, expect.any(Object))
|
||||
})
|
||||
|
|
@ -134,7 +134,7 @@ describe('# Should convert query object to query string in request url', () => {
|
|||
const expectedOptions = { params: { q1: 'q11', q2: 'q2', q3: 'q3' } }
|
||||
const request = new FetchRequest(options)
|
||||
|
||||
triggerMethod(request, method, localOptions)
|
||||
await triggerMethod(request, method, localOptions)
|
||||
|
||||
expect(global.fetch).toBeCalledWith(`${PATH}?${params2query(expectedOptions.params)}`, expect.any(Object))
|
||||
})
|
||||
|
|
@ -174,15 +174,15 @@ forCorrectMethods('# Should converted correct response body to json', async func
|
|||
|
||||
forCheckableMethods('# Should converted checkable response to Either<NetworkError, DATA_TYPE>', async function (method) {
|
||||
const DATA = { foo: 'bar' }
|
||||
type DATA_TYPE = {foo: 'bar'}
|
||||
interface DATA_TYPE { foo: 'bar' }
|
||||
mockFetch({ type: 'body', ...DATA })
|
||||
const request = new FetchRequest()
|
||||
|
||||
const result = await triggerMethod<DATA_TYPE>(request, method)
|
||||
|
||||
const resultIsEither = isEither<NetworkError, DATA_TYPE>(result)
|
||||
const resultIsOk = isEither<NetworkError, DATA_TYPE>(result) && result.isOk()
|
||||
const resultValue = isEither<NetworkError, DATA_TYPE>(result) && result.isOk() ? result.value : null
|
||||
const resultIsEither = isEither<unknown, DATA_TYPE>(result)
|
||||
const resultIsOk = isEither<unknown, DATA_TYPE>(result) && result.isOk()
|
||||
const resultValue = isEither<unknown, DATA_TYPE>(result) && result.isOk() ? result.value : null
|
||||
|
||||
expect(resultIsEither).toBe(true)
|
||||
expect(resultIsOk).toBe(true)
|
||||
|
|
@ -216,9 +216,9 @@ forCheckableMethods('# Should return Either<NetworkError, DATA_TYPE> if checkabl
|
|||
const request = new FetchRequest()
|
||||
const result = await triggerMethod(request, method)
|
||||
|
||||
const resultIsEither = isEither<NetworkError, void>(result)
|
||||
const resultIsNotOk = isEither<NetworkError, void>(result) && result.isFail()
|
||||
const resultValue = isEither<NetworkError, void>(result) && result.isFail() ? result.value : null
|
||||
const resultIsEither = isEither<NetworkError, unknown>(result)
|
||||
const resultIsNotOk = isEither<NetworkError, unknown>(result) && result.isFail()
|
||||
const resultValue = isEither<NetworkError, unknown>(result) && result.isFail() ? result.value : null
|
||||
|
||||
expect(resultIsEither).toBe(true)
|
||||
expect(resultIsNotOk).toBe(true)
|
||||
|
|
@ -233,7 +233,7 @@ describe('# Authorization header', function () {
|
|||
const request = new FetchRequest()
|
||||
request.setAuthorizationHeader(TOKEN)
|
||||
|
||||
triggerMethod(request, method)
|
||||
await triggerMethod(request, method)
|
||||
|
||||
expect(global.fetch).toBeCalledWith(PATH, expect.objectContaining(OPTIONS))
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,39 +6,39 @@ import { Either, fail, success } from './either'
|
|||
import params2query from './params-to-query'
|
||||
|
||||
export interface FetchRequestOptions {
|
||||
prefix: string;
|
||||
headers: Record<string, string>;
|
||||
params: Record<string, string | number | boolean>;
|
||||
prefix: string
|
||||
headers: Record<string, string>
|
||||
params: Record<string, string | number | boolean>
|
||||
}
|
||||
|
||||
export default class FetchRequest {
|
||||
private defaultOptions: FetchRequestOptions = {
|
||||
private readonly defaultOptions: FetchRequestOptions = {
|
||||
prefix: '',
|
||||
headers: {},
|
||||
params: {},
|
||||
}
|
||||
|
||||
private options: FetchRequestOptions
|
||||
private readonly options: FetchRequestOptions
|
||||
|
||||
constructor (options: Partial<FetchRequestOptions> = {}) {
|
||||
this.options = merge(this.defaultOptions, options)
|
||||
}
|
||||
|
||||
private generateFinalUrl = (url: string, options: Partial<FetchRequestOptions> = {}) => {
|
||||
private readonly generateFinalUrl = (url: string, options: Partial<FetchRequestOptions> = {}) => {
|
||||
const prefix = options.prefix ?? this.options.prefix
|
||||
const params = merge(this.options.params, options.params ?? {})
|
||||
|
||||
let finalUrl = `${prefix}${url}`
|
||||
if (Object.keys(params).length) finalUrl += `?${params2query(params)}`
|
||||
if (Object.keys(params).length > 0) finalUrl += `?${params2query(params)}`
|
||||
|
||||
return finalUrl
|
||||
}
|
||||
|
||||
private generateFinalHeaders = (options: Partial<FetchRequestOptions> = {}) => {
|
||||
private readonly generateFinalHeaders = (options: Partial<FetchRequestOptions> = {}) => {
|
||||
return merge(this.options.headers, options.headers ?? {})
|
||||
}
|
||||
|
||||
private handleResponse = <T>(response: Response): Promise<Either<NetworkError, T>> => {
|
||||
private readonly handleResponse = <T>(response: Response): Promise<Either<NetworkError, T>> => {
|
||||
if (response.ok) {
|
||||
return response.json().then(json => success(json as T))
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ export default class FetchRequest {
|
|||
return Promise.resolve(fail(new NetworkError(response)))
|
||||
}
|
||||
|
||||
private handleCorrectResponse = <T>(response: Response): Promise<T> => {
|
||||
private readonly handleCorrectResponse = <T>(response: Response): Promise<T> => {
|
||||
if (response.ok) {
|
||||
return response.json()
|
||||
}
|
||||
|
|
@ -55,9 +55,9 @@ export default class FetchRequest {
|
|||
}
|
||||
|
||||
private runFetch ({ method, url, data, options }: {
|
||||
method: 'GET' | 'DELETE' | 'POST' | 'PUT' | 'PATCH',
|
||||
url: string,
|
||||
data?: unknown,
|
||||
method: 'GET' | 'DELETE' | 'POST' | 'PUT' | 'PATCH'
|
||||
url: string
|
||||
data?: unknown
|
||||
options?: Partial<FetchRequestOptions>
|
||||
}) {
|
||||
const finalUrl = this.generateFinalUrl(url, options)
|
||||
|
|
@ -65,7 +65,7 @@ export default class FetchRequest {
|
|||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const fetchOptions: any = { method, headers }
|
||||
if (data) fetchOptions.body = JSON.stringify(data)
|
||||
if (data !== undefined) fetchOptions.body = JSON.stringify(data)
|
||||
return fetch(finalUrl, fetchOptions)
|
||||
}
|
||||
|
||||
|
|
@ -118,8 +118,7 @@ export default class FetchRequest {
|
|||
}
|
||||
|
||||
public setAuthorizationHeader (token: string): void {
|
||||
if (!this.options.headers) this.options.headers = {}
|
||||
if (token) this.options.headers.Authorization = `Token ${token}`
|
||||
if (token !== '') this.options.headers.Authorization = `Token ${token}`
|
||||
}
|
||||
|
||||
public deleteAuthorizationHeader (): void {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
function get<T> (key: string): T | null {
|
||||
try {
|
||||
const value = localStorage.getItem(key) || ''
|
||||
const value = localStorage.getItem(key) ?? ''
|
||||
return JSON.parse(value)
|
||||
} catch (e) {
|
||||
return null
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ interface FetchResponseBody {
|
|||
}
|
||||
interface FetchResponseFull {
|
||||
type: 'full'
|
||||
ok: boolean,
|
||||
status: number,
|
||||
ok: boolean
|
||||
status: number
|
||||
statusText: string
|
||||
json: () => Promise<unknown>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
interface WrapTestsProps <Item> {
|
||||
task: string
|
||||
list: Item[]
|
||||
fn: (item: Item) => void,
|
||||
only?: boolean,
|
||||
fn: (item: Item) => void
|
||||
only?: boolean
|
||||
testName?: (item: Item, index: number) => string
|
||||
}
|
||||
|
||||
|
|
@ -11,7 +11,7 @@ function wrapTests<Item> ({ task, list, fn, testName, only = false }: WrapTestsP
|
|||
|
||||
descFn(task, () => {
|
||||
list.forEach((item, index) => {
|
||||
const name = testName ? testName(item, index) : ''
|
||||
const name = testName !== undefined ? testName(item, index) : ''
|
||||
it(name, () => fn(item))
|
||||
})
|
||||
})
|
||||
|
|
|
|||
148
yarn.lock
148
yarn.lock
|
|
@ -1151,13 +1151,13 @@
|
|||
dependencies:
|
||||
"@types/yargs-parser" "*"
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^4.6.1":
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.6.1.tgz#99d77eb7a016fd5a5e749d2c44a7e4c317eb7da3"
|
||||
integrity sha512-SNZyflefTMK2JyrPfFFzzoy2asLmZvZJ6+/L5cIqg4HfKGiW2Gr1Go1OyEVqne/U4QwmoasuMwppoBHWBWF2nA==
|
||||
"@typescript-eslint/eslint-plugin@^4.7.0":
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.7.0.tgz#85c9bbda00c0cb604d3c241f7bc7fb171a2d3479"
|
||||
integrity sha512-li9aiSVBBd7kU5VlQlT1AqP0uWGDK6JYKUQ9cVDnOg34VNnd9t4jr0Yqc/bKxJr/tDCPDaB4KzoSFN9fgVxe/Q==
|
||||
dependencies:
|
||||
"@typescript-eslint/experimental-utils" "4.6.1"
|
||||
"@typescript-eslint/scope-manager" "4.6.1"
|
||||
"@typescript-eslint/experimental-utils" "4.7.0"
|
||||
"@typescript-eslint/scope-manager" "4.7.0"
|
||||
debug "^4.1.1"
|
||||
functional-red-black-tree "^1.0.1"
|
||||
regexpp "^3.0.0"
|
||||
|
|
@ -1175,15 +1175,15 @@
|
|||
eslint-scope "^5.0.0"
|
||||
eslint-utils "^2.0.0"
|
||||
|
||||
"@typescript-eslint/experimental-utils@4.6.1":
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.6.1.tgz#a9c691dfd530a9570274fe68907c24c07a06c4aa"
|
||||
integrity sha512-qyPqCFWlHZXkEBoV56UxHSoXW2qnTr4JrWVXOh3soBP3q0o7p4pUEMfInDwIa0dB/ypdtm7gLOS0hg0a73ijfg==
|
||||
"@typescript-eslint/experimental-utils@4.7.0":
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.7.0.tgz#8d1058c38bec3d3bbd9c898a1c32318d80faf3c5"
|
||||
integrity sha512-cymzovXAiD4EF+YoHAB5Oh02MpnXjvyaOb+v+BdpY7lsJXZQN34oIETeUwVT2XfV9rSNpXaIcknDLfupO/tUoA==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.3"
|
||||
"@typescript-eslint/scope-manager" "4.6.1"
|
||||
"@typescript-eslint/types" "4.6.1"
|
||||
"@typescript-eslint/typescript-estree" "4.6.1"
|
||||
"@typescript-eslint/scope-manager" "4.7.0"
|
||||
"@typescript-eslint/types" "4.7.0"
|
||||
"@typescript-eslint/typescript-estree" "4.7.0"
|
||||
eslint-scope "^5.0.0"
|
||||
eslint-utils "^2.0.0"
|
||||
|
||||
|
|
@ -1198,33 +1198,33 @@
|
|||
"@typescript-eslint/typescript-estree" "3.10.1"
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
"@typescript-eslint/parser@^4.6.1":
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.6.1.tgz#b801bff67b536ecc4a840ac9289ba2be57e02428"
|
||||
integrity sha512-lScKRPt1wM9UwyKkGKyQDqf0bh6jm8DQ5iN37urRIXDm16GEv+HGEmum2Fc423xlk5NUOkOpfTnKZc/tqKZkDQ==
|
||||
"@typescript-eslint/parser@^4.0.0", "@typescript-eslint/parser@^4.7.0":
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.7.0.tgz#44bdab0f788b478178368baa65d3365fdc63da1c"
|
||||
integrity sha512-+meGV8bMP1sJHBI2AFq1GeTwofcGiur8LoIr6v+rEmD9knyCqDlrQcFHR0KDDfldHIFDU/enZ53fla6ReF4wRw==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "4.6.1"
|
||||
"@typescript-eslint/types" "4.6.1"
|
||||
"@typescript-eslint/typescript-estree" "4.6.1"
|
||||
"@typescript-eslint/scope-manager" "4.7.0"
|
||||
"@typescript-eslint/types" "4.7.0"
|
||||
"@typescript-eslint/typescript-estree" "4.7.0"
|
||||
debug "^4.1.1"
|
||||
|
||||
"@typescript-eslint/scope-manager@4.6.1":
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.6.1.tgz#21872b91cbf7adfc7083f17b8041149148baf992"
|
||||
integrity sha512-f95+80r6VdINYscJY1KDUEDcxZ3prAWHulL4qRDfNVD0I5QAVSGqFkwHERDoLYJJWmEAkUMdQVvx7/c2Hp+Bjg==
|
||||
"@typescript-eslint/scope-manager@4.7.0":
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.7.0.tgz#2115526085fb72723ccdc1eeae75dec7126220ed"
|
||||
integrity sha512-ILITvqwDJYbcDCROj6+Ob0oCKNg3SH46iWcNcTIT9B5aiVssoTYkhKjxOMNzR1F7WSJkik4zmuqve5MdnA0DyA==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.6.1"
|
||||
"@typescript-eslint/visitor-keys" "4.6.1"
|
||||
"@typescript-eslint/types" "4.7.0"
|
||||
"@typescript-eslint/visitor-keys" "4.7.0"
|
||||
|
||||
"@typescript-eslint/types@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.10.1.tgz#1d7463fa7c32d8a23ab508a803ca2fe26e758727"
|
||||
integrity sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ==
|
||||
|
||||
"@typescript-eslint/types@4.6.1":
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.6.1.tgz#d3ad7478f53f22e7339dc006ab61aac131231552"
|
||||
integrity sha512-k2ZCHhJ96YZyPIsykickez+OMHkz06xppVLfJ+DY90i532/Cx2Z+HiRMH8YZQo7a4zVd/TwNBuRCdXlGK4yo8w==
|
||||
"@typescript-eslint/types@4.7.0":
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.7.0.tgz#5e95ef5c740f43d942542b35811f87b62fccca69"
|
||||
integrity sha512-uLszFe0wExJc+I7q0Z/+BnP7wao/kzX0hB5vJn4LIgrfrMLgnB2UXoReV19lkJQS1a1mHWGGODSxnBx6JQC3Sg==
|
||||
|
||||
"@typescript-eslint/typescript-estree@3.10.1":
|
||||
version "3.10.1"
|
||||
|
|
@ -1240,13 +1240,13 @@
|
|||
semver "^7.3.2"
|
||||
tsutils "^3.17.1"
|
||||
|
||||
"@typescript-eslint/typescript-estree@4.6.1":
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.6.1.tgz#6025cce724329413f57e4959b2d676fceeca246f"
|
||||
integrity sha512-/J/kxiyjQQKqEr5kuKLNQ1Finpfb8gf/NpbwqFFYEBjxOsZ621r9AqwS9UDRA1Rrr/eneX/YsbPAIhU2rFLjXQ==
|
||||
"@typescript-eslint/typescript-estree@4.7.0":
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.7.0.tgz#539531167f05ba20eb0b6785567076679e29d393"
|
||||
integrity sha512-5XZRQznD1MfUmxu1t8/j2Af4OxbA7EFU2rbo0No7meb46eHgGkSieFdfV6omiC/DGIBhH9H9gXn7okBbVOm8jw==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.6.1"
|
||||
"@typescript-eslint/visitor-keys" "4.6.1"
|
||||
"@typescript-eslint/types" "4.7.0"
|
||||
"@typescript-eslint/visitor-keys" "4.7.0"
|
||||
debug "^4.1.1"
|
||||
globby "^11.0.1"
|
||||
is-glob "^4.0.1"
|
||||
|
|
@ -1261,12 +1261,12 @@
|
|||
dependencies:
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@4.6.1":
|
||||
version "4.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.6.1.tgz#6b125883402d8939df7b54528d879e88f7ba3614"
|
||||
integrity sha512-owABze4toX7QXwOLT3/D5a8NecZEjEWU1srqxENTfqsY3bwVnl3YYbOh6s1rp2wQKO9RTHFGjKes08FgE7SVMw==
|
||||
"@typescript-eslint/visitor-keys@4.7.0":
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.7.0.tgz#6783824f22acfc49e754970ed21b88ac03b80e6f"
|
||||
integrity sha512-aDJDWuCRsf1lXOtignlfiPODkzSxxop7D0rZ91L6ZuMlcMCSh0YyK+gAfo5zN/ih6WxMwhoXgJWC3cWQdaKC+A==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "4.6.1"
|
||||
"@typescript-eslint/types" "4.7.0"
|
||||
eslint-visitor-keys "^2.0.0"
|
||||
|
||||
"@vue/compiler-core@3.0.2":
|
||||
|
|
@ -3079,6 +3079,19 @@ escodegen@^1.14.1, escodegen@^1.9.1:
|
|||
optionalDependencies:
|
||||
source-map "~0.6.1"
|
||||
|
||||
eslint-config-standard-with-typescript@^19.0.1:
|
||||
version "19.0.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-19.0.1.tgz#d486e08a82f6bf43a8e0ef1bc76088e26fe7a587"
|
||||
integrity sha512-hAKj81+f4a+9lnvpHwZ4XSL672CbwSe5UJ7fTdL/RsQdqs4IjHudMETZuNQwwU7NlYpBTF9se7FRf5Pp7CVdag==
|
||||
dependencies:
|
||||
"@typescript-eslint/parser" "^4.0.0"
|
||||
eslint-config-standard "^14.1.1"
|
||||
|
||||
eslint-config-standard@^14.1.1:
|
||||
version "14.1.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz#830a8e44e7aef7de67464979ad06b406026c56ea"
|
||||
integrity sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg==
|
||||
|
||||
eslint-config-standard@^16.0.1:
|
||||
version "16.0.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-16.0.1.tgz#9a385eea27f96b7918cb53f07e01e9d10cc56401"
|
||||
|
|
@ -3151,10 +3164,10 @@ eslint-plugin-promise@^4.2.1:
|
|||
resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a"
|
||||
integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==
|
||||
|
||||
eslint-plugin-standard@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.2.tgz#021211a9f077e63a6847e7bb9ab4247327ac8e0c"
|
||||
integrity sha512-nKptN8l7jksXkwFk++PhJB3cCDTcXOEyhISIN86Ue2feJ1LFyY3PrY3/xT2keXlJSY5bpmbiTG0f885/YKAvTA==
|
||||
eslint-plugin-standard@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz#0c3bf3a67e853f8bbbc580fb4945fbf16f41b7c5"
|
||||
integrity sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ==
|
||||
|
||||
eslint-plugin-vue@^7.1.0:
|
||||
version "7.1.0"
|
||||
|
|
@ -3241,7 +3254,7 @@ eslint@^6.8.0:
|
|||
text-table "^0.2.0"
|
||||
v8-compile-cache "^2.0.3"
|
||||
|
||||
eslint@^7.11.0:
|
||||
eslint@^7.11.0, eslint@^7.13.0:
|
||||
version "7.13.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.13.0.tgz#7f180126c0dcdef327bfb54b211d7802decc08da"
|
||||
integrity sha512-uCORMuOO8tUzJmsdRtrvcGq5qposf7Rw0LwkTJkoDbOycVQtQjmnhZSuLQnozLE4TmAzlMVV45eCHmQ1OpDKUQ==
|
||||
|
|
@ -3284,49 +3297,6 @@ eslint@^7.11.0:
|
|||
text-table "^0.2.0"
|
||||
v8-compile-cache "^2.0.3"
|
||||
|
||||
eslint@^7.12.1:
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.12.1.tgz#bd9a81fa67a6cfd51656cdb88812ce49ccec5801"
|
||||
integrity sha512-HlMTEdr/LicJfN08LB3nM1rRYliDXOmfoO4vj39xN6BLpFzF00hbwBoqHk8UcJ2M/3nlARZWy/mslvGEuZFvsg==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.0.0"
|
||||
"@eslint/eslintrc" "^0.2.1"
|
||||
ajv "^6.10.0"
|
||||
chalk "^4.0.0"
|
||||
cross-spawn "^7.0.2"
|
||||
debug "^4.0.1"
|
||||
doctrine "^3.0.0"
|
||||
enquirer "^2.3.5"
|
||||
eslint-scope "^5.1.1"
|
||||
eslint-utils "^2.1.0"
|
||||
eslint-visitor-keys "^2.0.0"
|
||||
espree "^7.3.0"
|
||||
esquery "^1.2.0"
|
||||
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"
|
||||
is-glob "^4.0.0"
|
||||
js-yaml "^3.13.1"
|
||||
json-stable-stringify-without-jsonify "^1.0.1"
|
||||
levn "^0.4.1"
|
||||
lodash "^4.17.19"
|
||||
minimatch "^3.0.4"
|
||||
natural-compare "^1.4.0"
|
||||
optionator "^0.9.1"
|
||||
progress "^2.0.0"
|
||||
regexpp "^3.1.0"
|
||||
semver "^7.2.1"
|
||||
strip-ansi "^6.0.0"
|
||||
strip-json-comments "^3.1.0"
|
||||
table "^5.2.3"
|
||||
text-table "^0.2.0"
|
||||
v8-compile-cache "^2.0.3"
|
||||
|
||||
espree@^6.1.2, espree@^6.2.1:
|
||||
version "6.2.1"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a"
|
||||
|
|
|
|||
Loading…
Reference in New Issue