Git Product home page Git Product logo

eslint-plugin-sql's Introduction

eslint-plugin-sql

NPM version Canonical Code Style Twitter Follow

SQL linting rules for ESLint.

In its current form, the plugin has been designed and tested to work with Postgres codebase.

Installation

  1. Install ESLint.
  2. Install eslint-plugin-sql plugin.
npm install eslint --save-dev
npm install eslint-plugin-sql --save-dev

Configuration

  1. Add plugins section and specify eslint-plugin-sql as a plugin.
  2. Enable rules.
{
  "plugins": [
    "sql"
  ],
  "rules": {
    "sql/format": [
      2,
      {
        "ignoreExpressions": false,
        "ignoreInline": true,
        "ignoreTagless": true
      }
    ],
    "sql/no-unsafe-query": [
      2,
      {
        "allowLiteral": false
      }
    ]
  }
}

Settings

placeholderRule

A regex used to ignore placeholders or other fragments of the query that'd make it invalid SQL query, e.g.

If you are using ? placeholders in your queries, you must ignore \? pattern as otherwise the string is not going to be recognized as a valid SQL query.

This configuration is relevant for sql/no-unsafe-query to match queries containing placeholders as well as for sql/format when used with {ignoreTagless: false} configuration.

Rules

format

The --fix option on the command line automatically fixes problems reported by this rule.

Matches queries in template literals. Warns when query formatting does not match the configured format (see Options).

This rule is used to format the queries using pg-formatter.

Options

The first option is an object with the following configuration.

configuration format default description
ignoreBaseIndent boolean false Does not leave base indent before linting.
ignoreExpressions boolean false Does not format template literals that contain expressions.
ignoreInline boolean true Does not format queries that are written on a single line.
ignoreStartWithNewLine boolean true Does not remove \n at the beginning of queries.
ignoreTagless boolean true Does not format queries that are written without using sql tag.
sqlTag string sql Template tag name for SQL.

The second option is an object with the pg-formatter configuration.

no-unsafe-query

Disallows use of SQL inside of template literals without the sql tag.

The sql tag can be anything, e.g.

Options

The first option is an object with the following configuration.

configuration format default description
allowLiteral boolean false Controls whether sql tag is required for template literals containing literal queries, i.e. template literals without expressions.
sqlTag string sql Template tag name for SQL.

eslint-plugin-sql's People

Contributors

frysztak avatar gajus avatar ivanjov avatar mrswitch avatar npdev453 avatar stuk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

eslint-plugin-sql's Issues

allow to supply custom isSqlQuery helper or use better library

Toying with the plugin, I'm coming across valid SQL queries that aren't recognized, such as:

SELECT * FROM article a WHERE NOT a.archived

-- or

SELECT * FROM article a WHERE (a.authz & 8)::bool

One solution would be to either allow users to supply their own SQL parser (though I haven't checked if eslint allows to pass functions as settings values in .eslintrc.js), or replace the sql-parse, which seems unmaintained, with something else.

The automated release is failing 🚨

🚨 The automated release from the main branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you can benefit from your bug fixes and new features again.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can fix this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the main branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here are some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

Broken on running eslint --fix on MacOS Sonoma

Description

It keeps appending perl locale issue to my sql:

select
    c.*
    exclude (xxx, xxx)
from
    current_records c
    left join historical_records h on c.xxx = h.xxx
where
    c.xxx != h._h_hashed perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LC_ALL = "C.UTF-8", LANG = (unset) are supported
    and installed on your system. perl: warning: Falling back to the standard locale ("C").perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LC_ALL = "C.UTF-8"...

where
perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LC_ALL = "C.UTF-8", LANG = (unset) are supported gets appended after formatted sql.

Config

...
  {
    files: ["lib/**/*.ts"],
    plugins: { "sql" },
    rules: {
      "sql/format": [
        "error",
        {
          ignoreInline: true,
          ignoreTagless: true,
        }, {
          functionCase: "lowercase",
          keywordCase: "lowercase",
          spaces: 4,
        },
      ],
    },
  },
...

System version

macOS Sonoma 14.3.1 @ Apple M1 Pro

Expected behaviour

Format well without appending any warnings.

Attempted solutions in StackOverflow

  • Export LANG=xx in rc profile file
  • Configure locale terminal app

Ensure that transaction is used the associated connection

Example,

const createReservation = async (
  connection: DatabaseConnectionType,
  sessionId: string,
  userId?: number,
  email?: string,
  eventId,
  seatIds: $ReadOnlyArray<number>,
  ticketIds: $ReadOnlyArray<number>
): Promise<ReservationType> => {
  return connection.transaction(async (transactionConnection) => {
    const reservationFee = await getReservationFee(transactionConnection);

    const {
      id: reservationId
    } = await transactionConnection.one(sql`INSERT INTO reservation (session_id, user_id, event_id, reservation_fee_id, email) VALUES (?, ?, ?, ?, ?) RETURNING id`, [
      sessionId,
      userId || null,
      eventId,
      reservationFee.id,
      email || null
    ]);

    await insertReservationSeats(transactionConnection, reservationId, seatIds);
    await insertReservationTickets(transactionConnection, reservationId, ticketIds);

    return getReservationByReservationId(transactionConnection, reservationId);
  });
};

Here it is easy to mistakenly use connection instead of transactionConnection.

This rule is a bit broad and biased towards the https://github.com/gajus/mightyql. It might require a dedicated ESLint plugin.

Option for `format` rule for matching indentation?

Hi @gajus ! First of all, thanks for your great work in the PostgreSQL + JS ecosystem, really cool stuff that you're doing always with Slonik and everything! πŸ’―

I was wondering if it would be possible to have an option for the format rule to adjust the formatted string . Here's an example of code that could be improved because of this:

async function a() {
  if (condition) {
    // ...some code...
    if (anotherCondition) {
      const b = await sql`
SELECT
  ${'foo'}
FROM
  ${'bar'}
`;
    }
  }
}

How this code could look:

async function a() {
  if (condition) {
    // ...some code...
    if (anotherCondition) {
      const b = await sql`
        SELECT
          ${'foo'}
        FROM
          ${'bar'}
      `;
    }
  }
}

Since SQL is not whitespace-sensitive I am assuming this would not be a destructive action.

If this option would be something conceivable to add to the plugin, I guess the AST tells us that some information of the starting indentation of the TaggedTemplateExpression may be available under the loc.start.column object property path:

Screen Shot 2020-11-19 at 20 15 40

And then splitting the formatted string by '\n', mapping over each line (except the first one) to add spaces:

formatted.map((line, i) => {
  if (i === 0) return line;

  const spaces = context.options[1].spaces || 4;
  const indentation = ' '.repeat(column + spaces);
  return `${indentation}${line}`;
}

...and then joining again with \n.

What are your thoughts?

Plugin schema lacks case options

Plugin schema lacks some options for pg-formatter that breaks plugin when those are passed in options.

  ...
  rules: {
    'sql/format': [
      'error',
      {
        ignoreExpressions: false,
        ignoreInline: true,
        ignoreTagless: true,
        ignoreStartWithNewLine: false,
      },
      {
        anonymize: false,
        functionCase: 'lowercase', //error
        keywordsCase: 'lowercase', //error
        spaces: 2,
        commaBreak: true,
      },
    ],
    ...

->

Error: apps/api/.eslintrc.cjs Β» @graphytools/eslint-config/node Β» /Users/abc/IdeaProjects/abc/abc/eslint-config/config/sql.js:
Configuration for rule "sql/format" is invalid:
Value {"anonymize":false,"spaces":2,"commaBreak":true,"keywordCase":"lowercase","noRcFile":false,"stripComments":false,"tabs":false} should NOT have additional properties.

Ref: https://github.com/gajus/eslint-plugin-sql/blob/master/src/rules/format.js#L115

plugin: 2.1.0
Eslint: 7.32

Result of using --fix for format results in code that does not meet rule's requirements

I'm using the plugin with the default configuration and when the format of my query is autofixed for the first time

sql`
SELECT

is produced which fails the format rule. However, if I simply change it to

sql`SELECT

The rule passes. This is not a major inconvenience, just a little strange and I thought you'd like to know. It's worth mentioning I actually prefer the first "invalid" output so it might be easier for the rule to just accept \n at the start of the string.

--fix creates broken code

sql`
SELECT
    1,
    2,3
`;

is converted into this broken code

sql`

SELECT
    1,
    2,
    3
`;

I have to remove the first empty line to fix the code manually.

versions

"eslint": "^8.18.0",
"eslint-plugin-sql": "^2.1.0",

configuration

{
  "plugins": [
    "sql"
  ],
    "env": {
        "es6": true
    },
  "rules": {
    "sql/format": [ 2 ],
    "sql/no-unsafe-query": [ 2, { "allowLiteral": false } ]
  }
}

Compatibility with Slonik v33+?

When I run this plugin on Slonik v33+, I'm getting:

TypeError: Cannot read properties of undefined (reading 'toLowerCase')

I think this is because sql.unsafe is unexpected, but I'm not really sure how to read eslint plugins. Unfortunately, not sure of a fix here, but thought I'd flag as a potential compatibility bug.

Compatibility with Slonik v33

(Opening a new issue since the other is closed β€” please correct me if this isn't what you prefer)

I'm still getting this error from issue #21 with version 2.3.2:

TypeError: Cannot read properties of undefined (reading 'toLowerCase')

Minimal example:

This works (no error):

const q = sql.unsafe`SELECT * FROM table_name WHERE column_name;`;

This doesn't (error):

const q = sql.unsafe`SELECT * FROM table_name WHERE column_name = true;`;

This is the error trace:

Rule: "sql/no-unsafe-query"
    at TemplateLiteral (node_modules/eslint-plugin-sql/dist/src/rules/noUnsafeQuery.js:34:86)
    at ruleErrorHandler (node_modules/eslint/lib/linter/linter.js:1115:28)
    at node_modules/eslint/lib/linter/safe-emitter.js:45:58
    at Array.forEach (<anonymous>)
    at Object.emit (node_modules/eslint/lib/linter/safe-emitter.js:45:38)
    at NodeEventGenerator.applySelector (node_modules/eslint/lib/linter/node-event-generator.js:297:26)
    at NodeEventGenerator.applySelectors (node_modules/eslint/lib/linter/node-event-generator.js:326:22)
    at NodeEventGenerator.enterNode (node_modules/eslint/lib/linter/node-event-generator.js:340:14)
    at CodePathAnalyzer.enterNode (node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js:795:23)
    at node_modules/eslint/lib/linter/linter.js:1150:32

The line in question (noUnsafeQuery.js:34:86):

const legacyTagName = tag === null || tag === void 0 ? void 0 : tag.name.toLowerCase();

Changing it to this prevented the error, although I'm not sure if it's correct:

const legacyTagName = tag === null || tag === void 0 || tag.name === void 0 ? void 0 : tag.name.toLowerCase();

I think this would be accomplished by changing noUnsafeQuery.ts:45 from:

      const legacyTagName = tag?.name.toLowerCase();

to:

      const legacyTagName = tag?.name?.toLowerCase();

I don't know if this is correct, though, because I'm not sure if tag, when defined, should always definitely have name.

Originally posted by @andymakingthings in #21 (comment)

sql/no-unsafe-queries break when no options are passed

Using configuration without options as:

{
  "rules": {
    "sql/no-unsafe-query": "error"
  }
}

results in an error:

TypeError: Error while loading rule 'sql/no-unsafe-query': Cannot destructure property 'allowLiteral' of 'context.options[0]' as it is undefined.

As there is only one parameter documented, and documentation states that the parameter defaults to false I would expect that no configuration was needed if the default value is the desired one.

This could be solved easily using optional chaining at the rule definition

const {allowLiteral} = context.options?.[0];

I would gladly submit a PR in case this is the desired behavior

New version on npm

Hi there,

this is really a request and not an issue. Would it be possible to get the latest version of this library published to npm? Latest version on npm is from 2 years ago and at least I could use the feature implemented in #6. Thanks.

Broken package

There is no main file in package v2.2.1 (./dist/src/index.js):

The package "eslint-plugin-sql" was not found when loaded as a Node module

The automated release is failing 🚨

🚨 The automated release from the main branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you can benefit from your bug fixes and new features again.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can fix this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the main branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here are some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two Factor Authentication for your account, set its level to "Authorization only" in your account settings. semantic-release cannot publish with the default "
Authorization and writes" level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

Custom sql tag supporting

Currently sql tag is not configurable but it can be SQL or SQLtag in different libraries or selfwrited code.

[RULE REQUEST] enforce SQL queries to use template strings

Add a rule require-template-queries, which would enforce use of template strings for queries.

These would be considered problems:

"SELECT text FROM article WHERE id = " + id
// Message: Use template strings for SQL queries

"SELECT text FROM article WHERE id = 3"
// Message: Use template strings for SQL queries

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.