This commit is contained in:
danilafilippov7299 2024-05-24 03:22:28 +04:00
commit 744d1abb2f
5 changed files with 1787 additions and 0 deletions

130
.gitignore vendored Normal file
View File

@ -0,0 +1,130 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

41
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,41 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
/* {
"name": "Launch via NPM",
"request": "launch",
"runtimeArgs": [
"run-script",
"debug"
],
"runtimeExecutable": "npm",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
}, */
{
"name": "server",
"program": "${workspaceFolder}/server.js",
"request": "launch",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
},
/* {
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}\\server.js"
} */
]
}

861
package-lock.json generated Normal file
View File

@ -0,0 +1,861 @@
{
"name": "webproject",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "webproject",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"express": "^4.19.2",
"pg": "^8.11.5",
"postgres": "^3.4.4",
"ws": "^8.17.0"
}
},
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
"dependencies": {
"mime-types": "~2.1.34",
"negotiator": "0.6.3"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
},
"node_modules/body-parser": {
"version": "1.20.2",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
"integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
"dependencies": {
"bytes": "3.1.2",
"content-type": "~1.0.5",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.11.0",
"raw-body": "2.5.2",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8",
"npm": "1.2.8000 || >= 1.4.16"
}
},
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/call-bind": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/content-disposition": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
"dependencies": {
"safe-buffer": "5.2.1"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/content-type": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
},
"node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/destroy": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
"engines": {
"node": ">= 0.8",
"npm": "1.2.8000 || >= 1.4.16"
}
},
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
},
"node_modules/encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/es-define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
"dependencies": {
"get-intrinsic": "^1.2.4"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
},
"node_modules/etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/express": {
"version": "4.19.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
"integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
"body-parser": "1.20.2",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.6.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "1.2.0",
"fresh": "0.5.2",
"http-errors": "2.0.0",
"merge-descriptors": "1.0.1",
"methods": "~1.1.2",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
"path-to-regexp": "0.1.7",
"proxy-addr": "~2.0.7",
"qs": "6.11.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.2.1",
"send": "0.18.0",
"serve-static": "1.15.0",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"type-is": "~1.6.18",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
},
"engines": {
"node": ">= 0.10.0"
}
},
"node_modules/finalhandler": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
"integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
"dependencies": {
"debug": "2.6.9",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
"statuses": "2.0.1",
"unpipe": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-intrinsic": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/gopd": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
"dependencies": {
"get-intrinsic": "^1.1.3"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-property-descriptors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"dependencies": {
"es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-proto": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
"dependencies": {
"depd": "2.0.0",
"inherits": "2.0.4",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"toidentifier": "1.0.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
},
"node_modules/methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/object-inspect": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
"integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/on-finished": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
"dependencies": {
"ee-first": "1.1.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
},
"node_modules/pg": {
"version": "8.11.5",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.11.5.tgz",
"integrity": "sha512-jqgNHSKL5cbDjFlHyYsCXmQDrfIX/3RsNwYqpd4N0Kt8niLuNoRNH+aazv6cOd43gPh9Y4DjQCtb+X0MH0Hvnw==",
"dependencies": {
"pg-connection-string": "^2.6.4",
"pg-pool": "^3.6.2",
"pg-protocol": "^1.6.1",
"pg-types": "^2.1.0",
"pgpass": "1.x"
},
"engines": {
"node": ">= 8.0.0"
},
"optionalDependencies": {
"pg-cloudflare": "^1.1.1"
},
"peerDependencies": {
"pg-native": ">=3.0.1"
},
"peerDependenciesMeta": {
"pg-native": {
"optional": true
}
}
},
"node_modules/pg-cloudflare": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz",
"integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==",
"optional": true
},
"node_modules/pg-connection-string": {
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz",
"integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA=="
},
"node_modules/pg-int8": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/pg-pool": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.2.tgz",
"integrity": "sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==",
"peerDependencies": {
"pg": ">=8.0"
}
},
"node_modules/pg-protocol": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.1.tgz",
"integrity": "sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg=="
},
"node_modules/pg-types": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
"dependencies": {
"pg-int8": "1.0.1",
"postgres-array": "~2.0.0",
"postgres-bytea": "~1.0.0",
"postgres-date": "~1.0.4",
"postgres-interval": "^1.1.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/pgpass": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
"dependencies": {
"split2": "^4.1.0"
}
},
"node_modules/postgres": {
"version": "3.4.4",
"resolved": "https://registry.npmjs.org/postgres/-/postgres-3.4.4.tgz",
"integrity": "sha512-IbyN+9KslkqcXa8AO9fxpk97PA4pzewvpi2B3Dwy9u4zpV32QicaEdgmF3eSQUzdRk7ttDHQejNgAEr4XoeH4A==",
"engines": {
"node": ">=12"
},
"funding": {
"type": "individual",
"url": "https://github.com/sponsors/porsager"
}
},
"node_modules/postgres-array": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
"engines": {
"node": ">=4"
}
},
"node_modules/postgres-bytea": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
"integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/postgres-date": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/postgres-interval": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
"dependencies": {
"xtend": "^4.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
"dependencies": {
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/qs": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
"dependencies": {
"side-channel": "^1.0.4"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/raw-body": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/send": {
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
"integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
"dependencies": {
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "2.0.0",
"mime": "1.6.0",
"ms": "2.1.3",
"on-finished": "2.4.1",
"range-parser": "~1.2.1",
"statuses": "2.0.1"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/send/node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/serve-static": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
"integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
"dependencies": {
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"parseurl": "~1.3.3",
"send": "0.18.0"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"dependencies": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
"node_modules/side-channel": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
"dependencies": {
"call-bind": "^1.0.7",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4",
"object-inspect": "^1.13.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/split2": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
"engines": {
"node": ">= 10.x"
}
},
"node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
"engines": {
"node": ">=0.6"
}
},
"node_modules/type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
"dependencies": {
"media-typer": "0.3.0",
"mime-types": "~2.1.24"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/ws": {
"version": "8.17.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz",
"integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"engines": {
"node": ">=0.4"
}
}
}
}

18
package.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "webproject",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.19.2",
"pg": "^8.11.5",
"postgres": "^3.4.4",
"ws": "^8.17.0"
}
}

737
server.js Normal file
View File

@ -0,0 +1,737 @@
//#region import
var http = require('http');
var fs = require('fs');
const express = require('express');
const WebSocket = require('ws');
const app = express();
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
server.listen(80, () => {
console.log(`Server started on port ${server.address().port} :)`);
});
const pg = require('pg');
const { Pool, Client } = pg
const pool = new Pool({
user: 'd',
password: '123',
host: '192.168.56.104',
port: 5432,
database: 'mydb',
})
async function query(q) {
return (await pool.query(q)).rows;
}
//#endregion
//#region Server CRUD Interface
function getTables() {
return query(`SELECT table_name
FROM information_schema.tables
WHERE table_schema='public'
AND table_type='BASE TABLE';`);
}
async function getTable(data) {
let table = data[0], filters = data[1];
if (table == "moovie") {
//q =
}
let q = `select * from ` + table;
let isFilters = false;
if (Array.isArray(filters) && filters.length != 0) {
q += " WHERE ";
filters.forEach(f => {
isFilters = true;
let n = typeof f[1] == "string" && f[1].length > 1 && (f[1][0] == ">" || f[1][0] == "<");
if (f[0] != null && f[1] != "") {
if (typeof f[1] == "number")
q += f[0] + "=" + f[1] + " AND ";
else
q += f[0] + (n ? "" : " LIKE '%") + f[1] + (n ? "" : "%'") + " AND ";
}
})
}
if (isFilters) q = q.slice(0, -4);
let querry = q;
try {
q = await query(q);
} catch {
return null;
}
q[q.length] = table;
q["querry"] = querry;
return q;
}
async function getDifficultMoovies() {
let q = `SELECT moovie_id, moovie_name, rating_rate, moovie_productionYear, moovie_about, moovie_timeAdded, subscription_name, subscription_price
FROM moovie
INNER JOIN rating ON moovie.moovie_id = rating.rating__fk_moovie
INNER JOIN subscription ON subscription_id = (
select customer__fk_subsription from customer
where customer_id = 9
)
where moovie_id IN (
select mooviesubscription_fk_moovie_id from moovieSubscription
Where moovieSubscription_fk_subscription_id = (
select customer__fk_subsription from customer
where customer_id = 9
)
);
`;
let querry = q;
q = await query(q);
q["querry"] = querry;
return q;
}
//#region Generate Interface
function createTabless() {
let q = `DROP TABLE if exists moovie cascade;
DROP SEQUENCE if exists SEQ_moovie;
CREATE SEQUENCE SEQ_moovie INCREMENT BY 1 START WITH 1;
CREATE TABLE moovie (
moovie_id integer PRIMARY KEY DEFAULT nextval('SEQ_moovie'),
moovie_name varchar(50) NOT NULL,
moovie_productionYear integer NOT NULL,
moovie_about varchar(50) NOT NULL,
moovie_timeAdded date NOT NULL
);
DROP TABLE if exists genre cascade;
DROP SEQUENCE if exists SEQ_genre;
CREATE SEQUENCE SEQ_genre INCREMENT BY 1 START WITH 1;
CREATE TABLE genre (
genre_id integer PRIMARY KEY DEFAULT nextval('SEQ_genre'),
genre_name varchar(50) NOT NULL
);
DROP TABLE if exists moovieGenre cascade;
DROP SEQUENCE if exists SEQ_moovieGenre;
CREATE SEQUENCE SEQ_moovieGenre INCREMENT BY 1 START WITH 1;
CREATE TABLE moovieGenre (
moovieGenre_id integer PRIMARY KEY DEFAULT nextval('SEQ_moovieGenre'),
moovieGenre_fk_moovie_id int REFERENCES moovie (moovie_id),
moovieGenre_fk_genre_id int REFERENCES genre (genre_id)
);
DROP TABLE if exists subscription cascade;
DROP SEQUENCE if exists SEQ_subscription;
CREATE SEQUENCE SEQ_subscription INCREMENT BY 1 START WITH 1;
CREATE TABLE subscription (
subscription_id integer PRIMARY KEY DEFAULT nextval('SEQ_subscription'),
subscription_name varchar(50) NOT NULL,
subscription_price integer NOT NULL,
subscription_fk_parentSubscription_id int NULL REFERENCES subscription (subscription_id)
);
DROP TABLE if exists moovieSubscription cascade;
DROP SEQUENCE if exists SEQ_moovieSubscription;
CREATE SEQUENCE SEQ_moovieSubscription INCREMENT BY 1 START WITH 1;
CREATE TABLE moovieSubscription (
moovieSubscription_id integer PRIMARY KEY DEFAULT nextval('SEQ_moovieSubscription'),
moovieSubscription_fk_moovie_id int REFERENCES moovie (moovie_id),
moovieSubscription_fk_subscription_id int REFERENCES subscription (subscription_id)
);
DROP TABLE if exists customer cascade;
DROP SEQUENCE if exists SEQ_customer;
CREATE SEQUENCE SEQ_customer INCREMENT BY 1 START WITH 1;
CREATE TABLE customer (
customer_id integer PRIMARY KEY DEFAULT nextval('SEQ_customer'),
customer_name varchar(50) NOT NULL,
customer_email varchar(50) NOT NULL,
customer_password varchar(50) NOT NULL,
customer_age int NOT NULL,
customer_phone varchar(50) NOT NULL,
customer__fk_subsription int NOT NULL REFERENCES subscription (subscription_id)
);
DROP TABLE if exists rating cascade;
DROP SEQUENCE if exists SEQ_rating;
CREATE SEQUENCE SEQ_rating INCREMENT BY 1 START WITH 1;
CREATE TABLE rating (
rating_id integer PRIMARY KEY DEFAULT nextval('SEQ_rating'),
rating_rate int NOT NULL,
rating_fk_user int NOT NULL REFERENCES customer (customer_id),
rating__fk_moovie int NOT NULL REFERENCES moovie (moovie_id)
);
COMMENT ON TABLE public.moovie IS 'Это таблица о Фильмах';
ALTER TABLE public.moovie ALTER COLUMN moovie_name SET NOT NULL;
ALTER TABLE public.moovie ALTER COLUMN moovie_name SET DEFAULT 'Название фильма';
ALTER TABLE public.moovie ALTER COLUMN moovie_productionYear SET NOT NULL;
--ALTER TABLE public.moovie ALTER COLUMN moovie_productionYear SET DEFAULT 2000;
ALTER TABLE public.moovie ALTER COLUMN moovie_about SET NOT NULL;
ALTER TABLE public.moovie ALTER COLUMN moovie_about SET DEFAULT 'Описание фильма';
ALTER TABLE public.moovie ALTER COLUMN moovie_timeAdded SET NOT NULL;
ALTER TABLE public.moovie ALTER COLUMN moovie_timeAdded SET DEFAULT '2024-06-16 12:00:00';
COMMENT ON TABLE public.genre IS 'Это таблица о Жанрах фильмов';
ALTER TABLE public.genre ALTER COLUMN genre_name SET NOT NULL;
ALTER TABLE public.genre ALTER COLUMN genre_name SET DEFAULT 'Название жанра';
COMMENT ON TABLE public.moovieGenre IS 'Это таблица много ко многим для таблиц Фильм и Жанр';
ALTER TABLE public.moovieGenre ALTER COLUMN moovieGenre_fk_moovie_id SET NOT NULL;
ALTER TABLE public.moovieGenre ALTER COLUMN moovieGenre_fk_genre_id SET NOT NULL;
COMMENT ON TABLE public.subscription IS 'Это таблица о подписках на фильмы';
ALTER TABLE public.subscription ALTER COLUMN subscription_name SET NOT NULL;
ALTER TABLE public.subscription ALTER COLUMN subscription_name SET DEFAULT 'Подписка';
ALTER TABLE public.subscription ALTER COLUMN subscription_price SET NOT NULL;
ALTER TABLE public.subscription ALTER COLUMN subscription_price SET DEFAULT 999;
COMMENT ON TABLE public.customer IS 'Это таблица о пользователях';
ALTER TABLE public.customer ALTER COLUMN customer_name SET NOT NULL;
ALTER TABLE public.customer ALTER COLUMN customer_name SET DEFAULT 'Пользователь 1';
ALTER TABLE public.customer ALTER COLUMN customer_password SET NOT NULL;
ALTER TABLE public.customer ALTER COLUMN customer_password SET DEFAULT '123';
ALTER TABLE public.customer ALTER COLUMN customer_age SET NOT NULL;
ALTER TABLE public.customer ALTER COLUMN customer_age SET DEFAULT '18';
ALTER TABLE public.customer ALTER COLUMN customer_phone SET NOT NULL;
ALTER TABLE public.customer ALTER COLUMN customer__fk_subsription SET NOT NULL;
COMMENT ON TABLE public.rating IS 'Это таблица об отзывах про фильмы';
ALTER TABLE public.rating ALTER COLUMN rating_rate SET NOT NULL;
ALTER TABLE public.rating ALTER COLUMN rating_rate SET DEFAULT 10;
ALTER TABLE public.rating ALTER COLUMN rating_fk_user SET NOT NULL;
ALTER TABLE public.rating ALTER COLUMN rating_fk_user SET DEFAULT 0;
ALTER TABLE public.rating ALTER COLUMN rating__fk_moovie SET NOT NULL;
ALTER TABLE public.rating ALTER COLUMN rating__fk_moovie SET DEFAULT 0;
ALTER TABLE public.mooviegenre DROP CONSTRAINT mooviegenre_mooviegenre_fk_genre_id_fkey;
ALTER TABLE public.mooviegenre ADD CONSTRAINT mooviegenre_mooviegenre_fk_genre_id_fkey FOREIGN KEY (mooviegenre_fk_genre_id) REFERENCES public.genre(genre_id) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE public.mooviegenre DROP CONSTRAINT mooviegenre_mooviegenre_fk_moovie_id_fkey;
ALTER TABLE public.mooviegenre ADD CONSTRAINT mooviegenre_mooviegenre_fk_moovie_id_fkey FOREIGN KEY (mooviegenre_fk_moovie_id) REFERENCES public.moovie(moovie_id) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE public.mooviesubscription DROP CONSTRAINT mooviesubscription_mooviesubscription_fk_moovie_id_fkey;
ALTER TABLE public.mooviesubscription ADD CONSTRAINT mooviesubscription_mooviesubscription_fk_moovie_id_fkey FOREIGN KEY (mooviesubscription_fk_moovie_id) REFERENCES public.moovie(moovie_id) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE public.mooviesubscription DROP CONSTRAINT mooviesubscription_mooviesubscription_fk_subscription_id_fkey;
ALTER TABLE public.mooviesubscription ADD CONSTRAINT mooviesubscription_mooviesubscription_fk_subscription_id_fkey FOREIGN KEY (mooviesubscription_fk_subscription_id) REFERENCES public."subscription"(subscription_id) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE public."subscription" DROP CONSTRAINT subscription_subscription_fk_parentsubscription_id_fkey;
ALTER TABLE public."subscription" ADD CONSTRAINT subscription_subscription_fk_parentsubscription_id_fkey FOREIGN KEY (subscription_fk_parentsubscription_id) REFERENCES public."subscription"(subscription_id) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE public.customer DROP CONSTRAINT customer_customer__fk_subsription_fkey;
ALTER TABLE public.customer ADD CONSTRAINT customer_customer__fk_subsription_fkey FOREIGN KEY (customer__fk_subsription) REFERENCES public."subscription"(subscription_id) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE public.rating DROP CONSTRAINT rating_rating__fk_moovie_fkey;
ALTER TABLE public.rating ADD CONSTRAINT rating_rating__fk_moovie_fkey FOREIGN KEY (rating__fk_moovie) REFERENCES public.moovie(moovie_id) ON DELETE CASCADE ON UPDATE CASCADE;
`;
return pool.query(q);
}
async function del() {
let q = `
DELETE FROM moovieSubscription;
DELETE FROM customer;
DELETE FROM genre;
DELETE FROM subscription;
DELETE FROM moovie;
ALTER SEQUENCE SEQ_moovie RESTART WITH 1;
ALTER SEQUENCE SEQ_genre RESTART WITH 1;
ALTER SEQUENCE SEQ_moovieGenre RESTART WITH 1;
ALTER SEQUENCE SEQ_subscription RESTART WITH 1;
ALTER SEQUENCE SEQ_moovieSubscription RESTART WITH 1;
ALTER SEQUENCE SEQ_customer RESTART WITH 1;
ALTER SEQUENCE SEQ_rating RESTART WITH 1;
`;
await pool.query(q);
}
let genress = ` Action Thriller Western Fantasy Science fiction Comedy Satire Drama Adventure Mystery Romantic comedy Melodrama Romance Hybrid genre Fairy tale Coming-of-age story Fantasy Suspense Detective fiction Biography Dark comedy Mystery Apocalyptic and post-apocalyptic fiction Slapstick Screenplay Historical drama Comedy horror Historical fantasy Body horror Tech noir Legal drama Film criticism`.split(" ");
async function createRandomGenres() {
let q = `
INSERT INTO genre VALUES
`;
for (let i = 0; i < count; i++) {
q += "(DEFAULT, '" + genress[Math.round((genress.length - 1) * Math.random())] + "'),";
}
let w = await pool.query(q.slice(0, -1));
w["querry"] = "INSERT INTO genre VALUES";
return w;
}
async function createRandomUsers(subscriptionsLength = count) {
let q = `
INSERT INTO customer VALUES
`;
for (let i = 0; i < count; i++) {
let w = Math.round(Math.random() * (subscriptionsLength - 2) + 1);
//console.log(w);
q += "(DEFAULT, " +
"'user" + i + "', 'email" + i + "@gmail.com'," + " 'password" + i + "', "
+ Math.round(Math.random() * (50 - 18) + 18) + ", " + "'phoneNumber" + i + "', "
+ w
+ "),";
}
let w = await pool.query(q.slice(0, -1));
w["querry"] = "INSERT INTO customer VALUES";
return w;
}
async function createRandomSubscriptions() {
let q = `
INSERT INTO subscription VALUES
`;
for (let i = 0; i < count; i++) {
q += "(DEFAULT, 'Подписка " + i.toString() + "', "
+ Math.round(Math.random() * 5000) + " " + ""/* Math.max(1, Math.round(Math.random() * (i-1))) */ + "),";
}
let w = await pool.query(q.slice(0, -1));
w["querry"] = " INSERT INTO subscription VALUES";
return w;
//query(q);
}
async function createRandomMoovies() {
let q = `
INSERT INTO moovie VALUES
`;
for (let i = 0; i < count; i++) {
q += "(DEFAULT, 'Фильм" + i + "', "
+ Math.round(Math.random() * (2024 - 1980) + 1980) + ", 'Описание" + i + "', '" + "2004-01-22" + "'),";
}
let w = await pool.query(q.slice(0, -1));
w["querry"] = "INSERT INTO moovie VALUES";
return w;
//query(q);
}
async function createRandomMoovieSubscriptions() {
let q = `
INSERT INTO moovieSubscription VALUES
`;
for (let i = 1; i < count / 10; i++) {
for (let t = 1; t < count / 5; t++) {
q += "(DEFAULT, " + t.toString() + ", " + i.toString() + "),";
}
}
let w = await pool.query(q.slice(0, -1));
w["querry"] = "INSERT INTO moovieSubscription VALUES";
return w;
//query(q);
}
async function createRandomRatings() {
let q = `
INSERT INTO rating VALUES
`;
for (let t = 1; t < count; t++) {
q += "(DEFAULT, " + Math.round(Math.random() * 10) + ", " +
Math.round(Math.random() * (count - 2) + 1) + ", " +
Math.round(Math.random() * (count - 2) + 1) + "),";
}
let w = await pool.query(q.slice(0, -1));
w["querry"] = "INSERT INTO rating VALUES";
return w;
//query(q);
}
//#endregion
//#endregion
//#region Measure
var result = [];
async function measure(f, args = [], multipleTimes = true) {
return new Promise(async resolve => {
let commonTime = null, res = "";
for (let i = 0; i < 10; i++) {
let t1 = process.hrtime.bigint();
res = await f(...args);
let t2 = process.hrtime.bigint();
if (commonTime == null) commonTime = (Number(t2 - t1) / 10 ** 6);
else commonTime = (commonTime + (Number(t2 - t1) / 10 ** 6)) / 2;
if (multipleTimes == false) break;
}
//console.log(Number(t2 - t1).toString() + " nanoseconds");
result.push(res["querry"] + " : " + commonTime.toFixed(1).toString() + "мс"/* " милиСекунд (10*-3)" */);
resolve();
})
}
var count = 15;
async function createTables() {
let ts = await getTables();
if (true || ts.length == 0) {
await createTabless();
}
//await del();
await measure(createRandomSubscriptions, [], false);
await measure(createRandomGenres, [], false);
await measure(createRandomUsers, [], false);
await measure(createRandomMoovies, [], false);
await measure(createRandomMoovieSubscriptions, [], false);
await measure(createRandomRatings, [], false);
await measure(getTable, [["subscription", []]])
await measure(getTable, [["moovie", []]])
await measure(getTable, [["moovie", [["moovie_productionYear", ">2021"], ["moovie_name", "2"]]]]);
await measure(getTable, [["genre", []]]);
await measure(getTable, [["moovieGenre", []]]);
await measure(getTable, [["subscription", []]]);
await measure(getTable, [["moovieSubscription", []]]);
await measure(getTable, [["customer", []]]);
await measure(getTable, [["rating", []]]);
await measure(getDifficultMoovies);
result.unshift("№ Запрос:Среднее время")
console.log(result.slice(0, -1).map((a, index) => ((index).toString() + ": " + a + ": ")).join(" "));
console.log(result[result.length - 1]);
}
//#endregion
function wsInterface() {
try {
ws = new WebSocket('ws://localhost:80')
} catch { }
ws.onopen = () => {
//document.getElementById('selects').children[0].select = true;
getTableInterface(document.getElementById('selects'));
console.log('ws opened on browser')
//ws.send('hello world')
}
ws.onclose = () => {
location.reload()
};
ws.onmessage = (message) => {
let data = JSON.parse(message.data).data;
callbacks[data[0].toString()](data[1]);
//console.log(`message received ${message}`)
}
}
wss.on('connection', (ws) => {
wsocket = ws;
ws.on('message', async (message) => {
let data = JSON.parse(message);
if (data?.type == "getTable") {
send([data.querry[0], await getTable(data.querry[1])]);
}
else if (data?.type == "create") {
pool.query(data.querry)
}
else if (data?.type == "update") {
pool.query(data.querry)
}
else if (data?.type == "delete") {
let qe = `
SET FOREIGN_KEY_CHECKS=0;
` + data.querry + `
SET FOREIGN_KEY_CHECKS=1;
`;
pool.query(data.querry)
}
});
});
//#region HTML CRUD Interface
function create(th) {
let newValues = Array.from(th.parentElement.children).slice(0, -1).map(a => "'" + a.children[0].value + "'");
ws.send(JSON.stringify({
"type": "create",
"querry": "INSERT INTO " + th.parentElement.parentElement.parentElement.getAttribute("name") + " VALUES (DEFAULT, " + newValues.slice(1, newValues.length).join(", ") + ")"
}));
setTimeout(() => {
getTableInterface(document.getElementById("selects"))
}, 100);
}
function change(th) {
let textarea = true;
let a = Array.from(th.parentElement.children);
a.slice(0, -2).forEach(element => {
if (textarea)
element.innerHTML = `<textarea type="text" style="width: 100%;">` + element.outerText + `</textarea>`;
else
element.innerHTML = `<input type="text" value="` + element.outerText + `" style="width: 100%;"></input>`;
})
a[a.length - 2].onclick = function () { update(this) };
a[a.length - 2].innerHTML = `
<td onclick=update(this)>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-return-left" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M14.5 1.5a.5.5 0 0 1 .5.5v4.8a2.5 2.5 0 0 1-2.5 2.5H2.707l3.347 3.346a.5.5 0 0 1-.708.708l-4.2-4.2a.5.5 0 0 1 0-.708l4-4a.5.5 0 1 1 .708.708L2.707 8.3H12.5A1.5 1.5 0 0 0 14 6.8V2a.5.5 0 0 1 .5-.5"/>
</svg>
</td>
`;
}
function update(th) {
let a = Array.from(th.parentElement.children);
let querry = `UPDATE ` + th.parentElement.parentElement.parentElement.getAttribute("name") + " SET ";
let types = Array.from(th.parentElement.parentElement.children[0].children).map(a => a.getAttribute("type"));
let at = Array.from(th.parentElement.parentElement.children[0].children).map(a => a.outerText);
a.slice(1, -2).forEach((element, index) => {
querry += at[index + 1] + " = ";
if (types[index + 1] == "number")
querry += element.children[0].value + ",";
else
querry += "'" + element.children[0].value + "',";
})
querry = querry.slice(0, -1);
querry += " WHERE " + at[0] + "=" + a[0].children[0].value;
ws.send(JSON.stringify({
"type": "update",
"querry": querry
}));
a.slice(0, -2).forEach(element => {
element.innerHTML = element.children[0].value
})
a[a.length - 2].onclick = function () { change(this) };
a[a.length - 2].innerHTML = `
<td onclick=change(this)>
<svg width="10" height="10" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2z"/>
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466"/>
</svg>
</td> `;
}
function remove(th) {
let a = Array.from(th.parentElement.children);
let at = Array.from(th.parentElement.parentElement.children[0].children).map(a => a.outerText);
ws.send(JSON.stringify({
"type": "delete",
"querry": "DELETE FROM " + th.parentElement.parentElement.parentElement.getAttribute("name") + " Cascade WHERE " + at[0] + "=" + + a[0].outerText
}));
th.parentElement.remove();
}
async function getTableInterface(th) {
let newFilter = th.id == "selects";
var g = document.getElementById("filter");
if (newFilter == false && g != null) {
let types = Array.from(document.getElementById("table").children[0].children[0].children).map(a => a.getAttribute("type"));
let at = Array.from(document.getElementById("table").children[0].children[0].children).map(a => a.outerText);;
g = Array.from(g.children[0].children[0].children)
.map((a, index) => [at[index], (types[index] == "number" && a.children[0].value != "" && a.children[0].value[0] != "<" && a.children[0].value[0] != ">" ? Number(a.children[0].value) : a.children[0].value)]);
}
else {
g = null
}
let table = [await sendInterface("getTable", [document.querySelector("#selects")[document.querySelector("#selects").selectedIndex].value, g])];
//let tables = await createTables();
if (table[0] == null) {
return;
}
table = table.map(t => createTableFromJSON(t, newFilter));
let d = document.getElementById("table")
if (newFilter) d = document.body.children[1];
if (table[0].length < 50) {
while (d.children[0].childNodes.length > 1) {
d.children[0].removeChild(d.children[0].lastChild);
}
} else {
d.innerHTML = table;
}
document.body.children[1].id = "";
}
//#endregion
//#region html Table Interfaces
function createTableFromJSON(jsonData, newFilter = false) {
let name = jsonData[jsonData.length - 1];
delete jsonData[jsonData.length - 1];
let text = "";
if (newFilter || document.getElementById("filter") == null) {
text = "<table id='filter'>";
Object.values(jsonData).forEach((row, index) => {
if (index == 0) {
text += "<tr>";
Object.keys(row).forEach((t, index) => {
text += "<td>" + `<textarea onkeyup =getTableInterface(this) type="text" style="width: 100%;">` + "" + `</textarea>` + "</td>";
});
text += "<td>" + `<textarea onkeyup =getTableInterface(this) type="text" style="width: 100%;">` + "" + `</textarea>` + "</td>";
text += "<td>" + `<textarea onkeyup =getTableInterface(this) type="text" style="width: 100%;">` + "" + `</textarea>` + "</td>";
text += "</tr>";
}
});
text += "</table> ";
}
text += "<table id='table' border='1' name='" + name + "'>";
Object.values(jsonData).forEach((row, index) => {
if (index == 0) {
text += "<tr>";
let v = Object.values(row);
Object.keys(row).forEach((t, index) => {
text += "<td type=" + (typeof v[index]).toString() + ">" + t + "</td>";
});
text += "</tr>";
}
text += "<tr>";
Object.values(row).forEach(t => {
if (t instanceof Date) t = t.toLocaleString('ru-RU')
text += "<td>" + (t == null ? "" : t.toString()) + "</td>";
});
text += `
<td onclick=change(this)>
<svg width="10" height="10" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-counterclockwise" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2z"/>
<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466"/>
</svg>
</td>
<td onclick=remove(this)>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-x" viewBox="0 0 16 16">
<path d="M6.146 6.146a.5.5 0 0 1 .708 0L8 7.293l1.146-1.147a.5.5 0 1 1 .708.708L8.707 8l1.147 1.146a.5.5 0 0 1-.708.708L8 8.707 6.854 9.854a.5.5 0 0 1-.708-.708L7.293 8 6.146 6.854a.5.5 0 0 1 0-.708"/>
<path d="M4 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 1h8a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1"/>
</svg>
</td>
</tr>`;
if (index == Object.values(jsonData).length - 1) {
Object.values(row).forEach(t => {
if (t instanceof Date) t = t.toLocaleString('ru-RU')
text += "<td>" + `<textarea type="text" style="width: 100%;">` + (t == null ? "" : t.toString()) + `</textarea>` + "</td>";
});
text += "<td onclick=create(this)>" + `Create` + "</td>";
}
//text += " </tr>";
});
return text;
};
let functionsToImport = [
createTableFromJSON,
create, change, update, remove, getTableInterface,
wsInterface, sendInterface,
"var ws; var id = 0, callbacks = []; wsInterface(); let w; ",
];
var once = true;
app.get('/', async function (request, response) {
if (once) {
once = false;
let tables = await createTables();
}
let ts = await getTables();
ts = ts.map(t => {
return "<option value=" + t.table_name + ">" + t.table_name + "</option>"
var option = document.createElement("option");
option.value = t.table_name;
option.text = t.table_name;
return option.toString();
})
let qw = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
font-size: 14px;
}
table {
width: 100%;
table-layout: fixed;
border-collapse: collapse;
margin: 20px;
}
th, td {
padding-right: 7px;
padding-left: 7px;
}
td {
overflow: hidden;
}
</style>
</head>
<body>
<select id="selects" onchange=getTableInterface(this) name="Таблица">
`+ ts.join(" ") + `
</select>
<div id="table"></div>`
+ " <script> " + (functionsToImport.map(a => a.toString())).join(" ") +
" </script> " + `
</body>
</html>
`;
response.writeHeader(200, { 'Content-Type': 'html' });
response.write(qw);
response.end();
})
let wsocket;
function send(data) {
wsocket.send(JSON.stringify({
data: data
}));
}
function sendInterface(s, data) {
return new Promise(resolve => {
ws.send(JSON.stringify({
"type": s,
"querry": [id, data]
}));
callbacks[id] = resolve;
id++
})
}
//#endregion