app.use(cors({credentials:true}));
import express from 'express';
import { connect as mongodbConnect } from './db/mongodb';
import { connect as redisConnect } from './db/redis';
import cors from 'cors';
import { Db } from 'mongodb';
import { RedisClientType } from 'redis';
import dayjs from 'dayjs';
import axios from 'axios';
import * as acorn from 'acorn';
import * as cheerio from 'cheerio';
import * as R from 'ramda';
import {isNull} from 'lodash';
const COLLECTION = 'stock';
const STOCKS = 'STOCKS';
const STOCK_LIST_UPDATED = 'STOCK_LIST_UPDATED';
const STOCK_IDS_URL = 'https://goodinfo.tw/tw/StockLib/js/TW_STOCK_ID_NM_LIST.js?0';
const DIVIDEND_PREFIX_URL = 'https://goodinfo.tw/tw/StockDividendPolicy.asp?STOCK_ID=';
(async ()=> {
const mongodbClient = await mongodbConnect();
const redisClient = await redisConnect();
const app = express();
app.use(cors({credentials:true}));
app.get('/stock', async function (req, res) {
const { search } = req.query;
const stock = await mongodbClient.collection(COLLECTION).findOne({
$or:[{id: search},{name: search}]
});
res.send(stock);
});
app.get('/stocks', async function (req, res) {
const stockListUpdatedString = await redisClient.get('STOCK_LIST_UPDATED');
if(isNull(stockListUpdatedString) || dayjs().isAfter(stockListUpdatedString, 'M')) {
const {data: stockIdsText} = await axios.get(STOCK_IDS_URL);
const stockIdsParsed = acorn.parse(
stockIdsText,
{ ecmaVersion: 2020 }
);
// TODO: https://github.com/acornjs/acorn/issues/741
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const stocksIdWithNameObject: {value: string}[] = stockIdsParsed.body[0].declarations[0].init.elements;
await Promise.all(stocksIdWithNameObject.map(async stockIdWithNameObject => {
const [id, name] = stockIdWithNameObject.value.split(' ');
redisClient.sAdd(STOCKS, stockIdWithNameObject.value);
}));
await redisClient.set('STOCK_LIST_UPDATED', dayjs().toString());
}
const stocks = await redisClient.sMembers(STOCKS);
res.send(stocks);
});
app.listen(3000);
})();