代码初提交
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
/node_modules
|
||||||
|
/dist
|
||||||
|
/typing
|
||||||
|
/package-lock.json
|
||||||
|
.DS_Store
|
4
.npmignore
Normal file
4
.npmignore
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
/src
|
||||||
|
/tsconfig.json
|
||||||
|
/node_modules
|
||||||
|
/.DS_Store
|
41
README.md
Normal file
41
README.md
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# kugou-lyric
|
||||||
|
|
||||||
|
search、 download、decode krc(or lrc) from Kugou
|
||||||
|
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
```
|
||||||
|
npm install kugou-lyric
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
it's verry easy to use this util, if you want to get more information, read `index.d.ts`.
|
||||||
|
|
||||||
|
there is a demo to show you how to use it.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { parser, search, fetch, util } from 'kugou-lyric'
|
||||||
|
// parser: util for parsing krc(decode first) and lrc
|
||||||
|
// search: search krc and lrc from Kugou
|
||||||
|
// fetch: download krc and lrc from Kugou
|
||||||
|
// util: some utils maybe you will use
|
||||||
|
|
||||||
|
async function main(){
|
||||||
|
// search lyrics, "name" and "time" is required
|
||||||
|
const lyrics = await search({ name: 'linkin park - Numb', time: time2ms('03:07') })
|
||||||
|
if(!lyrics.length) return
|
||||||
|
// get krc or lrc
|
||||||
|
const krc = await fetch({
|
||||||
|
id: lyrics[0].id,
|
||||||
|
accesskey: lyrics[0].accesskey,
|
||||||
|
fmt: 'krc', // if you want to download lrc, using "lrc"
|
||||||
|
decodeKrc: true, // won't decode krc when false
|
||||||
|
// you can use "util.decodeKrc" function to decode it
|
||||||
|
})
|
||||||
|
// parse krc
|
||||||
|
const result = parser.parseKrc(krc)
|
||||||
|
// {ti:xx, ar:xx, items:[{time:xx, duration:xx, words:[{text:xx, duration:xx}, ...]]}, ...]}
|
||||||
|
}
|
||||||
|
main()
|
||||||
|
```
|
37
package.json
Normal file
37
package.json
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"name": "kugou-lyric",
|
||||||
|
"version": "1.0.3",
|
||||||
|
"description": "",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types":"typing/index.d.ts",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/kangkang520/kugou-lyric.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"kugou",
|
||||||
|
"krc",
|
||||||
|
"lyric",
|
||||||
|
"lrc",
|
||||||
|
"酷狗",
|
||||||
|
"parser",
|
||||||
|
"fetch",
|
||||||
|
"search",
|
||||||
|
"music",
|
||||||
|
"player"
|
||||||
|
],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/base64-js": "^1.2.5",
|
||||||
|
"@types/node": "^10.12.18"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/request": "^2.48.1",
|
||||||
|
"base64-js": "^1.3.0",
|
||||||
|
"request": "^2.88.0"
|
||||||
|
}
|
||||||
|
}
|
7
src/consts.ts
Normal file
7
src/consts.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
export const LYRIC_SEARCH_URL = 'http://lyrics.kugou.com/search'
|
||||||
|
|
||||||
|
export const LYRIC_FETCH_URL = 'http://lyrics.kugou.com/download'
|
||||||
|
|
||||||
|
//'@Gaw^2tGQ61-ÎÒni'
|
||||||
|
export const KRC_ENCODE_KEY = new Buffer(new Uint8Array([64, 71, 97, 119, 94, 50, 116, 71, 81, 54, 49, 45, 206, 210, 110, 105]))
|
83
src/fetcher.ts
Normal file
83
src/fetcher.ts
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import request from 'request'
|
||||||
|
import base64 from 'base64-js'
|
||||||
|
import { parseParam, decodeKrc } from './util'
|
||||||
|
import { LYRIC_SEARCH_URL, LYRIC_FETCH_URL } from './consts'
|
||||||
|
|
||||||
|
export interface KugouLyricInfo {
|
||||||
|
id: string
|
||||||
|
accesskey: string
|
||||||
|
duration: number
|
||||||
|
uid: string
|
||||||
|
song: string
|
||||||
|
singer: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LyricSearchOption {
|
||||||
|
/** music name */
|
||||||
|
name: string
|
||||||
|
/** duration (unit:ms) */
|
||||||
|
time: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LyricFetchOption {
|
||||||
|
id: string
|
||||||
|
accesskey: string
|
||||||
|
fmt: 'lrc' | 'krc'
|
||||||
|
/** if need decode krc, give me true */
|
||||||
|
decodeKrc?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* search lyrics from Kugou
|
||||||
|
* @param option search option
|
||||||
|
*/
|
||||||
|
export function search(option: LyricSearchOption): Promise<Array<KugouLyricInfo>> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
//http://lyrics.kugou.com/search?ver=1&man=yes&client=pc&keyword=歌曲名&duration=歌曲总时长(毫秒)&hash=歌曲Hash值
|
||||||
|
const url = LYRIC_SEARCH_URL + '?' + parseParam({ ver: 1, man: 'yes', client: 'pc', keyword: option.name, duration: option.time })
|
||||||
|
let buffer = ''
|
||||||
|
const req = request(url)
|
||||||
|
let err: Error
|
||||||
|
req.on('data', data => buffer += data)
|
||||||
|
req.on('error', _err => err = _err)
|
||||||
|
req.on('complete', () => {
|
||||||
|
req.removeAllListeners()
|
||||||
|
if (err) return reject(err)
|
||||||
|
try {
|
||||||
|
var { candidates } = JSON.parse(buffer)
|
||||||
|
resolve(candidates)
|
||||||
|
} catch (err) {
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get lyric from Kugou
|
||||||
|
* @param option fetch option
|
||||||
|
*/
|
||||||
|
export function fetch(option: LyricFetchOption): Promise<Buffer> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
//http://lyrics.kugou.com/download?ver=1&client=pc&id=10515303&accesskey=3A20F6A1933DE370EBA0187297F5477D&fmt=lrc&charset=utf8
|
||||||
|
const url = LYRIC_FETCH_URL + '?' + parseParam({ ver: 1, client: 'pc', id: option.id, accesskey: option.accesskey, fmt: option.fmt, charset: 'utf8' })
|
||||||
|
const req = request(url)
|
||||||
|
let buffer = ''
|
||||||
|
let err: Error
|
||||||
|
req.on('data', data => buffer += data)
|
||||||
|
req.on('error', e => err = e)
|
||||||
|
req.on('complete', () => {
|
||||||
|
if (err) return reject(err)
|
||||||
|
try {
|
||||||
|
const res = JSON.parse(buffer)
|
||||||
|
if (res.fmt != 'lrc' && res.fmt != 'krc') throw new Error('unkown format')
|
||||||
|
if (!res.content) throw new Error('empty content')
|
||||||
|
let buf = new Buffer(base64.toByteArray(res.content))
|
||||||
|
if (res.fmt == 'krc' && option.decodeKrc) resolve(decodeKrc(buf))
|
||||||
|
else resolve(buf)
|
||||||
|
} catch (err) {
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
29
src/index.ts
Normal file
29
src/index.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { time2ms, decodeKrc } from "./util"
|
||||||
|
import * as parser from './parser'
|
||||||
|
import { search, fetch } from "./fetcher"
|
||||||
|
|
||||||
|
const util = {
|
||||||
|
time2ms,
|
||||||
|
decodeKrc
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
parser,
|
||||||
|
search, fetch,
|
||||||
|
util
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
try {
|
||||||
|
// const lrcs = await search({ name: '谢东 - 笑脸', time: time2ms('04:12') })
|
||||||
|
const lrcs = await search({ name: 'linkin park - numb', time: time2ms('03:07') })
|
||||||
|
const lyric = lrcs[0]
|
||||||
|
const lrc = await fetch({ id: lyric.id, accesskey: lyric.accesskey, fmt: 'krc', decodeKrc: true })
|
||||||
|
// const result = parseLrc(lrc)
|
||||||
|
const result = parser.parseKrc(lrc)
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
2
src/parser/index.ts
Normal file
2
src/parser/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export { parseLrc, LrcInfo, LrcItem } from './lrc'
|
||||||
|
export { parseKrc, KrcInfo, KrcItem, KrcWord } from './krc'
|
83
src/parser/krc.ts
Normal file
83
src/parser/krc.ts
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import { stringeq } from "./../util"
|
||||||
|
|
||||||
|
export interface KrcWord {
|
||||||
|
text: string
|
||||||
|
duration: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface KrcItem {
|
||||||
|
time: number
|
||||||
|
duration: number
|
||||||
|
words: Array<KrcWord>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface KrcInfo {
|
||||||
|
ti?: string
|
||||||
|
ar?: string
|
||||||
|
al?: string
|
||||||
|
by?: string
|
||||||
|
offset?: string
|
||||||
|
items: Array<KrcItem>
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseWords(str: string) {
|
||||||
|
const words: Array<KrcWord> = []
|
||||||
|
do {
|
||||||
|
const match = str.match(/^<(\d+),(\d+),(\d+)>([\s\S]+?)(<|$)/)
|
||||||
|
if (!match) break
|
||||||
|
const [sub, offset, duration, _, text] = match
|
||||||
|
const isEnd = sub[sub.length - 1] != '<'
|
||||||
|
words.push({ text: text, duration: parseInt(duration) })
|
||||||
|
if (isEnd) break
|
||||||
|
else str = str.substr(sub.length - 1)
|
||||||
|
} while (true)
|
||||||
|
return words
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parse krc
|
||||||
|
* @param content content of krc
|
||||||
|
*/
|
||||||
|
export function parseKrc(content: Buffer | string): KrcInfo {
|
||||||
|
const krc: KrcInfo = { items: [] }
|
||||||
|
//行分割
|
||||||
|
const lines = (content + '').split(/\r?\n/).map(s => s.trim()).filter(s => !!s)
|
||||||
|
//逐行转换
|
||||||
|
lines.forEach(line => {
|
||||||
|
//基本信息
|
||||||
|
if (stringeq(line, '[ti:')) krc.ti = line.match(/\[ti:([\s\S]*?)\]/)![1]
|
||||||
|
else if (stringeq(line, '[ar:')) krc.ar = line.match(/\[ar:([\s\S]*?)\]/)![1]
|
||||||
|
else if (stringeq(line, '[al:')) krc.al = line.match(/\[al:([\s\S]*?)\]/)![1]
|
||||||
|
else if (stringeq(line, '[by:')) krc.by = line.match(/\[by:([\s\S]*?)\]/)![1]
|
||||||
|
else if (stringeq(line, '[offset:')) krc.offset = line.match(/\[offset:([\s\S]*?)\]/)![1]
|
||||||
|
else {
|
||||||
|
//时间和文本
|
||||||
|
const match = line.match(/^((\[\d+,\d+\])+)([\s\S]+)$/)
|
||||||
|
if (!match) return
|
||||||
|
const times = match[1]
|
||||||
|
const body = match[3]
|
||||||
|
//时间
|
||||||
|
const tmatch = times.match(/\[\d+,\d+\]/g)
|
||||||
|
if (!tmatch) return
|
||||||
|
//文本
|
||||||
|
const words = parseWords(body)
|
||||||
|
//每个时间
|
||||||
|
tmatch.forEach(time => {
|
||||||
|
const match = time.match(/^\[(\d+),(\d+)\]$/)
|
||||||
|
if (!match) return
|
||||||
|
krc.items.push({
|
||||||
|
time: parseInt(match[1]),
|
||||||
|
duration: parseInt(match[2]),
|
||||||
|
words
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//排序
|
||||||
|
krc.items = krc.items.sort((a, b) => {
|
||||||
|
if (a.time == b.time) return 0
|
||||||
|
if (a.time > b.time) return 1
|
||||||
|
return -1
|
||||||
|
})
|
||||||
|
return krc
|
||||||
|
}
|
68
src/parser/lrc.ts
Normal file
68
src/parser/lrc.ts
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import { stringeq } from "./../util"
|
||||||
|
|
||||||
|
export interface LrcItem {
|
||||||
|
time: number
|
||||||
|
content: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LrcInfo {
|
||||||
|
ti?: string
|
||||||
|
ar?: string
|
||||||
|
al?: string
|
||||||
|
by?: string
|
||||||
|
offset?: string
|
||||||
|
items: Array<LrcItem>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parse lrc
|
||||||
|
* @param content content of lrc
|
||||||
|
*/
|
||||||
|
export function parseLrc(content: Buffer | string): LrcInfo {
|
||||||
|
const lrc: LrcInfo = { items: [] }
|
||||||
|
const lines = (content + '').trim().split(/\r?\n/).map(s => s.trim()).filter(s => !!s)
|
||||||
|
//逐行转换
|
||||||
|
lines.forEach(line => {
|
||||||
|
//基本信息
|
||||||
|
if (stringeq(line, '[ti:')) lrc.ti = line.match(/\[ti:([\s\S]*?)\]/)![1]
|
||||||
|
else if (stringeq(line, '[ar:')) lrc.ar = line.match(/\[ar:([\s\S]*?)\]/)![1]
|
||||||
|
else if (stringeq(line, '[al:')) lrc.al = line.match(/\[al:([\s\S]*?)\]/)![1]
|
||||||
|
else if (stringeq(line, '[by:')) lrc.by = line.match(/\[by:([\s\S]*?)\]/)![1]
|
||||||
|
else if (stringeq(line, '[offset:')) lrc.offset = line.match(/\[offset:([\s\S]*?)\]/)![1]
|
||||||
|
//歌词信息
|
||||||
|
else {
|
||||||
|
//整体匹配
|
||||||
|
const match = line.match(/^((\[\d+:\d+(\.\d+)?\])+)([\s\S]+?)$/)
|
||||||
|
if (!match) return
|
||||||
|
const times = match[1].trim()
|
||||||
|
const text = match[4].trim()
|
||||||
|
//时间匹配
|
||||||
|
const tmatch = times.match(/(\[\d+:\d+(\.\d+)?\])/g)
|
||||||
|
if (!tmatch) return
|
||||||
|
//逐个时间处理
|
||||||
|
tmatch.map(t => t.trim()).map(t => t.substr(1, t.length - 2)).forEach(time => {
|
||||||
|
//分秒匹配
|
||||||
|
const match = time.match(/^(\d+):(\d+)(\.\d+)?$/)
|
||||||
|
if (!match) return
|
||||||
|
let [_, m, s, ms] = match
|
||||||
|
//计算时间
|
||||||
|
let t = (parseInt(m) * 60 + parseInt(s)) * 1000
|
||||||
|
if (ms) {
|
||||||
|
ms = ms.substr(1)
|
||||||
|
if (ms.length == 2) t += parseInt(ms) * 10
|
||||||
|
else t += parseInt(ms)
|
||||||
|
}
|
||||||
|
if (isNaN(t)) return
|
||||||
|
//保存歌词
|
||||||
|
lrc.items.push({ time: t, content: text })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//时间排序
|
||||||
|
lrc.items = lrc.items.sort((a, b) => {
|
||||||
|
if (a.time == b.time) return 0
|
||||||
|
if (a.time > b.time) return 1
|
||||||
|
return -1
|
||||||
|
})
|
||||||
|
return lrc
|
||||||
|
}
|
40
src/util.ts
Normal file
40
src/util.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import zlib from 'zlib'
|
||||||
|
import { KRC_ENCODE_KEY } from './consts'
|
||||||
|
|
||||||
|
export function parseParam(param: { [i: string]: string | number }) {
|
||||||
|
return Object.keys(param).map(k => `${k}=${encodeURIComponent(param[k] + '')}`).join('&')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parse time ($Minutes:$Seconds) to ms
|
||||||
|
* @param time music time, such as: xx:xx
|
||||||
|
*/
|
||||||
|
export function time2ms(time: string) {
|
||||||
|
const [m, s] = time.split(/:/).map(s => parseInt(s.trim()))
|
||||||
|
if (isNaN(m) || isNaN(s)) throw new Error('time format error')
|
||||||
|
return (m * 60 + s) * 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* decode krc
|
||||||
|
* @param content krc content
|
||||||
|
*/
|
||||||
|
export function decodeKrc(content: Buffer): Buffer {
|
||||||
|
const buffer = new Buffer(content.length - 4)
|
||||||
|
//解码
|
||||||
|
for (let i = 4; i < content.length; i++) {
|
||||||
|
buffer[i - 4] = content[i] ^ KRC_ENCODE_KEY[(i - 4) % 16]
|
||||||
|
}
|
||||||
|
//解压
|
||||||
|
return zlib.unzipSync(buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function stringeq(str: string, sub: string, offset = 0) {
|
||||||
|
let eq = true
|
||||||
|
if (sub.length + offset > str.length) return false
|
||||||
|
for (let i = 0; i < sub.length; i++) {
|
||||||
|
if (sub[i] != str[i + offset]) return false
|
||||||
|
}
|
||||||
|
return eq
|
||||||
|
}
|
65
tsconfig.json
Normal file
65
tsconfig.json
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
/* Basic Options */
|
||||||
|
"target": "esnext", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
|
||||||
|
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
|
||||||
|
"lib": [
|
||||||
|
"es2015",
|
||||||
|
"esnext"
|
||||||
|
], /* 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', or 'react'. */
|
||||||
|
"declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||||
|
"declarationDir": "typing",
|
||||||
|
// "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": "./dist", /* 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 */
|
||||||
|
// "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. */
|
||||||
|
// "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. */
|
||||||
|
/* 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": [], /* 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. */
|
||||||
|
/* 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. */
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"typing",
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
|
}
|
Reference in New Issue
Block a user