diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000..699da6aa --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,118 @@ +version: 2.1 + +executors: + node-executor: + working_directory: ~/repo + docker: + # Jest has issues with node > 16.11.0, please stick node version until the issues are resolved + # https://github.com/facebook/jest/issues/11956 + - image: cimg/node:16.10.0 + +# Set some environment variables like the base SHA of PRs ...etc. +set_env: &set_env + name: Setup Environment Variables + command: | + + echo 'Fetching Base Commit from GitHub' + # Get the PR number from env for different kinds of PR + echo 'export CIRCLE_PR_NUMBER="${CIRCLE_PR_NUMBER:-${CIRCLE_PULL_REQUEST##*/}}"' >> $BASH_ENV + source $BASH_ENV + # Obtain the SHA via Github API + echo "export CIRCLE_PR_BASE_SHA=`curl -s https://api.github.com/repos/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/pulls/${CIRCLE_PR_NUMBER} | jq -r '.base.sha'`" >> $BASH_ENV + # Set the affected args for nx affect xxx commands + echo 'export AFFECTED_ARGS="--base=${CIRCLE_PR_BASE_SHA}"' >> $BASH_ENV + # Set the memory size for node processes + echo 'export NODE_OPTIONS="--max_old_space_size=6144"' >> $BASH_ENV + source $BASH_ENV + echo $AFFECTED_ARGS + +# Retrieve node_modules and the module cache from Circle CI storage. +yarn_cache: &yarn_cache + keys: + - node-deps-node16-{{ checksum "yarn.lock" }} + # fallback to using the latest cache if no exact match is found + - node-deps-node16- + +# Install node modules via yarn with the frozen lock file +yarn_install: &yarn_install + name: Install Dependencies + command: yarn install --frozen-lockfile --non-interactive + +# Install code cov uploader and check the signature +# https://docs.codecov.com/docs/codecov-uploader +codecov_install: &codecov_install + name: Install codecov + command: | + if [ ! -f ./codecov ]; then + curl -Os https://uploader.codecov.io/v0.1.0_4653/linux/codecov + curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --no-default-keyring --keyring trustedkeys.gpg --import # One-time step + curl -Os https://uploader.codecov.io/latest/linux/codecov + curl -Os https://uploader.codecov.io/latest/linux/codecov.SHA256SUM + curl -Os https://uploader.codecov.io/latest/linux/codecov.SHA256SUM.sig + gpgv codecov.SHA256SUM.sig codecov.SHA256SUM + shasum -a 256 -c codecov.SHA256SUM + chmod +x codecov + fi + +jobs: + install: + executor: node-executor + steps: + - checkout + - restore_cache: + <<: *yarn_cache + - run: + <<: *yarn_install + - save_cache: + key: node-deps-node16-{{ checksum "yarn.lock" }} + paths: + - ~/.cache + - node_modules + - restore_cache: + keys: + - codecov-0.1.0_4653 + - run: + <<: *codecov_install + - save_cache: + key: codecov-0.1.0_4653 + paths: + - ./codecov + + lint: + executor: node-executor + steps: + - checkout + - run: + <<: *set_env + - restore_cache: + <<: *yarn_cache + - run: yarn nx workspace-lint + - run: yarn nx affected --target=lint --head=HEAD --maxWarnings=0 ${AFFECTED_ARGS} + + test: + executor: node-executor + steps: + - checkout + - run: + <<: *set_env + - restore_cache: + <<: *yarn_cache + - restore_cache: + keys: + - codecov-0.1.0_4653 + - run: yarn nx affected --target=test --head=HEAD --ci --coverage --maxWorkers=2 --coverageReporters=lcov ${AFFECTED_ARGS} + # --maxWorkers=2 is required because we'll run virtual machine with 32 cores CPU (with actually 4 CPI), jest spawns lots of workers if we don't fix the worker size. + # https://support.circleci.com/hc/en-us/articles/360005442714-Your-test-tools-are-smart-and-that-s-a-problem-Learn-about-when-optimization-goes-wrong- + - run: ./codecov -t ${CODECOV_TOKEN} + +workflows: + version: 2 + pr-check: + jobs: + - install + - lint: + requires: + - install + - test: + requires: + - install diff --git a/.eslintrc.json b/.eslintrc.json index 06cc47d9..346a939b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -16,7 +16,8 @@ "sourceTag": "*", "onlyDependOnLibsWithTags": ["*"] } - ] + ], + "allowCircularSelfDependency": true } ] } @@ -24,7 +25,10 @@ { "files": ["*.ts", "*.tsx"], "extends": ["plugin:@nrwl/nx/typescript"], - "rules": {} + "rules": { + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-non-null-assertion": "off" + } }, { "files": ["*.js", "*.jsx"], diff --git a/packages/build/src/lib/schema-parser/schemaParser.ts b/packages/build/src/lib/schema-parser/schemaParser.ts index 4304cc4e..c38d2d39 100644 --- a/packages/build/src/lib/schema-parser/schemaParser.ts +++ b/packages/build/src/lib/schema-parser/schemaParser.ts @@ -7,15 +7,8 @@ import { import * as yaml from 'js-yaml'; import { RawAPISchema, SchemaParserMiddleware } from './middleware'; import * as compose from 'koa-compose'; -import { - inject, - injectable, - interfaces, - multiInject, - optional, -} from 'inversify'; +import { inject, injectable, multiInject, optional } from 'inversify'; import { TYPES } from '@vulcan-sql/build/containers'; -import { SchemaParserOptions } from '@vulcan-sql/build/options'; export interface SchemaParseResult { schemas: APISchema[]; } diff --git a/packages/core/src/containers/modules/templateEngine.ts b/packages/core/src/containers/modules/templateEngine.ts index a714b604..85982cf2 100644 --- a/packages/core/src/containers/modules/templateEngine.ts +++ b/packages/core/src/containers/modules/templateEngine.ts @@ -5,7 +5,6 @@ import { TemplateProvider, } from '@vulcan-sql/core/models'; import { - InMemoryCodeLoader, NunjucksCompiler, Compiler, TemplateEngine, diff --git a/packages/core/src/lib/artifact-builder/persistent-stores/localFilePersistentStore.ts b/packages/core/src/lib/artifact-builder/persistent-stores/localFilePersistentStore.ts index 3975dd37..af4bc4c8 100644 --- a/packages/core/src/lib/artifact-builder/persistent-stores/localFilePersistentStore.ts +++ b/packages/core/src/lib/artifact-builder/persistent-stores/localFilePersistentStore.ts @@ -1,7 +1,6 @@ import { promises as fs } from 'fs'; import { ArtifactBuilderProviderType, - IArtifactBuilderOptions, PersistentStore, VulcanExtensionId, VulcanInternalExtension, diff --git a/packages/core/src/lib/data-query/builder/dataQueryBuilder.ts b/packages/core/src/lib/data-query/builder/dataQueryBuilder.ts index bfbb5c2c..784ea16c 100644 --- a/packages/core/src/lib/data-query/builder/dataQueryBuilder.ts +++ b/packages/core/src/lib/data-query/builder/dataQueryBuilder.ts @@ -1,6 +1,5 @@ import { DataSource, - PreparedQueryParams, Pagination, BindParameters, } from '@vulcan-sql/core/models'; diff --git a/packages/core/src/lib/data-source/pg.ts b/packages/core/src/lib/data-source/pg.ts index 790f9bd6..321867b5 100644 --- a/packages/core/src/lib/data-source/pg.ts +++ b/packages/core/src/lib/data-source/pg.ts @@ -13,6 +13,7 @@ import { @VulcanInternalExtension() @VulcanExtensionId('pg') export class PGDataSource extends DataSource { + // eslint-disable-next-line @typescript-eslint/no-unused-vars public async execute(options: ExecuteOptions): Promise { return { getColumns: () => { diff --git a/packages/core/src/lib/template-engine/nunjucksCompiler.ts b/packages/core/src/lib/template-engine/nunjucksCompiler.ts index 8ee1f6fc..0620194c 100644 --- a/packages/core/src/lib/template-engine/nunjucksCompiler.ts +++ b/packages/core/src/lib/template-engine/nunjucksCompiler.ts @@ -108,6 +108,7 @@ export class NunjucksCompiler implements Compiler { } else if (extension instanceof FilterBuilder) { this.compileTimeEnv.addFilter( extension.filterName, + // eslint-disable-next-line @typescript-eslint/no-empty-function () => {}, // We don't need to implement transform function in compile time true ); diff --git a/packages/core/src/lib/utils/module.ts b/packages/core/src/lib/utils/module.ts index fc97d3d6..5b73b68b 100644 --- a/packages/core/src/lib/utils/module.ts +++ b/packages/core/src/lib/utils/module.ts @@ -33,7 +33,7 @@ export const mergedModules = async ( modules: Array ) => { const module = modules.reduce( - (merged: ModuleProperties, current: ModuleProperties, _) => { + (merged: ModuleProperties, current: ModuleProperties) => { for (const extension of Object.keys(current)) { // if current extension property has been existed in merged module, concat it. if (extension in merged) diff --git a/packages/serve/src/lib/route/route-component/graphQLRoute.ts b/packages/serve/src/lib/route/route-component/graphQLRoute.ts index dc09f623..bf5698e8 100644 --- a/packages/serve/src/lib/route/route-component/graphQLRoute.ts +++ b/packages/serve/src/lib/route/route-component/graphQLRoute.ts @@ -20,7 +20,8 @@ export class GraphQLRoute extends BaseRoute { return transformed; } - protected async prepare(ctx: KoaRouterContext) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + protected async prepare(_ctx: KoaRouterContext) { /** * TODO: the graphql need to transform from body. * Therefore, current request and pagination transformer not suitable (need to provide another graphql transform method or class) diff --git a/packages/serve/test/app.spec.ts b/packages/serve/test/app.spec.ts index 3452133b..f987ebe7 100644 --- a/packages/serve/test/app.spec.ts +++ b/packages/serve/test/app.spec.ts @@ -85,7 +85,7 @@ describe('Test vulcan server for practicing middleware', () => { await app.buildRoutes([fakeSchema], [APIProviderType.RESTFUL]); const server = http .createServer(app.getHandler()) - .listen(faker.internet.port()); + .listen(faker.datatype.number({ min: 20000, max: 30000 })); // arrange expected result const expected = { @@ -313,7 +313,7 @@ describe('Test vulcan server for calling restful APIs', () => { await app.buildRoutes([schema], [APIProviderType.RESTFUL]); server = http .createServer(app.getHandler()) - .listen(faker.internet.port()); + .listen(faker.datatype.number({ min: 20000, max: 30000 })); // arrange input api url const apiUrl = KoaRouter.url(schema.urlPath, ctx.params); diff --git a/packages/serve/test/middlewares/built-in-middlewares/corsMiddleware.spec.ts b/packages/serve/test/middlewares/built-in-middlewares/corsMiddleware.spec.ts index 437bfe77..dae4693d 100644 --- a/packages/serve/test/middlewares/built-in-middlewares/corsMiddleware.spec.ts +++ b/packages/serve/test/middlewares/built-in-middlewares/corsMiddleware.spec.ts @@ -22,7 +22,7 @@ describe('Test cors middlewares', () => { // use middleware in koa app app.use(middleware.handle.bind(middleware)); // Act - server = app.listen(faker.internet.port()); + server = app.listen(faker.datatype.number({ min: 20000, max: 30000 })); }); afterAll(() => { diff --git a/packages/serve/test/middlewares/built-in-middlewares/rateLimitMiddleware.spec.ts b/packages/serve/test/middlewares/built-in-middlewares/rateLimitMiddleware.spec.ts index d2075f79..7cf3d429 100644 --- a/packages/serve/test/middlewares/built-in-middlewares/rateLimitMiddleware.spec.ts +++ b/packages/serve/test/middlewares/built-in-middlewares/rateLimitMiddleware.spec.ts @@ -29,7 +29,7 @@ describe('Test rate limit middlewares', () => { }); app.use(router.routes()); // Act - server = app.listen(faker.internet.port()); + server = app.listen(faker.datatype.number({ min: 20000, max: 30000 })); }); afterAll(() => { diff --git a/packages/serve/test/middlewares/built-in-middlewares/response-format/helpers.spec.ts b/packages/serve/test/middlewares/built-in-middlewares/response-format/helpers.spec.ts index e792fbb3..7b5bd042 100644 --- a/packages/serve/test/middlewares/built-in-middlewares/response-format/helpers.spec.ts +++ b/packages/serve/test/middlewares/built-in-middlewares/response-format/helpers.spec.ts @@ -14,9 +14,13 @@ import { } from '@vulcan-sql/serve/response-formatter'; class HyperFormatter extends BaseResponseFormatter { - public format(): any {} + public format(): any { + return; + } - public toResponse() {} + public toResponse() { + return; + } } it.each([ diff --git a/packages/serve/test/middlewares/test-custom-middlewares/testModeMiddleware.ts b/packages/serve/test/middlewares/test-custom-middlewares/testModeMiddleware.ts index dc4fa624..4948b565 100644 --- a/packages/serve/test/middlewares/test-custom-middlewares/testModeMiddleware.ts +++ b/packages/serve/test/middlewares/test-custom-middlewares/testModeMiddleware.ts @@ -1,4 +1,3 @@ -import { VulcanInternalExtension } from '@vulcan-sql/core'; import { BaseRouteMiddleware } from '@vulcan-sql/serve/models'; import { KoaRouterContext, KoaNext } from '@vulcan-sql/serve/route'; diff --git a/packages/serve/test/server.spec.ts b/packages/serve/test/server.spec.ts index ba3453f8..f172b33c 100644 --- a/packages/serve/test/server.spec.ts +++ b/packages/serve/test/server.spec.ts @@ -26,5 +26,7 @@ it('Vulcan server should work with built artifacts', async () => { }); // Act, Assert - await expect(server.start(faker.internet.port())).resolves.not.toThrow(); + await expect( + server.start(faker.datatype.number({ min: 20000, max: 30000 })) + ).resolves.not.toThrow(); });