typescript

This commit is contained in:
2021-02-07 16:00:39 +01:00
parent d53d19bb4d
commit 16adeee59f
9 changed files with 233 additions and 64 deletions

1
.gitignore vendored
View File

@ -111,3 +111,4 @@ dist
/mods /mods
/mods-lock.json /mods-lock.json
/mods.json /mods.json
build

78
package-lock.json generated
View File

@ -4,6 +4,36 @@
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
"@types/node": {
"version": "14.14.25",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.25.tgz",
"integrity": "sha512-EPpXLOVqDvisVxtlbvzfyqSsFeQxltFbluZNRndIb8tr9KiBnYNLzrc1N3pyKUCww2RNrfHDViqDWWE1LCJQtQ==",
"dev": true
},
"arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"dev": true
},
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
"dev": true
},
"create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"dev": true
},
"diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true
},
"flex-exec": { "flex-exec": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/flex-exec/-/flex-exec-1.0.0.tgz", "resolved": "https://registry.npmjs.org/flex-exec/-/flex-exec-1.0.0.tgz",
@ -36,15 +66,63 @@
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
}, },
"make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true
},
"node-json-minify": { "node-json-minify": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-json-minify/-/node-json-minify-1.0.0.tgz", "resolved": "https://registry.npmjs.org/node-json-minify/-/node-json-minify-1.0.0.tgz",
"integrity": "sha1-e7NDL5ZYtr6x2ZP9XVOzyinQ15w=" "integrity": "sha1-e7NDL5ZYtr6x2ZP9XVOzyinQ15w="
}, },
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
},
"source-map-support": {
"version": "0.5.19",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
"dev": true,
"requires": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"ts-node": {
"version": "9.1.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz",
"integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==",
"dev": true,
"requires": {
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"source-map-support": "^0.5.17",
"yn": "3.1.1"
}
},
"typescript": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz",
"integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==",
"dev": true
},
"underscore": { "underscore": {
"version": "1.12.0", "version": "1.12.0",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.0.tgz", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.0.tgz",
"integrity": "sha512-21rQzss/XPMjolTiIezSu3JAjgagXKROtNrYFEOWK109qY1Uv2tVjPTZ1ci2HgvQDA16gHYSthQIJfB+XId/rQ==" "integrity": "sha512-21rQzss/XPMjolTiIezSu3JAjgagXKROtNrYFEOWK109qY1Uv2tVjPTZ1ci2HgvQDA16gHYSthQIJfB+XId/rQ=="
},
"yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"dev": true
} }
} }
} }

View File

@ -17,5 +17,10 @@
"gift": "^0.10.2", "gift": "^0.10.2",
"gradle-to-js": "^2.0.0", "gradle-to-js": "^2.0.0",
"node-json-minify": "^1.0.0" "node-json-minify": "^1.0.0"
},
"devDependencies": {
"@types/node": "^14.14.25",
"ts-node": "^9.1.1",
"typescript": "^4.1.3"
} }
} }

View File

@ -1,14 +1,25 @@
const { http, https } = require('follow-redirects'); import { https } from "follow-redirects";
const fs = require("fs"); import fs from "fs";
const util = require("./util.js"); interface modLockElement {
let mods_lock; fileId: number;
let downloadStarted = false; url: string;
let dep = new Map(); filename: string;
}
type modLockMap = Map<string, modLockElement>;
interface Dependency {
readonly addonId: number;
readonly type: number;
}
let mods_lock: modLockMap;
let downloadStarted: boolean = false;
let globCallback;
let config;
let dep: modLockMap = new Map();
function main() { function main() {
mods_lock = new Map(Object.entries(mods_lock)); mods_lock = new Map(Object.entries(mods_lock));
if(global.config.mods.curse.length === 0) globCallback("curse", {}); if(config.mods.curse.length === 0) globCallback("curse", {});
global.config.mods.curse.forEach(mod => { config.mods.curse.forEach((mod: string) => {
getData(`search?categoryId=0&gameId=432&gameVersion=${encodeURI(global.config.gameVersion)}&index=0&pageSize=15&searchFilter=${encodeURI(mod)}&sectionId=6&sort=0`, (result) => { // resolve projectID getData(`search?categoryId=0&gameId=432&gameVersion=${encodeURI(config.gameVersion)}&index=0&pageSize=15&searchFilter=${encodeURI(mod)}&sectionId=6&sort=0`, (result: Array<any>) => { // resolve projectID
let i = 0; let i = 0;
while(result[i].name !== mod) { while(result[i].name !== mod) {
++i; ++i;
@ -23,24 +34,24 @@ function main() {
} }
var resolveDepRecursionCount = 0; var resolveDepRecursionCount = 0;
function resolveDep(modId, callback) { function resolveDep(modId: number, callback: Function) {
++resolveDepRecursionCount; ++resolveDepRecursionCount;
getData(`${modId}/files`, (files) => { getData(`${modId}/files`, (files: Array<any>) => {
let rightVersion; let rightVersion: any;
for(let i = files.length - 1; i >= 0; --i) { for(let i = files.length - 1; i >= 0; --i) {
let versionArray = files[i].gameVersion; let versionArray = files[i].gameVersion;
if(versionMatch(versionArray, global.config.gameVersion) && (versionMatch(versionArray, global.config.modloader) || modloaderMatch(versionArray, global.config.modloader))) { if(versionMatch(versionArray, config.gameVersion) && (versionMatch(versionArray, config.modloader) || modloaderMatch(versionArray, config.modloader))) {
rightVersion = files[i]; rightVersion = files[i];
} }
} }
if(rightVersion === undefined) { if(rightVersion === undefined) {
getData(modId, (mod) => { getData(String(modId), (mod: any) => {
console.log(`cursemod ${mod.name}: no version for the correct minecraft version and modloader found`); console.log(`cursemod ${mod.name}: no version for the correct minecraft version and modloader found`);
}); });
return; return;
} }
dep.set(String(modId), {fileId: rightVersion.id, url: rightVersion.downloadUrl, filename: rightVersion.fileName}); dep.set(String(modId), {fileId: rightVersion.id, url: rightVersion.downloadUrl, filename: rightVersion.fileName});
rightVersion.dependencies.forEach(mod => { rightVersion.dependencies.forEach((mod: Dependency) => {
if(mod.type !== 3) return; if(mod.type !== 3) return;
resolveDep(mod.addonId, callback); resolveDep(mod.addonId, callback);
}); });
@ -49,9 +60,9 @@ function resolveDep(modId, callback) {
}); });
} }
function getData(url, callback) { function getData(url: string, callback: Function) {
https.get(`https://addons-ecs.forgesvc.net/api/v2/addon/${url}`, (resp) => { https.get(`https://addons-ecs.forgesvc.net/api/v2/addon/${url}`, (resp) => {
let data = ''; let data: string = '';
resp.on('data', (chunk) => { resp.on('data', (chunk) => {
data += chunk; data += chunk;
}); });
@ -80,24 +91,21 @@ function downloadMods() {
if(!downloadStarted) { if(!downloadStarted) {
downloadStarted = true; downloadStarted = true;
globCallback("curse", Object.fromEntries(dep)); globCallback("curse", Object.fromEntries(dep));
dep.forEach((mod, modId) => { dep.forEach((mod: modLockElement, modId: string) => {
let path = getPath(mod) let path = modPath(mod)
if(mods_lock.has(modId)) { if(mods_lock.has(modId)) {
if(mods_lock.get(modId).fileId === mod.fileId) return; if(mods_lock.get(modId)!.fileId === mod.fileId) return;
fs.unlink(path, () => {}); fs.unlink(path, () => {});
} }
downloadFile(mod.url, path); downloadFile(mod.url, path);
}); });
mods_lock.forEach((mod, modId) => { mods_lock.forEach((mod: modLockElement, modId: string) => {
if(!dep.has(modId)) fs.unlink(getPath(mod), () => {}) if(!dep.has(modId)) fs.unlink(modPath(mod), () => {})
}); });
} }
} }
function getPath(mod) {
return `mods/${mod.filename}`
}
function downloadFile(url, dest) { function downloadFile(url: string, dest: string) {
let file = fs.createWriteStream(dest); let file = fs.createWriteStream(dest);
console.log(`downloading ${url}`); console.log(`downloading ${url}`);
let request = https.get(url, (response) => { let request = https.get(url, (response) => {
@ -113,19 +121,20 @@ function downloadFile(url, dest) {
file.on('finish', () => file.close()); file.on('finish', () => file.close());
// check for request error too // check for request error too
request.on('error', (err) => { request.on('error', (err: Error) => {
fs.unlink(dest, () => {}); fs.unlink(dest, () => {});
throw err; throw err;
}); });
file.on('error', (err) => { // Handle errors file.on('error', (err: Error) => { // Handle errors
fs.unlink(dest, () => {}); fs.unlink(dest, () => {});
throw err; throw err;
}); });
} }
module.exports = function(mods_lock_p, callback) { module.exports = function(mods_lock_p, _config, callback) {
mods_lock = mods_lock_p; mods_lock = mods_lock_p;
globCallback = callback; globCallback = callback;
config = _config;
main(); main();
}; };

View File

@ -1,18 +1,27 @@
const git = require("gift"); import git from "gift";
const childProcess = require("child_process"); import childProcess from "child_process";
const fs = require("fs"); import fs from "fs";
const g2js = require('gradle-to-js/lib/parser'); import g2js from "gradle-to-js/lib/parser";
const util = require("./util.js"); interface modLockElement {
let modsLock; commitId: string;
let globCallback; url: string;
let loopCounter = 0; filename: string;
}
type modLockMap = Map<string, modLockElement>;
interface commit {
id: string;
}
let modsLock: modLockMap;
let globCallback: Function;
let loopCounter: number = 0;
let config;
function main () { function main () {
modsLock = new Map(Object.entries(modsLock)); modsLock = new Map(Object.entries(modsLock));
let deleteMods = new Map(modsLock); let deleteMods: modLockMap = new Map(modsLock);
let cacheDir = process.env.XDG_CACHE_HOME; let cacheDir = process.env.XDG_CACHE_HOME;
if(cacheDir == null) cacheDir = `${process.env.HOME}/.cache`; if(cacheDir == null) cacheDir = `${process.env.HOME}/.cache`;
let repoPathRoot = `${cacheDir}/minecraft-mod-packager`; let repoPathRoot = `${cacheDir}/minecraft-mod-packager`;
global.config.mods.git.forEach((gitRepo) => { config.mods.git.forEach((gitRepo) => {
++loopCounter; ++loopCounter;
deleteMods.delete(gitRepo.url); deleteMods.delete(gitRepo.url);
let repoPath = `${repoPathRoot}/${gitRepo.url.replace("://", "+")}/${gitRepo.branch}`; let repoPath = `${repoPathRoot}/${gitRepo.url.replace("://", "+")}/${gitRepo.branch}`;
@ -20,7 +29,7 @@ function main () {
if(err) { if(err) {
if(err.code !== "ENOENT") throw err; if(err.code !== "ENOENT") throw err;
console.log(`cloning git repo ${gitRepo.url}`); console.log(`cloning git repo ${gitRepo.url}`);
git.clone(gitRepo.url, repoPath, undefined, gitRepo.branch, (err, repo) => { git.clone(gitRepo.url, repoPath, undefined, gitRepo.branch, (err: Error, repo) => {
if(err) throw err; if(err) throw err;
build(repo, repoPath, gitRepo); build(repo, repoPath, gitRepo);
}); });
@ -28,7 +37,7 @@ function main () {
else { else {
let repo = git(repoPath); let repo = git(repoPath);
console.log(`pulling git repo ${gitRepo.url}`); console.log(`pulling git repo ${gitRepo.url}`);
repo.pull(["origin"], gitRepo.branch, (err) => { repo.pull(["origin"], gitRepo.branch, (err: Error) => {
if(err) throw err; if(err) throw err;
build(repo, repoPath, gitRepo); build(repo, repoPath, gitRepo);
}); });
@ -37,20 +46,18 @@ function main () {
}); });
deleteMods.forEach((mod, url) => { deleteMods.forEach((mod, url) => {
modsLock.delete(url); modsLock.delete(url);
fs.unlink(util.modPath(mod), (err) => { fs.unlink(modPath(mod), (err) => {
if(err) throw err; if(err) throw err;
}); });
}); });
mayCb(); mayCb();
} }
function build(repo, repoPath, gitRepo) { function build(repo, repoPath, gitRepo):void {
if(modsLock.has(gitRepo.url)) newLock = modsLock.get(gitRepo.url); let newLock: modLockElement;
else { newLock = modsLock.get(gitRepo.url) ?? {} as modLockElement;
newLock = {}; modsLock.set(gitRepo.url, newLock);
modsLock.set(gitRepo.url, newLock); repo.current_commit((err: Error, commit: commit) => {
}
repo.current_commit((err, commit) => {
if(err) throw err; if(err) throw err;
if(commit.id === newLock.commitId) cbDecrease(); if(commit.id === newLock.commitId) cbDecrease();
else { else {
@ -62,11 +69,11 @@ function build(repo, repoPath, gitRepo) {
fs.readFile(`${repoPath}/gradle.properties`, "utf-8", (err, data) => { fs.readFile(`${repoPath}/gradle.properties`, "utf-8", (err, data) => {
if(err) throw err; if(err) throw err;
g2js.parseText(data).then((gradleProp) => { g2js.parseText(data).then((gradleProp) => {
if(newLock.filename != null) fs.unlink(util.modPath(newLock), (err) => { if(newLock.filename != null) fs.unlink(modPath(newLock), (err) => {
if(err) throw err; if(err) throw err;
}); });
newLock.filename = `${gradleProp.archives_base_name}-${gradleProp.mod_version}.jar`; newLock.filename = `${gradleProp.archives_base_name}-${gradleProp.mod_version}.jar`;
fs.copyFile(`${buildPath}/${newLock.filename}`, util.modPath(newLock), (err) => { fs.copyFile(`${buildPath}/${newLock.filename}`, modPath(newLock), (err) => {
if(err) throw err; if(err) throw err;
}); });
cbDecrease(); cbDecrease();
@ -77,17 +84,18 @@ function build(repo, repoPath, gitRepo) {
}); });
} }
function cbDecrease() { function cbDecrease():void {
--loopCounter; --loopCounter;
mayCb(); mayCb();
} }
function mayCb() { function mayCb():void {
if(loopCounter <= 0) globCallback("git", Object.fromEntries(modsLock)); if(loopCounter <= 0) globCallback("git", Object.fromEntries(modsLock));
} }
module.exports = (mods_lock_p, cb) => { module.exports = (mods_lock_p, _config, cb) => {
globCallback = cb; globCallback = cb;
modsLock = mods_lock_p; modsLock = mods_lock_p;
config = _config;
main() main()
} }

View File

@ -1,10 +1,11 @@
const jsonMinify = require("node-json-minify"); const jsonMinify = require("node-json-minify");
const fs = require("fs"); const fs = require("fs");
let config;
switch(process.argv.length) { switch(process.argv.length) {
case 3: case 3:
process.chdir(process.argv[2]); process.chdir(process.argv[2]);
case 2: case 2:
global.config = JSON.parse(jsonMinify(fs.readFileSync("mods.json", "utf-8"))); config = JSON.parse(jsonMinify(fs.readFileSync("mods.json", "utf-8")));
break; break;
default: default:
throw "unexpected argument"; throw "unexpected argument";
@ -21,8 +22,8 @@ catch(err) {
} }
const numberCallback = 2; const numberCallback = 2;
let callbackCounter = 0; let callbackCounter = 0;
require("./curse.js")(modsLock.curse, finnish); require("./curse")(modsLock.curse, config, finnish);
require("./git.js")(modsLock.git, finnish); require("./git.js")(modsLock.git, config, finnish);
function finnish(name, data) { function finnish(name, data) {
save_mods_lock[name] = data; save_mods_lock[name] = data;

View File

@ -1,7 +0,0 @@
function modPath(mod) {
return `mods/${mod.filename}`;
}
module.exports = {
modPath: modPath
}

3
src/util.ts Normal file
View File

@ -0,0 +1,3 @@
function modPath(mod: any) {
return `mods/${mod.filename}`;
}

71
tsconfig.json Normal file
View File

@ -0,0 +1,71 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "ES2020", /* 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": ["es2020"], /* 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. */
// "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": false, /* 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 */
/* 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. */
// "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 */
"resolveJsonModule": true, /* Include modules imported with '.json' extension */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}