diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 0000000..a1448ea
--- /dev/null
+++ b/.eslintrc
@@ -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"
+ }
+}
\ No newline at end of file
diff --git a/cypress/.eslintrc b/cypress/.eslintrc
new file mode 100644
index 0000000..f7f4e24
--- /dev/null
+++ b/cypress/.eslintrc
@@ -0,0 +1,16 @@
+{
+ "root": true,
+ "env": {
+ "cypress/globals": true
+ },
+ "extends": [
+ "standard",
+ "plugin:cypress/recommended"
+ ],
+ "rules": {
+ "comma-dangle": [
+ "warn",
+ "always-multiline"
+ ]
+ }
+}
diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js
index 225d017..aa9918d 100644
--- a/cypress/plugins/index.js
+++ b/cypress/plugins/index.js
@@ -1,5 +1,3 @@
-/* eslint-disable @typescript-eslint/no-unused-vars */
-
///
// ***********************************************************
// This example plugins/index.js can be used to load plugins
diff --git a/package.json b/package.json
index 58657e8..61406c1 100644
--- a/package.json
+++ b/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": {
diff --git a/src/composable/useArticles.ts b/src/composable/useArticles.ts
index 47d1c75..b38b761 100644
--- a/src/composable/useArticles.ts
+++ b/src/composable/useArticles.ts
@@ -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)
diff --git a/src/composable/useFollowProfile.ts b/src/composable/useFollowProfile.ts
index 0bd67e4..7aea25b 100644
--- a/src/composable/useFollowProfile.ts
+++ b/src/composable/useFollowProfile.ts
@@ -19,7 +19,7 @@ export function useFollow ({ username, following, onUpdate }: UseFollowProps) {
async function toggleFollow () {
let response: Either
- if (following.value === true) {
+ if (following.value) {
response = await deleteFollowProfile(username.value)
} else {
response = await postFollowProfile(username.value)
diff --git a/src/composable/useProfile.ts b/src/composable/useProfile.ts
index e8cdd94..d14987b 100644
--- a/src/composable/useProfile.ts
+++ b/src/composable/useProfile.ts
@@ -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
}
diff --git a/src/config.ts b/src/config.ts
index ff629e1..9b239cb 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -1,3 +1,4 @@
export const CONFIG = {
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
API_HOST: import.meta.env.VITE_API_HOST || '',
}
diff --git a/src/plugins/set-authorization-token.ts b/src/plugins/set-authorization-token.ts
index 75da951..c7419bd 100644
--- a/src/plugins/set-authorization-token.ts
+++ b/src/plugins/set-authorization-token.ts
@@ -3,5 +3,5 @@ import storage from '../utils/storage'
export default function (): void {
const token = storage.get('user')?.token
- if (token) request.setAuthorizationHeader(token)
+ if (token !== undefined) request.setAuthorizationHeader(token)
}
diff --git a/src/router.ts b/src/router.ts
index ce5904d..5375938 100644
--- a/src/router.ts
+++ b/src/router.ts
@@ -2,16 +2,16 @@ import { createRouter, createWebHashHistory, RouteParams } from 'vue-router'
import Home from './pages/Home.vue'
export type AppRouteNames = 'global-feed'
- | 'my-feed'
- | 'tag'
- | 'article'
- | 'create-article'
- | 'edit-article'
- | 'login'
- | 'register'
- | 'profile'
- | 'profile-favorites'
- | 'settings'
+| 'my-feed'
+| 'tag'
+| 'article'
+| 'create-article'
+| 'edit-article'
+| 'login'
+| 'register'
+| 'profile'
+| 'profile-favorites'
+| 'settings'
export const router = createRouter({
history: createWebHashHistory(),
@@ -75,6 +75,6 @@ export const router = createRouter({
})
export function routerPush (name: AppRouteNames, params?: RouteParams): ReturnType {
- if (params) return router.push({ name, params })
+ if (params !== undefined) return router.push({ name, params })
else return router.push({ name })
}
diff --git a/src/services/article/deleteArticle.ts b/src/services/article/deleteArticle.ts
index ef826f9..6427b91 100644
--- a/src/services/article/deleteArticle.ts
+++ b/src/services/article/deleteArticle.ts
@@ -1,5 +1,5 @@
import { request } from '../index'
-export async function deleteArticle (slug: string): Promise {
+export function deleteArticle (slug: string): Promise {
return request.delete(`/articles/${slug}`)
}
diff --git a/src/services/article/getArticle.ts b/src/services/article/getArticle.ts
index 5e3a5d7..a4c5483 100644
--- a/src/services/article/getArticle.ts
+++ b/src/services/article/getArticle.ts
@@ -1,5 +1,5 @@
import { request } from '../index'
-export async function getArticle (slug: string): Promise {
+export function getArticle (slug: string): Promise {
return request.get(`/articles/${slug}`).then(res => res.article)
}
diff --git a/src/services/article/getArticles.ts b/src/services/article/getArticles.ts
index bf0904d..950ea2b 100644
--- a/src/services/article/getArticles.ts
+++ b/src/services/article/getArticles.ts
@@ -1,26 +1,26 @@
import { limit, request } from '../index'
-export async function getArticles (page = 1): Promise {
+export function getArticles (page = 1): Promise {
const params = { limit, offset: (page - 1) * limit }
return request.get('/articles', { params })
}
-export async function getFavoritedArticles (username: string, page = 1): Promise {
+export function getFavoritedArticles (username: string, page = 1): Promise {
const params = { limit, offset: (page - 1) * limit, favorited: username }
return request.get('/articles', { params })
}
-export async function getProfileArticles (username: string, page = 1): Promise {
+export function getProfileArticles (username: string, page = 1): Promise {
const params = { limit, offset: (page - 1) * limit, author: username }
return request.get('/articles', { params })
}
-export async function getFeeds (page = 1): Promise {
+export function getFeeds (page = 1): Promise {
const params = { limit, offset: (page - 1) * limit }
return request.get('/articles/feed', { params })
}
-export async function getArticlesByTag (tagName: string, page = 1): Promise {
+export function getArticlesByTag (tagName: string, page = 1): Promise {
const params = { tag: tagName, limit, offset: (page - 1) * limit }
return request.get('/articles', { params })
}
diff --git a/src/services/article/postArticle.ts b/src/services/article/postArticle.ts
index c1ac3c5..9707ed0 100644
--- a/src/services/article/postArticle.ts
+++ b/src/services/article/postArticle.ts
@@ -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 {
+export function postArticle (form: PostArticleForm): Promise {
return request.post('/articles', { article: form })
.then(res => res.article)
}
-export async function putArticle (slug: string, form: PostArticleForm): Promise {
+export function putArticle (slug: string, form: PostArticleForm): Promise {
return request.put(`/articles/${slug}`, { article: form })
.then(res => res.article)
}
diff --git a/src/services/auth/postLogin.ts b/src/services/auth/postLogin.ts
index 88f7300..c5dc286 100644
--- a/src/services/auth/postLogin.ts
+++ b/src/services/auth/postLogin.ts
@@ -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>
diff --git a/src/services/auth/postRegister.ts b/src/services/auth/postRegister.ts
index 859705f..da03b85 100644
--- a/src/services/auth/postRegister.ts
+++ b/src/services/auth/postRegister.ts
@@ -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>
diff --git a/src/services/comment/getComments.ts b/src/services/comment/getComments.ts
index 4badd12..5d26536 100644
--- a/src/services/comment/getComments.ts
+++ b/src/services/comment/getComments.ts
@@ -1,5 +1,5 @@
import { request } from '../index'
-export async function getCommentsByArticle (slug: string): Promise {
+export function getCommentsByArticle (slug: string): Promise {
return request.get(`/articles/${slug}/comments`).then(res => res.comments)
}
diff --git a/src/services/comment/postComment.ts b/src/services/comment/postComment.ts
index 4c7cea9..86ecbc6 100644
--- a/src/services/comment/postComment.ts
+++ b/src/services/comment/postComment.ts
@@ -1,10 +1,10 @@
import { request } from '../index'
-export async function deleteComment (slug: string, commentId: number): Promise> {
+export function deleteComment (slug: string, commentId: number): Promise> {
return request.delete(`/articles/${slug}/comments/${commentId}`)
}
-export async function postComment (slug: string, body: string): Promise {
+export function postComment (slug: string, body: string): Promise {
return request.post(`/articles/${slug}/comments`, { comment: { body } })
.then(res => res.comment)
}
diff --git a/src/services/profile/getProfile.ts b/src/services/profile/getProfile.ts
index c74f227..742f12e 100644
--- a/src/services/profile/getProfile.ts
+++ b/src/services/profile/getProfile.ts
@@ -1,5 +1,5 @@
import { request } from '../index'
-export async function getProfile (username: string): Promise {
+export function getProfile (username: string): Promise {
return request.get(`/profiles/${username}`).then(res => res.profile)
}
diff --git a/src/services/profile/putProfile.ts b/src/services/profile/putProfile.ts
index 6de9bfa..0b32aec 100644
--- a/src/services/profile/putProfile.ts
+++ b/src/services/profile/putProfile.ts
@@ -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 {
+export function putProfile (form: PutProfileForm): Promise {
return request.put('/user', form).then(res => res.user)
}
diff --git a/src/services/tag/getTags.ts b/src/services/tag/getTags.ts
index 9934c24..1c13211 100644
--- a/src/services/tag/getTags.ts
+++ b/src/services/tag/getTags.ts
@@ -1,5 +1,5 @@
import { request } from '../index'
-export async function getAllTags (): Promise {
+export function getAllTags (): Promise {
return request.get('/tags').then(res => res.tags)
}
diff --git a/src/shimes-vue.d.ts b/src/shimes-vue.d.ts
index 8a7a816..354e766 100644
--- a/src/shimes-vue.d.ts
+++ b/src/shimes-vue.d.ts
@@ -5,8 +5,8 @@ declare module '*.vue' {
export default Component
}
- interface ImportMeta {
- env: {
- VITE_API_HOST: string
- }
+interface ImportMeta {
+ env: {
+ VITE_API_HOST: string
}
+}
diff --git a/src/store/user.ts b/src/store/user.ts
index b7326cc..6e3cb32 100644
--- a/src/store/user.ts
+++ b/src/store/user.ts
@@ -23,7 +23,7 @@ export const checkAuthorization = (user: ComputedRef): user is Comp
}
export const updateUser = mutation('updateUser', (state, userData) => {
- if (!userData) {
+ if (userData === undefined || userData === null) {
storage.remove('user')
request.deleteAuthorizationHeader()
state.user = null
diff --git a/src/types/article.d.ts b/src/types/article.d.ts
index 85d25e7..7ffacf1 100644
--- a/src/types/article.d.ts
+++ b/src/types/article.d.ts
@@ -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
}
diff --git a/src/types/comment.d.ts b/src/types/comment.d.ts
index 6998746..6aa304e 100644
--- a/src/types/comment.d.ts
+++ b/src/types/comment.d.ts
@@ -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
}
diff --git a/src/types/response.d.ts b/src/types/response.d.ts
index 21fcece..4ad9aae 100644
--- a/src/types/response.d.ts
+++ b/src/types/response.d.ts
@@ -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[]
}
diff --git a/src/types/user.d.ts b/src/types/user.d.ts
index 1c652df..ccd73f7 100644
--- a/src/types/user.d.ts
+++ b/src/types/user.d.ts
@@ -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
}
diff --git a/src/utils/create-async-process.spec.ts b/src/utils/create-async-process.spec.ts
index 31ef13c..504fdd7 100644
--- a/src/utils/create-async-process.spec.ts
+++ b/src/utils/create-async-process.spec.ts
@@ -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)
diff --git a/src/utils/create-async-process.ts b/src/utils/create-async-process.ts
index bc604e4..4c98e0a 100644
--- a/src/utils/create-async-process.ts
+++ b/src/utils/create-async-process.ts
@@ -3,7 +3,7 @@ import { Ref, ref } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any
interface CreateAsyncProcessReturn any> {
active: Ref
- run: (...args : Parameters) => Promise>
+ run: (...args: Parameters) => Promise>
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
diff --git a/src/utils/map-checkable-response.spec.ts b/src/utils/map-checkable-response.spec.ts
index b20d994..9dae919 100644
--- a/src/utils/map-checkable-response.spec.ts
+++ b/src/utils/map-checkable-response.spec.ts
@@ -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): Either> => response.ok
+const createCheckableResponse = (response: Partial): Either> => response.ok === true
? success(response)
: fail(new NetworkError(response as Response))
diff --git a/src/utils/request.spec.ts b/src/utils/request.spec.ts
index 3cd0560..3a8f952 100644
--- a/src/utils/request.spec.ts
+++ b/src/utils/request.spec.ts
@@ -52,7 +52,7 @@ async function triggerMethod (request: FetchRequest, method: Method
}
}
-function forCorrectMethods (task: string, fn: (method: Method) => void): void {
+function forCorrectMethods (task: string, fn: (method: Method) => Promise): void {
wrapTests({
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 {
wrapTests({
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 {
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', 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(request, method)
- const resultIsEither = isEither(result)
- const resultIsOk = isEither(result) && result.isOk()
- const resultValue = isEither(result) && result.isOk() ? result.value : null
+ const resultIsEither = isEither(result)
+ const resultIsOk = isEither(result) && result.isOk()
+ const resultValue = isEither(result) && result.isOk() ? result.value : null
expect(resultIsEither).toBe(true)
expect(resultIsOk).toBe(true)
@@ -216,9 +216,9 @@ forCheckableMethods('# Should return Either if checkabl
const request = new FetchRequest()
const result = await triggerMethod(request, method)
- const resultIsEither = isEither(result)
- const resultIsNotOk = isEither(result) && result.isFail()
- const resultValue = isEither(result) && result.isFail() ? result.value : null
+ const resultIsEither = isEither(result)
+ const resultIsNotOk = isEither(result) && result.isFail()
+ const resultValue = isEither(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))
})
diff --git a/src/utils/request.ts b/src/utils/request.ts
index 6500bb3..6f91f43 100644
--- a/src/utils/request.ts
+++ b/src/utils/request.ts
@@ -6,39 +6,39 @@ import { Either, fail, success } from './either'
import params2query from './params-to-query'
export interface FetchRequestOptions {
- prefix: string;
- headers: Record;
- params: Record;
+ prefix: string
+ headers: Record
+ params: Record
}
export default class FetchRequest {
- private defaultOptions: FetchRequestOptions = {
+ private readonly defaultOptions: FetchRequestOptions = {
prefix: '',
headers: {},
params: {},
}
- private options: FetchRequestOptions
+ private readonly options: FetchRequestOptions
constructor (options: Partial = {}) {
this.options = merge(this.defaultOptions, options)
}
- private generateFinalUrl = (url: string, options: Partial = {}) => {
+ private readonly generateFinalUrl = (url: string, options: Partial = {}) => {
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 = {}) => {
+ private readonly generateFinalHeaders = (options: Partial = {}) => {
return merge(this.options.headers, options.headers ?? {})
}
- private handleResponse = (response: Response): Promise> => {
+ private readonly handleResponse = (response: Response): Promise> => {
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 = (response: Response): Promise => {
+ private readonly handleCorrectResponse = (response: Response): Promise => {
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
}) {
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 {
diff --git a/src/utils/storage.ts b/src/utils/storage.ts
index e3dc84a..1d3ff81 100644
--- a/src/utils/storage.ts
+++ b/src/utils/storage.ts
@@ -1,6 +1,6 @@
function get (key: string): T | null {
try {
- const value = localStorage.getItem(key) || ''
+ const value = localStorage.getItem(key) ?? ''
return JSON.parse(value)
} catch (e) {
return null
diff --git a/src/utils/test/mock-fetch.ts b/src/utils/test/mock-fetch.ts
index 67a9715..ec08db9 100644
--- a/src/utils/test/mock-fetch.ts
+++ b/src/utils/test/mock-fetch.ts
@@ -3,9 +3,9 @@ interface FetchResponseBody {
}
interface FetchResponseFull {
type: 'full'
- ok: boolean,
- status: number,
- statusText:string
+ ok: boolean
+ status: number
+ statusText: string
json: () => Promise
}
diff --git a/src/utils/test/wrap-tests.ts b/src/utils/test/wrap-tests.ts
index 60ddf04..0ef5f5b 100644
--- a/src/utils/test/wrap-tests.ts
+++ b/src/utils/test/wrap-tests.ts
@@ -1,8 +1,8 @@
interface WrapTestsProps - {
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
- ({ 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))
})
})
diff --git a/yarn.lock b/yarn.lock
index e963424..425b529 100644
--- a/yarn.lock
+++ b/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"