├── run-ts.sh
├── .vscode
└── settings.json
├── src
├── constants.ts
├── main.ts
└── fetchZksync.ts
├── .gitignore
├── README.md
├── package.json
└── tsconfig.json
/run-ts.sh:
--------------------------------------------------------------------------------
1 | ts-node -T src/main.ts
2 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "python.linting.enabled": true
3 | }
--------------------------------------------------------------------------------
/src/constants.ts:
--------------------------------------------------------------------------------
1 |
2 | export const PadWechatKey = 'xxxx' // iPad 微信登录接口 token,申请地址:http://pad-local.com/#/login
3 | export const TargetWeixinName = '名字' //你要通知的微信用户昵称
4 | export const TargetWallet = 'xxxxx' //需要监听的钱包地址
5 | export const NomicsAPIKey = 'xxxxxx' //api.nomics.com 自己申请 Key,申请地址:https://p.nomics.com/cryptocurrency-bitcoin-api
6 | export const BaseCurrencySymbol = 'ETH' //最后结算到币本位 or U本位,方便查看总资产是否亏损。可以填写 USD\EUR\CNY 或任何加密货币的 symbol
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | lib-cov
2 | *.seed
3 | *.log
4 | *.csv
5 | *.dat
6 | *.out
7 | *.pid
8 | *.gz
9 | *.swp
10 |
11 | pids
12 | logs
13 | results
14 | tmp
15 |
16 | # Build
17 | public/css/main.css
18 |
19 | # Coverage reports
20 | coverage
21 |
22 | # API keys and secrets
23 | .env
24 |
25 | # Dependency directory
26 | node_modules
27 | bower_components
28 |
29 | # Editors
30 | .idea
31 | *.iml
32 |
33 | # OS metadata
34 | .DS_Store
35 | Thumbs.db
36 |
37 | # Ignore built ts files
38 | dist/**/*
39 |
40 | # ignore yarn.lock
41 | yarn.lock
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # zigzag_wechat_bot
2 |
3 | ## 功能
4 | 1. 每隔6.5s 监控做市机器人接单情况,如有新单,会立刻微信通知
5 |
6 | 2. 通过微信远程执行操作,包括当前运行状态、重启做市程序、查看 pm2 list、查看实时微信机器人日志
7 |
8 |
9 | ## 注意事项
10 | 1. ZigZag 做市程序请参考 https://github.com/ZigZagExchange/market-maker 部署。
11 | 2. 需要使用 pm2 开启上面的做市程序
12 | 3. 前往 `constants.ts` 填入自己的配置
13 | 4. 需要 iPad 微信机器人key,前往 http://pad-local.com/#/login 申请
14 | 5. 需要实时币价接口 Key,前往 https://p.nomics.com/cryptocurrency-bitcoin-api 申请
15 | 6. 执行 `pm2 start src/main.ts` 开启微信机器人
16 | 7. 若上述方法不行,可以执行 `pm2 start run-ts.sh`
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "new-ts-bot",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "keywords": [],
7 | "author": "",
8 | "license": "ISC",
9 | "dependencies": {
10 | "node-fetch": "^2.6.7",
11 | "qrcode-terminal": "^0.12.0",
12 | "wechaty": "^1.20.2",
13 | "wechaty-puppet": "^1.20.1",
14 | "wechaty-puppet-padlocal": "^1.11.18"
15 | },
16 | "devDependencies": {
17 | "@types/node": "^17.0.40",
18 | "@types/react": "^18.0.12",
19 | "@types/request": "^2.48.8",
20 | "cross-env": "^7.0.3",
21 | "ts-node": "^10.7.0",
22 | "typescript": "^4.7.3"
23 | },
24 | "scripts": {
25 | "bot": "npx ts-node src/main.ts",
26 | "bot-esm": "cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node src/main.ts"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import { Contact, log, ScanStatus, WechatyBuilder } from "wechaty";
2 | import { PuppetPadlocal } from "wechaty-puppet-padlocal";
3 | import * as FetchZksync from "./fetchZksync";
4 | import * as Constant from "./constants";
5 |
6 | export const LOGPRE = "[cypto_bot]";
7 | const puppet = new PuppetPadlocal({
8 | token: Constant.PadWechatKey,
9 | });
10 | const bot = WechatyBuilder.build({
11 | name: "cypto_bot",
12 | puppet,
13 | });
14 |
15 | //与命令行 shell 交互
16 | const exec = require('child_process').exec;
17 |
18 | let _owner: Contact;
19 | export const getOwner = async () =>
20 | _owner ||
21 | (_owner = (await bot.Contact.find({ name: Constant.TargetWeixinName })) as Contact);
22 |
23 | bot
24 | .on("scan", async (qrcode, status) => {
25 | if (status === ScanStatus.Waiting && qrcode) {
26 | const qrcodeImageUrl = [
27 | "https://wechaty.js.org/qrcode/",
28 | encodeURIComponent(qrcode),
29 | ].join("");
30 | log.info(
31 | LOGPRE,
32 | `onScan: ${ScanStatus[status]}(${status}) - ${qrcodeImageUrl}`
33 | );
34 | require("qrcode-terminal").generate(qrcode, { small: true }); // show qrcode on console
35 | } else {
36 | log.info(LOGPRE, `onScan: ${ScanStatus[status]}(${status})`);
37 | }
38 | })
39 | .on("login", async (user) => {
40 | console.log("name:", user.name);
41 |
42 | const owner = await getOwner();
43 | if (!owner) return;
44 |
45 | owner.say(`${user}已登录 iPad 版`);
46 | log.info(LOGPRE, `${user} login`);
47 |
48 | //1. 先获取货币信息
49 | FetchZksync.fetchTokenInfo();
50 |
51 | //2. 定时爬取接口
52 | const callback = (message: string) => {
53 | owner.say(message);
54 | };
55 | const hello = () => {
56 | FetchZksync.hello(callback);
57 | };
58 | setInterval(hello, 6500); // 每隔6.5s轮询
59 | })
60 | .on("logout", async (user, reason) => {
61 | const owner = await getOwner();
62 | if (!owner) return;
63 |
64 | owner.say(`${user}已退出 iPad 版`);
65 | log.info(LOGPRE, `${user} logout, reason: ${reason}`);
66 | })
67 | .on("message", async (message) => {
68 | const owner = await getOwner();
69 | if (message.listener()?.self() && message.text() === '状态') {
70 | var isOnNodeJs = false;
71 | if (typeof process != 'undefined') {
72 | isOnNodeJs = true
73 | }
74 | await owner.say(`${isOnNodeJs ? "🟢 正在运行" : "🔴 程序停止"}`);
75 | } else if (message.listener()?.self() && message.text() === '重启') {
76 | exec('pm2 restart /root/cypto_bot/run-ts.sh',(error: any, stdout: any, stderr: any) => {
77 | console.log(stdout);
78 | if (stdout !== null) {
79 | owner.say(stdout);
80 | }
81 | console.log(stderr);
82 | if (error !== null) {
83 | console.log(`exec error: ${error}`);
84 | }
85 | });
86 | } else if (message.listener()?.self() && message.text() === 'list') {
87 | exec('pm2 jlist',(error:any, stdout:any, stderr:any) => {
88 |
89 | if (stdout !== null) {
90 | let json = JSON.parse(stdout)
91 | var output = ""
92 | for(var index in json) {
93 | let value = json[index]
94 | console.log("value:",value)
95 | let name = value["name"]
96 | let status = value["pm2_env"]["status"] //"online"
97 | let mem = `${Number(value["monit"]["memory"]) / 1024 / 1024}MB`
98 | let cpu = `${Number(value["monit"]["cpu"])}%`
99 | output += `${name}-${status}-${mem}-${cpu}\n`
100 | }
101 | owner.say(output);
102 | }
103 | console.log(stderr);
104 | if (error !== null) {
105 | console.log(`exec error: ${error}`);
106 | }
107 | });
108 | } else if (message.listener()?.self() && message.text() === 'log') {
109 | exec('pm2 logs run-ts --nostream --lines 5',(error:any, stdout:any, stderr:any) => {
110 | if (stdout !== null) {
111 | owner.say(stdout);
112 | }
113 | console.log(stderr);
114 | if (error !== null) {
115 | console.log(`exec error: ${error}`);
116 | }
117 | });
118 | } else if (message.listener()?.self() && message.text() === 'cmd') {
119 | owner.say('状态\n重启\nlist\nlog');
120 | }
121 | })
122 | .on("error", (error) => {
123 | log.error(LOGPRE, `on error: ${error}`);
124 | });
125 |
126 | bot.start().then(() => {
127 | log.info(LOGPRE, "started.");
128 | });
129 |
--------------------------------------------------------------------------------
/src/fetchZksync.ts:
--------------------------------------------------------------------------------
1 | const fetch = require("node-fetch");
2 | import * as Constant from "./constants";
3 |
4 | // 获取所有 token 信息
5 | let tokenInfo: { [x: string]: any };
6 | let balances_str = "";
7 | export async function fetchTokenInfo() {
8 | fetch("https://api.zksync.io/jsrpc", {
9 | headers: {
10 | accept: "application/json, text/plain, */*",
11 | "accept-language": "zh-CN,zh;q=0.9",
12 | "content-type": "application/json",
13 | "sec-fetch-dest": "empty",
14 | "sec-fetch-mode": "cors",
15 | "sec-fetch-site": "cross-site",
16 | "sec-gpc": "1",
17 | Referer: "https://zkscan.io/",
18 | "Referrer-Policy": "strict-origin-when-cross-origin",
19 | },
20 | body: '{"id":1,"jsonrpc":"2.0","method":"tokens","params":null}',
21 | method: "POST",
22 | })
23 | .then((response: { json: () => any }) => response.json())
24 | .then((json: { [x: string]: {} }) => {
25 | tokenInfo = json["result"];
26 | })
27 | .catch((error: any) => console.log("error", error));
28 | }
29 |
30 | let lastNonce = 0;
31 | let all_coin_to_eth_price = 0 //所有币价转换到 eth 的总和,用 eth 衡量总资产
32 | export function hello(callback: (message: string) => void) {
33 | // 获取余额
34 | let balances_raw: { [x: string]: any } = {};
35 | let balances: { [x: string]: any } = {};
36 | let hasNewTransition = false;
37 | fetch("https://api.zksync.io/jsrpc", {
38 | headers: {
39 | accept: "application/json, text/plain, */*",
40 | "accept-language": "zh-CN,zh;q=0.9",
41 | "content-type": "application/json",
42 | "sec-fetch-dest": "empty",
43 | "sec-fetch-mode": "cors",
44 | "sec-fetch-site": "cross-site",
45 | "sec-gpc": "1",
46 | Referer: "https://zkscan.io/",
47 | "Referrer-Policy": "strict-origin-when-cross-origin",
48 | },
49 | body: `{"id":1,"jsonrpc":"2.0","method":"account_info","params":[${Constant.TargetWallet}]}`,
50 | method: "POST",
51 | })
52 | .then((response: { json: () => any }) => response.json())
53 | .then((json: { [x: string]: { [x: string]: { [x: string]: any } } }) => {
54 | let newNonce = json["result"]["committed"]["nonce"];
55 | if (newNonce > lastNonce) {
56 | lastNonce = newNonce;
57 | hasNewTransition = true;
58 | balances_raw = json["result"]["committed"]["balances"];
59 | balances_str = "";
60 | for (let key in balances_raw) {
61 | let token_balance = balances_raw[key];
62 | let token_info = tokenInfo[key];
63 | let decimals = token_info["decimals"];
64 | let symbol = token_info["symbol"];
65 | /*
66 | AAVE 0.12451426904
67 | AVAX 0.4980558464
68 | */
69 | let price = token_balance / 10 ** decimals
70 | balances_str += ` ${symbol}: ${price}\n`;
71 | balances[symbol] = price
72 | }
73 | } else {
74 | hasNewTransition = false;
75 | }
76 | })
77 | .then(async () => {
78 | // 获取最新市场价格
79 | let eth_coin_sbls: any = Object.keys(balances)
80 | eth_coin_sbls = eth_coin_sbls.join(',')
81 |
82 | fetch(`https://api.nomics.com/v1/currencies/ticker?key=${Constant.NomicsAPIKey}&ids=${eth_coin_sbls}&interval=1h&convert=${Constant.BaseCurrencySymbol}&per-page=100&page=1`)
83 | .then((response: any) => response.json())
84 | .then((json: { [x: string]: {} }) => {
85 | // console.log("获取最新市场价格:", json)
86 | var to_eth: { [id: string] : String; } = {};
87 | for (let index in json) {
88 | let pair:{ [id: string] : String; } = json[index]
89 | let key = String(pair["symbol"])
90 | to_eth[key] = pair["price"]
91 | }
92 | // console.log("获取最新市场价格dict:\n",to_eth)
93 |
94 | all_coin_to_eth_price = 0
95 | for (let key in balances) {
96 | let value = balances[key] //0.0001 SOL
97 | let toETHPrice = to_eth[key] // 1sol : 0.0012eth
98 | let resultETHPrice = Number(value) * Number(toETHPrice)
99 | all_coin_to_eth_price += resultETHPrice
100 | }
101 |
102 | if (hasNewTransition) {
103 | console.log("发现新交易!");
104 | getTransition(callback);
105 | } else {
106 | console.log("无新交易");
107 | }
108 | })
109 | })
110 | .catch((error: any) => console.log("error", error));
111 | }
112 |
113 | // 获取最新交易
114 | function getTransition(callback: (message: string) => void) {
115 | return fetch(
116 | `https://api.zksync.io/api/v0.1/account/${Constant.TargetWallet}/history/0/10`,
117 | {
118 | headers: {
119 | accept: "application/json, text/plain, */*",
120 | "accept-language": "zh-CN,zh;q=0.9",
121 | "sec-fetch-dest": "empty",
122 | "sec-fetch-mode": "cors",
123 | "sec-fetch-site": "cross-site",
124 | "sec-gpc": "1",
125 | Referer: "https://zkscan.io/",
126 | "Referrer-Policy": "strict-origin-when-cross-origin",
127 | },
128 | body: null,
129 | method: "GET",
130 | }
131 | )
132 | .then((response: { json: () => any }) => response.json())
133 | .then((json: any[]) => {
134 | let firstObj = json[0];
135 | let tx = firstObj["tx"];
136 | let type = tx["type"];
137 | let fee = tx["fee"];
138 | let feeToken_id = tx["feeToken"];
139 | let nonce = tx["nonce"];
140 | console.log("nonce:", nonce);
141 | let ordes = tx["orders"];
142 | let to_object = ordes.find(
143 | (o: { [x: string]: any }) => o["nonce"] === nonce
144 | );
145 |
146 | let from_object = ordes.find(
147 | (o: { [x: string]: any }) => o["tokenBuy"] === to_object["tokenSell"]
148 | );
149 |
150 | let from_addr = from_object["recipient"];
151 | let to_addr = to_object["recipient"];
152 | let from_amount = from_object["amount"];
153 | let to_amount = to_object["amount"];
154 | let from_token_id = from_object["tokenSell"];
155 | let to_token_id = to_object["tokenSell"];
156 |
157 | // /1000000
158 | // /1000000000000000000
159 |
160 | let fee_str = null;
161 | let from_amount_str = null;
162 | let to_amount_str = null;
163 | for (let key in tokenInfo) {
164 | let value = tokenInfo[key];
165 | let id = value["id"];
166 | if (id == feeToken_id) {
167 | let decimals = value["decimals"];
168 | let symbol = value["symbol"];
169 | fee_str = `【fee】: ${fee / 10 ** decimals} ${symbol}`;
170 | }
171 |
172 | if (id == from_token_id) {
173 | let decimals = value["decimals"];
174 | let symbol = value["symbol"];
175 | from_amount_str = `${from_amount / 10 ** decimals} ${symbol}`;
176 | }
177 |
178 | if (id == to_token_id) {
179 | let decimals = value["decimals"];
180 | let symbol = value["symbol"];
181 | to_amount_str = `${to_amount / 10 ** decimals} ${symbol}`;
182 | }
183 |
184 | if (
185 | fee_str != null &&
186 | from_amount_str != null &&
187 | to_amount_str != null
188 | ) {
189 | break;
190 | }
191 | }
192 |
193 | let state_str = `${firstObj["success"] ? "成功" : "失败"} | ${
194 | firstObj["verified"] ? "已确认" : "未确认"
195 | } | ${firstObj["commited"] ? "已提交" : "未提交"} | ${
196 | firstObj["fail_reason"]
197 | }`;
198 | let nonce_str = `【nonce】: ${lastNonce}`;
199 | let from_str = `【from】: ${from_addr}`;
200 | let to_str = `【to】: ${to_addr}`;
201 | let amount_str = `【Amount】: ${from_amount_str} -> ${to_amount_str}`;
202 | let final_balances_str = `【余额】:{\n${balances_str}}`;
203 | let all_eth = `【总资产】:${all_coin_to_eth_price} ETH`
204 |
205 | let message = `🍻检测到新交易:${type}\n${state_str}\n${nonce_str}\n${from_str}\n${to_str}\n${amount_str}\n${fee_str}\n${final_balances_str}\n${all_eth}`;
206 | // console.log("最终输出结果:", message);
207 |
208 | callback(message);
209 |
210 | /*
211 | 检测到新交易:Swap
212 | 状态:成功 | 已确认
213 | nonce: 45
214 | from: 0x3df204d52430315c9b56bbe22b6e9c2f1f9b37f7
215 | to: 自己
216 | Amount:
217 | fee: 0.306 USDT
218 | 余额: {
219 | AAVE 0.12451426904
220 | AVAX 0.4980558464
221 | DAI 0.08157772
222 | ETH 0.016354639445
223 | SOL 1.451859896
224 | UNI 3.957894376
225 | USDC 0.252422
226 | USDT 709.223038
227 | }
228 | 总资产: 0.5 ETH
229 | */
230 | })
231 | .catch((error: any) => console.log("error", error));
232 | }
233 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Visit https://aka.ms/tsconfig to read more about this file */
4 |
5 | /* Projects */
6 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
8 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
12 |
13 | /* Language and Environment */
14 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
16 | // "jsx": "preserve", /* Specify what JSX code is generated. */
17 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
22 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
25 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
26 |
27 | /* Modules */
28 | "module": "commonjs", /* Specify what module code is generated. */
29 | "rootDir": "./src", /* Specify the root folder within your source files. */
30 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
32 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
33 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
34 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
35 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */
36 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
37 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
38 | // "resolveJsonModule": true, /* Enable importing .json files. */
39 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
40 |
41 | /* JavaScript Support */
42 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
43 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
44 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
45 |
46 | /* Emit */
47 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
48 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */
49 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
50 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
51 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
52 | "outDir": "./dist", /* Specify an output folder for all emitted files. */
53 | // "removeComments": true, /* Disable emitting comments. */
54 | // "noEmit": true, /* Disable emitting files from a compilation. */
55 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
56 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
57 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
58 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
59 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
60 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
61 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
62 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
63 | // "newLine": "crlf", /* Set the newline character for emitting files. */
64 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
65 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
66 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
67 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
68 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
69 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
70 |
71 | /* Interop Constraints */
72 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
73 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
74 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
75 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
76 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
77 |
78 | /* Type Checking */
79 | "strict": true, /* Enable all strict type-checking options. */
80 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
81 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
82 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
83 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
84 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
85 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
86 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
87 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
88 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
89 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
90 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
91 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
92 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
93 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
94 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
95 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
96 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
97 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
98 |
99 | /* Completeness */
100 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
101 | "skipLibCheck": true /* Skip type checking all .d.ts files. */
102 | }
103 | }
104 |
--------------------------------------------------------------------------------