diff --git a/package-lock.json b/package-lock.json index 7969aef..a4b34c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,11 +8,15 @@ "name": "@cloudquery/plugin-sdk-javascript", "version": "0.0.2", "license": "MPL-2.0", + "dependencies": { + "@cloudquery/plugin-pb-javascript": "^0.0.5", + "yargs": "^17.7.2" + }, "devDependencies": { "@ava/typescript": "^4.1.0", - "@cloudquery/plugin-pb-js": "^0.0.4", "@grpc/grpc-js": "^1.9.0", "@tsconfig/node16": "^16.1.0", + "@types/yargs": "^17.0.24", "@typescript-eslint/eslint-plugin": "^6.2.1", "@typescript-eslint/parser": "^6.2.1", "ava": "^5.3.1", @@ -49,11 +53,10 @@ "node": "^14.19 || ^16.15 || ^18 || ^20" } }, - "node_modules/@cloudquery/plugin-pb-js": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/@cloudquery/plugin-pb-js/-/plugin-pb-js-0.0.4.tgz", - "integrity": "sha512-5IKaHpR6JIPRNr44WaCiwowBHNEj3B5SQUFHJ43JMmKQG2uOU7uZDX+8brclT5P191SdYlgYeVjFv7h6fdfxlQ==", - "dev": true, + "node_modules/@cloudquery/plugin-pb-javascript": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@cloudquery/plugin-pb-javascript/-/plugin-pb-javascript-0.0.5.tgz", + "integrity": "sha512-Vw+3zKYcdKxQuL/J4dVUhpFAWQ5OUyRW0Qgior8vYfzmjXGrnXYaskzxc4Y5TtkjJ4376+r2MV7poP2pvKpc7w==", "dependencies": { "google-protobuf": "^3.21.2" }, @@ -404,6 +407,21 @@ "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", "dev": true }, + "node_modules/@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.1.tgz", @@ -689,7 +707,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -698,7 +715,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -1143,7 +1159,6 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -1169,7 +1184,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -1180,8 +1194,7 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/common-path-prefix": { "version": "3.0.0", @@ -1396,14 +1409,12 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, "engines": { "node": ">=6" } @@ -1932,7 +1943,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -2030,8 +2040,7 @@ "node_modules/google-protobuf": { "version": "3.21.2", "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.2.tgz", - "integrity": "sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==", - "dev": true + "integrity": "sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==" }, "node_modules/graphemer": { "version": "1.4.0", @@ -2192,7 +2201,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -2987,7 +2995,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3317,7 +3324,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -3331,7 +3337,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -3637,7 +3642,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -3673,7 +3677,6 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, "engines": { "node": ">=10" } @@ -3688,7 +3691,6 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -3706,7 +3708,6 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, "engines": { "node": ">=12" } diff --git a/package.json b/package.json index 147e6e5..21ab81a 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "files": [ "dist", "!dist/**/*.test.*", - "!dist/tsconfig.tsbuildinfo" + "!dist/tsconfig.tsbuildinfo", + "!dist/**/*.map" ], "scripts": { "dev": "ts-node src/index.ts", @@ -38,9 +39,9 @@ "author": "cloudquery (https://github.com/cloudquery)", "devDependencies": { "@ava/typescript": "^4.1.0", - "@cloudquery/plugin-pb-js": "^0.0.4", "@grpc/grpc-js": "^1.9.0", "@tsconfig/node16": "^16.1.0", + "@types/yargs": "^17.0.24", "@typescript-eslint/eslint-plugin": "^6.2.1", "@typescript-eslint/parser": "^6.2.1", "ava": "^5.3.1", @@ -62,5 +63,9 @@ }, "compile": "tsc" } + }, + "dependencies": { + "@cloudquery/plugin-pb-javascript": "^0.0.5", + "yargs": "^17.7.2" } } diff --git a/src/index.test.ts b/src/grpc/server.test.ts similarity index 76% rename from src/index.test.ts rename to src/grpc/server.test.ts index 9e697f0..62f2dc5 100644 --- a/src/index.test.ts +++ b/src/grpc/server.test.ts @@ -1,5 +1,5 @@ import test from 'ava'; -import { getServer } from '.'; +import { getServer } from './server'; test('getServer', (t) => { const serve = getServer(); diff --git a/src/index.ts b/src/grpc/server.ts similarity index 91% rename from src/index.ts rename to src/grpc/server.ts index 74d4c2d..3dd3d0a 100644 --- a/src/index.ts +++ b/src/grpc/server.ts @@ -1,5 +1,5 @@ -import { discovery1 } from '@cloudquery/plugin-pb-js'; -import { pluginV3 } from '@cloudquery/plugin-pb-js'; +import { discovery1 } from '@cloudquery/plugin-pb-javascript'; +import { pluginV3 } from '@cloudquery/plugin-pb-javascript'; import grpc = require('@grpc/grpc-js'); class DiscoveryServer extends discovery1.cloudquery.discovery.v1.UnimplementedDiscoveryService { @@ -92,11 +92,10 @@ export const getServer = () => { return server; }; -const main = () => { +export const startServer = (address: string) => { const server = getServer(); - server.bindAsync(`0.0.0.0:9999`, grpc.ServerCredentials.createInsecure(), (err, port) => { + server.bindAsync(address, grpc.ServerCredentials.createInsecure(), (err, port) => { server.start(); + console.log('server running on port', port); }); }; - -main(); diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..644afcf --- /dev/null +++ b/src/main.ts @@ -0,0 +1,4 @@ +#!/usr/bin/env node +import { serve } from './serve'; + +serve.parse(); diff --git a/src/serve.test.ts b/src/serve.test.ts new file mode 100644 index 0000000..116e620 --- /dev/null +++ b/src/serve.test.ts @@ -0,0 +1,26 @@ +import test from 'ava'; +import { serve as serveWithExit, ServeArgs } from './serve'; + +const serve = serveWithExit.exitProcess(false); + +test('should return error without command', (t) => { + t.throws(() => serve.parse([]), { message: 'Specify a command to run' }); +}); + +test('should pass with serve command and return default flags', (t) => { + delete process.env.CQ_TELEMETRY_LEVEL; + const results = serve.parse(['serve']) as ServeArgs; + const { address, network, logLevel, logFormat, sentry, otelEndpoint, telemetryLevel } = results; + t.deepEqual( + { address, network, logLevel, logFormat, sentry, otelEndpoint, telemetryLevel }, + { + address: 'localhost:7777', + network: 'tcp', + logLevel: 'info', + logFormat: 'text', + sentry: true, + otelEndpoint: '', + telemetryLevel: 'all', + }, + ); +}); diff --git a/src/serve.ts b/src/serve.ts new file mode 100644 index 0000000..48fae33 --- /dev/null +++ b/src/serve.ts @@ -0,0 +1,82 @@ +import yargs from 'yargs'; +import { hideBin } from 'yargs/helpers'; + +const NETWORK_CHOICES = ['tcp', 'tcp4', 'tcp6', 'unix', 'unixpacket'] as const; +const LOG_LEVEL_CHOICES = ['trace', 'debug', 'info', 'warn', 'error'] as const; +const LOG_FORMAT_CHOICES = ['json', 'text'] as const; +const TELEMETRY_LEVEL_CHOICES = ['none', 'errors', 'stats', 'all'] as const; + +export type ServeArgs = { + address: string; + network: (typeof NETWORK_CHOICES)[number]; + logLevel: (typeof LOG_LEVEL_CHOICES)[number]; + logFormat: (typeof LOG_FORMAT_CHOICES)[number]; + sentry: boolean; + otelEndpoint: string; + otelEndpointInsecure: boolean; + telemetryLevel: (typeof TELEMETRY_LEVEL_CHOICES)[number]; +}; + +export const serve = yargs(hideBin(process.argv)) + .command( + 'serve', + 'start plugin gRPC server', + () => {}, + ({ address, network, logLevel, logFormat, sentry: sentry, otelEndpoint, telemetryLevel }: ServeArgs) => { + console.log({ address, network, logLevel, logFormat, sentry, otelEndpoint, telemetryLevel }); + }, + ) + .options({ + address: { + alias: 'a', + type: 'string', + description: 'address to bind to', + default: 'localhost:7777', + }, + network: { + alias: 'n', + type: 'string', + choices: NETWORK_CHOICES, + description: 'network to bind to', + default: 'tcp', + }, + 'log-level': { + alias: 'l', + type: 'string', + choices: LOG_LEVEL_CHOICES, + description: 'log level', + default: 'info', + }, + 'log-format': { + alias: 'f', + type: 'string', + choices: LOG_FORMAT_CHOICES, + description: 'log format', + default: 'text', + }, + sentry: { + type: 'boolean', + description: 'enable sentry reporting. Pass `--no-sentry` to disable.', + default: true, + }, + 'otel-endpoint': { + type: 'string', + description: 'OpenTelemetry collector endpoint', + default: '', + }, + 'otel-endpoint-insecure': { + type: 'boolean', + description: 'use Open Telemetry HTTP endpoint (for development only)', + default: false, + }, + 'telemetry-level': { + type: 'string', + description: 'CQ Telemetry level', + hidden: true, + choices: TELEMETRY_LEVEL_CHOICES, + default: 'all', + }, + }) + .env('CQ_') + .strict() + .demandCommand(1, 1, 'Specify a command to run'); diff --git a/tsconfig.json b/tsconfig.json index c04fca4..995e24e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,6 +3,7 @@ "compilerOptions": { "allowJs": true, "declaration": true, - "outDir": "dist" + "outDir": "dist", + "sourceMap": true } }