diff --git a/packages/scripts/src/scripts/syncEsmConfig.ts b/packages/scripts/src/scripts/syncEsmConfig.ts index eb2c5e1..650cc43 100644 --- a/packages/scripts/src/scripts/syncEsmConfig.ts +++ b/packages/scripts/src/scripts/syncEsmConfig.ts @@ -21,7 +21,7 @@ export async function syncEsmConfig(...argv: string[]) { const pkgDir = args.packages getFolders(pkgDir) - .map(file => path.join(pkgDir, file, TSCONFIG_FILENAME)) + .map(folder => path.join(folder, TSCONFIG_FILENAME)) .filter(file => fs.existsSync(file)) .forEach(file => { const tsconfig = JSON.parse(fs.readFileSync(file, 'utf8')) diff --git a/packages/server/src/application/CLIBootstrap.ts b/packages/server/src/application/ServerBootstrap.ts similarity index 80% rename from packages/server/src/application/CLIBootstrap.ts rename to packages/server/src/application/ServerBootstrap.ts index 3a71362..efab0cf 100644 --- a/packages/server/src/application/CLIBootstrap.ts +++ b/packages/server/src/application/ServerBootstrap.ts @@ -10,7 +10,7 @@ import { Config } from './Config' import { ServerConfigurator } from './configureServer' import { createServer } from './createServer' -export interface CLIBootstrapParams { +export interface ServerBootstrapParams { readonly config: Config readonly configureServer: ServerConfigurator readonly namespace?: Namespace @@ -26,7 +26,7 @@ function getFunctions(obj: object): Function[] { .filter(f => typeof f === 'function') } -export class CLIBootstrap implements Bootstrap { +export class ServerBootstrap implements Bootstrap { protected config: Config protected configureServer: ServerConfigurator protected namespace: Namespace @@ -37,7 +37,7 @@ export class CLIBootstrap implements Bootstrap { readonly application: Application readonly database: Database - constructor(params: CLIBootstrapParams) { + constructor(params: ServerBootstrapParams) { this.config = { ...params.config, app: { @@ -76,22 +76,6 @@ export class CLIBootstrap implements Bootstrap { return createServer(configureServer(this.getConfig(), database)) } - async exec(command = 'listen') { - switch (command) { - case 'listen': - await this.listen() - return - case 'migrate': - await this.migrate() - return - case 'migrate-undo': - await this.migrateUndo() - return - default: - throw new Error('Unknown command: ' + command) - } - } - async listen( port: number | string | undefined = process.env.PORT || 3000, hostname: string | undefined= process.env.BIND_HOST, @@ -106,18 +90,6 @@ export class CLIBootstrap implements Bootstrap { } } - async migrate() { - const connection = await this.database.connect() - await connection.runMigrations() - await connection.close() - } - - async migrateUndo() { - const connection = await this.database.connect() - await connection.undoLastMigration() - await connection.close() - } - protected async start( port: number | string | undefined = process.env.PORT, hostname?: string, @@ -140,11 +112,12 @@ export class CLIBootstrap implements Bootstrap { }) const apiLogger = loggerFactory.getLogger('api') + const address = this.getAddress() - if (hostname) { - apiLogger.info('Listening on %s %s', port, hostname) + if (typeof address === 'string') { + apiLogger.info('Listening on %s', address) } else { - apiLogger.info('Listening on %s', port) + apiLogger.info('Listening on %s %s', address.address, address.port) } } @@ -157,7 +130,7 @@ export class CLIBootstrap implements Bootstrap { } async close(): Promise { - return new Promise((resolve, reject) => { + await new Promise((resolve, reject) => { this.server!.close(err => { if (!err) { return resolve() diff --git a/packages/server/src/application/index.ts b/packages/server/src/application/index.ts index 5f41e0f..aea6a4f 100644 --- a/packages/server/src/application/index.ts +++ b/packages/server/src/application/index.ts @@ -1,4 +1,4 @@ -export * from './CLIBootstrap' +export * from './ServerBootstrap' export * from './Bootstrap' export * from './Application' export * from './Config' diff --git a/packages/server/src/application/processArgs.ts b/packages/server/src/application/processArgs.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/server/src/bootstrap.ts b/packages/server/src/bootstrap.ts index ed111cb..06f1b40 100644 --- a/packages/server/src/bootstrap.ts +++ b/packages/server/src/bootstrap.ts @@ -1,8 +1,12 @@ -import { CLIBootstrap } from './application' +import { ServerBootstrap } from './application' import { configureServer } from './application/configureServer' import { config } from './config' +import * as entities from './entities' +import * as migrations from './migrations' -export default new CLIBootstrap({ +export default new ServerBootstrap({ config, + entities, + migrations, configureServer, }) diff --git a/packages/server/src/cli/CLI.ts b/packages/server/src/cli/CLI.ts new file mode 100644 index 0000000..34ca154 --- /dev/null +++ b/packages/server/src/cli/CLI.ts @@ -0,0 +1,72 @@ +import { Bootstrap } from "../application"; +import { argparse, arg } from "@rondo.dev/argparse"; + +export class CLI { + constructor(readonly bootstrap: Bootstrap) { + } + + execute(argv: string[]) { + const choices: Array = ['start', 'migrate'] + const {parse} = argparse({ + command: arg('string', { + default: 'start', + choices, + positional: true, + description: 'Command to run', + }), + args: arg('string[]', { + n: '*', + positional: true, + description: 'Command arguments', + }), + help: arg('boolean', {alias: 'h'}), + }) + const args = parse(argv) + const command = args.command as keyof typeof commands + commands[command](this.bootstrap, [args.command, ...args.args]) + } + +} + +const commands = { + async start(bootstrap: Bootstrap, argv: string[]) { + const {parse} = argparse({ + host: arg('string', { + description: '', + }), + socket: arg('number', { + alias: 's', + description: 'Socket to listen on', + }), + port: arg('number', { + alias: 'p', + description: 'Port to listen on', + }), + help: arg('boolean', {alias: 'h'}), + }) + const args = parse(argv) + await bootstrap.listen(args.port || args.socket, args.host) + }, + async migrate(bootstrap: Bootstrap, argv: string[]) { + const {parse} = argparse({ + undo: arg('boolean', { + alias: 'u', + description: 'Undo last migration', + }), + help: arg('boolean', {alias: 'h'}), + }) + + const args = parse(argv) + + const {database} = bootstrap + const connection = await database.connect() + try { + await (args.undo + ? connection.undoLastMigration() + : connection.runMigrations()) + } finally { + await connection.close() + } + }, + +} diff --git a/packages/server/src/cli/index.ts b/packages/server/src/cli/index.ts new file mode 100644 index 0000000..8abad35 --- /dev/null +++ b/packages/server/src/cli/index.ts @@ -0,0 +1 @@ +export * from './CLI' diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 171e65c..ac228bb 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -4,6 +4,7 @@ if (require.main === module) { } } export * from './application' +export * from './cli' export * from './database' export * from './entities' export * from './error' @@ -18,7 +19,8 @@ import * as rpc from './rpc' export {rpc} import bootstrap from './bootstrap' +import { CLI } from './cli' if (require.main === module) { - bootstrap.exec(process.argv[2]) + new CLI(bootstrap).execute(process.argv.slice(1)) } diff --git a/packages/server/src/migrations/index.ts b/packages/server/src/migrations/index.ts new file mode 100644 index 0000000..9cee5a0 --- /dev/null +++ b/packages/server/src/migrations/index.ts @@ -0,0 +1,11 @@ +// This file has been autogenerated by exportDir script +export * from './1547031984999-user' +export * from './1547474320589-session' +export * from './1547480973242-sessionUserId' +export * from './1548148128477-comments' +export * from './1548155222136-unique-votes' +export * from './1548347305012-indices' +export * from './1548412884820-role-unique' +export * from './1552227347990-comment-parentid-nullable' +export * from './1552227652042-nullable' +export * from './1552899385211-user-first-last-name' diff --git a/packages/server/src/test.ts b/packages/server/src/test.ts index 9085ad4..e831263 100644 --- a/packages/server/src/test.ts +++ b/packages/server/src/test.ts @@ -1,13 +1,13 @@ import { APIDef } from '@rondo.dev/common' import { createNamespace } from 'cls-hooked' -import { CLIBootstrap } from './application' +import { ServerBootstrap } from './application' import { configureServer } from './application/configureServer' import { config } from './config' import { TestUtils } from './test-utils' export const exit = jest.fn() -export const bootstrap = new CLIBootstrap({ +export const bootstrap = new ServerBootstrap({ config, configureServer, namespace: createNamespace('test'), diff --git a/packages/server/tsconfig.esm.json b/packages/server/tsconfig.esm.json index 80c3152..01405c2 100644 --- a/packages/server/tsconfig.esm.json +++ b/packages/server/tsconfig.esm.json @@ -7,6 +7,9 @@ { "path": "../common/tsconfig.esm.json" }, + { + "path": "../argparse/tsconfig.esm.json" + }, { "path": "../client/tsconfig.esm.json" }, @@ -32,4 +35,4 @@ "path": "../validator/tsconfig.esm.json" } ] -} +} \ No newline at end of file diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json index 003b2ff..be10daf 100644 --- a/packages/server/tsconfig.json +++ b/packages/server/tsconfig.json @@ -6,6 +6,7 @@ }, "references": [ {"path": "../common"}, + {"path": "../argparse"}, {"path": "../client"}, {"path": "../jsonrpc"}, {"path": "../logger"},