diff --git a/.github/workflows/on_pr.yml b/.github/workflows/on_pr.yml new file mode 100644 index 0000000..929883d --- /dev/null +++ b/.github/workflows/on_pr.yml @@ -0,0 +1,19 @@ +name: On Pull Request + +on: + pull_request: + branches: + - main + - release/* + types: + - ready_for_review + - opened + - reopened + - synchronize + +jobs: + test: + uses: ./.github/workflows/test.yml +# artifact: +# needs: test +# uses: ./.github/workflows/artifact.yml diff --git a/.github/workflows/on_push.yml b/.github/workflows/on_push.yml new file mode 100644 index 0000000..3b10d4c --- /dev/null +++ b/.github/workflows/on_push.yml @@ -0,0 +1,17 @@ +name: On Push + +on: + push: + branches: + - main + - release/* + +jobs: + test: + uses: ./.github/workflows/test.yml +# artifact: +# needs: test +# permissions: +# contents: read +# packages: write +# uses: ./.github/workflows/artifact.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..f25e092 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,23 @@ +name: Test DBOS eslint plugin + +on: + workflow_call: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Use Node.js 18 + uses: actions/setup-node@v3 + with: + node-version: 18 + - name: Compile and Test + working-directory: ./ + run: | + npm install + npm test + env: + NPM_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} + SILENCE_LOGS: true diff --git a/README.md b/README.md index 10d9561..68b2e5c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,26 @@ -# eslint-plugin +# DBOS eslint plugin eslint plugin for DBOS sdk + +The [DBOS SDK](https://github.com/dbos-inc/dbos-ts) (from [DBOS, Inc.](https://dbos.dev)) is a **Typescript framework built on the database** that helps you develop transactional backend applications. + +This [eslint](https://eslint.org) plugin assists in the following aspects of coding: +- Correct use of the DBOS SDK +- Conformance to TypeScript best practices +- Identification of code that may contain security vulnerabilities +- + +## Getting Started + +The fastest way to get started with DBOS is by following the [quickstart](https://docs.dbos.dev/getting-started/quickstart), where you'll learn how to get a backend running in less than five minutes. + +The tutorial and examples include setup of `eslint` with this plugin. + +## Additional Documentation + +You can find our full documentation at [https://docs.dbos.dev/](https://docs.dbos.dev/). + +Check out our [Getting Started](https://docs.dbos.dev/category/getting-started) for an overview of how to build an application. + +## Community + +Please join our community on [Discord](https://discord.gg/fMwQjeW5zg)! If you see a bug or have a feature request, don't hesitate to open an issue here on GitHub. diff --git a/dbos-rules.js b/dbos-rules.js index d4a0c11..97776b4 100644 --- a/dbos-rules.js +++ b/dbos-rules.js @@ -19,6 +19,7 @@ const baseConfig = "no-secrets/no-secrets": "error", "@dbos-inc/detect-nondeterministic-calls": "error", "@dbos-inc/detect-new-date": "error", + "@dbos-inc/detect-native-code": "error", }, "extends": [ ], @@ -53,9 +54,35 @@ const extConfig = module.exports = { meta: { "name": "@dbos-inc/eslint-plugin", - "version": "0.0.2", + "version": "0.0.4", }, rules: { + 'detect-native-code': { + // Rule configuration for detection of libraries based on native code + meta: { + type: 'suggestion', + docs: { + description: 'Detect calls to libraries with native functions like bcrypt, which should be replaced with native JS', + }, + schema: [], + }, + create: function (context) { + return { + CallExpression(node) { + //console.log(node.callee.type+JSON.stringify(node)); + if (node.callee.type === 'MemberExpression' && + node.callee.object.name === 'bcrypt' && + (node.callee.property.name === 'compare' || node.callee.property.name === 'hash')) + { + context.report({ + node: node, + message: "Avoid using the 'bcrypt' library, which contains native code. Instead, use 'bcryptjs'. Also, note that some bcrypt functions generate random data and should only be called from DBOS communicators.", + }); + } + }, + }; + }, + }, 'detect-nondeterministic-calls': { // Rule configuration for Math.random() detection meta: { @@ -72,7 +99,7 @@ module.exports = { if (node.callee.type === 'MemberExpression' && node.callee.object.name === 'Math' && node.callee.property.name === 'random') - { + { context.report({ node: node, message: 'Avoid calling Math.random() directly; it can lead to non-reproducible behavior.', diff --git a/dbos-rules.test.js b/dbos-rules.test.js index 71ab9f8..2d20958 100644 --- a/dbos-rules.test.js +++ b/dbos-rules.test.js @@ -45,5 +45,27 @@ ruleTester.run( } ); +ruleTester.run( + "detect-native-code", // rule name + ruleUnderTest.rules['detect-native-code'], // rule code + { // checks + // 'valid' checks cases that should pass + valid: [{ + code: "const foo = 'bar';", + }], + // 'invalid' checks cases that should not pass + invalid: [{ + code: "const foo = bcrypt.hash('xxx', 10);", + //output: 'const foo = *NEED SUGGESTION*;', + errors: 1, + }], + invalid: [{ + code: "const foo = bcrypt.compare('xxx', pass);", + //output: 'const foo = *NEED SUGGESTION*;', + errors: 1, + }], + } +); + console.log("All tests passed!"); diff --git a/package.json b/package.json index 84a8fff..5426832 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@dbos-inc/eslint-plugin", - "version": "0.0.2", + "version": "0.0.4", "description": "eslint plugin for DBOS SDK", "license": "MIT", "repository": {