Skip to content

Commit

Permalink
enable linting and update client module config
Browse files Browse the repository at this point in the history
kajgm committed Jun 12, 2024
1 parent fc1d255 commit ef629f0
Showing 25 changed files with 2,181 additions and 1,670 deletions.
17 changes: 0 additions & 17 deletions .eslintrc.cjs

This file was deleted.

4 changes: 4 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"root": true,
"ignorePatterns": ["/*", "!/client", "!/server"]
}
5 changes: 3 additions & 2 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
@@ -30,8 +30,9 @@ jobs:
build:
runs-on: ${{ matrix.os }}
env:
VITE_VUE_APP_STOCK_TICKERS: 'GME,RDDT'
VITE_VUE_APP_CRYPTO_TICKERS: 'ETH-USD,BTC-USD'
FMP_KEY: ''
STOCK_TICKERS: 'MSFT,AAPL,NVDA,AMD,INTC,AMZN'
CRYPTO_TICKERS: 'ETH-USD,BTC-USD'
timeout-minutes: 10
strategy:
matrix:
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -28,17 +28,18 @@ A minimal tracker for Stocks and Cryptocurrencies. Intended for use on external
npm install
```

### Create a `.env` file (using the .env.template) and add parameters
### Create a `.env` file within `client/` (using .env.template) and add parameters

```
VITE_VUE_APP_FMP_KEY="<your_api_key>"
VITE_VUE_APP_STOCK_TICKERS="MSFT,AAPL,NVDA,AMD,INTC,AMZN"
VITE_VUE_APP_CRYPTO_TICKERS="ETH-USD,BTC-USD"
FMP_KEY="<your_api_key>"
STOCK_TICKERS="MSFT,AAPL,NVDA,AMD,INTC,AMZN"
CRYPTO_TICKERS="ETH-USD,BTC-USD"
```

### Compile and Hot-Reload for Development

```sh
cd client
npm run dev
```

@@ -51,7 +52,7 @@ npm run build
### Run Unit Tests with [Vitest](https://vitest.dev/)

```sh
npm run test:unit
npm run test
```

### Lint with [ESLint](https://eslint.org/)
@@ -66,7 +67,7 @@ To deploy within Docker, please follow these steps:

1. Install [Docker Engine](https://docs.docker.com/engine/install/)

2. Build the dockerfile
2. Build the dockerfile within the client directory
> Tip: Run `sudo usermod -aG docker <user>` to avoid prefixing the following commands with sudo
```
6 changes: 3 additions & 3 deletions client/.env.template
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
VITE_VUE_APP_FMP_KEY="<your_api_key>"
VITE_VUE_APP_STOCK_TICKERS="GME,RDDT"
VITE_VUE_APP_CRYPTO_TICKERS="ETH-USD,BTC-USD"
FMP_KEY="<your_api_key>"
STOCK_TICKERS="MSFT,AAPL,NVDA,AMD,INTC,AMZN"
CRYPTO_TICKERS="ETH-USD,BTC-USD"
40 changes: 40 additions & 0 deletions client/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution');

module.exports = {
extends: [
'plugin:vue/vue3-recommended',
'eslint:recommended',
'plugin:@typescript-eslint/recommended-type-checked',
'@vue/eslint-config-typescript',
'@vue/eslint-config-prettier/skip-formatting',
'prettier'
],
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 'latest',
project: ['./tsconfig.json'],
tsconfigRootDir: __dirname,
parser: '@typescript-eslint/parser'
},
rules: {
'@typescript-eslint/consistent-type-imports': 2,
'@typescript-eslint/prefer-for-of': 2,
'@typescript-eslint/unbound-method': 0,
'@typescript-eslint/no-unused-vars': 0,
'@typescript-eslint/no-unsafe-assignment': 0,
'vue/multi-word-component-names': 0,
'vue/require-typed-ref': 2,
'vue/component-api-style': [2, ['script-setup']],
'vue/block-lang': [2, { script: { lang: 'ts' } }],
'vue/define-macros-order': 2,
'vue/define-props-declaration': 2,
'vue/no-ref-object-reactivity-loss': 2,
'vue/no-undef-properties': 2,
'vue/no-unused-components': [2, { ignoreWhenBindingPresent: true }],
'vue/no-unused-properties': 2,
'vue/no-unused-refs': 2,
'prettier/prettier': 2
},
ignorePatterns: ['/*', '!/src', '!/tests']
};
11 changes: 3 additions & 8 deletions client/package.json
Original file line number Diff line number Diff line change
@@ -12,25 +12,18 @@
"build": "vite build",
"preview": "vite preview",
"test": "vitest",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"lint": "eslint \"**/*.{ts,vue}\"",
"format": "prettier --write src/"
},
"dependencies": {
"axios": "^1.7.2"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.8.0",
"@tsconfig/node20": "^20.1.4",
"@types/jsdom": "^21.1.6",
"@vitejs/plugin-vue": "^5.0.4",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"@vue/eslint-config-prettier": "^9.0.0",
"@vue/eslint-config-typescript": "^13.0.0",
"@vue/test-utils": "^2.4.5",
"@vue/tsconfig": "^0.5.1",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
"eslint-plugin-vue": "^9.23.0",
"jsdom": "^24.0.0",
"npm-run-all2": "^6.1.2",
"pinia": "^2.1.7",
@@ -39,8 +32,10 @@
"socket.io-client": "^4.7.5",
"tailwindcss": "^3.4.4",
"ts-node": "^10.9.2",
"ts-node-dev": "^2.0.0",
"typescript": "~5.4.0",
"vite": "^5.2.8",
"vite-plugin-environment": "^1.1.3",
"vitest": "^1.4.0",
"vue": "^3.4.21",
"vue-router": "^4.3.3",
10 changes: 5 additions & 5 deletions client/src/App.vue
Original file line number Diff line number Diff line change
@@ -5,10 +5,10 @@ import { restApiPoll } from './api/api';
import { useTickerStore } from './store/ticker';
const tickerStore = useTickerStore();
const stockStr = import.meta.env.VITE_VUE_APP_STOCK_TICKERS;
const cryptoStr = import.meta.env.VITE_VUE_APP_CRYPTO_TICKERS;
const stockTickers = stockStr && (stockStr.split(',') as string[]);
const cryptoTickers = cryptoStr && (cryptoStr.split(',') as string[]);
const stockStr = process.env.STOCK_TICKERS;
const cryptoStr = process.env.CRYPTO_TICKERS;
const stockTickers = stockStr && stockStr.split(',');
const cryptoTickers = cryptoStr && cryptoStr.split(',');
onMounted(() => {
// Crypto Coinbase websocket
@@ -18,7 +18,7 @@ onMounted(() => {
}
// Financial Modeling Prep api polling
if (import.meta.env.VITE_VUE_APP_FMP_KEY && stockTickers) {
if (process.env.FMP_KEY && stockTickers) {
stockTickers.forEach((e: string) => tickerStore.addNewTicker(e, 'STOCK'));
restApiPoll();
} else {
12 changes: 6 additions & 6 deletions client/src/api/api.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import axios from 'axios';
import { type ApiRequestData, type TickerData } from '@/types/types';
import { useTickerStore } from '@/store/ticker';
import { priceDirection } from '@/helpers/helpers';
import { type ApiRequestData, type TickerData } from '@/types/types.js';
import { useTickerStore } from '@/store/ticker.js';
import { priceDirection } from '@/helpers/helpers.js';

// Limited to 250 requests per day
// Standard trading day is open 6.5 hours
@@ -23,10 +23,10 @@ export function restApiPoll() {

if ((openHours <= currentTime && currentTime <= closeHours && isWeekday) || tickerStore.apiStatus != 'CONNECTED') {
axios
.get(STOCK_ENDPOINT + tickerStore.stockTickers.toString() + '?apikey=' + import.meta.env.VITE_VUE_APP_FMP_KEY)
.get(STOCK_ENDPOINT + tickerStore.stockTickers.toString() + '?apikey=' + process.env.FMP_KEY)
.then((res) => {
for (let i = 0; i < res.data.length; i++) {
const apiTicker = res.data[i] as ApiRequestData;
for (const ticker of res.data) {
const apiTicker = ticker as ApiRequestData;
const prevRes = tickerStore.tickerValue(apiTicker.symbol);
const stock = {
id: apiTicker.symbol,
4 changes: 2 additions & 2 deletions client/src/components/ticker/TickerBox.vue
Original file line number Diff line number Diff line change
@@ -4,14 +4,14 @@ import { concatNumber } from '@/helpers/helpers';
import { computed } from 'vue';
import type { TickerData, SizeType, TypeSizeMap } from '@/types/types';
const tickerStore = useTickerStore();
const { tickerId, boxSize, rLink } = defineProps<{
tickerId: string;
boxSize: SizeType;
rLink: string;
}>();
const tickerStore = useTickerStore();
const ticker = computed<TickerData>(() => {
return tickerStore.tickerValue(tickerId);
});
2 changes: 1 addition & 1 deletion client/src/helpers/helpers.ts
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ export function priceDirection(currentdirection: string, currentPrice: number, p
}

//Credit to: https://stackoverflow.com/a/9462382
export function concatNumber(num: number, digits: number, extraPrecise?: Boolean, ignoreTrailing?: boolean): string {
export function concatNumber(num: number, digits: number, extraPrecise?: boolean, ignoreTrailing?: boolean): string {
const lookup = [
{ value: 1, symbol: '' },
{ value: 1e3, symbol: 'k' },
2 changes: 2 additions & 0 deletions client/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unsafe-argument */
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
@@ -9,6 +10,7 @@ const app = createApp(App);
app.use(pinia);
app.use(router);

// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
void router.isReady().then(() => {
app.mount('#app');
});
12 changes: 7 additions & 5 deletions client/src/socket/socket.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useTickerStore } from '@/store/ticker';
import { priceDirection } from '@/helpers/helpers';
import { type StatusType, type TickerData, type WebsocketData } from '@/types/types';
import { useTickerStore } from '@/store/ticker.js';
import { priceDirection } from '@/helpers/helpers.js';
import { WebSocketMessage, type StatusType, type TickerData, type WebsocketData } from '@/types/types.js';

const CRYPTO_ENDPOINT = 'wss://ws-feed.exchange.coinbase.com';

@@ -27,8 +27,10 @@ export function websocketConnect() {
tickerStore.setSocketStatus('CONNECTED');
};

socket.onmessage = (e) => {
const msg = JSON.parse(e.data);
socket.onmessage = (e: MessageEvent<unknown>) => {
const msg = JSON.parse(e.data as string);

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (msg['type'] == 'ticker') {
const socketTicker = msg as WebsocketData;
const prevRes = tickerStore.tickerValue(socketTicker.product_id);
2 changes: 1 addition & 1 deletion client/src/store/ticker.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { defineStore } from 'pinia';
import { type TickerData, type StatusType, type TickerType } from '@/types/types';
import { type TickerData, type StatusType, type TickerType } from '@/types/types.js';

interface State {
stockTickers: string[];
2 changes: 2 additions & 0 deletions client/src/types/types.ts
Original file line number Diff line number Diff line change
@@ -35,6 +35,8 @@ export interface ApiRequestData {
timestamp: number;
}

export type WebSocketMessage = { data: object };

export interface WebsocketData {
best_ask: string;
best_ask_size: string;
10 changes: 5 additions & 5 deletions client/src/views/Chart.vue
Original file line number Diff line number Diff line change
@@ -4,21 +4,21 @@ import { computed } from 'vue';
import type { TickerData, SizeType } from '@/types/types';
import TickerBox from '@/components/ticker/TickerBox.vue';
const tickerStore = useTickerStore();
const boxSize = 'LARGE' as SizeType;
const { tickerId } = defineProps<{
tickerId: string;
}>();
const tickerStore = useTickerStore();
const boxSize = 'LARGE' as SizeType;
const ticker = computed<TickerData>(() => {
return tickerStore.tickerValue(tickerId);
});
</script>

<template>
<div class="flex flex-wrap justify-center m-auto w-full h-full">
<TickerBox :tickerId="ticker.id" :boxSize="boxSize" rLink="/"></TickerBox>
<TickerBox :ticker-id="ticker.id" :box-size="boxSize" r-link="/"></TickerBox>
</div>
</template>
2 changes: 1 addition & 1 deletion client/src/views/TickerGrid.vue
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ const boxSize = 'SMALL' as SizeType;
</div>
<div v-else-if="tickerStore.status.overall == 'CONNECTED'" class="flex flex-wrap justify-center m-auto w-full h-full">
<div v-for="id in tickerStore.tickerKeys" :key="id" class="w-1/2 h-1/2">
<TickerBox :tickerId="id" :boxSize="boxSize" :rLink="id"></TickerBox>
<TickerBox :ticker-id="id" :box-size="boxSize" :r-link="id"></TickerBox>
</div>
</div>
</template>
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-call */
import { describe, it, expect, beforeEach } from 'vitest';
import { setActivePinia, createPinia } from 'pinia';
import { mount } from '@vue/test-utils';
import router from '../../router';
import App from '../../App.vue';
import router from '../src/router';
import App from '../src/App.vue';

describe('App', () => {
beforeEach(() => {
7 changes: 3 additions & 4 deletions client/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"extends": "../tsconfig.options.json",
"include": ["vite-env.d.ts", "src/**/*", "src/**/*.vue"],
"exclude": ["src/**/__tests__/*", "**/node_modules/**/*"],
"include": ["vite-env.d.ts", "src/**/*", "src/**/*.vue", "tests/**/*.spec.ts"],
"exclude": ["**/node_modules/**/*"],
"compilerOptions": {
"module": "esnext",
"module": "NodeNext",
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"baseUrl": ".",
"paths": {
@@ -12,7 +12,6 @@
},
"types": ["vite/client", "@types/node"],
"allowJs": true,
"moduleResolution": "node",
"importHelpers": true,
"noUnusedLocals": false,
"noImplicitReturns": false
6 changes: 3 additions & 3 deletions client/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/// <reference types="vite/client" />

interface ImportMetaEnv {
readonly VITE_VUE_APP_FMP_KEY: string;
readonly VITE_VUE_APP_STOCK_TICKERS: string;
readonly VITE_VUE_APP_CRYPTO_TICKERS: string;
readonly FMP_KEY: string;
readonly STOCK_TICKERS: string;
readonly CRYPTO_TICKERS: string;
}
11 changes: 10 additions & 1 deletion client/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
import EnvironmentPlugin from 'vite-plugin-environment';

// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
plugins: [
vue(),
EnvironmentPlugin(['FMP_KEY', 'STOCK_TICKERS', 'CRYPTO_TICKERS'])
// EnvironmentPlugin({
// FMP_KEY: 'undefined',
// STOCK_TICKERS: 'MSFT,AAPL,NVDA,AMD,INTC,AMZN',
// CRYPTO_TICKERS: 'ETH-USD,BTC-USD'
// })
],
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
Loading

0 comments on commit ef629f0

Please sign in to comment.