Skip to content

Commit

Permalink
fix: make BaseSqlExpression a unique class (#17158)
Browse files Browse the repository at this point in the history
  • Loading branch information
lohart13 committed Apr 12, 2024
1 parent 23091a3 commit 6a5ea6c
Show file tree
Hide file tree
Showing 13 changed files with 35 additions and 24 deletions.
4 changes: 2 additions & 2 deletions packages/core/src/expression-builders/association-path.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BaseSqlExpression } from './base-sql-expression.js';
import { BaseSqlExpression, SQL_IDENTIFIER } from './base-sql-expression.js';

export class AssociationPath extends BaseSqlExpression {
private declare readonly brand: 'associationPath';
protected declare readonly [SQL_IDENTIFIER]: 'associationPath';

constructor(
readonly associationPath: readonly string[],
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/expression-builders/attribute.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { parseAttributeSyntax } from '../utils/attribute-syntax.js';
import type { AssociationPath } from './association-path.js';
import { BaseSqlExpression } from './base-sql-expression.js';
import { BaseSqlExpression, SQL_IDENTIFIER } from './base-sql-expression.js';
import type { Cast } from './cast.js';
import type { DialectAwareFn } from './dialect-aware-fn.js';
import type { JsonPath } from './json-path.js';
Expand All @@ -9,7 +9,7 @@ import type { JsonPath } from './json-path.js';
* Use {@link attribute} instead.
*/
export class Attribute extends BaseSqlExpression {
private declare readonly brand: 'attribute';
protected declare readonly [SQL_IDENTIFIER]: 'attribute';

constructor(readonly attributeName: string) {
super();
Expand Down
9 changes: 8 additions & 1 deletion packages/core/src/expression-builders/base-sql-expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,20 @@ import type { Literal } from './literal.js';
import type { Value } from './value.js';
import type { Where } from './where.js';

/**
* A symbol that can be used as the key for a static property on a BaseSqlExpression class to uniquely identify it.
*/
export declare const SQL_IDENTIFIER: unique symbol;

/**
* Utility functions for representing SQL functions, and columns that should be escaped.
* Please do not use these functions directly, use Sequelize.fn and Sequelize.col instead.
*
* @private
*/
export class BaseSqlExpression {}
export class BaseSqlExpression {
protected declare readonly [SQL_IDENTIFIER]: string;
}

export type DynamicSqlExpression =
| List
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/expression-builders/cast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import { isPlainObject } from '@sequelize/utils';
import type { DataType } from '../abstract-dialect/data-types.js';
import { Op } from '../operators.js';
import type { Expression } from '../sequelize.js';
import { BaseSqlExpression } from './base-sql-expression.js';
import { BaseSqlExpression, SQL_IDENTIFIER } from './base-sql-expression.js';
import { where } from './where.js';

/**
* Do not use me directly. Use {@link cast}
*/
export class Cast extends BaseSqlExpression {
private declare readonly brand: 'cast';
protected declare readonly [SQL_IDENTIFIER]: 'cast';

constructor(
readonly expression: Expression,
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/expression-builders/col.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { BaseSqlExpression } from './base-sql-expression.js';
import { BaseSqlExpression, SQL_IDENTIFIER } from './base-sql-expression.js';

/**
* Do not use me directly. Use {@link col}
*/
export class Col extends BaseSqlExpression {
private declare readonly brand: 'col';
protected declare readonly [SQL_IDENTIFIER]: 'col';

readonly identifiers: string[];

Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/expression-builders/fn.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { isPlainObject } from '@sequelize/utils';
import { Op } from '../operators.js';
import type { Expression } from '../sequelize.js';
import { BaseSqlExpression } from './base-sql-expression.js';
import { BaseSqlExpression, SQL_IDENTIFIER } from './base-sql-expression.js';
import { where } from './where.js';

/**
* Do not use me directly. Use {@link fn}
*/
export class Fn extends BaseSqlExpression {
private declare readonly brand: 'fn';
protected declare readonly [SQL_IDENTIFIER]: 'fn';

readonly fn: string;
readonly args: readonly Expression[];
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/expression-builders/identifier.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { BaseSqlExpression } from './base-sql-expression.js';
import { BaseSqlExpression, SQL_IDENTIFIER } from './base-sql-expression.js';

/**
* Use {@link identifier} instead.
*/
export class Identifier extends BaseSqlExpression {
private declare readonly brand: 'identifier';
protected declare readonly [SQL_IDENTIFIER]: 'identifier';

constructor(readonly value: string) {
super();
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/expression-builders/json-path.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { Expression } from '../sequelize.js';
import { BaseSqlExpression } from './base-sql-expression.js';
import { BaseSqlExpression, SQL_IDENTIFIER } from './base-sql-expression.js';

/**
* Do not use me directly. Use {@link jsonPath}.
*/
export class JsonPath extends BaseSqlExpression {
private declare readonly brand: 'jsonPath';
protected declare readonly [SQL_IDENTIFIER]: 'jsonPath';

constructor(
readonly expression: Expression,
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/expression-builders/list.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { BaseSqlExpression } from './base-sql-expression.js';
import { BaseSqlExpression, SQL_IDENTIFIER } from './base-sql-expression.js';

/**
* Use {@link list} instead.
*/
export class List extends BaseSqlExpression {
private declare readonly brand: 'list';
protected declare readonly [SQL_IDENTIFIER]: 'list';

constructor(readonly values: unknown[]) {
super();
Expand Down
5 changes: 2 additions & 3 deletions packages/core/src/expression-builders/literal.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { BaseSqlExpression } from './base-sql-expression.js';
import { BaseSqlExpression, SQL_IDENTIFIER } from './base-sql-expression.js';

/**
* Do not use me directly. Use {@link literal}
*/
export class Literal extends BaseSqlExpression {
/** this (type-only) brand prevents TypeScript from thinking Cast is assignable to Literal because they share the same shape */
private declare readonly brand: 'literal';
protected declare readonly [SQL_IDENTIFIER]: 'literal';

readonly val: ReadonlyArray<string | BaseSqlExpression>;

Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/expression-builders/value.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { BaseSqlExpression } from './base-sql-expression.js';
import { BaseSqlExpression, SQL_IDENTIFIER } from './base-sql-expression.js';

/**
* Used to represent a value that will either be escaped to a literal, or a bind parameter.
* You do not need to use this function directly, it will be used automatically when you interpolate parameters
* in a template string tagged with {@link sql}.
*/
export class Value extends BaseSqlExpression {
private declare readonly brand: 'value';
protected declare readonly [SQL_IDENTIFIER]: 'value';

constructor(readonly value: unknown) {
super();
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/expression-builders/where.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { PojoWhere } from '../abstract-dialect/where-sql-builder.js';
import type { WhereOperators } from '../model.js';
import type { Op } from '../operators.js';
import type { Expression } from '../sequelize.js';
import { BaseSqlExpression } from './base-sql-expression.js';
import { BaseSqlExpression, SQL_IDENTIFIER } from './base-sql-expression.js';

/**
* Do not use me directly. Use {@link where}
*/
export class Where<Operator extends keyof WhereOperators = typeof Op.eq> extends BaseSqlExpression {
private declare readonly brand: 'where';
protected declare readonly [SQL_IDENTIFIER]: 'where';

readonly where: PojoWhere | WhereOptions;

Expand Down
5 changes: 5 additions & 0 deletions packages/core/test/types/sequelize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ MyModel.hasOne(Model2);
MyModel.findAll();

async function test() {
// @ts-expect-error -- this should fail
await sequelize.query(1234);
// @ts-expect-error -- this should fail
await sequelize.query(/test/);

const [results, meta]: [unknown[], unknown] = await sequelize.query('SELECT * FROM `user`', {
type: QueryTypes.RAW,
});
Expand Down

0 comments on commit 6a5ea6c

Please sign in to comment.