🚀 Add TypeScript code

This commit is contained in:
C-3PO 2018-11-09 00:52:03 +01:00
parent 59f6ae0f11
commit 89faa530ec
Signed by: c3po
GPG key ID: 62993C4BB4D86F24
17 changed files with 368 additions and 8 deletions

View file

@ -7,3 +7,6 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
[*.php]
indent_size = 4

2
.gitignore vendored
View file

@ -1,3 +1,5 @@
.vscode
!.vscode/settings.json
dist
node_modules
dbSettings.js

View file

@ -1,6 +1,19 @@
# ssn-auto
A tool that regularly checks for new patches and will automatically download, install and process them. Designed to be deployed on the Jedipedia server and may be difficult to set up in other environments. If you want to build your own patching tool, start with the [ssn-tools](/swtor/ssn-tools) repository.
A tool that regularly checks for new patches and will automatically download, install and process them. Designed to be deployed on the Jedipedia server and not supported to be set up in other environments, so we offer limited support. If you want to build your own patching tool, start with the [ssn-tools](/swtor/ssn-tools) repository.
## Installation
After downloading this repository, create a file called `dbSettings.js` with the following contents, putting in the database settings as required:
```js
module.exports = {
host: 'localhost',
user: 'INSERT_USER_NAME',
password: 'INSERT_PASSWORD',
database: 'INSERT_DATABASE_NAME',
};
```
## License

4
dbSettings.d.ts vendored Normal file
View file

@ -0,0 +1,4 @@
export const host: string;
export const user: string;
export const password: string;
export const database: string;

117
package-lock.json generated
View file

@ -1,4 +1,119 @@
{
"name": "ssn-auto",
"lockfileVersion": 1
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"@types/mysql": {
"version": "2.15.5",
"resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.5.tgz",
"integrity": "sha512-4QAISTUGZbcFh7bqdndo08xRdES5OTU+JODy8VCZbe1yiXyGjqw1H83G43XjQ3IbC10wn9xlGd44A5RXJwNh0Q==",
"requires": {
"@types/node": "*"
}
},
"@types/node": {
"version": "10.12.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.2.tgz",
"integrity": "sha512-53ElVDSnZeFUUFIYzI8WLQ25IhWzb6vbddNp8UHlXQyU0ET2RhV5zg0NfubzU7iNMh5bBXb0htCzfvrSVNgzaQ=="
},
"bignumber.js": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz",
"integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA=="
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
"mysql": {
"version": "2.16.0",
"resolved": "https://registry.npmjs.org/mysql/-/mysql-2.16.0.tgz",
"integrity": "sha512-dPbN2LHonQp7D5ja5DJXNbCLe/HRdu+f3v61aguzNRQIrmZLOeRoymBYyeThrR6ug+FqzDL95Gc9maqZUJS+Gw==",
"requires": {
"bignumber.js": "4.1.0",
"readable-stream": "2.3.6",
"safe-buffer": "5.1.2",
"sqlstring": "2.3.1"
}
},
"process-nextick-args": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
},
"readable-stream": {
"version": "2.3.6",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
},
"sqlstring": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
"integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A="
},
"ssn": {
"version": "git+https://git.jedipedia.net/swtor/ssn.git#5caa3a935d8a1dda040fbe2f7d63114213b01e81",
"from": "git+https://git.jedipedia.net/swtor/ssn.git",
"requires": {
"@types/node": "^10.12.2",
"ssn-installer": "git+https://git.jedipedia.net/swtor/ssn-installer.git#488e49b6b234caca0bfbc3f746fa16abdc002dea",
"xml-js": "^1.6.8"
}
},
"ssn-installer": {
"version": "git+https://git.jedipedia.net/swtor/ssn-installer.git#488e49b6b234caca0bfbc3f746fa16abdc002dea",
"from": "git+https://git.jedipedia.net/swtor/ssn-installer.git"
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.1.0"
}
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"xml-js": {
"version": "1.6.8",
"resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.8.tgz",
"integrity": "sha512-kUv/geyN80d+s1T68uBfjoz+PjNUjwwf5AWWRwKRqqQaGozpMVsFsKYnenPsxlbN/VL7f0ia8NfLLPCDwX+95Q==",
"requires": {
"sax": "^1.2.4"
}
}
}
}

View file

@ -6,9 +6,16 @@
"type": "git",
"url": "https://git.jedipedia.net/swtor/ssn-auto.git"
},
"main": "src/index.php",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"start": "rm -rf dist && tsc",
"test": "echo \"Error: no test specified\" && exit 1",
"update": "rm -rf node_modules package-lock.json && npm install"
},
"dependencies": {}
"dependencies": {
"@types/mysql": "^2.15.5",
"mysql": "^2.16.0",
"ssn": "git+https://git.jedipedia.net/swtor/ssn.git"
}
}

28
src/getConfig.ts Normal file
View file

@ -0,0 +1,28 @@
import { Product } from 'ssn';
import IProductData from './interfaces/IProductData';
const data: { [key in Product]: IProductData } = {
assets_swtor_main: { manifestVersion: 294, httpVersion: 294 },
assets_swtor_de_de: { manifestVersion: 297, httpVersion: 297 },
assets_swtor_en_us: { manifestVersion: 299, httpVersion: 299 },
assets_swtor_fr_fr: { manifestVersion: 299, httpVersion: 299 },
assets_swtor_test_main: { manifestVersion: 292, httpVersion: 292 },
assets_swtor_test_de_de: { manifestVersion: 295, httpVersion: 295 },
assets_swtor_test_en_us: { manifestVersion: 295, httpVersion: 295 },
assets_swtor_test_fr_fr: { manifestVersion: 295, httpVersion: 295 },
retailclient_swtor: { manifestVersion: 247, httpVersion: 247 },
retailclient_publictest: { manifestVersion: 269, httpVersion: 269 },
retailclient_betatest: { manifestVersion: 13, httpVersion: 13 },
retailclient_liveqatest: { manifestVersion: 203, httpVersion: 205 },
retailclient_liveeptest: { manifestVersion: 133, httpVersion: 199 },
retailclient_cstraining: { manifestVersion: 141, httpVersion: 141 },
retailclient_squadron157: { manifestVersion: 11, httpVersion: -1 },
eualas: { manifestVersion: 0, httpVersion: 0 },
patcher2014: { manifestVersion: 8, httpVersion: 7 },
patcher2017: { manifestVersion: 0, httpVersion: 0 },
movies_de_de: { manifestVersion: 5, httpVersion: 5 },
movies_en_us: { manifestVersion: 5, httpVersion: 5 },
movies_fr_fr: { manifestVersion: 5, httpVersion: 5 },
};
export default data;

View file

@ -1,3 +0,0 @@
<?php
echo 'Hello World!';

37
src/index.ts Normal file
View file

@ -0,0 +1,37 @@
import { getSolidpkg, Product } from 'ssn';
import products from './getConfig';
import IProductData from './interfaces/IProductData';
import * as model from './model/model';
import * as database from './model/database';
//create lock file to prevent conflicts?
const newPatches: any[] = [];
model.init().then(() => {
database.exit();
});
/*//for each product, check new versions
Object.entries(products).forEach(([product, { manifestVersion, httpVersion }]: [string, IProductData]) => {
const curVersion = 100;
//Check patch to next release
for (let i = curVersion; i < curVersion + 3; i += 1) {
getSolidpkg(product as Product, i, i + 1).then((result) => {
console.log(result);
newPatches.push({ product, version: i, result });
}).catch(() => {
//do nothing
});
}
//TODO
});*/
//parse results
//TODO: need to wait for all promises to be complete
//if new version was found, try to install it
//also check manifest in case a new version is available for installation. remember time when patch became available for installation but otherwise do nothing
//delete lock file

View file

@ -0,0 +1,6 @@
export default interface IProductData {
/** Latest release number of this product according to manifest. */
manifestVersion: number;
/** Latest release number of this product available from the patch server. */
httpVersion: number;
}

3
src/logger/writeLog.ts Normal file
View file

@ -0,0 +1,3 @@
export default function writeLog(message: string, severity: number = 0) {
console.warn(message);
}

View file

@ -0,0 +1,9 @@
//Generated by `SHOW CREATE TABLE ssn_versions`
const createStatement = `CREATE TABLE \`ssn_versions\` (
\`product\` tinytext COLLATE utf8mb4_unicode_520_ci NOT NULL,
\`manifest\` smallint(6) NOT NULL DEFAULT '-1',
\`http\` smallint(6) NOT NULL DEFAULT '-1',
PRIMARY KEY (\`product\`(25))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci`;
export default createStatement;

30
src/model/database.ts Normal file
View file

@ -0,0 +1,30 @@
import * as mysql from 'mysql';
import * as dbSettings from '../../dbSettings';
const connection = mysql.createConnection(dbSettings);
export function init() {
return new Promise((resolve, reject) => {
connection.connect(function(err) {
if (err) {
reject(err);
}
resolve();
});
});
}
export function query(command: string): Promise<{ results: any, fields?: mysql.FieldInfo[] }> {
return new Promise((resolve, reject) => {
connection.query(command, function(error, results, fields) {
if (error !== null) {
reject(error);
}
resolve({ results, fields });
});
});
}
export function exit(): void {
connection.end();
}

39
src/model/model.ts Normal file
View file

@ -0,0 +1,39 @@
import { Product } from 'ssn';
import * as database from './database';
import products from './products';
import writeLog from '../logger/writeLog';
import createStatement from './createStatement';
export async function init() {
await database.init();
//Only create table if it does not exist yet
const createIfNotExists = createStatement.replace(/^CREATE TABLE/, 'CREATE TABLE IF NOT EXISTS');
await database.query(createIfNotExists);
/**Products that are missing from the database and need to be inserted. */
const missingProducts: Product[] = [];
/** Products inside the database table that are not valid products. Will be printed to error log and ignored */
const erroneousProducts: Product[] = [];
const { results: existingRows } = await database.query('SELECT * FROM ssn_versions');
console.log(existingRows);
return;
existingRows.forEach((row: any) => {
//TODO: match with products
});
//If row does not exist, INSERT into table
await Promise.all(missingProducts.map((product) => {
return database.query(`INSERT INTO ssn_versions ${product}`);
}));
//If row exists that is not in products, ignore it and output error
erroneousProducts.forEach((product) => {
writeLog(`Product ${product} in database table is invalid.`);
});
//TODO: insert products
}

27
src/model/products.ts Normal file
View file

@ -0,0 +1,27 @@
import { Product } from 'ssn';
const productList: Product[] = [
'assets_swtor_de_de',
'assets_swtor_en_us',
'assets_swtor_fr_fr',
'assets_swtor_main',
'assets_swtor_test_de_de',
'assets_swtor_test_en_us',
'assets_swtor_test_fr_fr',
'assets_swtor_test_main',
'eualas',
'movies_de_de',
'movies_en_us',
'movies_fr_fr',
'patcher2014',
'patcher2017',
'retailclient_betatest',
'retailclient_cstraining',
'retailclient_liveeptest',
'retailclient_liveqatest',
'retailclient_publictest',
'retailclient_squadron157',
'retailclient_swtor',
];
export default productList;

18
src/tslint.json Normal file
View file

@ -0,0 +1,18 @@
{
"defaultSeverity": "error",
"extends": [
"tslint:recommended",
],
"jsRules": {},
"rules": {
"comment-format": false,
"indent": [true, "spaces", 2],
"max-line-length": false,
"no-bitwise": false,
"no-console": false,
"no-invalid-this": [true, "check-function-in-method"],
"object-literal-sort-keys": [true, "match-declaration-order"],
"quotemark": [true, "single"],
},
"rulesDirectory": [],
}

22
tsconfig.json Normal file
View file

@ -0,0 +1,22 @@
{
"compilerOptions": {
"baseUrl": ".",
"declaration": true,
"inlineSourceMap": true,
"inlineSources": true,
"module": "commonjs",
"moduleResolution": "node",
"newLine": "lf",
"outDir": "dist",
"paths": {
"*": [
"node_modules/*"
]
},
"strict": true,
"target": "es2018",
},
"include": [
"src/**/*"
]
}