init:框架
This commit is contained in:
		
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| .idea/* | ||||
| /config.yaml | ||||
| node_modules/* | ||||
| /pnpm-lock.yaml | ||||
							
								
								
									
										36
									
								
								config.yaml.example
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								config.yaml.example
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| # 教务cookie | ||||
| cookie: "JSESSIONID=asd;" | ||||
| # 在 https://qmsg.zendee.cn 申请 | ||||
| qmsgKey: "v9631222364dd7ae99909cb63b7445c5" | ||||
| # 轮询间隔毫秒 | ||||
| interval: 100 | ||||
| # 监控列表 | ||||
| # channel: bx(必修),xx(限选),rx(任选) | ||||
| # kch:课程号;kxh:课序号 | ||||
| monit: | ||||
|   list: | ||||
|     - kch: sd01332200 | ||||
|       kxh: 100 | ||||
|       channel: rx | ||||
| # 抢课列表,列表中全抢 | ||||
| acquire: | ||||
|   list: | ||||
|     - kch: sd01332200 | ||||
|       kxh: 100 | ||||
|       channel: rx | ||||
|     - kch: sd00812930 | ||||
|       kxh: 900 | ||||
|       channel: xx | ||||
| # 换课列表(先退掉冲突的课再抢课),列表中任抢其一 | ||||
| replace: | ||||
|   list: | ||||
|     - kch: sd01332200 | ||||
|       kxh: 100 | ||||
|       channel: bx | ||||
|     - kch: sd01332200 | ||||
|       kxh: 100 | ||||
|       channel: bx | ||||
|   exit: | ||||
|     kch: sd01332299 | ||||
|     kxh: 100 | ||||
|     channel: bx | ||||
							
								
								
									
										23
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| { | ||||
|   "name": "sdu-course-bot", | ||||
|   "version": "1.0.0", | ||||
|   "description": "", | ||||
|   "main": "index.js", | ||||
|   "scripts": { | ||||
|     "test": "ts-node src/test.ts", | ||||
|     "start": "ts-node src/index.ts" | ||||
|   }, | ||||
|   "author": "", | ||||
|   "license": "ISC", | ||||
|   "dependencies": { | ||||
|     "@types/node": "^16.9.1", | ||||
|     "@types/qs": "^6.9.7", | ||||
|     "axios": "^0.21.4", | ||||
|     "axios-retry": "^3.1.9", | ||||
|     "dayjs": "^1.10.7", | ||||
|     "qs": "^6.10.1", | ||||
|     "ts-node": "^10.2.1", | ||||
|     "typescript": "^4.4.3", | ||||
|     "yaml": "^1.10.2" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										79
									
								
								src/actions.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/actions.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| import {ICourse} from "./types" | ||||
| import {acquireCourse, exitCourse, findJsonCourse, getTimeNow, logAndNotifyUser, sleep} from "./includes" | ||||
| import {JsonCourseList} from "./poll" | ||||
|  | ||||
| export async function monitProcess(course: ICourse) { | ||||
|     let lastSyrs = -1 | ||||
|     while (true) { | ||||
|         let single = findJsonCourse(course) | ||||
|         if (single == undefined) { | ||||
|             console.log('[monit]无法找到课程 ' + course.kch + ' on channel ' + course.channel) | ||||
|         } else { | ||||
|             if (lastSyrs == -1) { | ||||
|                 console.log('[monit]开始监控 ' + single.kcmc + ' ,当前剩余人数:' + single.syrs) | ||||
|                 lastSyrs = parseInt(single.syrs) | ||||
|             } else { | ||||
|                 if (lastSyrs != parseInt(single.syrs)) { | ||||
|                     logAndNotifyUser('[monit]' + single.kcmc + ' 新剩余人数:' + single.syrs + ' at ' + getTimeNow()) | ||||
|                     lastSyrs = parseInt(single.syrs) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         await sleep(50) | ||||
|     } | ||||
| } | ||||
|  | ||||
| export async function acquireProcess(course: ICourse) { | ||||
|     while (true) { | ||||
|         let single = findJsonCourse(course) | ||||
|         if (single == undefined) { | ||||
|             console.log('[acquire]无法找到课程 ' + course.kch + ' on channel ' + course.channel) | ||||
|         } else { | ||||
|             if (parseInt(single.syrs) > 0) { | ||||
|                 logAndNotifyUser('[acquire]发现 ' + single.kcmc + ' 剩余人数为' + single.syrs + ',进行抢课 at ' + getTimeNow()) | ||||
|                 if (await acquireCourse(single, course.channel)) { | ||||
|                     logAndNotifyUser('[acquire]抢课成功 ' + single.kcmc + ' at ' + getTimeNow()) | ||||
|                     return | ||||
|                 } else { | ||||
|                     logAndNotifyUser('[acquire]抢课失败 ' + single.kcmc + ' at ' + getTimeNow()) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         await sleep(50) | ||||
|     } | ||||
| } | ||||
|  | ||||
| export async function replaceProcess(courseList: ICourse[], exit: ICourse) { | ||||
|     while (true) { | ||||
|         let exitJsonCourse = findJsonCourse(exit) | ||||
|         if (exitJsonCourse == undefined) { | ||||
|             console.log('[replace]找不到需要需要退课的课程 ' + exit.kch + ' on channel ' + exit.channel) | ||||
|         } else { | ||||
|             for (let course of courseList) { | ||||
|                 let single = findJsonCourse(course) | ||||
|                 if (single == undefined) { | ||||
|                     console.log('[replace]无法找到课程 ' + course.kch + ' on channel ' + course.channel) | ||||
|                     continue | ||||
|                 } | ||||
|                 if (parseInt(single.syrs) > 0) { | ||||
|                     logAndNotifyUser('[replace]发现 ' + single.kcmc + ' 剩余人数为' + single.syrs + ',进行换课 at ' + getTimeNow()) | ||||
|                     if (!(await exitCourse(exitJsonCourse, exit.channel))) { | ||||
|                         logAndNotifyUser('[replace]退课 ' + exitJsonCourse.kcmc + ' 失败 at ' + getTimeNow()) | ||||
|                     } | ||||
|                     if (await acquireCourse(single, course.channel)) { | ||||
|                         logAndNotifyUser('[replace]换课 ' + single.kcmc + ' 成功 at ' + getTimeNow()) | ||||
|                         return | ||||
|                     } else { | ||||
|                         logAndNotifyUser('[replace]选课 ' + single.kcmc + ' 失败,进行回滚 at ' + getTimeNow()) | ||||
|                         if (await acquireCourse(exitJsonCourse, exit.channel)) { | ||||
|                             logAndNotifyUser('[replace]回滚 ' + single.kcmc + ' 成功 at ' + getTimeNow()) | ||||
|                         } else { | ||||
|                             logAndNotifyUser('[replace]回滚 ' + single.kcmc + ' 失败 at ' + getTimeNow()) | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         await sleep(50) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										25
									
								
								src/config.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/config.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| import yaml from "yaml" | ||||
| import * as fs from "fs" | ||||
| import {IAppConfig, TChannel} from "./types" | ||||
|  | ||||
| let appConfig: IAppConfig = yaml.parse(fs.readFileSync('config.yaml', 'utf-8')) | ||||
| let channels: TChannel[] = [] | ||||
| for (let course of appConfig.monit?.list || []) { | ||||
|     if (!channels.includes(course.channel)) { | ||||
|         channels.push(course.channel) | ||||
|     } | ||||
| } | ||||
| for (let course of appConfig.acquire?.list || []) { | ||||
|     if (!channels.includes(course.channel)) { | ||||
|         channels.push(course.channel) | ||||
|     } | ||||
| } | ||||
| if (appConfig.replace) { | ||||
|     for (let course of appConfig.replace.list) { | ||||
|         if (!channels.includes(course.channel)) { | ||||
|             channels.push(course.channel) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| appConfig.channels = channels | ||||
| export {appConfig} | ||||
							
								
								
									
										66
									
								
								src/includes.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/includes.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| import axios from 'axios' | ||||
| import {appConfig} from "./config" | ||||
| import * as qs from "qs" | ||||
| import dayjs from "dayjs" | ||||
| import {ICourse, IJsonCourse, TChannel} from "./types" | ||||
| import {JsonCourseList} from "./poll" | ||||
| import axiosRetry from "axios-retry" | ||||
|  | ||||
| let sduAxios = axios.create({ | ||||
|     headers: { | ||||
|         'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', | ||||
|         'Cookie': appConfig.cookie | ||||
|     }, | ||||
|     baseURL: 'https://bkzhjx.wh.sdu.edu.cn/', | ||||
|     timeout: 5, | ||||
|     // maxRedirects: 0 | ||||
| }) | ||||
|  | ||||
| axiosRetry(sduAxios, { | ||||
|     retries: 2, | ||||
|     shouldResetTimeout: true, | ||||
|     retryCondition: (_error) => true, | ||||
| }) | ||||
|  | ||||
| export async function logAndNotifyUser(text: string) { | ||||
|     console.log(text) | ||||
|     await axios.post('https://qmsg.zendee.cn/send/' + appConfig.qmsgKey, qs.stringify({ | ||||
|         msg: text | ||||
|     }), { | ||||
|         headers: { | ||||
|             'Content-Type': 'application/x-www-form-urlencoded' | ||||
|         } | ||||
|     }) | ||||
| } | ||||
|  | ||||
| export function sleep(ms: number) { | ||||
|     return new Promise(resolve => setTimeout(resolve, ms)) | ||||
| } | ||||
|  | ||||
| export function getTimeNow() { | ||||
|     return dayjs().format('hh:mm:ss A') | ||||
| } | ||||
|  | ||||
| export function findJsonCourse(course: ICourse): IJsonCourse | undefined { | ||||
|     return JsonCourseList[course.channel].find(single => single.kch == course.kch && parseInt(single.kxh) == course.kxh) | ||||
| } | ||||
|  | ||||
| export async function acquireCourse(course: IJsonCourse, channel: TChannel): Promise<boolean> { | ||||
|     if (channel == 'bx' || channel == 'xx') { | ||||
|  | ||||
|     } else { | ||||
|  | ||||
|     } | ||||
|     return true | ||||
| } | ||||
|  | ||||
| export async function exitCourse(course: IJsonCourse, channel: TChannel): Promise<boolean> { | ||||
|     if (channel == 'bx' || channel == 'xx') { | ||||
|  | ||||
|     } else { | ||||
|  | ||||
|     } | ||||
|     return true | ||||
| } | ||||
|  | ||||
| export {sduAxios} | ||||
							
								
								
									
										35
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| import {JsonCourseList, poll} from "./poll" | ||||
| import {appConfig} from "./config" | ||||
| import {acquireProcess, monitProcess, replaceProcess} from "./actions" | ||||
| import {sleep} from "./includes" | ||||
|  | ||||
| async function start() { | ||||
|     console.log('开始启动轮询进程') | ||||
|     poll() | ||||
|     while (true) { | ||||
|         let pollInitComplete = true | ||||
|         for (let channel of appConfig.channels) { | ||||
|             if (JsonCourseList[channel].length == 0) { | ||||
|                 pollInitComplete = false | ||||
|             } | ||||
|         } | ||||
|         if (pollInitComplete) { | ||||
|             break | ||||
|         } | ||||
|         await sleep(50) | ||||
|     } | ||||
|     console.log('轮询进程启动完毕') | ||||
|     console.log('开始启动用户进程') | ||||
|     for (let course of appConfig.monit?.list || []) { | ||||
|         monitProcess(course) | ||||
|     } | ||||
|     for (let course of appConfig.acquire?.list || []) { | ||||
|         acquireProcess(course) | ||||
|     } | ||||
|     if (appConfig.replace) { | ||||
|         replaceProcess(appConfig.replace.list, appConfig.replace.exit) | ||||
|     } | ||||
|     console.log('用户进程启动完毕') | ||||
| } | ||||
|  | ||||
| start() | ||||
							
								
								
									
										79
									
								
								src/poll.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/poll.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| import {IJsonCourse} from "./types" | ||||
| import {getTimeNow, sduAxios, sleep} from "./includes" | ||||
| import {appConfig} from "./config" | ||||
| import * as qs from "qs" | ||||
|  | ||||
| let reqData = [ | ||||
|     {"name": "sEcho", "value": "1"}, | ||||
|     {"name": "iColumns", "value": "2000"},// 1 | ||||
|     {"name": "sColumns", "value": ""}, | ||||
|     {"name": "iDisplayStart", "value": "0"}, | ||||
|     {"name": "iDisplayLength", "value": "2000"},// 1 | ||||
|     {"name": "mDataProp_0", "value": "kch"}, | ||||
|     {"name": "mDataProp_1", "value": "kcmc"}, | ||||
|     {"name": "mDataProp_2", "value": "kxhnew"}, | ||||
|     {"name": "mDataProp_3", "value": "jkfs"}, | ||||
|     {"name": "mDataProp_4", "value": "xmmc"}, | ||||
|     {"name": "mDataProp_5", "value": "xf"}, | ||||
|     {"name": "mDataProp_6", "value": "skls"}, | ||||
|     {"name": "mDataProp_7", "value": "sksj"}, | ||||
|     {"name": "mDataProp_8", "value": "skdd"}, | ||||
|     {"name": "mDataProp_9", "value": "xqmc"}, | ||||
|     {"name": "mDataProp_10", "value": "xkrs"}, | ||||
|     {"name": "mDataProp_11", "value": "syrs"}, | ||||
|     {"name": "mDataProp_12", "value": "ctsm"}, | ||||
|     {"name": "mDataProp_13", "value": "szkcflmc"}, | ||||
|     {"name": "mDataProp_14", "value": "czOper"} | ||||
| ] | ||||
| export const JsonCourseList = <{ bx: IJsonCourse[], xx: IJsonCourse[], rx: IJsonCourse[] }>{ | ||||
|     bx: [], | ||||
|     xx: [], | ||||
|     rx: [] | ||||
| } | ||||
|  | ||||
| async function updateBx() { | ||||
|     try { | ||||
|         let resp = await sduAxios.post('/jsxsd/xsxkkc/xsxkBxxk?1=1&kcxx=&skls=&skfs=', qs.stringify(reqData)) | ||||
|         JsonCourseList.bx.length = 0 | ||||
|         JsonCourseList.bx.push(...resp.data.aaData) | ||||
|         console.log('更新必修JsonList成功') | ||||
|     } catch (e) { | ||||
|         console.log('获取必修JsonList失败 at ' + getTimeNow()) | ||||
|     } | ||||
| } | ||||
|  | ||||
| async function updateXx() { | ||||
|     try { | ||||
|         let resp = await sduAxios.post('/jsxsd/xsxkkc/xsxkXxxk?1=1&kcxx=&skls=&skfs=', qs.stringify(reqData)) | ||||
|         JsonCourseList.xx.length = 0 | ||||
|         JsonCourseList.xx.push(...resp.data.aaData) | ||||
|     } catch (e) { | ||||
|         console.log('获取限选JsonList失败 at ' + getTimeNow()) | ||||
|     } | ||||
| } | ||||
|  | ||||
| async function updateRx() { | ||||
|     try { | ||||
|         let resp = await sduAxios.post('/jsxsd/xsxkkc/xsxkGgxxkxk?kcxx=&skls=&skxq=&skjc=&sfym=false&sfct=false&szjylb=&sfxx=false&skfs=', qs.stringify(reqData)) | ||||
|         JsonCourseList.rx.length = 0 | ||||
|         JsonCourseList.rx.push(...resp.data.aaData) | ||||
|     } catch (e) { | ||||
|         console.log('获取任选JsonList失败 at ' + getTimeNow()) | ||||
|     } | ||||
| } | ||||
|  | ||||
| export async function poll() { | ||||
|     if (appConfig.channels.includes('bx')) { | ||||
|         await updateBx() | ||||
|         await sleep(appConfig.interval) | ||||
|     } | ||||
|     if (appConfig.channels.includes('xx')) { | ||||
|         await updateXx() | ||||
|         await sleep(appConfig.interval) | ||||
|     } | ||||
|     if (appConfig.channels.includes('rx')) { | ||||
|         await updateRx() | ||||
|         await sleep(appConfig.interval) | ||||
|     } | ||||
|     setImmediate(poll) | ||||
| } | ||||
							
								
								
									
										15
									
								
								src/test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/test.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| import {appConfig} from "./config" | ||||
|  | ||||
| console.log('channels: ' + appConfig.channels) | ||||
| for (let course of appConfig.monit?.list || []) { | ||||
|     console.log('添加监控课程 ' + course.kch + ' on channel ' + course.channel) | ||||
| } | ||||
| for (let course of appConfig.acquire?.list || []) { | ||||
|     console.log('添加抢课课程 ' + course.kch + ' on channel ' + course.channel) | ||||
| } | ||||
| if (appConfig.replace) { | ||||
|     console.log('添加退课课程 ' + appConfig.replace.exit.kch + ' on channel ' + appConfig.replace.exit.channel) | ||||
|     for (let course of appConfig.replace.list) { | ||||
|         console.log('添加换课课程 ' + course.kch + ' on channel ' + course.channel) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										91
									
								
								src/types.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/types.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | ||||
| export type TChannel = 'bx' | 'xx' | 'rx' | ||||
|  | ||||
| export interface ICourse { | ||||
|     kch: string, | ||||
|     kxh: number, | ||||
|     channel: TChannel | ||||
| } | ||||
|  | ||||
| export interface IAppConfig { | ||||
|     cookie: string, | ||||
|     qmsgKey: string, | ||||
|     interval: number, | ||||
|     channels: TChannel[], | ||||
|     monit?: { | ||||
|         list: ICourse[] | ||||
|     }, | ||||
|     acquire?: { | ||||
|         list: ICourse[] | ||||
|     }, | ||||
|     replace?: { | ||||
|         list: ICourse[], | ||||
|         exit: ICourse | ||||
|     } | ||||
| } | ||||
|  | ||||
| export interface IJsonCourse { | ||||
|     parentjx0404id: null; | ||||
|     mfkc: string; | ||||
|     ksfs: string; | ||||
|     jx02kcmkid: null; | ||||
|     ktmc: string; | ||||
|     tzdlb: string; | ||||
|     kcsx: string; | ||||
|     skfs: string; | ||||
|     kch: string; | ||||
|     syrs: string; | ||||
|     kxh: string; | ||||
|     sksj: string; | ||||
|     szkcfl: string; | ||||
|     kcjj: null; | ||||
|     skfsmc: string; | ||||
|     wlpt: null; | ||||
|     kcxzmc: string; | ||||
|     kexuhao: null; | ||||
|     xbyq: null; | ||||
|     sftk: null; | ||||
|     kkdw: string; | ||||
|     kcxzm: string; | ||||
|     szkcflmc: string; | ||||
|     xnxq01id: string; | ||||
|     dwmc: string; | ||||
|     kxhnew: string; | ||||
|     pkrs: number; | ||||
|     xkrs: number; | ||||
|     fzmc: null; | ||||
|     cfbs: null; | ||||
|     kcmc: string; | ||||
|     xyxsnj: null; | ||||
|     kkapList: KkapList[]; | ||||
|     dyrsbl: null; | ||||
|     isnetworkcourse: string; | ||||
|     sklsid: string; | ||||
|     skls: string; | ||||
|     xqid: string; | ||||
|     sfkfxk: string; | ||||
|     skdd: string; | ||||
|     xf: number; | ||||
|     skdws: null; | ||||
|     txsfkxq: string; | ||||
|     xmmc: null; | ||||
|     zxs: number; | ||||
|     jx0404id: string; | ||||
|     xqmc: string; | ||||
|     jx02id: string; | ||||
|     xbyqmc: null; | ||||
|     jkfs: null; | ||||
| } | ||||
|  | ||||
| export interface KkapList { | ||||
|     jssj: string; | ||||
|     jzwmc: string; | ||||
|     jgxm: string; | ||||
|     skjcmc: string; | ||||
|     skzcList: string[]; | ||||
|     xq: string; | ||||
|     kbjcmsid: string; | ||||
|     kkzc: string; | ||||
|     kssj: string; | ||||
|     jsmc: string; | ||||
|     kkdlb: string; | ||||
| } | ||||
							
								
								
									
										86
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| { | ||||
|   "compilerOptions": { | ||||
|     /* Visit https://aka.ms/tsconfig.json to read more about this file */ | ||||
|  | ||||
|     /* Basic Options */ | ||||
|     // "incremental": true,                         /* Enable incremental compilation */ | ||||
|     "target": "ES2016", | ||||
|     /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ | ||||
|     "module": "commonjs", | ||||
|     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ | ||||
|     // "lib": [],                                   /* Specify library files to be included in the compilation. */ | ||||
|     "allowJs": true, | ||||
|     /* Allow javascript files to be compiled. */ | ||||
|     // "checkJs": true,                             /* Report errors in .js files. */ | ||||
|     // "jsx": "preserve",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ | ||||
|     // "declaration": true,                         /* Generates corresponding '.d.ts' file. */ | ||||
|     // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */ | ||||
|     // "sourceMap": true,                           /* Generates corresponding '.map' file. */ | ||||
|     // "outFile": "./",                             /* Concatenate and emit output to single file. */ | ||||
|     "outDir": "./build", | ||||
|     /* Redirect output structure to the directory. */ | ||||
|     "rootDir": "./src", | ||||
|     /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ | ||||
|     // "composite": true,                           /* Enable project compilation */ | ||||
|     // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */ | ||||
|     // "removeComments": true,                      /* Do not emit comments to output. */ | ||||
|     // "noEmit": true,                              /* Do not emit outputs. */ | ||||
|     // "importHelpers": true,                       /* Import emit helpers from 'tslib'. */ | ||||
|     // "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ | ||||
|     // "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ | ||||
|  | ||||
|     /* Strict Type-Checking Options */ | ||||
|     "strict": true, | ||||
|     /* Enable all strict type-checking options. */ | ||||
|     // "noImplicitAny": true,                       /* Raise error on expressions and declarations with an implied 'any' type. */ | ||||
|     // "strictNullChecks": true,                    /* Enable strict null checks. */ | ||||
|     // "strictFunctionTypes": true,                 /* Enable strict checking of function types. */ | ||||
|     // "strictBindCallApply": true,                 /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ | ||||
|     // "strictPropertyInitialization": true,        /* Enable strict checking of property initialization in classes. */ | ||||
|     // "noImplicitThis": true,                      /* Raise error on 'this' expressions with an implied 'any' type. */ | ||||
|     // "alwaysStrict": true,                        /* Parse in strict mode and emit "use strict" for each source file. */ | ||||
|  | ||||
|     /* Additional Checks */ | ||||
|     // "noUnusedLocals": true,                      /* Report errors on unused locals. */ | ||||
|     // "noUnusedParameters": true,                  /* Report errors on unused parameters. */ | ||||
|     // "noImplicitReturns": true,                   /* Report error when not all code paths in function return a value. */ | ||||
|     // "noFallthroughCasesInSwitch": true,          /* Report errors for fallthrough cases in switch statement. */ | ||||
|     // "noUncheckedIndexedAccess": true,            /* Include 'undefined' in index signature results */ | ||||
|     // "noPropertyAccessFromIndexSignature": true,  /* Require undeclared properties from index signatures to use element accesses. */ | ||||
|  | ||||
|     /* Module Resolution Options */ | ||||
|     // "moduleResolution": "node",                  /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ | ||||
|     // "baseUrl": "./",                             /* Base directory to resolve non-absolute module names. */ | ||||
|     // "paths": {},                                 /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ | ||||
|     // "rootDirs": [],                              /* List of root folders whose combined content represents the structure of the project at runtime. */ | ||||
|     "typeRoots": [ | ||||
|       //      "./node_modules/**/*", | ||||
|       "./node_modules/@types" | ||||
|     ], | ||||
|     /* List of folders to include type definitions from. */ | ||||
|     // "types": [],                                 /* Type declaration files to be included in compilation. */ | ||||
|     // "allowSyntheticDefaultImports": true,        /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ | ||||
|     "esModuleInterop": true, | ||||
|     /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ | ||||
|     // "preserveSymlinks": true,                    /* Do not resolve the real path of symlinks. */ | ||||
|     // "allowUmdGlobalAccess": true,                /* Allow accessing UMD globals from modules. */ | ||||
|  | ||||
|     /* Source Map Options */ | ||||
|     // "sourceRoot": "",                            /* Specify the location where debugger should locate TypeScript files instead of source locations. */ | ||||
|     // "mapRoot": "",                               /* Specify the location where debugger should locate map files instead of generated locations. */ | ||||
|     // "inlineSourceMap": true,                     /* Emit a single file with source maps instead of having a separate file. */ | ||||
|     // "inlineSources": true,                       /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ | ||||
|  | ||||
|     /* Experimental Options */ | ||||
|     "experimentalDecorators": true, | ||||
|     /* Enables experimental support for ES7 decorators. */ | ||||
|     "emitDecoratorMetadata": true, | ||||
|     /* Enables experimental support for emitting type metadata for decorators. */ | ||||
|  | ||||
|     /* Advanced Options */ | ||||
|     "skipLibCheck": true, | ||||
|     /* Skip type checking of declaration files. */ | ||||
|     "forceConsistentCasingInFileNames": true | ||||
|     /* Disallow inconsistently-cased references to the same file. */ | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user