22 changed files with 2844 additions and 300 deletions
@ -1,50 +0,0 @@
@@ -1,50 +0,0 @@
|
||||
Recreate Love Letter as Browser Game (not for profit) |
||||
|
||||
Design Envisioned UI |
||||
Pick Modules around it |
||||
Express |
||||
Socket.IO |
||||
|
||||
Design Data Format |
||||
- Handle Multiple Games |
||||
- Allow Invites to Game |
||||
Design Backend |
||||
Design FrontEnd |
||||
Design an Invite Feature |
||||
Make it reconnectable |
||||
No logins, but have unique IDs |
||||
Make it https |
||||
Animations |
||||
Design Chat |
||||
Design Guide on how to play |
||||
Design Bots to play against |
||||
|
||||
#Basic setup with socket.io + Express |
||||
https://medium.com/@raj_36650/integrate-socket-io-with-node-js-express-2292ca13d891 |
||||
|
||||
#Guide for HTTPs on Express, SSL Cert |
||||
https://medium.com/@nitinpatel_20236/how-to-create-an-https-server-on-localhost-using-express-366435d61f28 |
||||
|
||||
#Socket.IO handling Cleaner |
||||
https://socket.io/docs/v4/server-application-structure/ |
||||
|
||||
#Automatic Node Reload on changes |
||||
https://stackoverflow.com/questions/45622125/how-can-i-add-live-reload-to-my-nodejs-server |
||||
|
||||
#socket.io, socket attributes |
||||
https://socket.io/docs/v4/client-socket-instance/ |
||||
|
||||
#MEVN stack. MongoDB, Express, VueJS, NodeJs |
||||
https://vegibit.com/vue-js-express-tutorial/ |
||||
https://mfikri.com/en/blog/nodejs-express-mysql-vue |
||||
|
||||
Install VUE Global |
||||
npm install -g @vue/cli |
||||
vue --version |
||||
|
||||
|
||||
___________________________________________________________________ |
||||
|
||||
|
||||
|
||||
|
||||
@ -1,29 +0,0 @@
@@ -1,29 +0,0 @@
|
||||
// Object Definitions
|
||||
class player { |
||||
constructor (userid, |
||||
username, |
||||
gameid, |
||||
lastActivity, |
||||
connected) { |
||||
this.userid = userid |
||||
this.username = username |
||||
this.gameid = gameid |
||||
this.lastActivity = lastActivity |
||||
this.connected = connected |
||||
} |
||||
} |
||||
class table { |
||||
} |
||||
class game { |
||||
} |
||||
// Object Initialization
|
||||
let state = { |
||||
players:[], |
||||
tables:[], |
||||
games:[] |
||||
} |
||||
|
||||
module.exports = { |
||||
state: state, |
||||
players: state.players |
||||
} |
||||
@ -1,66 +0,0 @@
@@ -1,66 +0,0 @@
|
||||
// Sends Updates to socket when players change
|
||||
const wrtColor = require('../common/wrtColor') |
||||
|
||||
function mapRemoveLastActivityProp (player) { |
||||
// Make this specific by props to remove
|
||||
let {lastActivity, ...other} = player |
||||
// return {
|
||||
// id: player.id,
|
||||
// username: player.username,
|
||||
// gameid: player.gameid
|
||||
// }
|
||||
return other |
||||
} |
||||
|
||||
function continuousEmitPlayers (state,io) { |
||||
let previousPlayersRelevant = [] |
||||
let timerId = setTimeout(function tick() { |
||||
// get players excluding the "lastActivity" because it is constantly updating
|
||||
playersRelevant = state.players.map(mapRemoveLastActivityProp) |
||||
// console.log(playersRelevant)
|
||||
// convert to string for comparison
|
||||
if ((JSON.stringify(playersRelevant)) !== (JSON.stringify(previousPlayersRelevant))) { |
||||
// if changes happen, emit to all sockets
|
||||
// wrtColor.blue('change to Players. Push to Sockets')
|
||||
io.emit('playersUpdate', playersRelevant) |
||||
} |
||||
previousPlayersRelevant = playersRelevant |
||||
timerId = setTimeout(tick, 1000) |
||||
}, 1000) |
||||
} |
||||
|
||||
function socketGetPlayers (state,socket) { |
||||
playersRelevant = state.players.map(mapRemoveLastActivityProp) |
||||
socket.emit('playersUpdate', playersRelevant) |
||||
} |
||||
|
||||
function checkValidPlayerName(players,name) { |
||||
|
||||
let response = { |
||||
valid: true, |
||||
reason: "" |
||||
} |
||||
|
||||
// Returns True/False
|
||||
// 15 character limit
|
||||
// No special characters
|
||||
// name not in use already
|
||||
|
||||
|
||||
} |
||||
|
||||
function socketRegisterPlayer (io,state,data) { |
||||
wrtColor.warn('socketRegisterPlayer') |
||||
console.log(data) |
||||
//console.log(state.players)
|
||||
io.emit('msg',{poop:"salad"}) |
||||
let checkResult = checkValidPlayerName(state.players, name) |
||||
console.log(checkResult) |
||||
// add them to state.players
|
||||
} |
||||
|
||||
module.exports = { |
||||
continuousEmitPlayers: continuousEmitPlayers, |
||||
socketGetPlayers: socketGetPlayers, |
||||
socketRegisterPlayer: socketRegisterPlayer, |
||||
} |
||||
@ -1,22 +0,0 @@
@@ -1,22 +0,0 @@
|
||||
const serverConfig = require('../config/serverConfig.js') // Server Config
|
||||
const wrtColor = require('./common/wrtColor') |
||||
const fs = require('fs') |
||||
|
||||
|
||||
|
||||
function stateMonitor (state) { |
||||
setInterval(function() { |
||||
// Convert to string
|
||||
let stateString = JSON.stringify(state, null, 2) |
||||
fs.writeFile(serverConfig.stateJsonPath, stateString, (err) => { |
||||
if (err) { |
||||
throw err |
||||
} |
||||
// wrtColor.blue("state.json saved")
|
||||
}) |
||||
}, serverConfig.stateMonitorRate) |
||||
} |
||||
|
||||
module.exports = { |
||||
stateMonitor: stateMonitor |
||||
} |
||||
@ -1,18 +0,0 @@
@@ -1,18 +0,0 @@
|
||||
module.exports = { |
||||
// Server
|
||||
certKeyPath: './cert/server.key', //Called by server.js
|
||||
certPath: './cert/server.cert', //Called by server.js
|
||||
httpsPort: 9000, |
||||
frontEndUrl: 'https://localhost', // Vue running from https
|
||||
//PlayerCleanup
|
||||
cleanupInterval: 5000, // runs every 5 seconds
|
||||
playerExpiration: 60000, //300000, // 5 minutes without activity before being removed
|
||||
//State Monitor
|
||||
stateJsonPath: './log/state.json', |
||||
stateMonitorRate: 1000, |
||||
//Player Settings
|
||||
playersUpdateCheckRate: 500, // Rate between checks to send player updates to sockets
|
||||
|
||||
playerNameMaxLength: 15, |
||||
playerIdLength: 6, |
||||
} |
||||
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
{ |
||||
"verbose": false, |
||||
"watch": "src/**/*.ts", |
||||
"execMap": { |
||||
"ts": "ts-node" |
||||
} |
||||
} |
||||
@ -1,44 +0,0 @@
@@ -1,44 +0,0 @@
|
||||
const path = require('path') |
||||
const fs = require('fs') |
||||
const express = require('express') |
||||
const serverConfig = require('./config/serverConfig.js') // Server Config
|
||||
const wrtColor = require('./components/common/wrtColor') |
||||
|
||||
//Http 80 Route traffic to the frontend VUE application running with HTTPS
|
||||
const http = require('http') |
||||
const httpApp = express() |
||||
httpApp.all('*', (req, res) => res.redirect(301, `${serverConfig.frontEndUrl}`)) //301 - Moved Permanently
|
||||
const httpServer = http.createServer(httpApp) |
||||
httpServer.listen(80, () => { |
||||
//console.log(`http redirectiong 80 to Vue front end at ${serverConfig.frontEndUrl}`)
|
||||
wrtColor.green(`http redirectiong 80 to Vue front end at ${serverConfig.frontEndUrl}`) |
||||
}) |
||||
|
||||
//Https to run socket.io
|
||||
const https = require('https') |
||||
const httpsApp = express() |
||||
const keyPath = fs.readFileSync(path.resolve(__dirname, `${serverConfig.certKeyPath}`)) |
||||
const certPath = fs.readFileSync(path.resolve(__dirname, `${serverConfig.certPath}`)) |
||||
const servOptions = { |
||||
key: keyPath, |
||||
cert: certPath |
||||
} |
||||
const httpsServer = https.createServer(servOptions,httpsApp) |
||||
httpsServer.listen(serverConfig.httpsPort, () => { |
||||
//console.log(`https listening on ${serverConfig.httpsPort} to handle socket.io requests`)
|
||||
wrtColor.green(`https listening on ${serverConfig.httpsPort} to handle socket.io requests`) |
||||
}) |
||||
|
||||
// Attach Socket.IO to https server
|
||||
const io = require('socket.io') (httpsServer, { |
||||
cors: { //https://socket.io/docs/v3/handling-cors/
|
||||
origin: `${serverConfig.frontEndUrl}`, |
||||
methods: ["GET", "POST"] |
||||
} |
||||
}) |
||||
|
||||
//load gameManagement
|
||||
require('./components/serverMgmt') |
||||
//pass socket.io connections to socketHandler
|
||||
const { socketHandler } = require('./components/serverMgmt.js') |
||||
socketHandler(io) |
||||
@ -1,14 +1,14 @@
@@ -1,14 +1,14 @@
|
||||
let validCharacters = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'] |
||||
|
||||
genRandomString = (stringLength) => { |
||||
export function genRandomString (stringLength) { |
||||
let newString = '' |
||||
for (let i = 0; i < stringLength; i++) { |
||||
$index = Math.floor(Math.random() * 35) |
||||
let $index = Math.floor(Math.random() * 35) |
||||
newString += validCharacters[$index] |
||||
} |
||||
return newString |
||||
} |
||||
|
||||
module.exports = { |
||||
genRandomString: genRandomString |
||||
} |
||||
// module.exports = {
|
||||
// genRandomString: genRandomString
|
||||
// }
|
||||
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
export interface Player { |
||||
name: String |
||||
gameId: String |
||||
lastActivity: Number |
||||
connected: Boolean |
||||
} |
||||
|
||||
export interface Table {} |
||||
|
||||
export interface Game {} |
||||
|
||||
export interface State { |
||||
players: Player[] |
||||
tables: Table[] |
||||
games: Game[] |
||||
} |
||||
|
||||
export let state : State = { |
||||
players: [ |
||||
// {
|
||||
// name: "Charlie",
|
||||
// gameId: "0",
|
||||
// lastActivity: 0,
|
||||
// connected: false
|
||||
// }
|
||||
], |
||||
tables: [], |
||||
games: [], |
||||
} |
||||
@ -1,32 +1,34 @@
@@ -1,32 +1,34 @@
|
||||
const serverConfig = require('../../config/serverConfig.js') // Server Config
|
||||
import { Config } from "../../config/config" |
||||
const config: Config = require('../../config/config.json') |
||||
const wrtColor = require('../common/wrtColor') |
||||
// const { sleep } = require('./common/sleep')
|
||||
|
||||
function filterExpired(player) { |
||||
// let diff = ((new Date())-player.lastActivity)
|
||||
// console.log(`${player.username} diff: ${diff}`)
|
||||
if (((new Date())-player.lastActivity) <= serverConfig.playerExpiration) { |
||||
if (((new Date().valueOf())-player.lastActivity) <= config.playerExpiration) { |
||||
// if (config.playerExpiration >= ((new Date())-player.lastActivity)) {
|
||||
return player |
||||
} else { |
||||
// console.log(`Expired Session: ${player.username}`)
|
||||
wrtColor.magenta(`Expired Session: ${player.username}`) |
||||
wrtColor.magenta(`Expired Session: ${player.name}`) |
||||
} |
||||
} |
||||
|
||||
function playerCleanup (state) { |
||||
export function playerCleanup (state) { |
||||
// setInterval(function() { //<--This works, but I'm concerned about Memory Leak. I need to learn more.
|
||||
// console.log(state)
|
||||
// state.players = state.players.filter(checkExpired)
|
||||
// }, serverConfig.cleanupInterval)
|
||||
// }, config.cleanupInterval)
|
||||
|
||||
//setTimeout Version self-calling function
|
||||
let timerId = setTimeout(function tick() { |
||||
// console.log(state)
|
||||
state.players = state.players.filter(filterExpired) |
||||
timerId = setTimeout(tick, serverConfig.cleanupInterval) |
||||
}, serverConfig.cleanupInterval) |
||||
timerId = setTimeout(tick, config.cleanupInterval) |
||||
}, config.cleanupInterval) |
||||
} |
||||
|
||||
module.exports = { |
||||
playerCleanup: playerCleanup |
||||
} |
||||
// module.exports = {
|
||||
// playerCleanup: playerCleanup
|
||||
// }
|
||||
@ -0,0 +1,82 @@
@@ -0,0 +1,82 @@
|
||||
// Sends Updates to socket when players change
|
||||
const wrtColor = require('../common/wrtColor') |
||||
|
||||
function mapRemoveLastActivityProp (player) { |
||||
// Make this specific by props to remove
|
||||
let {lastActivity, ...other} = player |
||||
// return {
|
||||
// id: player.id,
|
||||
// name: player.username,
|
||||
// gameid: player.gameid
|
||||
// }
|
||||
return other |
||||
} |
||||
|
||||
export function continuousEmitPlayers (state,io) { |
||||
let previousPlayersRelevant = [] |
||||
let timerId = setTimeout(function tick() { |
||||
// get players excluding the "lastActivity" because it is constantly updating
|
||||
let playersRelevant = state.players.map(mapRemoveLastActivityProp) |
||||
// console.log(playersRelevant)
|
||||
// convert to string for comparison
|
||||
if ((JSON.stringify(playersRelevant)) !== (JSON.stringify(previousPlayersRelevant))) { |
||||
// if changes happen, emit to all sockets
|
||||
// wrtColor.blue('change to Players. Push to Sockets')
|
||||
io.emit('playersUpdate', playersRelevant) |
||||
} |
||||
previousPlayersRelevant = playersRelevant |
||||
timerId = setTimeout(tick, 1000) |
||||
}, 1000) |
||||
} |
||||
|
||||
export function socketGetPlayers (state,socket) { |
||||
let playersRelevant = state.players.map(mapRemoveLastActivityProp) |
||||
socket.emit('playersUpdate', playersRelevant) |
||||
} |
||||
|
||||
function checkValidPlayerName(players, playerName) { |
||||
//let playerNameString = String(playerName)
|
||||
|
||||
let response = { |
||||
valid: true, |
||||
fails: [] |
||||
} |
||||
// 20 character limit
|
||||
if (playerName.length > 20) { |
||||
response.valid = false |
||||
response.fails.push('more than 20 characters') |
||||
} |
||||
// Check for unallowed characters
|
||||
if (!/^[a-z]+$/i.test(playerName)) { |
||||
response.valid = false |
||||
response.fails.push('unallowed characters') |
||||
} |
||||
// Name not in use already (case sensitive)
|
||||
// if (players.some(p => p.name.toString().toUpperCase() === playerName.toUpperCase())) {
|
||||
// response.valid = false
|
||||
// response.fails.push('name in use')
|
||||
// }
|
||||
if (players.filter(p => p.name.toUpperCase() === playerName.toUpperCase()).length > 0) { |
||||
response.valid = false |
||||
response.fails.push('name in use') |
||||
} |
||||
|
||||
return response |
||||
} |
||||
|
||||
export function socketRegisterPlayer (io,state,data) { |
||||
wrtColor.warn('socketRegisterPlayer') |
||||
console.log(data) |
||||
//console.log(state.players)
|
||||
// io.emit('msg',{poop:"salad"})
|
||||
let checkResult = checkValidPlayerName(state.players, data.playerName) |
||||
//console.log(checkResult)
|
||||
io.emit('msg',checkResult) |
||||
// add them to state.players
|
||||
} |
||||
|
||||
// module.exports = {
|
||||
// continuousEmitPlayers: continuousEmitPlayers,
|
||||
// socketGetPlayers: socketGetPlayers,
|
||||
// socketRegisterPlayer: socketRegisterPlayer,
|
||||
// }
|
||||
@ -1,52 +1,44 @@
@@ -1,52 +1,44 @@
|
||||
// const serverConfig = require('../config/serverConfig.js')
|
||||
// import { Config } from "../config/config"
|
||||
// const config: Config = require('../config/config.json')
|
||||
const wrtColor = require('./common/wrtColor') |
||||
|
||||
//Load Object Definitions and Initialize them
|
||||
require('./objectDefinitions') |
||||
let { state } = require('./objectDefinitions') |
||||
// Loab Object Definitions and Initialize state (Holds players/tables/games)
|
||||
import { state } from "./objectDefinitions" |
||||
console.log(state) |
||||
|
||||
|
||||
// TODO: TEST FUNCTIONS
|
||||
require('./testFunctions') |
||||
const { addTestPlayers, addFluxPlayers } = require('./testFunctions') |
||||
wrtColor.test('adding Test Players') |
||||
// TODO: TEST Functions
|
||||
//require('./test/playerTestFunctions')
|
||||
const { addTestPlayers, addFluxPlayers } = require('./test/playerTestFunctions') |
||||
addTestPlayers(state.players) |
||||
addFluxPlayers(state) |
||||
|
||||
|
||||
|
||||
//--- Socket Handling ---
|
||||
const { socketGetPlayers } = require('./players/playerMgmtFuncs') |
||||
const { continuousEmitPlayers } = require ('./players/playerMgmtFuncs') |
||||
const { socketRegisterPlayer } = require ('./players/playerMgmtFuncs') |
||||
function socketHandler (io) { |
||||
// --- Socket Handling ---
|
||||
const { socketGetPlayers } = require('./players/playerMgmtFuncs.ts') |
||||
const { continuousEmitPlayers } = require ('./players/playerMgmtFuncs.ts') |
||||
const { socketRegisterPlayer } = require ('./players/playerMgmtFuncs.ts') |
||||
export function socketHandler (io) { |
||||
io.on('connection', function (socket) { |
||||
//--- Connection ---
|
||||
wrtColor.cyan(`socket connection established, id ${socket.id}`) |
||||
|
||||
|
||||
//--- Register other socket event handler functions ---
|
||||
socket.on('getPlayers', () => socketGetPlayers(state,socket)) |
||||
socket.on('registerPlayer', (data) => socketRegisterPlayer(io,state,data)) |
||||
//......//
|
||||
|
||||
|
||||
//--- Disconnection ---
|
||||
socket.on('disconnect', (reason) => { wrtColor.yellow(`socket disconnected, ${socket.id}, ${reason}`)}) |
||||
}) |
||||
|
||||
//--- Continuous Processes for Sockets ---
|
||||
continuousEmitPlayers(state,io) |
||||
continuousEmitPlayers(state,io)
|
||||
} |
||||
|
||||
|
||||
//--- Continuous Server Side Processes ---
|
||||
//--- Continuous Non-Socket Processes ---
|
||||
// State Monitor
|
||||
const { stateMonitor } = require('./serverProcesses/stateMonitor') |
||||
stateMonitor(state) |
||||
// Player Cleanup
|
||||
const { playerCleanup } = require('./players/playerCleanup') |
||||
const { stateMonitor } = require('./stateMonitor') |
||||
playerCleanup(state) |
||||
stateMonitor(state) |
||||
|
||||
|
||||
|
||||
module.exports = { |
||||
socketHandler: socketHandler |
||||
} |
||||
|
||||
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
import { Config } from "../../config/config" |
||||
const config: Config = require('../../config/config.json') |
||||
// const wrtColor = require('./common/wrtColor')
|
||||
const fs = require('fs') |
||||
|
||||
export function stateMonitor (state) { |
||||
setInterval(function() { |
||||
// Convert to string
|
||||
let stateString = JSON.stringify(state, null, 2) |
||||
fs.writeFile(config.stateJsonPath, stateString, (err) => { |
||||
if (err) { |
||||
throw err |
||||
} |
||||
// wrtColor.blue("state.json saved")
|
||||
}) |
||||
}, config.stateMonitorRate) |
||||
} |
||||
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
{ |
||||
"certKeyPath": "../cert/server.key", |
||||
"certPath": "../cert/server.cert", |
||||
"httpsPort": 9000, |
||||
"frontEndUrl": "https://localhost", |
||||
"cleanupInterval": 5000, |
||||
"playerExpiration": 60000, |
||||
"stateJsonPath": "./log/state.json", |
||||
"stateMonitorRate": 1000, |
||||
"playersUpdateCheckRate": 500, |
||||
"playerNameMaxLength": 20, |
||||
"playerIdLength": 6 |
||||
} |
||||
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
export interface Config { |
||||
// Server
|
||||
certKeyPath: string |
||||
certPath: string |
||||
httpsPort: number |
||||
frontEndUrl: string |
||||
//PlayerCleanup
|
||||
cleanupInterval: number |
||||
playerExpiration: number |
||||
//State Monitor
|
||||
stateJsonPath: string |
||||
stateMonitorRate: number |
||||
//Player Settings
|
||||
playersUpdateCheckRate: number |
||||
playerNameMaxLength: number |
||||
playerIdLength: number |
||||
} |
||||
|
||||
// // --- Moved to a separate file ---
|
||||
// export let config : Config = {
|
||||
// // Server
|
||||
// certKeyPath: "../cert/server.key",
|
||||
// certPath: "../cert/server.cert",
|
||||
// httpsPort: 9000,
|
||||
// frontEndUrl: "https://localhost",
|
||||
// //Player Cleanup
|
||||
// cleanupInterval: 5000,
|
||||
// playerExpiration: 60000,
|
||||
// //State Monitor
|
||||
// stateJsonPath: "./log/state.json",
|
||||
// stateMonitorRate: 1000,
|
||||
// //Player Settings
|
||||
// playersUpdateCheckRate: 500,
|
||||
// playerNameMaxLength: 20,
|
||||
// playerIdLength: 6,
|
||||
// }
|
||||
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
import { Config } from './config/config' |
||||
const config: Config = require('./config/config.json') |
||||
console.log('config:',config) |
||||
const wrtColor = require('./components/common/wrtColor') |
||||
|
||||
const fs = require('fs') |
||||
const express = require('express') |
||||
|
||||
//Http 80 Route traffic to the frontend VUE application running with HTTPS
|
||||
const http = require('http') |
||||
const httpApp = express() |
||||
httpApp.all('*', (req, res) => res.redirect(301, `${config.frontEndUrl}`)) //301 - Moved Permanently
|
||||
const httpServer = http.createServer(httpApp) |
||||
httpServer.listen(80, () => { |
||||
wrtColor.green(`http redirectiong 80 to Vue front end at ${config.frontEndUrl}`) |
||||
}) |
||||
|
||||
//Https to run socket.io
|
||||
const https = require('https') |
||||
const httpsApp = express() |
||||
const path = require('path') |
||||
const keyPath = fs.readFileSync(path.resolve(__dirname, `${config.certKeyPath}`)) |
||||
const certPath = fs.readFileSync(path.resolve(__dirname, `${config.certPath}`)) |
||||
const servOptions = { |
||||
key: keyPath, |
||||
cert: certPath |
||||
} |
||||
const httpsServer = https.createServer(servOptions,httpsApp) |
||||
httpsServer.listen(config.httpsPort, () => { |
||||
wrtColor.green(`https listening on ${config.httpsPort} to handle socket.io requests`) |
||||
}) |
||||
|
||||
//Attach Socket.IO to https
|
||||
const io = require('socket.io') (httpsServer, { |
||||
cors: { //https://socket.io/docs/v3/handling-cors/
|
||||
origin: `${config.frontEndUrl}`, |
||||
methods: ["GET", "POST"] |
||||
} |
||||
}) |
||||
|
||||
//load gameManagement
|
||||
require('./components/serverMgmt') |
||||
// pass socket.io connections to socketHandler
|
||||
const { socketHandler } = require('./components/serverMgmt') |
||||
socketHandler(io) |
||||
|
||||
|
||||
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
{ |
||||
"compilerOptions": { |
||||
"target": "es6", |
||||
"module": "commonjs", |
||||
"rootDir": "src", |
||||
"outDir": "dist", |
||||
"sourceMap": true, |
||||
"resolveJsonModule": true, |
||||
"lib": ["es6", "dom"], |
||||
"esModuleInterop": true |
||||
}, |
||||
"include": [ |
||||
"src/**/*.ts" |
||||
, "src/components/common/randomString.js", "src/components/common/randomString.js" ], |
||||
"exclude": [ |
||||
"node_modules" |
||||
] |
||||
} |
||||
Loading…
Reference in new issue