From 5f9f32db71e97da1915866dcc7df50582bce38a8 Mon Sep 17 00:00:00 2001 From: Jed Foster Date: Fri, 19 Jun 2020 15:32:24 -0700 Subject: [PATCH 1/2] fix(server): add ts-node to dev dependencies The `start` script relies on ts-node, but it was not present in devDependencies. --- packages/server/package-lock.json | 71 +++++++++++++++++++++---------- packages/server/package.json | 1 + 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/packages/server/package-lock.json b/packages/server/package-lock.json index da873e0a..f0b25cea 100644 --- a/packages/server/package-lock.json +++ b/packages/server/package-lock.json @@ -1524,6 +1524,12 @@ "picomatch": "^2.0.4" } }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -3145,9 +3151,9 @@ "dev": true }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -3182,9 +3188,9 @@ } }, "inquirer": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", - "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.2.0.tgz", + "integrity": "sha512-E0c4rPwr9ByePfNlTIB8z51kK1s2n6jrHuJeEHENl/sbq2G/S1auvibgEwNR4uSyiU+PiYHqSwsgGiXjG8p5ZQ==", "dev": true, "requires": { "ansi-escapes": "^4.2.1", @@ -3350,9 +3356,9 @@ } }, "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", "dev": true, "requires": { "esrecurse": "^4.1.0", @@ -3360,29 +3366,29 @@ } }, "eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" } }, "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true }, "espree": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.0.0.tgz", - "integrity": "sha512-/r2XEx5Mw4pgKdyb7GNLQNsu++asx/dltf/CI8RFi9oGHxmQFgvLbc5Op4U6i8Oaj+kdslhJtVlEZeAqH5qOTw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz", + "integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==", "dev": true, "requires": { - "acorn": "^7.1.1", + "acorn": "^7.2.0", "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" + "eslint-visitor-keys": "^1.2.0" } }, "esprima": { @@ -4198,9 +4204,9 @@ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" }, "graphql": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.0.0.tgz", - "integrity": "sha512-ZyVO1xIF9F+4cxfkdhOJINM+51B06Friuv4M66W7HzUOeFd+vNzUn4vtswYINPi6sysjf1M2Ri/rwZALqgwbaQ==" + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.1.0.tgz", + "integrity": "sha512-0TVyfOlCGhv/DBczQkJmwXOK6fjWkjzY3Pt7wY8i0gcYXq8aogG3weCsg48m72lywKSeOqedEHvVPOvZvSD51Q==" }, "growly": { "version": "1.3.0", @@ -9890,6 +9896,19 @@ } } }, + "ts-node": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", + "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + } + }, "tslib": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", @@ -10487,6 +10506,12 @@ "decamelize": "^1.2.0" } }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + }, "z-schema": { "version": "3.25.1", "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.25.1.tgz", diff --git a/packages/server/package.json b/packages/server/package.json index d33477bc..0e353fb5 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -79,6 +79,7 @@ "nodemon": "2.0.4", "ts-jest": "26.1.0", "ts-loader": "7.0.5", + "ts-node": "^8.10.2", "typescript": "3.9.3" }, "config": { From 9d0de45e8def5528663e1ba4d02d701be3c3cf37 Mon Sep 17 00:00:00 2001 From: Jed Foster Date: Fri, 19 Jun 2020 15:34:04 -0700 Subject: [PATCH 2/2] feat(server): expose api base path in app.config --- packages/cli/src/commands/create-stack.ts | 9 ++++++++- packages/cli/src/commands/run.ts | 11 +++++++++-- packages/cli/src/commands/update-stack.ts | 7 +++++++ packages/server/src/app/app.config.ts | 1 + packages/server/src/app/core.app.ts | 2 +- packages/server/src/factory.ts | 1 + .../server/src/specifications/swagger/swagger.ts | 6 +++++- .../server/src/specifications/swagger/swaggerspec.ts | 12 ++++++++---- packages/server/tests/handler.spec.ts | 1 + packages/template/src/handler.ts | 1 + 10 files changed, 42 insertions(+), 9 deletions(-) diff --git a/packages/cli/src/commands/create-stack.ts b/packages/cli/src/commands/create-stack.ts index ca6e7655..f7ff2e29 100644 --- a/packages/cli/src/commands/create-stack.ts +++ b/packages/cli/src/commands/create-stack.ts @@ -74,6 +74,12 @@ export class CreateStackCommand extends Command { options: ['info', 'debug'], // default value if flag not passed (can be a function that returns a string or undefined) required: false, // make flag required (this is not common and you should probably use an argument instead) }), + apiRoute: flags.string({ + description: 'path to use for api route', // help description for flag + hidden: false, // hide from help + default: '/api', + required: false, // make flag required (this is not common and you should probably use an argument instead) + }), }; static args = [ @@ -195,7 +201,8 @@ export class CreateStackCommand extends Command { appconfig.readOnly = flags.readonly; appconfig.enableSwagger = flags.swagger; appconfig.stackName = stackName!; - appconfig.logLevel = flags.loglevel as LogLevel;; + appconfig.logLevel = flags.loglevel as LogLevel; + appconfig.apiRoutePath = flags.apiRoute; Helpers.createDir(stackFolder + '/config'); fs.writeFileSync( path.normalize(stackFolder + '/config/appconfig.json'), diff --git a/packages/cli/src/commands/run.ts b/packages/cli/src/commands/run.ts index 8af7f930..c61d234f 100644 --- a/packages/cli/src/commands/run.ts +++ b/packages/cli/src/commands/run.ts @@ -41,6 +41,12 @@ export class Run extends Command { options: ['info', 'debug'], // default value if flag not passed (can be a function that returns a string or undefined) required: false, // make flag required (this is not common and you should probably use an argument instead) }), + apiRoute: flags.string({ + description: 'path to use for api route', // help description for flag + hidden: false, // hide from help + default: '/api', + required: false, // make flag required (this is not common and you should probably use an argument instead) + }), }; static args = [ @@ -62,6 +68,7 @@ export class Run extends Command { defaultConfig.readOnly = flags.readonly; defaultConfig.enableSwagger = flags.swagger; defaultConfig.logLevel = flags.loglevel as LogLevel; + defaultConfig.apiRoutePath = flags.apiRoute; defaultConfig.jsonFile = args.file; if (args.file && flags.env) { const promise = startServer( @@ -91,7 +98,7 @@ export class Run extends Command { }, { text: `${chalk.blueBright('API Routes')}`, - link: 'http://localhost:3000/api/{routes}', + link: 'http://localhost:3000' + flags.apiRoute + '/{routes}', }, ], { text: { minWidth: 30 }, link: { minWidth: 20 } }, @@ -102,7 +109,7 @@ export class Run extends Command { [ { text: `${chalk.blueBright('API Routes')}`, - link: 'http://localhost:3000/api/{routes}', + link: 'http://localhost:3000' + flags.apiRoute + '/{routes}', }, ], { text: { minWidth: 30 }, link: { minWidth: 20 } }, diff --git a/packages/cli/src/commands/update-stack.ts b/packages/cli/src/commands/update-stack.ts index 9b57a595..a6ad4f21 100644 --- a/packages/cli/src/commands/update-stack.ts +++ b/packages/cli/src/commands/update-stack.ts @@ -52,6 +52,12 @@ export class UpdateStackCommand extends Command { options: ['info', 'debug'], // default value if flag not passed (can be a function that returns a string or undefined) required: false, // make flag required (this is not common and you should probably use an argument instead) }), + apiRoute: flags.string({ + description: 'path to use for api route', // help description for flag + hidden: false, // hide from help + default: '/api', + required: false, // make flag required (this is not common and you should probably use an argument instead) + }), }; async run() { @@ -132,6 +138,7 @@ export class UpdateStackCommand extends Command { appConfig.readOnly = flags.readonly; appConfig.enableSwagger = flags.swagger; appConfig.logLevel = flags.loglevel as LogLevel; + appConfig.apiRoutePath = flags.apiRoute; fs.writeFileSync( path.normalize(stackFolder + '/config/appconfig.json'), JSON.stringify(appConfig, null, 2), diff --git a/packages/server/src/app/app.config.ts b/packages/server/src/app/app.config.ts index ddeecd50..52206bc4 100644 --- a/packages/server/src/app/app.config.ts +++ b/packages/server/src/app/app.config.ts @@ -6,6 +6,7 @@ export class AppConfig { enableSwagger = true; logLevel = LogLevel.info; stackName = 'jsonsls'; + apiRoutePath = '/api'; static merge = (t: T, u: U) => Object.assign({}, t, u); } diff --git a/packages/server/src/app/core.app.ts b/packages/server/src/app/core.app.ts index 4a7121f3..7f7df568 100644 --- a/packages/server/src/app/core.app.ts +++ b/packages/server/src/app/core.app.ts @@ -101,7 +101,7 @@ export class CoreApp { 1 ); this.server.use(middlewares); - this.server.use('/api', router); + this.server.use(appConfig.apiRoutePath, router); if (!this.swaggerSpec && appConfig.enableSwagger) { this.swaggerSpec = this.apispec.generateSpecification(db, true); const swaggerSetupMiddleware = swaggerUi.setup(this.swaggerSpec); diff --git a/packages/server/src/factory.ts b/packages/server/src/factory.ts index 1d00bd84..a4dd7629 100644 --- a/packages/server/src/factory.ts +++ b/packages/server/src/factory.ts @@ -84,6 +84,7 @@ export class ServerFactory { server, new SwaggerConfig(appConfig.readOnly, appConfig.enableApiKeyAuth), env.basePath, + appConfig.apiRoutePath, packageJsonFilePath ); const core = new coreserver( diff --git a/packages/server/src/specifications/swagger/swagger.ts b/packages/server/src/specifications/swagger/swagger.ts index b148e2d2..607f8fc0 100644 --- a/packages/server/src/specifications/swagger/swagger.ts +++ b/packages/server/src/specifications/swagger/swagger.ts @@ -12,15 +12,18 @@ export class Swagger implements ApiSpecification { private server: express.Express; private config: SwaggerConfig; private basePath: string; + private apiRoutePath: string; constructor( server: express.Express, config: SwaggerConfig, basePath: string, + apiRoutePath: string, packageJsonFilePath: string ) { this.server = server; this.config = config; this.basePath = basePath; + this.apiRoutePath = apiRoutePath; this.swaggerSpec = new SwaggerSpec(packageJsonFilePath); } @@ -33,7 +36,8 @@ export class Swagger implements ApiSpecification { this.server, {}, this.config.readOnly, - this.basePath + this.basePath, + this.apiRoutePath ); const auth: ApiKeySecurity = { type: 'apiKey', diff --git a/packages/server/src/specifications/swagger/swaggerspec.ts b/packages/server/src/specifications/swagger/swaggerspec.ts index 8dd9b27a..c5b1d486 100644 --- a/packages/server/src/specifications/swagger/swaggerspec.ts +++ b/packages/server/src/specifications/swagger/swaggerspec.ts @@ -71,7 +71,7 @@ export class SwaggerSpec { return sorted; } - initSpec(readOnly: boolean, basePath: string) { + initSpec(readOnly: boolean, basePath: string, routePath: string) { const info = this.updateSpecFromPackage(basePath); let specification: Spec = { swagger: '2.0', @@ -80,7 +80,10 @@ export class SwaggerSpec { }; specification.swagger = '2.0'; specification.paths = {}; - const excludedRoutes = ['/api/:resource/:id/:nested', '/api/db']; + const excludedRoutes = [ + routePath + '/:resource/:id/:nested', + routePath + '/db', + ]; const endpoints = listEndpoints(this.app); endpoints.forEach((endpoint: EndPoint) => { if (readOnly) { @@ -134,11 +137,12 @@ export class SwaggerSpec { app: express.Express, predefinedSpec: object, readOnly: boolean, - basePath: string + basePath: string, + apiRoutePath: string ) => { this.app = app; this.predefinedSpec = predefinedSpec; - this.spec = this.initSpec(readOnly, basePath); + this.spec = this.initSpec(readOnly, basePath, apiRoutePath); return this.spec; }; diff --git a/packages/server/tests/handler.spec.ts b/packages/server/tests/handler.spec.ts index 746f915a..7a95e9e6 100644 --- a/packages/server/tests/handler.spec.ts +++ b/packages/server/tests/handler.spec.ts @@ -16,6 +16,7 @@ const swagger = new Swagger( server, new SwaggerConfig(appConfig.readOnly, appConfig.enableApiKeyAuth), environment.basePath, + appConfig.apiRoutePath, 'package.json' ); const localServer = new TestServer( diff --git a/packages/template/src/handler.ts b/packages/template/src/handler.ts index c983ab0a..737ac82e 100644 --- a/packages/template/src/handler.ts +++ b/packages/template/src/handler.ts @@ -23,6 +23,7 @@ const swagger = new Swagger( server, new SwaggerConfig(appConfig.readOnly, appConfig.enableApiKeyAuth), environment.basePath, + appConfig.apiRoutePath, './package.json' );