From bc1c597d2436adaf56af734cb1a9ae11dbe819a9 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Mon, 16 May 2022 14:13:01 +0300 Subject: [PATCH 001/334] Make all Formatter class fields private No more need for these being protected after the reorganization of tokens preprocessing code. --- src/core/Formatter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/Formatter.ts b/src/core/Formatter.ts index c4f78b5ec9..675fc32b57 100644 --- a/src/core/Formatter.ts +++ b/src/core/Formatter.ts @@ -24,8 +24,8 @@ export default class Formatter { private currentNewline = true; private previousReservedToken: Token = EOF_TOKEN; private previousCommandToken: Token = EOF_TOKEN; - protected tokens: Token[] = []; - protected index = -1; + private tokens: Token[] = []; + private index = -1; constructor(cfg: FormatOptions) { this.cfg = cfg; From 1551936ddcc56050996f613ac4c8d8f1f5571a64 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Mon, 16 May 2022 17:27:48 +0300 Subject: [PATCH 002/334] Extract StatementFormatter class Now the Formatter contains the overall general wire-it-all-together code, while StatementFormatter deals with formatting each of the SQL statements. --- src/core/Formatter.ts | 490 +-------------------------------- src/core/Indentation.ts | 14 + src/core/StatementFormatter.ts | 467 +++++++++++++++++++++++++++++++ 3 files changed, 493 insertions(+), 478 deletions(-) create mode 100644 src/core/StatementFormatter.ts diff --git a/src/core/Formatter.ts b/src/core/Formatter.ts index 675fc32b57..e774317529 100644 --- a/src/core/Formatter.ts +++ b/src/core/Formatter.ts @@ -1,49 +1,22 @@ -import Indentation from './Indentation'; -import InlineBlock from './InlineBlock'; +import { indentString } from './Indentation'; import Params from './Params'; -import { trimSpacesEnd } from '../utils'; -import { isReserved, isCommand, isToken, Token, TokenType, EOF_TOKEN } from './token'; import Tokenizer from './Tokenizer'; import { FormatOptions } from '../types'; import formatCommaPositions from './formatCommaPositions'; import formatAliasPositions from './formatAliasPositions'; -import { toTabularToken, replaceTabularPlaceholders } from './tabularStyle'; -import AliasAs from './AliasAs'; import AsTokenFactory from './AsTokenFactory'; import Parser, { Statement } from './Parser'; +import StatementFormatter from './StatementFormatter'; +import { Token } from './token'; /** Main formatter class that produces a final output string from list of tokens */ export default class Formatter { private cfg: FormatOptions; - private indentation: Indentation; - private inlineBlock: InlineBlock; - private aliasAs: AliasAs; private params: Params; - private asTokenFactory: AsTokenFactory; - - private currentNewline = true; - private previousReservedToken: Token = EOF_TOKEN; - private previousCommandToken: Token = EOF_TOKEN; - private tokens: Token[] = []; - private index = -1; constructor(cfg: FormatOptions) { this.cfg = cfg; - this.indentation = new Indentation(this.indentString()); - this.inlineBlock = new InlineBlock(this.cfg.expressionWidth); - this.aliasAs = new AliasAs(this.cfg.aliasAs, this); this.params = new Params(this.cfg.params); - this.asTokenFactory = new AsTokenFactory(this.cfg.keywordCase); - } - - private indentString(): string { - if (this.isTabularStyle()) { - return ' '.repeat(10); - } - if (this.cfg.useTabs) { - return '\t'; - } - return ' '.repeat(this.cfg.tabWidth); } /** @@ -60,468 +33,29 @@ export default class Formatter { */ public format(query: string): string { const tokens = this.tokenizer().tokenize(query); - this.asTokenFactory = new AsTokenFactory(this.cfg.keywordCase, tokens); - const ast = new Parser(tokens).parse(); - const formattedQuery = this.formatAst(ast); + const formattedQuery = this.formatAst(ast, tokens); const finalQuery = this.postFormat(formattedQuery); return finalQuery.trimEnd(); } - /** - * Does post-processing on the formatted query. - */ - private postFormat(query: string): string { - if (this.cfg.tabulateAlias) { - query = formatAliasPositions(query); - } - if (this.cfg.commaPosition === 'before' || this.cfg.commaPosition === 'tabular') { - query = formatCommaPositions(query, this.cfg.commaPosition, this.indentString()); - } + private formatAst(statements: Statement[], tokens: Token[]): string { + const asTokenFactory = new AsTokenFactory(this.cfg.keywordCase, tokens); - return query; - } - - private formatAst(statements: Statement[]): string { return statements - .map(this.formatStatement, this) + .map(stat => new StatementFormatter(this.cfg, this.params, asTokenFactory).format(stat)) .join('\n'.repeat(this.cfg.linesBetweenQueries + 1)); } - private formatStatement(statement: Statement): string { - this.tokens = statement.tokens; - let formattedQuery = ''; - this.previousCommandToken = EOF_TOKEN; - this.previousReservedToken = EOF_TOKEN; - this.currentNewline = true; - this.indentation.resetIndentation(); - - for (this.index = 0; this.index < this.tokens.length; this.index++) { - let token = this.tokens[this.index]; - - // if token is a Reserved Keyword, Command, Binary Command, Dependent Clause, Logical Operator, CASE, END - if (isReserved(token)) { - this.previousReservedToken = token; - if ( - token.type === TokenType.RESERVED_LOGICAL_OPERATOR || - token.type === TokenType.RESERVED_DEPENDENT_CLAUSE || - token.type === TokenType.RESERVED_COMMAND || - token.type === TokenType.RESERVED_BINARY_COMMAND - ) { - token = toTabularToken(token, this.cfg.indentStyle); - } - if (token.type === TokenType.RESERVED_COMMAND) { - this.previousCommandToken = token; - } - } - - if (token.type === TokenType.LINE_COMMENT) { - formattedQuery = this.formatLineComment(token, formattedQuery); - } else if (token.type === TokenType.BLOCK_COMMENT) { - formattedQuery = this.formatBlockComment(token, formattedQuery); - } else if (token.type === TokenType.RESERVED_COMMAND) { - this.currentNewline = this.checkNewline(token); - formattedQuery = this.formatCommand(token, formattedQuery); - } else if (token.type === TokenType.RESERVED_BINARY_COMMAND) { - formattedQuery = this.formatBinaryCommand(token, formattedQuery); - } else if (token.type === TokenType.RESERVED_DEPENDENT_CLAUSE) { - formattedQuery = this.formatDependentClause(token, formattedQuery); - } else if (token.type === TokenType.RESERVED_JOIN_CONDITION) { - formattedQuery = this.formatJoinCondition(token, formattedQuery); - } else if (token.type === TokenType.RESERVED_LOGICAL_OPERATOR) { - formattedQuery = this.formatLogicalOperator(token, formattedQuery); - } else if (token.type === TokenType.RESERVED_KEYWORD) { - formattedQuery = this.formatKeyword(token, formattedQuery); - } else if (token.type === TokenType.BLOCK_START) { - formattedQuery = this.formatBlockStart(token, formattedQuery); - } else if (token.type === TokenType.BLOCK_END) { - formattedQuery = this.formatBlockEnd(token, formattedQuery); - } else if (token.type === TokenType.RESERVED_CASE_START) { - formattedQuery = this.formatCaseStart(token, formattedQuery); - } else if (token.type === TokenType.RESERVED_CASE_END) { - formattedQuery = this.formatCaseEnd(token, formattedQuery); - } else if (token.type === TokenType.PLACEHOLDER) { - formattedQuery = this.formatPlaceholder(token, formattedQuery); - } else if (token.type === TokenType.OPERATOR) { - formattedQuery = this.formatOperator(token, formattedQuery); - } else { - formattedQuery = this.formatWord(token, formattedQuery); - } - } - return replaceTabularPlaceholders(formattedQuery); - } - - /** - * Formats word tokens + any potential AS tokens for aliases - */ - private formatWord(token: Token, query: string): string { - let finalQuery = query; - if (this.aliasAs.shouldAddBefore(token)) { - finalQuery = this.formatWithSpaces(this.asTokenFactory.token(), finalQuery); - } - - finalQuery = this.formatWithSpaces(token, finalQuery); - - if (this.aliasAs.shouldAddAfter()) { - finalQuery = this.formatWithSpaces(this.asTokenFactory.token(), finalQuery); - } - - return finalQuery; - } - - /** - * Checks if a newline should currently be inserted - */ - private checkNewline(token: Token): boolean { - const nextTokens = this.tokensUntilNextCommandOrQueryEnd(); - - // auto break if SELECT includes CASE statements - if (this.isWithinSelect() && nextTokens.some(isToken.CASE)) { - return true; - } - - switch (this.cfg.multilineLists) { - case 'always': - return true; - case 'avoid': - return false; - case 'expressionWidth': - return this.inlineWidth(token, nextTokens) > this.cfg.expressionWidth; - default: // multilineLists mode is a number - return ( - this.countClauses(nextTokens) > this.cfg.multilineLists || - this.inlineWidth(token, nextTokens) > this.cfg.expressionWidth - ); - } - } - - private inlineWidth(token: Token, tokens: Token[]): number { - const tokensString = tokens.map(({ value }) => (value === ',' ? value + ' ' : value)).join(''); - return `${token.whitespaceBefore}${token.value} ${tokensString}`.length; - } - - /** - * Counts comma-separated clauses (doesn't count commas inside blocks) - * Note: There's always at least one clause. - */ - private countClauses(tokens: Token[]): number { - let count = 1; - let openBlocks = 0; - for (const { type, value } of tokens) { - if (value === ',' && openBlocks === 0) { - count++; - } - if (type === TokenType.BLOCK_START) { - openBlocks++; - } - if (type === TokenType.BLOCK_END) { - openBlocks--; - } - } - return count; - } - - /** get all tokens between current token and next Reserved Command or query end */ - private tokensUntilNextCommandOrQueryEnd(): Token[] { - const tail = this.tokens.slice(this.index + 1); - return tail.slice( - 0, - tail.length ? tail.findIndex(token => isCommand(token) || token.value === ';') : undefined - ); - } - - /** Formats a line comment onto query */ - private formatLineComment(token: Token, query: string): string { - return this.addNewline(query + this.show(token)); - } - - /** Formats a block comment onto query */ - private formatBlockComment(token: Token, query: string): string { - return this.addNewline(this.addNewline(query) + this.indentComment(token.value)); - } - - /** Aligns comment to current indentation level */ - private indentComment(comment: string): string { - return comment.replace(/\n[ \t]*/gu, '\n' + this.indentation.getIndent() + ' '); - } - - /** - * Formats a Reserved Command onto query, increasing indentation level where necessary - */ - private formatCommand(token: Token, query: string): string { - this.indentation.decreaseTopLevel(); - - query = this.addNewline(query); - - // indent tabular formats, except when preceding a ( - if (this.isTabularStyle()) { - if (this.tokenLookAhead().value !== '(') { - this.indentation.increaseTopLevel(); - } - } else { - this.indentation.increaseTopLevel(); - } - - query += this.equalizeWhitespace(this.show(token)); // print token onto query - if (this.currentNewline && !this.isTabularStyle()) { - query = this.addNewline(query); - } else { - query += ' '; - } - return query; - } - - /** - * Formats a Reserved Binary Command onto query, joining neighbouring tokens - */ - private formatBinaryCommand(token: Token, query: string): string { - const isJoin = /JOIN/i.test(token.value); // check if token contains JOIN - if (!isJoin || this.isTabularStyle()) { - // decrease for boolean set operators or in tabular mode - this.indentation.decreaseTopLevel(); - } - query = this.addNewline(query) + this.equalizeWhitespace(this.show(token)); - return isJoin ? query + ' ' : this.addNewline(query); - } - - /** - * Formats a Reserved Keyword onto query, skipping AS if disabled - */ - private formatKeyword(token: Token, query: string): string { - if (isToken.AS(token) && this.aliasAs.shouldRemove()) { - return query; - } - - return this.formatWithSpaces(token, query); - } - - /** - * Formats a Reserved Dependent Clause token onto query, supporting the keyword that precedes it - */ - private formatDependentClause(token: Token, query: string): string { - return this.addNewline(query) + this.equalizeWhitespace(this.show(token)) + ' '; - } - - // Formats ON and USING keywords - private formatJoinCondition(token: Token, query: string): string { - return query + this.equalizeWhitespace(this.show(token)) + ' '; - } - - /** - * Formats an Operator onto query, following rules for specific characters - */ - private formatOperator(token: Token, query: string): string { - // special operator - if (token.value === ',') { - return this.formatComma(token, query); - } else if (token.value === ';') { - return this.formatQuerySeparator(token, query); - } else if (['$', '['].includes(token.value)) { - return this.formatWithSpaces(token, query, 'before'); - } else if ([':', ']'].includes(token.value)) { - return this.formatWithSpaces(token, query, 'after'); - } else if (['.', '{', '}', '`'].includes(token.value)) { - return this.formatWithoutSpaces(token, query); - } - - // regular operator - if (this.cfg.denseOperators && this.tokenLookBehind().type !== TokenType.RESERVED_COMMAND) { - // do not trim whitespace if SELECT * - return this.formatWithoutSpaces(token, query); - } - return this.formatWithSpaces(token, query); - } - - /** - * Formats a Logical Operator onto query, joining boolean conditions - */ - private formatLogicalOperator(token: Token, query: string): string { - // ignore AND when BETWEEN x [AND] y - if (isToken.AND(token) && isToken.BETWEEN(this.tokenLookBehind(2))) { - return this.formatWithSpaces(token, query); - } - - if (this.isTabularStyle()) { - this.indentation.decreaseTopLevel(); - } - - if (this.cfg.logicalOperatorNewline === 'before') { - return ( - (this.currentNewline ? this.addNewline(query) : query) + - this.equalizeWhitespace(this.show(token)) + - ' ' - ); - } else { - query += this.show(token); - return this.currentNewline ? this.addNewline(query) : query; - } - } - - /** Replace any sequence of whitespace characters with single space */ - private equalizeWhitespace(string: string): string { - return string.replace(/\s+/gu, ' '); - } - - private formatBlockStart(token: Token, query: string): string { - // Take out the preceding space unless there was whitespace there in the original query - // or another opening parens or line comment - const preserveWhitespaceFor = [ - TokenType.BLOCK_START, - TokenType.LINE_COMMENT, - TokenType.OPERATOR, - ]; - if ( - token.whitespaceBefore?.length === 0 && - !preserveWhitespaceFor.includes(this.tokenLookBehind().type) - ) { - query = trimSpacesEnd(query); - } else if (!this.cfg.newlineBeforeOpenParen) { - query = query.trimEnd() + ' '; - } - query += this.show(token); - this.inlineBlock.beginIfPossible(this.tokens, this.index); - - if (!this.inlineBlock.isActive()) { - this.indentation.increaseBlockLevel(); - query = this.addNewline(query); + private postFormat(query: string): string { + if (this.cfg.tabulateAlias) { + query = formatAliasPositions(query); } - return query; - } - - private formatBlockEnd(token: Token, query: string): string { - if (this.inlineBlock.isActive()) { - this.inlineBlock.end(); - return this.formatWithSpaces(token, query, 'after'); // do not add space before ) - } else { - return this.formatMultilineBlockEnd(token, query); + if (this.cfg.commaPosition === 'before' || this.cfg.commaPosition === 'tabular') { + query = formatCommaPositions(query, this.cfg.commaPosition, indentString(this.cfg)); } - } - private formatCaseStart(token: Token, query: string): string { - query = this.formatWithSpaces(token, query); - this.indentation.increaseBlockLevel(); - if (this.cfg.multilineLists === 'always') { - query = this.addNewline(query); - } return query; } - - private formatCaseEnd(token: Token, query: string): string { - return this.formatMultilineBlockEnd(token, query); - } - - private formatMultilineBlockEnd(token: Token, query: string): string { - this.indentation.decreaseBlockLevel(); - - if (this.isTabularStyle()) { - // +1 extra indentation step for the closing paren - query = this.addNewline(query) + this.indentation.getSingleIndent(); - } else if (this.cfg.newlineBeforeCloseParen) { - query = this.addNewline(query); - } else { - query = query.trimEnd() + ' '; - } - - return this.formatWithSpaces(token, query); - } - - /** - * Formats a Placeholder item onto query, to be replaced with the value of the placeholder - */ - formatPlaceholder(token: Token, query: string): string { - return query + this.params.get(token) + ' '; - } - - /** - * Formats a comma Operator onto query, ending line unless in an Inline Block - */ - private formatComma(token: Token, query: string): string { - query = trimSpacesEnd(query) + this.show(token) + ' '; - - if (this.inlineBlock.isActive()) { - return query; - } else if (isToken.LIMIT(this.getPreviousReservedToken())) { - return query; - } else if (this.currentNewline) { - return this.addNewline(query); - } else { - return query; - } - } - - /** Simple append of token onto query */ - private formatWithoutSpaces(token: Token, query: string): string { - return trimSpacesEnd(query) + this.show(token); - } - - /** - * Add token onto query with spaces - either before, after, or both - */ - private formatWithSpaces( - token: Token, - query: string, - addSpace: 'before' | 'after' | 'both' = 'both' - ): string { - const before = addSpace === 'after' ? trimSpacesEnd(query) : query; - const after = addSpace === 'before' ? '' : ' '; - return before + this.show(token) + after; - } - - private formatQuerySeparator(token: Token, query: string): string { - return [ - trimSpacesEnd(query), - this.cfg.newlineBeforeSemicolon ? '\n' : '', - this.show(token), - ].join(''); - } - - /** Converts token to string, uppercasing if enabled */ - private show(token: Token): string { - if (isReserved(token)) { - switch (this.cfg.keywordCase) { - case 'preserve': - return token.value; - case 'upper': - return token.value.toUpperCase(); - case 'lower': - return token.value.toLowerCase(); - } - } else { - return token.value; - } - } - - /** Inserts a newline onto the query */ - private addNewline(query: string): string { - query = trimSpacesEnd(query); - if (!query.endsWith('\n') && query !== '') { - query += '\n'; - } - return query + this.indentation.getIndent(); - } - - private isTabularStyle(): boolean { - return this.cfg.indentStyle === 'tabularLeft' || this.cfg.indentStyle === 'tabularRight'; - } - - /** Returns the latest encountered reserved keyword token */ - public getPreviousReservedToken(): Token { - return this.previousReservedToken; - } - - /** True when currently within SELECT command */ - public isWithinSelect(): boolean { - return isToken.SELECT(this.previousCommandToken); - } - - /** Fetches nth previous token from the token stream */ - public tokenLookBehind(n = 1): Token { - return this.tokens[this.index - n] || EOF_TOKEN; - } - - /** Fetches nth next token from the token stream */ - public tokenLookAhead(n = 1): Token { - return this.tokens[this.index + n] || EOF_TOKEN; - } } diff --git a/src/core/Indentation.ts b/src/core/Indentation.ts index 8e5a0033e6..9b4e1e9f15 100644 --- a/src/core/Indentation.ts +++ b/src/core/Indentation.ts @@ -1,3 +1,4 @@ +import { FormatOptions } from '../types'; import { last } from '../utils'; const INDENT_TYPE_TOP_LEVEL = 'top-level'; @@ -77,3 +78,16 @@ export default class Indentation { this.indentTypes = []; } } + +/** + * Creates a string to use for one step of indentation. + */ +export function indentString(cfg: FormatOptions): string { + if (cfg.indentStyle === 'tabularLeft' || cfg.indentStyle === 'tabularRight') { + return ' '.repeat(10); + } + if (cfg.useTabs) { + return '\t'; + } + return ' '.repeat(cfg.tabWidth); +} diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts new file mode 100644 index 0000000000..90ec642a81 --- /dev/null +++ b/src/core/StatementFormatter.ts @@ -0,0 +1,467 @@ +import Indentation, { indentString } from './Indentation'; +import InlineBlock from './InlineBlock'; +import Params from './Params'; +import { trimSpacesEnd } from '../utils'; +import { isReserved, isCommand, isToken, Token, TokenType, EOF_TOKEN } from './token'; +import { FormatOptions } from '../types'; +import { toTabularToken, replaceTabularPlaceholders } from './tabularStyle'; +import AliasAs from './AliasAs'; +import AsTokenFactory from './AsTokenFactory'; +import { Statement } from './Parser'; + +/** Formats single SQL statement */ +export default class StatementFormatter { + private cfg: FormatOptions; + private indentation: Indentation; + private inlineBlock: InlineBlock; + private aliasAs: AliasAs; + private params: Params; + private asTokenFactory: AsTokenFactory; + + private currentNewline = true; + private previousReservedToken: Token = EOF_TOKEN; + private previousCommandToken: Token = EOF_TOKEN; + private tokens: Token[] = []; + private index = -1; + + constructor(cfg: FormatOptions, params: Params, asTokenFactory: AsTokenFactory) { + this.cfg = cfg; + this.indentation = new Indentation(indentString(cfg)); + this.inlineBlock = new InlineBlock(this.cfg.expressionWidth); + this.aliasAs = new AliasAs(this.cfg.aliasAs, this); + this.params = params; + this.asTokenFactory = asTokenFactory; + } + + public format(statement: Statement): string { + this.tokens = statement.tokens; + let formattedQuery = ''; + + for (this.index = 0; this.index < this.tokens.length; this.index++) { + let token = this.tokens[this.index]; + + // if token is a Reserved Keyword, Command, Binary Command, Dependent Clause, Logical Operator, CASE, END + if (isReserved(token)) { + this.previousReservedToken = token; + if ( + token.type === TokenType.RESERVED_LOGICAL_OPERATOR || + token.type === TokenType.RESERVED_DEPENDENT_CLAUSE || + token.type === TokenType.RESERVED_COMMAND || + token.type === TokenType.RESERVED_BINARY_COMMAND + ) { + token = toTabularToken(token, this.cfg.indentStyle); + } + if (token.type === TokenType.RESERVED_COMMAND) { + this.previousCommandToken = token; + } + } + + if (token.type === TokenType.LINE_COMMENT) { + formattedQuery = this.formatLineComment(token, formattedQuery); + } else if (token.type === TokenType.BLOCK_COMMENT) { + formattedQuery = this.formatBlockComment(token, formattedQuery); + } else if (token.type === TokenType.RESERVED_COMMAND) { + this.currentNewline = this.checkNewline(token); + formattedQuery = this.formatCommand(token, formattedQuery); + } else if (token.type === TokenType.RESERVED_BINARY_COMMAND) { + formattedQuery = this.formatBinaryCommand(token, formattedQuery); + } else if (token.type === TokenType.RESERVED_DEPENDENT_CLAUSE) { + formattedQuery = this.formatDependentClause(token, formattedQuery); + } else if (token.type === TokenType.RESERVED_JOIN_CONDITION) { + formattedQuery = this.formatJoinCondition(token, formattedQuery); + } else if (token.type === TokenType.RESERVED_LOGICAL_OPERATOR) { + formattedQuery = this.formatLogicalOperator(token, formattedQuery); + } else if (token.type === TokenType.RESERVED_KEYWORD) { + formattedQuery = this.formatKeyword(token, formattedQuery); + } else if (token.type === TokenType.BLOCK_START) { + formattedQuery = this.formatBlockStart(token, formattedQuery); + } else if (token.type === TokenType.BLOCK_END) { + formattedQuery = this.formatBlockEnd(token, formattedQuery); + } else if (token.type === TokenType.RESERVED_CASE_START) { + formattedQuery = this.formatCaseStart(token, formattedQuery); + } else if (token.type === TokenType.RESERVED_CASE_END) { + formattedQuery = this.formatCaseEnd(token, formattedQuery); + } else if (token.type === TokenType.PLACEHOLDER) { + formattedQuery = this.formatPlaceholder(token, formattedQuery); + } else if (token.type === TokenType.OPERATOR) { + formattedQuery = this.formatOperator(token, formattedQuery); + } else { + formattedQuery = this.formatWord(token, formattedQuery); + } + } + return replaceTabularPlaceholders(formattedQuery); + } + + /** + * Formats word tokens + any potential AS tokens for aliases + */ + private formatWord(token: Token, query: string): string { + let finalQuery = query; + if (this.aliasAs.shouldAddBefore(token)) { + finalQuery = this.formatWithSpaces(this.asTokenFactory.token(), finalQuery); + } + + finalQuery = this.formatWithSpaces(token, finalQuery); + + if (this.aliasAs.shouldAddAfter()) { + finalQuery = this.formatWithSpaces(this.asTokenFactory.token(), finalQuery); + } + + return finalQuery; + } + + /** + * Checks if a newline should currently be inserted + */ + private checkNewline(token: Token): boolean { + const nextTokens = this.tokensUntilNextCommandOrQueryEnd(); + + // auto break if SELECT includes CASE statements + if (this.isWithinSelect() && nextTokens.some(isToken.CASE)) { + return true; + } + + switch (this.cfg.multilineLists) { + case 'always': + return true; + case 'avoid': + return false; + case 'expressionWidth': + return this.inlineWidth(token, nextTokens) > this.cfg.expressionWidth; + default: // multilineLists mode is a number + return ( + this.countClauses(nextTokens) > this.cfg.multilineLists || + this.inlineWidth(token, nextTokens) > this.cfg.expressionWidth + ); + } + } + + private inlineWidth(token: Token, tokens: Token[]): number { + const tokensString = tokens.map(({ value }) => (value === ',' ? value + ' ' : value)).join(''); + return `${token.whitespaceBefore}${token.value} ${tokensString}`.length; + } + + /** + * Counts comma-separated clauses (doesn't count commas inside blocks) + * Note: There's always at least one clause. + */ + private countClauses(tokens: Token[]): number { + let count = 1; + let openBlocks = 0; + for (const { type, value } of tokens) { + if (value === ',' && openBlocks === 0) { + count++; + } + if (type === TokenType.BLOCK_START) { + openBlocks++; + } + if (type === TokenType.BLOCK_END) { + openBlocks--; + } + } + return count; + } + + /** get all tokens between current token and next Reserved Command or query end */ + private tokensUntilNextCommandOrQueryEnd(): Token[] { + const tail = this.tokens.slice(this.index + 1); + return tail.slice( + 0, + tail.length ? tail.findIndex(token => isCommand(token) || token.value === ';') : undefined + ); + } + + /** Formats a line comment onto query */ + private formatLineComment(token: Token, query: string): string { + return this.addNewline(query + this.show(token)); + } + + /** Formats a block comment onto query */ + private formatBlockComment(token: Token, query: string): string { + return this.addNewline(this.addNewline(query) + this.indentComment(token.value)); + } + + /** Aligns comment to current indentation level */ + private indentComment(comment: string): string { + return comment.replace(/\n[ \t]*/gu, '\n' + this.indentation.getIndent() + ' '); + } + + /** + * Formats a Reserved Command onto query, increasing indentation level where necessary + */ + private formatCommand(token: Token, query: string): string { + this.indentation.decreaseTopLevel(); + + query = this.addNewline(query); + + // indent tabular formats, except when preceding a ( + if (this.isTabularStyle()) { + if (this.tokenLookAhead().value !== '(') { + this.indentation.increaseTopLevel(); + } + } else { + this.indentation.increaseTopLevel(); + } + + query += this.equalizeWhitespace(this.show(token)); // print token onto query + if (this.currentNewline && !this.isTabularStyle()) { + query = this.addNewline(query); + } else { + query += ' '; + } + return query; + } + + /** + * Formats a Reserved Binary Command onto query, joining neighbouring tokens + */ + private formatBinaryCommand(token: Token, query: string): string { + const isJoin = /JOIN/i.test(token.value); // check if token contains JOIN + if (!isJoin || this.isTabularStyle()) { + // decrease for boolean set operators or in tabular mode + this.indentation.decreaseTopLevel(); + } + query = this.addNewline(query) + this.equalizeWhitespace(this.show(token)); + return isJoin ? query + ' ' : this.addNewline(query); + } + + /** + * Formats a Reserved Keyword onto query, skipping AS if disabled + */ + private formatKeyword(token: Token, query: string): string { + if (isToken.AS(token) && this.aliasAs.shouldRemove()) { + return query; + } + + return this.formatWithSpaces(token, query); + } + + /** + * Formats a Reserved Dependent Clause token onto query, supporting the keyword that precedes it + */ + private formatDependentClause(token: Token, query: string): string { + return this.addNewline(query) + this.equalizeWhitespace(this.show(token)) + ' '; + } + + // Formats ON and USING keywords + private formatJoinCondition(token: Token, query: string): string { + return query + this.equalizeWhitespace(this.show(token)) + ' '; + } + + /** + * Formats an Operator onto query, following rules for specific characters + */ + private formatOperator(token: Token, query: string): string { + // special operator + if (token.value === ',') { + return this.formatComma(token, query); + } else if (token.value === ';') { + return this.formatQuerySeparator(token, query); + } else if (['$', '['].includes(token.value)) { + return this.formatWithSpaces(token, query, 'before'); + } else if ([':', ']'].includes(token.value)) { + return this.formatWithSpaces(token, query, 'after'); + } else if (['.', '{', '}', '`'].includes(token.value)) { + return this.formatWithoutSpaces(token, query); + } + + // regular operator + if (this.cfg.denseOperators && this.tokenLookBehind().type !== TokenType.RESERVED_COMMAND) { + // do not trim whitespace if SELECT * + return this.formatWithoutSpaces(token, query); + } + return this.formatWithSpaces(token, query); + } + + /** + * Formats a Logical Operator onto query, joining boolean conditions + */ + private formatLogicalOperator(token: Token, query: string): string { + // ignore AND when BETWEEN x [AND] y + if (isToken.AND(token) && isToken.BETWEEN(this.tokenLookBehind(2))) { + return this.formatWithSpaces(token, query); + } + + if (this.isTabularStyle()) { + this.indentation.decreaseTopLevel(); + } + + if (this.cfg.logicalOperatorNewline === 'before') { + return ( + (this.currentNewline ? this.addNewline(query) : query) + + this.equalizeWhitespace(this.show(token)) + + ' ' + ); + } else { + query += this.show(token); + return this.currentNewline ? this.addNewline(query) : query; + } + } + + /** Replace any sequence of whitespace characters with single space */ + private equalizeWhitespace(string: string): string { + return string.replace(/\s+/gu, ' '); + } + + private formatBlockStart(token: Token, query: string): string { + // Take out the preceding space unless there was whitespace there in the original query + // or another opening parens or line comment + const preserveWhitespaceFor = [ + TokenType.BLOCK_START, + TokenType.LINE_COMMENT, + TokenType.OPERATOR, + ]; + if ( + token.whitespaceBefore?.length === 0 && + !preserveWhitespaceFor.includes(this.tokenLookBehind().type) + ) { + query = trimSpacesEnd(query); + } else if (!this.cfg.newlineBeforeOpenParen) { + query = query.trimEnd() + ' '; + } + query += this.show(token); + this.inlineBlock.beginIfPossible(this.tokens, this.index); + + if (!this.inlineBlock.isActive()) { + this.indentation.increaseBlockLevel(); + query = this.addNewline(query); + } + return query; + } + + private formatBlockEnd(token: Token, query: string): string { + if (this.inlineBlock.isActive()) { + this.inlineBlock.end(); + return this.formatWithSpaces(token, query, 'after'); // do not add space before ) + } else { + return this.formatMultilineBlockEnd(token, query); + } + } + + private formatCaseStart(token: Token, query: string): string { + query = this.formatWithSpaces(token, query); + this.indentation.increaseBlockLevel(); + if (this.cfg.multilineLists === 'always') { + query = this.addNewline(query); + } + return query; + } + + private formatCaseEnd(token: Token, query: string): string { + return this.formatMultilineBlockEnd(token, query); + } + + private formatMultilineBlockEnd(token: Token, query: string): string { + this.indentation.decreaseBlockLevel(); + + if (this.isTabularStyle()) { + // +1 extra indentation step for the closing paren + query = this.addNewline(query) + this.indentation.getSingleIndent(); + } else if (this.cfg.newlineBeforeCloseParen) { + query = this.addNewline(query); + } else { + query = query.trimEnd() + ' '; + } + + return this.formatWithSpaces(token, query); + } + + /** + * Formats a Placeholder item onto query, to be replaced with the value of the placeholder + */ + formatPlaceholder(token: Token, query: string): string { + return query + this.params.get(token) + ' '; + } + + /** + * Formats a comma Operator onto query, ending line unless in an Inline Block + */ + private formatComma(token: Token, query: string): string { + query = trimSpacesEnd(query) + this.show(token) + ' '; + + if (this.inlineBlock.isActive()) { + return query; + } else if (isToken.LIMIT(this.getPreviousReservedToken())) { + return query; + } else if (this.currentNewline) { + return this.addNewline(query); + } else { + return query; + } + } + + /** Simple append of token onto query */ + private formatWithoutSpaces(token: Token, query: string): string { + return trimSpacesEnd(query) + this.show(token); + } + + /** + * Add token onto query with spaces - either before, after, or both + */ + private formatWithSpaces( + token: Token, + query: string, + addSpace: 'before' | 'after' | 'both' = 'both' + ): string { + const before = addSpace === 'after' ? trimSpacesEnd(query) : query; + const after = addSpace === 'before' ? '' : ' '; + return before + this.show(token) + after; + } + + private formatQuerySeparator(token: Token, query: string): string { + return [ + trimSpacesEnd(query), + this.cfg.newlineBeforeSemicolon ? '\n' : '', + this.show(token), + ].join(''); + } + + /** Converts token to string, uppercasing if enabled */ + private show(token: Token): string { + if (isReserved(token)) { + switch (this.cfg.keywordCase) { + case 'preserve': + return token.value; + case 'upper': + return token.value.toUpperCase(); + case 'lower': + return token.value.toLowerCase(); + } + } else { + return token.value; + } + } + + /** Inserts a newline onto the query */ + private addNewline(query: string): string { + query = trimSpacesEnd(query); + if (!query.endsWith('\n') && query !== '') { + query += '\n'; + } + return query + this.indentation.getIndent(); + } + + private isTabularStyle(): boolean { + return this.cfg.indentStyle === 'tabularLeft' || this.cfg.indentStyle === 'tabularRight'; + } + + /** Returns the latest encountered reserved keyword token */ + public getPreviousReservedToken(): Token { + return this.previousReservedToken; + } + + /** True when currently within SELECT command */ + public isWithinSelect(): boolean { + return isToken.SELECT(this.previousCommandToken); + } + + /** Fetches nth previous token from the token stream */ + public tokenLookBehind(n = 1): Token { + return this.tokens[this.index - n] || EOF_TOKEN; + } + + /** Fetches nth next token from the token stream */ + public tokenLookAhead(n = 1): Token { + return this.tokens[this.index + n] || EOF_TOKEN; + } +} From abeffb179d979fa7028f3725113bc7e9d384af9c Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Mon, 16 May 2022 17:46:48 +0300 Subject: [PATCH 003/334] Extract config utils --- src/core/Formatter.ts | 2 +- src/core/Indentation.ts | 14 -------------- src/core/StatementFormatter.ts | 17 +++++++---------- src/core/config.ts | 23 +++++++++++++++++++++++ 4 files changed, 31 insertions(+), 25 deletions(-) create mode 100644 src/core/config.ts diff --git a/src/core/Formatter.ts b/src/core/Formatter.ts index e774317529..bcfdcdffd0 100644 --- a/src/core/Formatter.ts +++ b/src/core/Formatter.ts @@ -1,4 +1,3 @@ -import { indentString } from './Indentation'; import Params from './Params'; import Tokenizer from './Tokenizer'; import { FormatOptions } from '../types'; @@ -8,6 +7,7 @@ import AsTokenFactory from './AsTokenFactory'; import Parser, { Statement } from './Parser'; import StatementFormatter from './StatementFormatter'; import { Token } from './token'; +import { indentString } from './config'; /** Main formatter class that produces a final output string from list of tokens */ export default class Formatter { diff --git a/src/core/Indentation.ts b/src/core/Indentation.ts index 9b4e1e9f15..8e5a0033e6 100644 --- a/src/core/Indentation.ts +++ b/src/core/Indentation.ts @@ -1,4 +1,3 @@ -import { FormatOptions } from '../types'; import { last } from '../utils'; const INDENT_TYPE_TOP_LEVEL = 'top-level'; @@ -78,16 +77,3 @@ export default class Indentation { this.indentTypes = []; } } - -/** - * Creates a string to use for one step of indentation. - */ -export function indentString(cfg: FormatOptions): string { - if (cfg.indentStyle === 'tabularLeft' || cfg.indentStyle === 'tabularRight') { - return ' '.repeat(10); - } - if (cfg.useTabs) { - return '\t'; - } - return ' '.repeat(cfg.tabWidth); -} diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 90ec642a81..9deb2cab69 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -1,4 +1,4 @@ -import Indentation, { indentString } from './Indentation'; +import Indentation from './Indentation'; import InlineBlock from './InlineBlock'; import Params from './Params'; import { trimSpacesEnd } from '../utils'; @@ -8,6 +8,7 @@ import { toTabularToken, replaceTabularPlaceholders } from './tabularStyle'; import AliasAs from './AliasAs'; import AsTokenFactory from './AsTokenFactory'; import { Statement } from './Parser'; +import { indentString, isTabularStyle } from './config'; /** Formats single SQL statement */ export default class StatementFormatter { @@ -195,7 +196,7 @@ export default class StatementFormatter { query = this.addNewline(query); // indent tabular formats, except when preceding a ( - if (this.isTabularStyle()) { + if (isTabularStyle(this.cfg)) { if (this.tokenLookAhead().value !== '(') { this.indentation.increaseTopLevel(); } @@ -204,7 +205,7 @@ export default class StatementFormatter { } query += this.equalizeWhitespace(this.show(token)); // print token onto query - if (this.currentNewline && !this.isTabularStyle()) { + if (this.currentNewline && !isTabularStyle(this.cfg)) { query = this.addNewline(query); } else { query += ' '; @@ -217,7 +218,7 @@ export default class StatementFormatter { */ private formatBinaryCommand(token: Token, query: string): string { const isJoin = /JOIN/i.test(token.value); // check if token contains JOIN - if (!isJoin || this.isTabularStyle()) { + if (!isJoin || isTabularStyle(this.cfg)) { // decrease for boolean set operators or in tabular mode this.indentation.decreaseTopLevel(); } @@ -282,7 +283,7 @@ export default class StatementFormatter { return this.formatWithSpaces(token, query); } - if (this.isTabularStyle()) { + if (isTabularStyle(this.cfg)) { this.indentation.decreaseTopLevel(); } @@ -354,7 +355,7 @@ export default class StatementFormatter { private formatMultilineBlockEnd(token: Token, query: string): string { this.indentation.decreaseBlockLevel(); - if (this.isTabularStyle()) { + if (isTabularStyle(this.cfg)) { // +1 extra indentation step for the closing paren query = this.addNewline(query) + this.indentation.getSingleIndent(); } else if (this.cfg.newlineBeforeCloseParen) { @@ -441,10 +442,6 @@ export default class StatementFormatter { return query + this.indentation.getIndent(); } - private isTabularStyle(): boolean { - return this.cfg.indentStyle === 'tabularLeft' || this.cfg.indentStyle === 'tabularRight'; - } - /** Returns the latest encountered reserved keyword token */ public getPreviousReservedToken(): Token { return this.previousReservedToken; diff --git a/src/core/config.ts b/src/core/config.ts new file mode 100644 index 0000000000..f39cab4136 --- /dev/null +++ b/src/core/config.ts @@ -0,0 +1,23 @@ +import { FormatOptions } from '../types'; + +// Utility functions for config options + +/** + * Creates a string to use for one step of indentation. + */ +export function indentString(cfg: FormatOptions): string { + if (cfg.indentStyle === 'tabularLeft' || cfg.indentStyle === 'tabularRight') { + return ' '.repeat(10); + } + if (cfg.useTabs) { + return '\t'; + } + return ' '.repeat(cfg.tabWidth); +} + +/** + * True when indentStyle is one of the tabular ones. + */ +export function isTabularStyle(cfg: FormatOptions): boolean { + return cfg.indentStyle === 'tabularLeft' || cfg.indentStyle === 'tabularRight'; +} From 7e5d658fb9c6e50b6309a9a39cba28e7f447c07a Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Mon, 16 May 2022 18:45:17 +0300 Subject: [PATCH 004/334] Split formatWithSpaces() to three simpler methods --- src/core/StatementFormatter.ts | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 9deb2cab69..cb687d490b 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -259,9 +259,9 @@ export default class StatementFormatter { } else if (token.value === ';') { return this.formatQuerySeparator(token, query); } else if (['$', '['].includes(token.value)) { - return this.formatWithSpaces(token, query, 'before'); + return this.formatWithSpaceBefore(token, query); } else if ([':', ']'].includes(token.value)) { - return this.formatWithSpaces(token, query, 'after'); + return this.formatWithSpaceAfter(token, query); } else if (['.', '{', '}', '`'].includes(token.value)) { return this.formatWithoutSpaces(token, query); } @@ -333,7 +333,7 @@ export default class StatementFormatter { private formatBlockEnd(token: Token, query: string): string { if (this.inlineBlock.isActive()) { this.inlineBlock.end(); - return this.formatWithSpaces(token, query, 'after'); // do not add space before ) + return this.formatWithSpaceAfter(token, query); // do not add space before ) } else { return this.formatMultilineBlockEnd(token, query); } @@ -396,17 +396,16 @@ export default class StatementFormatter { return trimSpacesEnd(query) + this.show(token); } - /** - * Add token onto query with spaces - either before, after, or both - */ - private formatWithSpaces( - token: Token, - query: string, - addSpace: 'before' | 'after' | 'both' = 'both' - ): string { - const before = addSpace === 'after' ? trimSpacesEnd(query) : query; - const after = addSpace === 'before' ? '' : ' '; - return before + this.show(token) + after; + private formatWithSpaces(token: Token, query: string): string { + return query + this.show(token) + ' '; + } + + private formatWithSpaceBefore(token: Token, query: string) { + return query + this.show(token); + } + + private formatWithSpaceAfter(token: Token, query: string) { + return trimSpacesEnd(query) + this.show(token) + ' '; } private formatQuerySeparator(token: Token, query: string): string { From b1ca18656a33ee11d602d53b05d27abe10d3f592 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 17 May 2022 00:04:13 +0300 Subject: [PATCH 005/334] Store raw and clean values inside tokens - value is now a cleaned up canonical token value (e.g. extra spaces stripped and uppercased) - text is the original raw value matched from source This simplifies lots of code that previously used regexes to test for different kinds of tokens. Now simple string equals can be used. --- src/core/AsTokenFactory.ts | 3 ++- src/core/InlineBlock.ts | 14 +++++------ src/core/StatementFormatter.ts | 27 ++++++++-------------- src/core/Tokenizer.ts | 36 ++++++++++++++++++++++++----- src/core/tabularStyle.ts | 4 ++-- src/core/token.ts | 12 ++++------ src/languages/bigquery.formatter.ts | 9 ++++---- src/languages/mariadb.formatter.ts | 2 +- src/languages/mysql.formatter.ts | 2 +- src/languages/plsql.formatter.ts | 4 ++-- src/languages/sparksql.formatter.ts | 8 +++---- src/utils.ts | 6 +++++ 12 files changed, 73 insertions(+), 54 deletions(-) diff --git a/src/core/AsTokenFactory.ts b/src/core/AsTokenFactory.ts index 5988abbdc5..e8810e4386 100644 --- a/src/core/AsTokenFactory.ts +++ b/src/core/AsTokenFactory.ts @@ -10,7 +10,7 @@ export default class AsTokenFactory { private autoDetectCase(tokens: Token[]) { const asTokens = tokens.filter(isToken.AS); - const upperAsTokens = asTokens.filter(({ value }) => value === 'AS'); + const upperAsTokens = asTokens.filter(({ text }) => text === 'AS'); return upperAsTokens.length > asTokens.length / 2 ? 'upper' : 'lower'; } @@ -19,6 +19,7 @@ export default class AsTokenFactory { return { type: TokenType.RESERVED_KEYWORD, value: this.asTokenValue(), + text: this.asTokenValue(), }; } diff --git a/src/core/InlineBlock.ts b/src/core/InlineBlock.ts index 5e5e4300fc..b48e17b4ac 100644 --- a/src/core/InlineBlock.ts +++ b/src/core/InlineBlock.ts @@ -82,14 +82,14 @@ export default class InlineBlock { // Reserved words that cause newlines, comments and semicolons // are not allowed inside inline parentheses block - isForbiddenToken({ type, value }: Token) { + isForbiddenToken(token: Token) { return ( - type === TokenType.RESERVED_COMMAND || - type === TokenType.RESERVED_LOGICAL_OPERATOR || - // type === TokenType.LINE_COMMENT || - type === TokenType.BLOCK_COMMENT || - value === ';' || - isToken.CASE({ type, value }) // CASE cannot have inline blocks + token.type === TokenType.RESERVED_COMMAND || + token.type === TokenType.RESERVED_LOGICAL_OPERATOR || + // token.type === TokenType.LINE_COMMENT || + token.type === TokenType.BLOCK_COMMENT || + token.value === ';' || + isToken.CASE(token) // CASE cannot have inline blocks ); } } diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index cb687d490b..6d2178a988 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -1,7 +1,7 @@ import Indentation from './Indentation'; import InlineBlock from './InlineBlock'; import Params from './Params'; -import { trimSpacesEnd } from '../utils'; +import { equalizeWhitespace, trimSpacesEnd } from '../utils'; import { isReserved, isCommand, isToken, Token, TokenType, EOF_TOKEN } from './token'; import { FormatOptions } from '../types'; import { toTabularToken, replaceTabularPlaceholders } from './tabularStyle'; @@ -204,7 +204,7 @@ export default class StatementFormatter { this.indentation.increaseTopLevel(); } - query += this.equalizeWhitespace(this.show(token)); // print token onto query + query += this.show(token); // print token onto query if (this.currentNewline && !isTabularStyle(this.cfg)) { query = this.addNewline(query); } else { @@ -222,7 +222,7 @@ export default class StatementFormatter { // decrease for boolean set operators or in tabular mode this.indentation.decreaseTopLevel(); } - query = this.addNewline(query) + this.equalizeWhitespace(this.show(token)); + query = this.addNewline(query) + this.show(token); return isJoin ? query + ' ' : this.addNewline(query); } @@ -241,12 +241,12 @@ export default class StatementFormatter { * Formats a Reserved Dependent Clause token onto query, supporting the keyword that precedes it */ private formatDependentClause(token: Token, query: string): string { - return this.addNewline(query) + this.equalizeWhitespace(this.show(token)) + ' '; + return this.addNewline(query) + this.show(token) + ' '; } // Formats ON and USING keywords private formatJoinCondition(token: Token, query: string): string { - return query + this.equalizeWhitespace(this.show(token)) + ' '; + return query + this.show(token) + ' '; } /** @@ -288,22 +288,13 @@ export default class StatementFormatter { } if (this.cfg.logicalOperatorNewline === 'before') { - return ( - (this.currentNewline ? this.addNewline(query) : query) + - this.equalizeWhitespace(this.show(token)) + - ' ' - ); + return (this.currentNewline ? this.addNewline(query) : query) + this.show(token) + ' '; } else { query += this.show(token); return this.currentNewline ? this.addNewline(query) : query; } } - /** Replace any sequence of whitespace characters with single space */ - private equalizeWhitespace(string: string): string { - return string.replace(/\s+/gu, ' '); - } - private formatBlockStart(token: Token, query: string): string { // Take out the preceding space unless there was whitespace there in the original query // or another opening parens or line comment @@ -421,11 +412,11 @@ export default class StatementFormatter { if (isReserved(token)) { switch (this.cfg.keywordCase) { case 'preserve': - return token.value; + return equalizeWhitespace(token.text); case 'upper': - return token.value.toUpperCase(); + return equalizeWhitespace(token.text.toUpperCase()); case 'lower': - return token.value.toLowerCase(); + return equalizeWhitespace(token.text.toLowerCase()); } } else { return token.value; diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 08419e76ff..6662014923 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -1,10 +1,12 @@ import * as regexFactory from './regexFactory'; -import { escapeRegExp } from '../utils'; +import { equalizeWhitespace, escapeRegExp, id } from '../utils'; import { Token, TokenType } from './token'; // convert to partial type import in TS 4.5 export const WHITESPACE_REGEX = /^(\s+)/u; const NULL_REGEX = /(?!)/; // zero-width negative lookahead, matches nothing +const toCanonicalKeyword = (text: string) => equalizeWhitespace(text.toUpperCase()); + /** Struct that defines how a SQL language can be broken into tokens */ interface TokenizerOptions { reservedKeywords: string[]; @@ -142,7 +144,7 @@ export default class Tokenizer { throw new Error(`Parse error: Unexpected "${input.slice(0, 100)}"`); } // Advance the string - input = input.substring(token.value.length); + input = input.substring(token.text.length); tokens.push({ ...token, whitespaceBefore }); } @@ -164,6 +166,7 @@ export default class Tokenizer { input, type: tokenType, regex: this.REGEX_MAP[tokenType], + transform: id, }); /** Attempts to match next token from input string, tests RegExp patterns in decreasing priority */ @@ -207,7 +210,12 @@ export default class Tokenizer { ]; return placeholderTokenRegexMap.reduce((acc, { regex, parseKey }) => { - const token = this.getTokenOnFirstMatch({ input, regex, type: TokenType.PLACEHOLDER }); + const token = this.getTokenOnFirstMatch({ + input, + regex, + type: TokenType.PLACEHOLDER, + transform: id, + }); return token ? { ...token, key: parseKey(token.value) } : acc; }, undefined as Token | undefined); } @@ -240,8 +248,15 @@ export default class Tokenizer { ]; return reservedTokenList.reduce( - (matchedToken, tokenType) => matchedToken || this.matchToken(tokenType)(input), - undefined as Token | undefined + (matchedToken: Token | undefined, tokenType) => + matchedToken || + this.getTokenOnFirstMatch({ + input, + type: tokenType, + regex: this.REGEX_MAP[tokenType], + transform: toCanonicalKeyword, + }), + undefined ); } @@ -256,12 +271,21 @@ export default class Tokenizer { input, type, regex, + transform, }: { input: string; type: TokenType; regex: RegExp; + transform: (s: string) => string; }): Token | undefined { const matches = input.match(regex); - return matches ? ({ type, value: matches[1] } as Token) : undefined; + if (matches) { + return { + type, + text: matches[1], + value: transform(matches[1]), + }; + } + return undefined; } } diff --git a/src/core/tabularStyle.ts b/src/core/tabularStyle.ts index 6221b99039..205b448462 100644 --- a/src/core/tabularStyle.ts +++ b/src/core/tabularStyle.ts @@ -16,7 +16,7 @@ export function toTabularToken(token: Token, indentStyle: IndentStyle): Token { return token; } - let bufferItem = token.value; // store which part of keyword receives 10-space buffer + let bufferItem = token.text; // store which part of keyword receives 10-space buffer let tail = [] as string[]; // rest of keyword if (bufferItem.length >= 10 && bufferItem.includes(' ')) { // split for long keywords like INNER JOIN or UNION DISTINCT @@ -31,7 +31,7 @@ export function toTabularToken(token: Token, indentStyle: IndentStyle): Token { return { ...token, - value: bufferItem + ['', ...tail].join(' '), + text: bufferItem + ['', ...tail].join(' '), }; } diff --git a/src/core/token.ts b/src/core/token.ts index ceaf1b2054..9ef22229b6 100644 --- a/src/core/token.ts +++ b/src/core/token.ts @@ -22,8 +22,9 @@ export enum TokenType { /** Struct to store the most basic cohesive unit of language grammar */ export interface Token { - value: string; type: TokenType; + text: string; // The raw original text that was matched + value: string; // Cleaned up `text` e.g. keyword converted to uppercase and extra spaces removed key?: string; whitespaceBefore?: string; } @@ -32,19 +33,16 @@ export interface Token { * For use as a "missing token" * e.g. in lookAhead and lookBehind to avoid dealing with null values */ -export const EOF_TOKEN = { type: TokenType.EOF, value: '«EOF»' }; +export const EOF_TOKEN = { type: TokenType.EOF, text: '«EOF»', value: '«EOF»' }; /** Special Unicode character to serve as a placeholder for tabular formats as \w whitespace is unavailable */ export const ZWS = '​'; // uses zero-width space (​ / U+200B) -const ZWS_REGEX = '\u200b'; -const spaces = `[${ZWS_REGEX}\\s]`; /** Checks if two tokens are equivalent */ export const testToken = - (compareToken: Token) => + (compareToken: { type: TokenType; value: string }) => (token: Token): boolean => - token.type === compareToken.type && - new RegExp(`^${spaces}*${compareToken.value}${spaces}*$`, 'iu').test(token.value); + token.type === compareToken.type && token.value === compareToken.value; /** Util object that allows for easy checking of Reserved Keywords */ export const isToken = { diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index 58c6201f52..159e7debc1 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -872,14 +872,13 @@ function preprocess(tokens: Token[]) { const token = tokens[i]; const nextToken = tokens[i + 1] || EOF_TOKEN; - if ((/ARRAY/i.test(token.value) || /STRUCT/i.test(token.value)) && nextToken.value === '<') { + if ((token.value === 'ARRAY' || token.value === 'STRUCT') && nextToken.value === '<') { const endIndex = findClosingAngleBracketIndex(tokens, i + 1); + const typeDefTokens = tokens.slice(i, endIndex + 1); processed.push({ ...token, - value: tokens - .slice(i, endIndex + 1) - .map(t => t.value) - .join(''), + value: typeDefTokens.map(t => t.value).join(''), + text: typeDefTokens.map(t => t.text).join(''), }); i = endIndex; } else { diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index ecef2f9df1..e0143a3845 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1197,7 +1197,7 @@ function preprocess(tokens: Token[]) { const nextToken = tokens[i + 1] || EOF_TOKEN; if (isToken.SET(token) && nextToken.value === '(') { // This is SET datatype, not SET statement - return { type: TokenType.RESERVED_KEYWORD, value: token.value }; + return { ...token, type: TokenType.RESERVED_KEYWORD }; } return token; }); diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index 527cf919d5..ce49c3939d 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1360,7 +1360,7 @@ function preprocess(tokens: Token[]) { const nextToken = tokens[i + 1] || EOF_TOKEN; if (isToken.SET(token) && nextToken.value === '(') { // This is SET datatype, not SET statement - return { type: TokenType.RESERVED_KEYWORD, value: token.value }; + return { ...token, type: TokenType.RESERVED_KEYWORD }; } return token; }); diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 3838cc3c84..76c00c68eb 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -499,12 +499,12 @@ function preprocess(tokens: Token[]) { // `table`[.]`column` if (token.value === '.' && nextToken.value.startsWith('`') && prevToken.value.endsWith('`')) { // This is an operator, do not insert spaces - return { type: TokenType.OPERATOR, value: token.value }; + return { ...token, type: TokenType.OPERATOR }; } // BY [SET] if (isToken.SET(token) && isToken.BY(previousReservedToken)) { - return { type: TokenType.RESERVED_KEYWORD, value: token.value }; + return { ...token, type: TokenType.RESERVED_KEYWORD }; } if (isReserved(token)) { diff --git a/src/languages/sparksql.formatter.ts b/src/languages/sparksql.formatter.ts index 7d757cd080..dffff9f5a8 100644 --- a/src/languages/sparksql.formatter.ts +++ b/src/languages/sparksql.formatter.ts @@ -823,14 +823,14 @@ function preprocess(tokens: Token[]) { // [WINDOW](...) if (isToken.WINDOW(token) && nextToken.type === TokenType.BLOCK_START) { // This is a function call, treat it as a reserved word - return { type: TokenType.RESERVED_KEYWORD, value: token.value }; + return { ...token, type: TokenType.RESERVED_KEYWORD }; } // TODO: deprecate this once ITEMS is merged with COLLECTION - if (/ITEMS/i.test(token.value) && token.type === TokenType.RESERVED_KEYWORD) { - if (!(/COLLECTION/i.test(prevToken.value) && /TERMINATED/i.test(nextToken.value))) { + if (token.value === 'ITEMS' && token.type === TokenType.RESERVED_KEYWORD) { + if (!(prevToken.value === 'COLLECTION' && nextToken.value === 'TERMINATED')) { // this is a word and not COLLECTION ITEMS - return { type: TokenType.WORD, value: token.value }; + return { type: TokenType.WORD, text: token.text, value: token.text }; } } diff --git a/src/utils.ts b/src/utils.ts index 5322b1a257..ca4638a51f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -22,3 +22,9 @@ export const maxLength = (strings: string[]) => strings.reduce((max, cur) => Math.max(max, cur.length), 0); export const isNumber = (value: any): value is number => typeof value === 'number'; + +// replaces long whitespace sequences with just one space +export const equalizeWhitespace = (s: string) => s.replace(/\s+/gu, ' '); + +// identity function +export const id = (x: T) => x; From 7fa33026d511ada5e36de44533e9408570f01825 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 17 May 2022 17:54:15 +0300 Subject: [PATCH 006/334] Document SQL syntax for identifiers --- sql/syntax.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 sql/syntax.md diff --git a/sql/syntax.md b/sql/syntax.md new file mode 100644 index 0000000000..3daffd7051 --- /dev/null +++ b/sql/syntax.md @@ -0,0 +1,26 @@ +# SQL syntax + +Reference of SQL syntax variations. + +## Identifiers + +SQL standard specifies double-quotes `".."` for delimited identifiers. +There is a considerable variation in implementations: + +- `` `..` `` [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical) +- `".."` [DB2](https://www.ibm.com/docs/en/db2/9.7?topic=elements-identifiers) +- `` `..` `` [Hive](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362034#LanguageManualDDL-AlterColumn) +- `` `..` ``, `".."`1, `[..]`2 [MariaDB](https://mariadb.com/kb/en/identifier-names/) +- `` `..` ``, `".."`1 [MySQL](https://dev.mysql.com/doc/refman/8.0/en/identifiers.html) +- `` `..` `` [N1QL](https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/identifiers.html) +- `".."` [PL/SQL](https://docs.oracle.com/database/121/LNPLS/fundamentals.htm#LNPLS99973) +- `".."`, `U&".."` [PostgreSQL](https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS) +- `".."` [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_names.html) +- `` `..` `` [Spark](https://spark.apache.org/docs/latest/sql-ref-identifier.html) +- `".."`, `` `..` ``, `[..]` [SQLite](https://www.sqlite.org/lang_keywords.html) +- `".."`, `[..]` [Transact-SQL](https://docs.microsoft.com/en-us/sql/relational-databases/databases/database-identifiers?view=sql-server-ver15) + +Notes: + +1. when ANSI_QUOTES mode enabled +2. when MSSQL mode enabled From a3164b3ca281e5c0a50e5fa3a7d6420c9ef304d1 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 18 May 2022 12:10:55 +0300 Subject: [PATCH 007/334] Document normal identifier syntax --- sql/syntax.md | 59 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/sql/syntax.md b/sql/syntax.md index 3daffd7051..ee758d14ca 100644 --- a/sql/syntax.md +++ b/sql/syntax.md @@ -4,23 +4,58 @@ Reference of SQL syntax variations. ## Identifiers +## Normal identifiers + +Most dialects support `[a-zA-Z_]` as first character and `[a-zA-Z0-9_]` as rest of the characters. +The differences from this are listed below: + +- [BigQuery][]: single dashes (`-`) can be used, but not at the beginning or end. +- [DB2][]: first char can only be a (uppercase) letter (a lowercase letter gets converted to uppercase). +- [Hive][]: _(no differences)_ +- [MariaDB][]: no first-letter restrictions. The characters `[a-zA-Z0-9_$]` and unicode letters are allowed everywhere. Can begin with digit, but can't only contain digits. +- [MySQL][]: same as MariaDB. +- [N1QL][]: _(no differences)_ +- [PL/SQL][]: can't start with `_`. Allows `$`, `#` in rest of the identifier. +- [PostgreSQL][]: additionally `$` after first char. Also unicode letters are allowed. +- [Redshift][]: also unicode letters are allowed. +- [Spark][]: _Seems like the usual syntax is allowed. But the docs are confusing._ +- [SQLite][sqlite-syntax-pdf]: _(no differences)_ +- [Transact-SQL][]: `@` and `#` are allowed as first chars plus `$` in the rest. Also unicode letters are allowed. + Though the beginning `@` signifies a local variable or parameter and `#` a temporary table or procedure. + +## Delimited identifiers + SQL standard specifies double-quotes `".."` for delimited identifiers. There is a considerable variation in implementations: -- `` `..` `` [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical) -- `".."` [DB2](https://www.ibm.com/docs/en/db2/9.7?topic=elements-identifiers) -- `` `..` `` [Hive](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362034#LanguageManualDDL-AlterColumn) -- `` `..` ``, `".."`1, `[..]`2 [MariaDB](https://mariadb.com/kb/en/identifier-names/) -- `` `..` ``, `".."`1 [MySQL](https://dev.mysql.com/doc/refman/8.0/en/identifiers.html) -- `` `..` `` [N1QL](https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/identifiers.html) -- `".."` [PL/SQL](https://docs.oracle.com/database/121/LNPLS/fundamentals.htm#LNPLS99973) -- `".."`, `U&".."` [PostgreSQL](https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS) -- `".."` [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_names.html) -- `` `..` `` [Spark](https://spark.apache.org/docs/latest/sql-ref-identifier.html) -- `".."`, `` `..` ``, `[..]` [SQLite](https://www.sqlite.org/lang_keywords.html) -- `".."`, `[..]` [Transact-SQL](https://docs.microsoft.com/en-us/sql/relational-databases/databases/database-identifiers?view=sql-server-ver15) +- `` `..` `` [BigQuery][] +- `".."` [DB2][] +- `` `..` `` [Hive][] +- `` `..` ``, `".."`1, `[..]`2 [MariaDB][] +- `` `..` ``, `".."`1 [MySQL][] +- `` `..` `` [N1QL][] +- `".."` [PL/SQL][] +- `".."`, `U&".."` [PostgreSQL][] +- `".."` [Redshift][] +- `` `..` `` [Spark][] +- `".."`, `` `..` ``, `[..]` [SQLite][sqlite-keywords] +- `".."`, `[..]` [Transact-SQL][] Notes: 1. when ANSI_QUOTES mode enabled 2. when MSSQL mode enabled + +[bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical +[db2]: https://www.ibm.com/docs/en/db2/9.7?topic=elements-identifiers +[hive]: https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362034#LanguageManualDDL-AlterColumn +[mariadb]: https://mariadb.com/kb/en/identifier-names/ +[mysql]: https://dev.mysql.com/doc/refman/8.0/en/identifiers.html +[n1ql]: https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/identifiers.html +[pl/sql]: https://docs.oracle.com/database/121/LNPLS/fundamentals.htm#LNPLS99973 +[postgresql]: https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS +[redshift]: https://docs.aws.amazon.com/redshift/latest/dg/r_names.html +[spark]: https://spark.apache.org/docs/latest/sql-ref-identifier.html +[sqlite-keywords]: https://www.sqlite.org/lang_keywords.html +[sqlite-syntax-pdf]: https://www.pearsonhighered.com/assets/samplechapter/0/6/7/2/067232685X.pdf +[transact-sql]: https://docs.microsoft.com/en-us/sql/relational-databases/databases/database-identifiers?view=sql-server-ver15 From f9d6c85c6bf8d9900b7dc558b5e20075cd970373 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 18 May 2022 12:42:48 +0300 Subject: [PATCH 008/334] Links to SQL formatting styles and other tools --- sql/formatting.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 sql/formatting.md diff --git a/sql/formatting.md b/sql/formatting.md new file mode 100644 index 0000000000..40c9e5ca8c --- /dev/null +++ b/sql/formatting.md @@ -0,0 +1,19 @@ +# SQL formatting + +## SQL formatting standards + +Links to recources describing how to format SQL. + +- [StackOverflow: SQL Formatting standards](https://stackoverflow.com/questions/519876/sql-formatting-standards) +- [StackOverflow: What SQL coding standard do you follow?](https://stackoverflow.com/questions/522356/what-sql-coding-standard-do-you-follow) + +## Tools + +Other tools that perform SQL formatting. + +- [sqlparse](https://pypi.org/project/sqlparse/) Python library. [online demo](https://sqlformat.org/) +- [Instant SQL formatter](https://www.dpriver.com/pp/sqlformat.htm) online tool and VS plugin. +- [SQL Complete](https://www.devart.com/dbforge/sql/sqlcomplete/) a proprietary tool from Devart. +- [SQL Formatter](https://www.apexsql.com/sql-tools-refactor.aspx) a proprietary tool from ApexSQL. +- [SQLinForm](https://www.sqlinform.com/) a proprietary tool (also free versions available) +- [SQL Pretty Printer](https://www.dpriver.com/) a proprietary tool. From b1d0bac2a5c48981a52d6f8194bc8ddbdf6f5919 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 18 May 2022 19:34:27 +0300 Subject: [PATCH 009/334] Additional links to formatters and articles --- sql/formatting.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/sql/formatting.md b/sql/formatting.md index 40c9e5ca8c..dabd73ff47 100644 --- a/sql/formatting.md +++ b/sql/formatting.md @@ -6,14 +6,24 @@ Links to recources describing how to format SQL. - [StackOverflow: SQL Formatting standards](https://stackoverflow.com/questions/519876/sql-formatting-standards) - [StackOverflow: What SQL coding standard do you follow?](https://stackoverflow.com/questions/522356/what-sql-coding-standard-do-you-follow) +- [StackOverflow: SQL Statement indentation good practice](https://stackoverflow.com/questions/272210/sql-statement-indentation-good-practice) +- [How to indent SQL? The definitive guide to simple and effective indentation](https://www.linkedin.com/pulse/how-indent-sql-definitive-guide-simple-effective-gianni-tommasi/) +- [24 Rules to the SQL Formatting Standard](https://learnsql.com/blog/24-rules-sql-code-formatting-standard/) +- [How to Properly Format SQL Code](https://dzone.com/articles/24-rules-to-the-sql-formatting-standard) +- [SQL style guide by Simon Holywell](https://www.sqlstyle.guide/) +- [Transact-SQL Formatting Standards](https://www.red-gate.com/simple-talk/databases/sql-server/t-sql-programming-sql-server/transact-sql-formatting-standards-coding-styles/) ## Tools Other tools that perform SQL formatting. -- [sqlparse](https://pypi.org/project/sqlparse/) Python library. [online demo](https://sqlformat.org/) +- [sqlparse](https://pypi.org/project/sqlparse/) Python library. [Online demo](https://sqlformat.org/) - [Instant SQL formatter](https://www.dpriver.com/pp/sqlformat.htm) online tool and VS plugin. -- [SQL Complete](https://www.devart.com/dbforge/sql/sqlcomplete/) a proprietary tool from Devart. +- [Freeformatter.com](https://www.freeformatter.com/sql-formatter.html) a site with online formatters for many languages. +- [Code Beautify](https://codebeautify.org/sqlformatter) another site with multiple formatters. +- [SQL Complete](https://www.devart.com/dbforge/sql/sqlcomplete/) a proprietary tool from Devart. [Online version](https://sql-format.com/) - [SQL Formatter](https://www.apexsql.com/sql-tools-refactor.aspx) a proprietary tool from ApexSQL. - [SQLinForm](https://www.sqlinform.com/) a proprietary tool (also free versions available) - [SQL Pretty Printer](https://www.dpriver.com/) a proprietary tool. +- [SQL Fluff](https://docs.sqlfluff.com/en/stable/index.html) A linter for SQL (also has formatting rules). +- [SQL Prompt](https://www.red-gate.com/website/sql-formatter) A proprietary tool, has an online demo of the formatter. From 6dea67bc977125bb2d065b395a9416d37b83d147 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 18 May 2022 21:05:00 +0300 Subject: [PATCH 010/334] Rename sparksql files to spark So the name would align with language:"spark" value. --- ...arksql.formatter.ts => spark.formatter.ts} | 28 +++++++++---------- src/sqlFormatter.ts | 4 +-- test/{sparksql.test.ts => spark.test.ts} | 10 +++---- 3 files changed, 21 insertions(+), 21 deletions(-) rename src/languages/{sparksql.formatter.ts => spark.formatter.ts} (94%) rename test/{sparksql.test.ts => spark.test.ts} (92%) diff --git a/src/languages/sparksql.formatter.ts b/src/languages/spark.formatter.ts similarity index 94% rename from src/languages/sparksql.formatter.ts rename to src/languages/spark.formatter.ts index dffff9f5a8..605ce59fb8 100644 --- a/src/languages/sparksql.formatter.ts +++ b/src/languages/spark.formatter.ts @@ -777,7 +777,7 @@ const reservedBinaryCommands = [ const reservedDependentClauses = ['WHEN', 'ELSE']; // http://spark.apache.org/docs/latest/sql-programming-guide.html -export default class SparkSqlFormatter extends Formatter { +export default class SparkFormatter extends Formatter { static reservedCommands = reservedCommands; static reservedBinaryCommands = reservedBinaryCommands; static reservedDependentClauses = reservedDependentClauses; @@ -797,19 +797,19 @@ export default class SparkSqlFormatter extends Formatter { tokenizer() { return new Tokenizer({ - reservedCommands: SparkSqlFormatter.reservedCommands, - reservedBinaryCommands: SparkSqlFormatter.reservedBinaryCommands, - reservedDependentClauses: SparkSqlFormatter.reservedDependentClauses, - reservedJoinConditions: SparkSqlFormatter.reservedJoinConditions, - reservedLogicalOperators: SparkSqlFormatter.reservedLogicalOperators, - reservedKeywords: SparkSqlFormatter.reservedKeywords, - stringTypes: SparkSqlFormatter.stringTypes, - blockStart: SparkSqlFormatter.blockStart, - blockEnd: SparkSqlFormatter.blockEnd, - indexedPlaceholderTypes: SparkSqlFormatter.indexedPlaceholderTypes, - namedPlaceholderTypes: SparkSqlFormatter.namedPlaceholderTypes, - lineCommentTypes: SparkSqlFormatter.lineCommentTypes, - operators: SparkSqlFormatter.operators, + reservedCommands: SparkFormatter.reservedCommands, + reservedBinaryCommands: SparkFormatter.reservedBinaryCommands, + reservedDependentClauses: SparkFormatter.reservedDependentClauses, + reservedJoinConditions: SparkFormatter.reservedJoinConditions, + reservedLogicalOperators: SparkFormatter.reservedLogicalOperators, + reservedKeywords: SparkFormatter.reservedKeywords, + stringTypes: SparkFormatter.stringTypes, + blockStart: SparkFormatter.blockStart, + blockEnd: SparkFormatter.blockEnd, + indexedPlaceholderTypes: SparkFormatter.indexedPlaceholderTypes, + namedPlaceholderTypes: SparkFormatter.namedPlaceholderTypes, + lineCommentTypes: SparkFormatter.lineCommentTypes, + operators: SparkFormatter.operators, preprocess, }); } diff --git a/src/sqlFormatter.ts b/src/sqlFormatter.ts index 4040ab2ca2..c3f6e41d6d 100644 --- a/src/sqlFormatter.ts +++ b/src/sqlFormatter.ts @@ -7,7 +7,7 @@ import N1qlFormatter from './languages/n1ql.formatter'; import PlSqlFormatter from './languages/plsql.formatter'; import PostgreSqlFormatter from './languages/postgresql.formatter'; import RedshiftFormatter from './languages/redshift.formatter'; -import SparkSqlFormatter from './languages/sparksql.formatter'; +import SparkFormatter from './languages/spark.formatter'; import SqliteFormatter from './languages/sqlite.formatter'; import StandardSqlFormatter from './languages/standardsql.formatter'; import TSqlFormatter from './languages/tsql.formatter'; @@ -25,7 +25,7 @@ export const formatters = { plsql: PlSqlFormatter, postgresql: PostgreSqlFormatter, redshift: RedshiftFormatter, - spark: SparkSqlFormatter, + spark: SparkFormatter, sql: StandardSqlFormatter, sqlite: SqliteFormatter, tsql: TSqlFormatter, diff --git a/test/sparksql.test.ts b/test/spark.test.ts similarity index 92% rename from test/sparksql.test.ts rename to test/spark.test.ts index 3c560315d1..7a015cb01a 100644 --- a/test/sparksql.test.ts +++ b/test/spark.test.ts @@ -1,6 +1,6 @@ import dedent from 'dedent-js'; import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; -import SparkSqlFormatter from '../src/languages/sparksql.formatter'; +import SparkFormatter from '../src/languages/spark.formatter'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; import supportsAlterTable from './features/alterTable'; @@ -12,21 +12,21 @@ import supportsSchema from './features/schema'; import supportsStrings from './features/strings'; import supportsArray from './features/array'; -describe('SparkSqlFormatter', () => { +describe('SparkFormatter', () => { const language = 'spark'; const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(language, format); supportsCreateTable(language, format); supportsAlterTable(language, format); - supportsStrings(language, format, SparkSqlFormatter.stringTypes); + supportsStrings(language, format, SparkFormatter.stringTypes); supportsBetween(language, format); supportsSchema(language, format); supportsOperators( language, format, - SparkSqlFormatter.operators, - SparkSqlFormatter.reservedLogicalOperators + SparkFormatter.operators, + SparkFormatter.reservedLogicalOperators ); supportsArray(language, format); supportsJoin(language, format, { From 8c262fbb28ae7d36256878f5e79356c4610dcd8c Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 18 May 2022 21:09:14 +0300 Subject: [PATCH 011/334] Rename standardsql files to sql So it aligns with language:"sql" name --- ...ndardsql.formatter.ts => sql.formatter.ts} | 26 +++++++++---------- src/sqlFormatter.ts | 4 +-- test/sql.test.ts | 10 +++---- test/sqlite.test.ts | 2 +- 4 files changed, 21 insertions(+), 21 deletions(-) rename src/languages/{standardsql.formatter.ts => sql.formatter.ts} (87%) diff --git a/src/languages/standardsql.formatter.ts b/src/languages/sql.formatter.ts similarity index 87% rename from src/languages/standardsql.formatter.ts rename to src/languages/sql.formatter.ts index ee34dca9a7..ac749dea68 100644 --- a/src/languages/standardsql.formatter.ts +++ b/src/languages/sql.formatter.ts @@ -369,7 +369,7 @@ const reservedBinaryCommands = [ */ const reservedDependentClauses = ['WHEN', 'ELSE']; -export default class StandardSqlFormatter extends Formatter { +export default class SqlFormatter extends Formatter { static reservedCommands = reservedCommands; static reservedBinaryCommands = reservedBinaryCommands; static reservedDependentClauses = reservedDependentClauses; @@ -386,18 +386,18 @@ export default class StandardSqlFormatter extends Formatter { tokenizer() { return new Tokenizer({ - reservedCommands: StandardSqlFormatter.reservedCommands, - reservedBinaryCommands: StandardSqlFormatter.reservedBinaryCommands, - reservedDependentClauses: StandardSqlFormatter.reservedDependentClauses, - reservedJoinConditions: StandardSqlFormatter.reservedJoinConditions, - reservedLogicalOperators: StandardSqlFormatter.reservedLogicalOperators, - reservedKeywords: StandardSqlFormatter.reservedKeywords, - stringTypes: StandardSqlFormatter.stringTypes, - blockStart: StandardSqlFormatter.blockStart, - blockEnd: StandardSqlFormatter.blockEnd, - indexedPlaceholderTypes: StandardSqlFormatter.indexedPlaceholderTypes, - namedPlaceholderTypes: StandardSqlFormatter.namedPlaceholderTypes, - lineCommentTypes: StandardSqlFormatter.lineCommentTypes, + reservedCommands: SqlFormatter.reservedCommands, + reservedBinaryCommands: SqlFormatter.reservedBinaryCommands, + reservedDependentClauses: SqlFormatter.reservedDependentClauses, + reservedJoinConditions: SqlFormatter.reservedJoinConditions, + reservedLogicalOperators: SqlFormatter.reservedLogicalOperators, + reservedKeywords: SqlFormatter.reservedKeywords, + stringTypes: SqlFormatter.stringTypes, + blockStart: SqlFormatter.blockStart, + blockEnd: SqlFormatter.blockEnd, + indexedPlaceholderTypes: SqlFormatter.indexedPlaceholderTypes, + namedPlaceholderTypes: SqlFormatter.namedPlaceholderTypes, + lineCommentTypes: SqlFormatter.lineCommentTypes, }); } } diff --git a/src/sqlFormatter.ts b/src/sqlFormatter.ts index c3f6e41d6d..e6febe62f9 100644 --- a/src/sqlFormatter.ts +++ b/src/sqlFormatter.ts @@ -9,7 +9,7 @@ import PostgreSqlFormatter from './languages/postgresql.formatter'; import RedshiftFormatter from './languages/redshift.formatter'; import SparkFormatter from './languages/spark.formatter'; import SqliteFormatter from './languages/sqlite.formatter'; -import StandardSqlFormatter from './languages/standardsql.formatter'; +import SqlFormatter from './languages/sql.formatter'; import TSqlFormatter from './languages/tsql.formatter'; import { FormatOptions } from './types'; @@ -26,7 +26,7 @@ export const formatters = { postgresql: PostgreSqlFormatter, redshift: RedshiftFormatter, spark: SparkFormatter, - sql: StandardSqlFormatter, + sql: SqlFormatter, sqlite: SqliteFormatter, tsql: TSqlFormatter, }; diff --git a/test/sql.test.ts b/test/sql.test.ts index 79dbe27629..d79a8719e8 100644 --- a/test/sql.test.ts +++ b/test/sql.test.ts @@ -1,6 +1,6 @@ import dedent from 'dedent-js'; import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; -import StandardSqlFormatter from '../src/languages/standardsql.formatter'; +import SqlFormatter from '../src/languages/sql.formatter'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; import supportsCreateTable from './features/createTable'; @@ -13,7 +13,7 @@ import supportsOperators from './features/operators'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; -describe('StandardSqlFormatter', () => { +describe('SqlFormatter', () => { const language = 'sql'; const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); @@ -22,15 +22,15 @@ describe('StandardSqlFormatter', () => { supportsConstraints(language, format); supportsAlterTable(language, format); supportsDeleteFrom(language, format); - supportsStrings(language, format, StandardSqlFormatter.stringTypes); + supportsStrings(language, format, SqlFormatter.stringTypes); supportsBetween(language, format); supportsSchema(language, format); supportsJoin(language, format); supportsOperators( language, format, - StandardSqlFormatter.operators, - StandardSqlFormatter.reservedLogicalOperators + SqlFormatter.operators, + SqlFormatter.reservedLogicalOperators ); it('replaces ? indexed placeholders with param values', () => { diff --git a/test/sqlite.test.ts b/test/sqlite.test.ts index 9160bdbacc..1a015f3c72 100644 --- a/test/sqlite.test.ts +++ b/test/sqlite.test.ts @@ -1,6 +1,6 @@ import dedent from 'dedent-js'; import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; -import SqliteFormatter from '../src/languages/standardsql.formatter'; +import SqliteFormatter from '../src/languages/sqlite.formatter'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; import supportsCreateTable from './features/createTable'; From 26106fa1836ebc682690e2d2c397229830e81be2 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 18 May 2022 21:34:31 +0300 Subject: [PATCH 012/334] Eliminate unnecessary static fields from *Formatter classes --- src/languages/bigquery.formatter.ts | 40 ++++++++++----------------- src/languages/db2.formatter.ts | 40 ++++++++++----------------- src/languages/hive.formatter.ts | 40 ++++++++++----------------- src/languages/mariadb.formatter.ts | 33 ++++++++-------------- src/languages/mysql.formatter.ts | 33 ++++++++-------------- src/languages/n1ql.formatter.ts | 27 ++++++------------ src/languages/plsql.formatter.ts | 33 ++++++++-------------- src/languages/postgresql.formatter.ts | 36 +++++++++--------------- src/languages/redshift.formatter.ts | 36 +++++++++--------------- src/languages/spark.formatter.ts | 36 +++++++++--------------- src/languages/sql.formatter.ts | 30 +++++++------------- src/languages/sqlite.formatter.ts | 34 ++++++++--------------- src/languages/tsql.formatter.ts | 39 ++++++++++---------------- 13 files changed, 159 insertions(+), 298 deletions(-) diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index 159e7debc1..5c8786bcf7 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -825,41 +825,29 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://cloud.google.com/bigquery/docs/reference/#standard-sql-reference export default class BigQueryFormatter extends Formatter { - static reservedCommands = reservedCommands; - static reservedBinaryCommands = reservedBinaryCommands; - static reservedDependentClauses = reservedDependentClauses; - static reservedJoinConditions = ['ON', 'USING']; static reservedLogicalOperators = ['AND', 'OR']; - static fullReservedWords = dedupe([ - ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), - ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), - ]); - static stringTypes: StringPatternType[] = ['""', "''", '``']; // add: '''''', """""" ; prefixes: r, b - static blockStart = ['(']; - static blockEnd = [')']; - static indexedPlaceholderTypes = ['?']; - static namedPlaceholderTypes = []; - static lineCommentTypes = ['--', '#']; - static specialWordChars = { any: '_@$-' }; static operators = ['>>', '<<', '||']; // TODO: handle trailing comma in select clause tokenizer() { return new Tokenizer({ - reservedCommands: BigQueryFormatter.reservedCommands, - reservedBinaryCommands: BigQueryFormatter.reservedBinaryCommands, - reservedDependentClauses: BigQueryFormatter.reservedDependentClauses, - reservedJoinConditions: BigQueryFormatter.reservedJoinConditions, + reservedCommands, + reservedBinaryCommands, + reservedDependentClauses, + reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: BigQueryFormatter.reservedLogicalOperators, - reservedKeywords: BigQueryFormatter.fullReservedWords, + reservedKeywords: dedupe([ + ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), + ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), + ]), stringTypes: BigQueryFormatter.stringTypes, - blockStart: BigQueryFormatter.blockStart, - blockEnd: BigQueryFormatter.blockEnd, - indexedPlaceholderTypes: BigQueryFormatter.indexedPlaceholderTypes, - namedPlaceholderTypes: BigQueryFormatter.namedPlaceholderTypes, - lineCommentTypes: BigQueryFormatter.lineCommentTypes, - specialWordChars: BigQueryFormatter.specialWordChars, + blockStart: ['('], + blockEnd: [')'], + indexedPlaceholderTypes: ['?'], + namedPlaceholderTypes: [], + lineCommentTypes: ['--', '#'], + specialWordChars: { any: '_@$-' }, operators: BigQueryFormatter.operators, preprocess, }); diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index 7246a4cac2..97e2868c2b 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -859,40 +859,28 @@ const reservedDependentClauses = ['WHEN', 'ELSE', 'ELSEIF']; // https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_72/db2/rbafzintro.htm export default class Db2Formatter extends Formatter { - static reservedCommands = reservedCommands; - static reservedBinaryCommands = reservedBinaryCommands; - static reservedDependentClauses = reservedDependentClauses; - static reservedJoinConditions = ['ON', 'USING']; static reservedLogicalOperators = ['AND', 'OR']; - static fullReservedWords = dedupe([ - ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), - ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), - ]); - static stringTypes: StringPatternType[] = [`""`, "''", '``', '[]', "x''"]; - static blockStart = ['(']; - static blockEnd = [')']; - static indexedPlaceholderTypes = ['?']; - static namedPlaceholderTypes = [':']; - static lineCommentTypes = ['--']; - static specialWordChars = { any: '#@' }; static operators = ['**', '!>', '!<', '||']; tokenizer() { return new Tokenizer({ - reservedCommands: Db2Formatter.reservedCommands, - reservedBinaryCommands: Db2Formatter.reservedBinaryCommands, - reservedDependentClauses: Db2Formatter.reservedDependentClauses, - reservedJoinConditions: Db2Formatter.reservedJoinConditions, + reservedCommands, + reservedBinaryCommands, + reservedDependentClauses, + reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: Db2Formatter.reservedLogicalOperators, - reservedKeywords: Db2Formatter.fullReservedWords, + reservedKeywords: dedupe([ + ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), + ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), + ]), stringTypes: Db2Formatter.stringTypes, - blockStart: Db2Formatter.blockStart, - blockEnd: Db2Formatter.blockEnd, - indexedPlaceholderTypes: Db2Formatter.indexedPlaceholderTypes, - namedPlaceholderTypes: Db2Formatter.namedPlaceholderTypes, - lineCommentTypes: Db2Formatter.lineCommentTypes, - specialWordChars: Db2Formatter.specialWordChars, + blockStart: ['('], + blockEnd: [')'], + indexedPlaceholderTypes: ['?'], + namedPlaceholderTypes: [':'], + lineCommentTypes: ['--'], + specialWordChars: { any: '#@' }, operators: Db2Formatter.operators, }); } diff --git a/src/languages/hive.formatter.ts b/src/languages/hive.formatter.ts index 2fe011276e..63d11ff053 100644 --- a/src/languages/hive.formatter.ts +++ b/src/languages/hive.formatter.ts @@ -614,40 +614,28 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://cwiki.apache.org/confluence/display/Hive/LanguageManual export default class HiveFormatter extends Formatter { - static reservedCommands = reservedCommands; - static reservedBinaryCommands = reservedBinaryCommands; - static reservedDependentClauses = reservedDependentClauses; - static reservedJoinConditions = ['ON', 'USING']; static reservedLogicalOperators = ['AND', 'OR']; - static fullReservedWords = dedupe([ - ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), - ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), - ]); - static stringTypes: StringPatternType[] = ['""', "''", '``']; - static blockStart = ['(']; - static blockEnd = [')']; - static indexedPlaceholderTypes = ['?']; - static namedPlaceholderTypes = []; - static lineCommentTypes = ['--']; - static specialWordChars = {}; static operators = ['<=>', '==', '||']; tokenizer() { return new Tokenizer({ - reservedCommands: HiveFormatter.reservedCommands, - reservedBinaryCommands: HiveFormatter.reservedBinaryCommands, - reservedDependentClauses: HiveFormatter.reservedDependentClauses, - reservedJoinConditions: HiveFormatter.reservedJoinConditions, + reservedCommands, + reservedBinaryCommands, + reservedDependentClauses, + reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: HiveFormatter.reservedLogicalOperators, - reservedKeywords: HiveFormatter.fullReservedWords, + reservedKeywords: dedupe([ + ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), + ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), + ]), stringTypes: HiveFormatter.stringTypes, - blockStart: HiveFormatter.blockStart, - blockEnd: HiveFormatter.blockEnd, - indexedPlaceholderTypes: HiveFormatter.indexedPlaceholderTypes, - namedPlaceholderTypes: HiveFormatter.namedPlaceholderTypes, - lineCommentTypes: HiveFormatter.lineCommentTypes, - specialWordChars: HiveFormatter.specialWordChars, + blockStart: ['('], + blockEnd: [')'], + indexedPlaceholderTypes: ['?'], + namedPlaceholderTypes: [], + lineCommentTypes: ['--'], + specialWordChars: {}, operators: HiveFormatter.operators, }); } diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index e0143a3845..68f254055b 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1156,36 +1156,25 @@ const reservedDependentClauses = ['WHEN', 'ELSE', 'ELSEIF', 'ELSIF']; // For reference: https://mariadb.com/kb/en/sql-statements-structure/ export default class MariaDbFormatter extends Formatter { - static reservedCommands = reservedCommands; - static reservedBinaryCommands = reservedBinaryCommands; - static reservedJoinConditions = ['ON', 'USING']; static reservedLogicalOperators = ['AND', 'OR', 'XOR']; - static reservedDependentClauses = reservedDependentClauses; - static reservedKeywords = dedupe([...reservedKeywords, ...reservedFunctions]); static stringTypes: StringPatternType[] = ['``', "''", '""']; - static blockStart = ['(']; - static blockEnd = [')']; - static indexedPlaceholderTypes = ['?']; - static namedPlaceholderTypes = []; - static lineCommentTypes = ['--', '#']; - static specialWordChars = { prefix: '@' }; static operators = [':=', '<<', '>>', '<=>', '&&', '||']; tokenizer() { return new Tokenizer({ - reservedCommands: MariaDbFormatter.reservedCommands, - reservedBinaryCommands: MariaDbFormatter.reservedBinaryCommands, - reservedDependentClauses: MariaDbFormatter.reservedDependentClauses, - reservedJoinConditions: MariaDbFormatter.reservedJoinConditions, + reservedCommands, + reservedBinaryCommands, + reservedDependentClauses, + reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: MariaDbFormatter.reservedLogicalOperators, - reservedKeywords: MariaDbFormatter.reservedKeywords, + reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: MariaDbFormatter.stringTypes, - blockStart: MariaDbFormatter.blockStart, - blockEnd: MariaDbFormatter.blockEnd, - indexedPlaceholderTypes: MariaDbFormatter.indexedPlaceholderTypes, - namedPlaceholderTypes: MariaDbFormatter.namedPlaceholderTypes, - lineCommentTypes: MariaDbFormatter.lineCommentTypes, - specialWordChars: MariaDbFormatter.specialWordChars, + blockStart: ['('], + blockEnd: [')'], + indexedPlaceholderTypes: ['?'], + namedPlaceholderTypes: [], + lineCommentTypes: ['--', '#'], + specialWordChars: { prefix: '@' }, operators: MariaDbFormatter.operators, preprocess, }); diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index ce49c3939d..3703c3b815 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1319,36 +1319,25 @@ const reservedDependentClauses = ['WHEN', 'ELSE', 'ELSEIF']; // https://dev.mysql.com/doc/refman/8.0/en/ export default class MySqlFormatter extends Formatter { - static reservedCommands = reservedCommands; - static reservedBinaryCommands = reservedBinaryCommands; - static reservedDependentClauses = reservedDependentClauses; - static reservedJoinConditions = ['ON', 'USING']; static reservedLogicalOperators = ['AND', 'OR', 'XOR']; - static reservedKeywords = dedupe([...reservedKeywords, ...reservedFunctions]); static stringTypes: StringPatternType[] = ['``', "''", '""']; - static blockStart = ['(']; - static blockEnd = [')']; - static indexedPlaceholderTypes = ['?']; - static namedPlaceholderTypes = []; - static lineCommentTypes = ['--', '#']; - static specialWordChars = { prefix: '@:' }; static operators = [':=', '<<', '>>', '<=>', '&&', '||', '->', '->>']; tokenizer() { return new Tokenizer({ - reservedCommands: MySqlFormatter.reservedCommands, - reservedBinaryCommands: MySqlFormatter.reservedBinaryCommands, - reservedDependentClauses: MySqlFormatter.reservedDependentClauses, - reservedJoinConditions: MySqlFormatter.reservedJoinConditions, + reservedCommands, + reservedBinaryCommands, + reservedDependentClauses, + reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: MySqlFormatter.reservedLogicalOperators, - reservedKeywords: MySqlFormatter.reservedKeywords, + reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: MySqlFormatter.stringTypes, - blockStart: MySqlFormatter.blockStart, - blockEnd: MySqlFormatter.blockEnd, - indexedPlaceholderTypes: MySqlFormatter.indexedPlaceholderTypes, - namedPlaceholderTypes: MySqlFormatter.namedPlaceholderTypes, - lineCommentTypes: MySqlFormatter.lineCommentTypes, - specialWordChars: MySqlFormatter.specialWordChars, + blockStart: ['('], + blockEnd: [')'], + indexedPlaceholderTypes: ['?'], + namedPlaceholderTypes: [], + lineCommentTypes: ['--', '#'], + specialWordChars: { prefix: '@:' }, operators: MySqlFormatter.operators, preprocess, }); diff --git a/src/languages/n1ql.formatter.ts b/src/languages/n1ql.formatter.ts index 324c77a860..53eb8eb3a3 100644 --- a/src/languages/n1ql.formatter.ts +++ b/src/languages/n1ql.formatter.ts @@ -512,32 +512,23 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // For reference: http://docs.couchbase.com.s3-website-us-west-1.amazonaws.com/server/6.0/n1ql/n1ql-language-reference/index.html export default class N1qlFormatter extends Formatter { - static reservedCommands = reservedCommands; - static reservedBinaryCommands = reservedBinaryCommands; - static reservedDependentClauses = reservedDependentClauses; - static reservedJoinConditions = ['ON', 'USING']; static reservedLogicalOperators = ['AND', 'OR', 'XOR']; - static reservedKeywords = dedupe([...reservedKeywords, ...reservedFunctions]); static stringTypes: StringPatternType[] = [`""`, "''", '``']; - static blockStart = ['(', '[', '{']; - static blockEnd = [')', ']', '}']; - static namedPlaceholderTypes = ['$']; - static lineCommentTypes = ['#', '--']; static operators = ['==']; tokenizer() { return new Tokenizer({ - reservedCommands: N1qlFormatter.reservedCommands, - reservedBinaryCommands: N1qlFormatter.reservedBinaryCommands, - reservedDependentClauses: N1qlFormatter.reservedDependentClauses, - reservedJoinConditions: N1qlFormatter.reservedJoinConditions, + reservedCommands, + reservedBinaryCommands, + reservedDependentClauses, + reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: N1qlFormatter.reservedLogicalOperators, - reservedKeywords: N1qlFormatter.reservedKeywords, + reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: N1qlFormatter.stringTypes, - blockStart: N1qlFormatter.blockStart, - blockEnd: N1qlFormatter.blockEnd, - namedPlaceholderTypes: N1qlFormatter.namedPlaceholderTypes, - lineCommentTypes: N1qlFormatter.lineCommentTypes, + blockStart: ['(', '[', '{'], + blockEnd: [')', ']', '}'], + namedPlaceholderTypes: ['$'], + lineCommentTypes: ['#', '--'], operators: N1qlFormatter.operators, }); } diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 76c00c68eb..7f96b340d8 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -443,19 +443,8 @@ const reservedBinaryCommands = [ const reservedDependentClauses = ['WHEN', 'ELSE']; export default class PlSqlFormatter extends Formatter { - static reservedCommands = reservedCommands; - static reservedBinaryCommands = reservedBinaryCommands; - static reservedDependentClauses = reservedDependentClauses; - static reservedJoinConditions = ['ON', 'USING']; static reservedLogicalOperators = ['AND', 'OR', 'XOR']; - static reservedKeywords = dedupe(reservedKeywords); static stringTypes: StringPatternType[] = [`""`, "N''", "''", '``']; - static blockStart = ['(']; - static blockEnd = [')']; - static indexedPlaceholderTypes = ['?']; - static namedPlaceholderTypes = [':']; - static lineCommentTypes = ['--']; - static specialWordChars = { any: '_$#.@' }; static operators = [ '||', '**', @@ -470,19 +459,19 @@ export default class PlSqlFormatter extends Formatter { tokenizer() { return new Tokenizer({ - reservedCommands: PlSqlFormatter.reservedCommands, - reservedBinaryCommands: PlSqlFormatter.reservedBinaryCommands, - reservedDependentClauses: PlSqlFormatter.reservedDependentClauses, - reservedJoinConditions: PlSqlFormatter.reservedJoinConditions, + reservedCommands, + reservedBinaryCommands, + reservedDependentClauses, + reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: PlSqlFormatter.reservedLogicalOperators, - reservedKeywords: PlSqlFormatter.reservedKeywords, + reservedKeywords: dedupe(reservedKeywords), stringTypes: PlSqlFormatter.stringTypes, - blockStart: PlSqlFormatter.blockStart, - blockEnd: PlSqlFormatter.blockEnd, - indexedPlaceholderTypes: PlSqlFormatter.indexedPlaceholderTypes, - namedPlaceholderTypes: PlSqlFormatter.namedPlaceholderTypes, - lineCommentTypes: PlSqlFormatter.lineCommentTypes, - specialWordChars: PlSqlFormatter.specialWordChars, + blockStart: ['('], + blockEnd: [')'], + indexedPlaceholderTypes: ['?'], + namedPlaceholderTypes: [':'], + lineCommentTypes: ['--'], + specialWordChars: { any: '_$#.@' }, operators: PlSqlFormatter.operators, preprocess, }); diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index b5232bebff..c62be701ee 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1669,37 +1669,27 @@ const binaryOperators = [ // https://www.postgresql.org/docs/14/index.html export default class PostgreSqlFormatter extends Formatter { - static reservedCommands = reservedCommands; - static reservedBinaryCommands = reservedBinaryCommands; - static reservedDependentClauses = reservedDependentClauses; - static reservedJoinConditions = ['ON', 'USING']; static reservedLogicalOperators = ['AND', 'OR']; - static reservedKeywords = dedupe([ - ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), - ...reservedKeywords, - ]); static stringTypes: StringPatternType[] = [`""`, "''", "U&''", 'U&""', '$$', '``', "E''"]; - static blockStart = ['(']; - static blockEnd = [')']; - static indexedPlaceholderTypes = ['$']; - static namedPlaceholderTypes = [':']; - static lineCommentTypes = ['--']; static operators = binaryOperators; tokenizer() { return new Tokenizer({ - reservedCommands: PostgreSqlFormatter.reservedCommands, - reservedBinaryCommands: PostgreSqlFormatter.reservedBinaryCommands, - reservedDependentClauses: PostgreSqlFormatter.reservedDependentClauses, - reservedJoinConditions: PostgreSqlFormatter.reservedJoinConditions, + reservedCommands, + reservedBinaryCommands, + reservedDependentClauses, + reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: PostgreSqlFormatter.reservedLogicalOperators, - reservedKeywords: PostgreSqlFormatter.reservedKeywords, + reservedKeywords: dedupe([ + ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), + ...reservedKeywords, + ]), stringTypes: PostgreSqlFormatter.stringTypes, - blockStart: PostgreSqlFormatter.blockStart, - blockEnd: PostgreSqlFormatter.blockEnd, - indexedPlaceholderTypes: PostgreSqlFormatter.indexedPlaceholderTypes, - namedPlaceholderTypes: PostgreSqlFormatter.namedPlaceholderTypes, - lineCommentTypes: PostgreSqlFormatter.lineCommentTypes, + blockStart: ['('], + blockEnd: [')'], + indexedPlaceholderTypes: ['$'], + namedPlaceholderTypes: [':'], + lineCommentTypes: ['--'], operators: PostgreSqlFormatter.operators, }); } diff --git a/src/languages/redshift.formatter.ts b/src/languages/redshift.formatter.ts index 02943fddca..a2b3f38f5d 100644 --- a/src/languages/redshift.formatter.ts +++ b/src/languages/redshift.formatter.ts @@ -716,37 +716,27 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://docs.aws.amazon.com/redshift/latest/dg/cm_chap_SQLCommandRef.html export default class RedshiftFormatter extends Formatter { - static reservedCommands = reservedCommands; - static reservedBinaryCommands = reservedBinaryCommands; - static reservedDependentClauses = reservedDependentClauses; - static reservedJoinConditions = ['ON', 'USING']; static reservedLogicalOperators = ['AND', 'OR']; - static reservedKeywords = dedupe([ - ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), - ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), - ]); static stringTypes: StringPatternType[] = [`""`, "''", '``']; - static blockStart = ['(']; - static blockEnd = [')']; - static indexedPlaceholderTypes = ['?']; - static namedPlaceholderTypes = ['@', '#', '$']; - static lineCommentTypes = ['--']; static operators = ['|/', '||/', '<<', '>>', '||']; tokenizer() { return new Tokenizer({ - reservedCommands: RedshiftFormatter.reservedCommands, - reservedBinaryCommands: RedshiftFormatter.reservedBinaryCommands, - reservedDependentClauses: RedshiftFormatter.reservedDependentClauses, - reservedJoinConditions: RedshiftFormatter.reservedJoinConditions, + reservedCommands, + reservedBinaryCommands, + reservedDependentClauses, + reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: RedshiftFormatter.reservedLogicalOperators, - reservedKeywords: RedshiftFormatter.reservedKeywords, + reservedKeywords: dedupe([ + ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), + ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), + ]), stringTypes: RedshiftFormatter.stringTypes, - blockStart: RedshiftFormatter.blockStart, - blockEnd: RedshiftFormatter.blockEnd, - indexedPlaceholderTypes: RedshiftFormatter.indexedPlaceholderTypes, - namedPlaceholderTypes: RedshiftFormatter.namedPlaceholderTypes, - lineCommentTypes: RedshiftFormatter.lineCommentTypes, + blockStart: ['('], + blockEnd: [')'], + indexedPlaceholderTypes: ['?'], + namedPlaceholderTypes: ['@', '#', '$'], + lineCommentTypes: ['--'], operators: RedshiftFormatter.operators, }); } diff --git a/src/languages/spark.formatter.ts b/src/languages/spark.formatter.ts index 605ce59fb8..cff2cf9b5a 100644 --- a/src/languages/spark.formatter.ts +++ b/src/languages/spark.formatter.ts @@ -778,37 +778,27 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // http://spark.apache.org/docs/latest/sql-programming-guide.html export default class SparkFormatter extends Formatter { - static reservedCommands = reservedCommands; - static reservedBinaryCommands = reservedBinaryCommands; - static reservedDependentClauses = reservedDependentClauses; - static reservedJoinConditions = ['ON', 'USING']; static reservedLogicalOperators = ['AND', 'OR', 'XOR']; - static reservedKeywords = dedupe([ - ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), - ...reservedKeywords, - ]); static stringTypes: StringPatternType[] = [`""`, "''", '``', '{}']; - static blockStart = ['(']; - static blockEnd = [')']; - static indexedPlaceholderTypes = ['?']; - static namedPlaceholderTypes = ['$']; - static lineCommentTypes = ['--']; static operators = ['<=>', '&&', '||', '==', '->']; tokenizer() { return new Tokenizer({ - reservedCommands: SparkFormatter.reservedCommands, - reservedBinaryCommands: SparkFormatter.reservedBinaryCommands, - reservedDependentClauses: SparkFormatter.reservedDependentClauses, - reservedJoinConditions: SparkFormatter.reservedJoinConditions, + reservedCommands, + reservedBinaryCommands, + reservedDependentClauses, + reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: SparkFormatter.reservedLogicalOperators, - reservedKeywords: SparkFormatter.reservedKeywords, + reservedKeywords: dedupe([ + ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), + ...reservedKeywords, + ]), stringTypes: SparkFormatter.stringTypes, - blockStart: SparkFormatter.blockStart, - blockEnd: SparkFormatter.blockEnd, - indexedPlaceholderTypes: SparkFormatter.indexedPlaceholderTypes, - namedPlaceholderTypes: SparkFormatter.namedPlaceholderTypes, - lineCommentTypes: SparkFormatter.lineCommentTypes, + blockStart: ['('], + blockEnd: [')'], + indexedPlaceholderTypes: ['?'], + namedPlaceholderTypes: ['$'], + lineCommentTypes: ['--'], operators: SparkFormatter.operators, preprocess, }); diff --git a/src/languages/sql.formatter.ts b/src/languages/sql.formatter.ts index ac749dea68..adb90151b6 100644 --- a/src/languages/sql.formatter.ts +++ b/src/languages/sql.formatter.ts @@ -370,34 +370,24 @@ const reservedBinaryCommands = [ const reservedDependentClauses = ['WHEN', 'ELSE']; export default class SqlFormatter extends Formatter { - static reservedCommands = reservedCommands; - static reservedBinaryCommands = reservedBinaryCommands; - static reservedDependentClauses = reservedDependentClauses; - static reservedJoinConditions = ['ON', 'USING']; static reservedLogicalOperators = ['AND', 'OR']; - static reservedKeywords = dedupe(reservedKeywords); static stringTypes: StringPatternType[] = [`""`, "''", '``']; - static blockStart = ['(']; - static blockEnd = [')']; - static indexedPlaceholderTypes = ['?']; - static namedPlaceholderTypes = []; - static lineCommentTypes = ['--']; static operators = []; tokenizer() { return new Tokenizer({ - reservedCommands: SqlFormatter.reservedCommands, - reservedBinaryCommands: SqlFormatter.reservedBinaryCommands, - reservedDependentClauses: SqlFormatter.reservedDependentClauses, - reservedJoinConditions: SqlFormatter.reservedJoinConditions, + reservedCommands, + reservedBinaryCommands, + reservedDependentClauses, + reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: SqlFormatter.reservedLogicalOperators, - reservedKeywords: SqlFormatter.reservedKeywords, + reservedKeywords: dedupe(reservedKeywords), stringTypes: SqlFormatter.stringTypes, - blockStart: SqlFormatter.blockStart, - blockEnd: SqlFormatter.blockEnd, - indexedPlaceholderTypes: SqlFormatter.indexedPlaceholderTypes, - namedPlaceholderTypes: SqlFormatter.namedPlaceholderTypes, - lineCommentTypes: SqlFormatter.lineCommentTypes, + blockStart: ['('], + blockEnd: [')'], + indexedPlaceholderTypes: ['?'], + namedPlaceholderTypes: [], + lineCommentTypes: ['--'], }); } } diff --git a/src/languages/sqlite.formatter.ts b/src/languages/sqlite.formatter.ts index efaf869923..ec0339ca44 100644 --- a/src/languages/sqlite.formatter.ts +++ b/src/languages/sqlite.formatter.ts @@ -421,37 +421,27 @@ const reservedBinaryCommands = [ const reservedDependentClauses = ['WHEN', 'ELSE']; export default class SqliteFormatter extends Formatter { - static reservedCommands = reservedCommands; - static reservedBinaryCommands = reservedBinaryCommands; - static reservedDependentClauses = reservedDependentClauses; - static reservedJoinConditions = ['ON', 'USING']; static reservedLogicalOperators = ['AND', 'OR']; - static reservedKeywords = [...standardReservedWords, ...nonStandardSqliteReservedWords]; - // https://www.sqlite.org/lang_keywords.html static stringTypes: StringPatternType[] = [`""`, "''", '``', '[]']; - static blockStart = ['(']; - static blockEnd = [')']; - // https://www.sqlite.org/lang_expr.html#parameters - static indexedPlaceholderTypes = ['?']; - static namedPlaceholderTypes = [':', '@', '$']; - static lineCommentTypes = ['--']; // https://www.sqlite.org/lang_expr.html static operators = ['||', '<<', '>>', '==', '!=']; tokenizer() { return new Tokenizer({ - reservedCommands: SqliteFormatter.reservedCommands, - reservedBinaryCommands: SqliteFormatter.reservedBinaryCommands, - reservedDependentClauses: SqliteFormatter.reservedDependentClauses, - reservedJoinConditions: SqliteFormatter.reservedJoinConditions, + reservedCommands, + reservedBinaryCommands, + reservedDependentClauses, + reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: SqliteFormatter.reservedLogicalOperators, - reservedKeywords: SqliteFormatter.reservedKeywords, + // https://www.sqlite.org/lang_keywords.html + reservedKeywords: [...standardReservedWords, ...nonStandardSqliteReservedWords], stringTypes: SqliteFormatter.stringTypes, - blockStart: SqliteFormatter.blockStart, - blockEnd: SqliteFormatter.blockEnd, - indexedPlaceholderTypes: SqliteFormatter.indexedPlaceholderTypes, - namedPlaceholderTypes: SqliteFormatter.namedPlaceholderTypes, - lineCommentTypes: SqliteFormatter.lineCommentTypes, + blockStart: ['('], + blockEnd: [')'], + // https://www.sqlite.org/lang_expr.html#parameters + indexedPlaceholderTypes: ['?'], + namedPlaceholderTypes: [':', '@', '$'], + lineCommentTypes: ['--'], operators: SqliteFormatter.operators, }); } diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index 3c5da01b48..7f62a4a8f8 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1232,39 +1232,28 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://docs.microsoft.com/en-us/sql/t-sql/language-reference?view=sql-server-ver15 export default class TSqlFormatter extends Formatter { - static reservedCommands = reservedCommands; - static reservedBinaryCommands = reservedBinaryCommands; - static reservedDependentClauses = reservedDependentClauses; - static reservedJoinConditions = ['ON', 'USING']; static reservedLogicalOperators = ['AND', 'OR']; - static reservedKeywords = dedupe([ - ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), - ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), - ]); static stringTypes: StringPatternType[] = [`""`, "N''", "''", '[]', '``']; - static blockStart = ['(']; - static blockEnd = [')']; - static indexedPlaceholderTypes = []; - static namedPlaceholderTypes = ['@']; - static lineCommentTypes = ['--']; - static specialWordChars = { any: '#@' }; static operators = ['!<', '!>', '+=', '-=', '*=', '/=', '%=', '|=', '&=', '^=', '::']; tokenizer() { return new Tokenizer({ - reservedCommands: TSqlFormatter.reservedCommands, - reservedBinaryCommands: TSqlFormatter.reservedBinaryCommands, - reservedDependentClauses: TSqlFormatter.reservedDependentClauses, - reservedJoinConditions: TSqlFormatter.reservedJoinConditions, + reservedCommands, + reservedBinaryCommands, + reservedDependentClauses, + reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: TSqlFormatter.reservedLogicalOperators, - reservedKeywords: TSqlFormatter.reservedKeywords, + reservedKeywords: dedupe([ + ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), + ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), + ]), stringTypes: TSqlFormatter.stringTypes, - blockStart: TSqlFormatter.blockStart, - blockEnd: TSqlFormatter.blockEnd, - indexedPlaceholderTypes: TSqlFormatter.indexedPlaceholderTypes, - namedPlaceholderTypes: TSqlFormatter.namedPlaceholderTypes, - lineCommentTypes: TSqlFormatter.lineCommentTypes, - specialWordChars: TSqlFormatter.specialWordChars, + blockStart: ['('], + blockEnd: [')'], + indexedPlaceholderTypes: [], + namedPlaceholderTypes: ['@'], + lineCommentTypes: ['--'], + specialWordChars: { any: '#@' }, operators: TSqlFormatter.operators, // TODO: Support for money constants }); From 153c82124d059cb26dfe0c749c869e4f4fa7fcaa Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 18 May 2022 21:46:30 +0300 Subject: [PATCH 013/334] Additional defaults for Tokenizer So we don't need to repeat the common config options that are the same in most dialects. --- src/core/Tokenizer.ts | 26 +++++++++++++------------- src/languages/bigquery.formatter.ts | 4 ---- src/languages/db2.formatter.ts | 4 ---- src/languages/hive.formatter.ts | 6 ------ src/languages/mariadb.formatter.ts | 4 ---- src/languages/mysql.formatter.ts | 4 ---- src/languages/n1ql.formatter.ts | 1 - src/languages/plsql.formatter.ts | 4 ---- src/languages/postgresql.formatter.ts | 4 ---- src/languages/redshift.formatter.ts | 4 ---- src/languages/spark.formatter.ts | 4 ---- src/languages/sql.formatter.ts | 5 ----- src/languages/sqlite.formatter.ts | 4 ---- src/languages/tsql.formatter.ts | 5 ----- 14 files changed, 13 insertions(+), 66 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 6662014923..66caad1fc9 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -11,16 +11,16 @@ const toCanonicalKeyword = (text: string) => equalizeWhitespace(text.toUpperCase interface TokenizerOptions { reservedKeywords: string[]; reservedCommands: string[]; - reservedLogicalOperators: string[]; + reservedLogicalOperators?: string[]; reservedDependentClauses: string[]; reservedBinaryCommands: string[]; - reservedJoinConditions: string[]; + reservedJoinConditions?: string[]; stringTypes: regexFactory.StringPatternType[]; - blockStart: string[]; - blockEnd: string[]; + blockStart?: string[]; + blockEnd?: string[]; indexedPlaceholderTypes?: string[]; - namedPlaceholderTypes: string[]; - lineCommentTypes: string[]; + namedPlaceholderTypes?: string[]; + lineCommentTypes?: string[]; specialWordChars?: { prefix?: string; any?: string; suffix?: string }; operators?: string[]; preprocess?: (tokens: Token[]) => Token[]; @@ -72,7 +72,7 @@ export default class Tokenizer { specialWordCharsAll ), [TokenType.RESERVED_LOGICAL_OPERATOR]: regexFactory.createReservedWordRegex( - cfg.reservedLogicalOperators, + cfg.reservedLogicalOperators ?? ['AND', 'OR'], specialWordCharsAll ), [TokenType.RESERVED_COMMAND]: regexFactory.createReservedWordRegex( @@ -84,7 +84,7 @@ export default class Tokenizer { specialWordCharsAll ), [TokenType.RESERVED_JOIN_CONDITION]: regexFactory.createReservedWordRegex( - cfg.reservedJoinConditions, + cfg.reservedJoinConditions ?? ['ON', 'USING'], specialWordCharsAll ), [TokenType.OPERATOR]: regexFactory.createOperatorRegex('+-/*%&|^><=.,;[]{}`:$@', [ @@ -94,11 +94,11 @@ export default class Tokenizer { '!=', ...(cfg.operators ?? []), ]), - [TokenType.BLOCK_START]: regexFactory.createParenRegex(cfg.blockStart), - [TokenType.BLOCK_END]: regexFactory.createParenRegex(cfg.blockEnd), + [TokenType.BLOCK_START]: regexFactory.createParenRegex(cfg.blockStart ?? ['(']), + [TokenType.BLOCK_END]: regexFactory.createParenRegex(cfg.blockEnd ?? [')']), [TokenType.RESERVED_CASE_START]: /^(CASE)\b/iu, [TokenType.RESERVED_CASE_END]: /^(END)\b/iu, - [TokenType.LINE_COMMENT]: regexFactory.createLineCommentRegex(cfg.lineCommentTypes), + [TokenType.LINE_COMMENT]: regexFactory.createLineCommentRegex(cfg.lineCommentTypes ?? ['--']), [TokenType.BLOCK_COMMENT]: /^(\/\*[^]*?(?:\*\/|$))/u, [TokenType.NUMBER]: /^(0x[0-9a-fA-F]+|0b[01]+|(-\s*)?[0-9]+(\.[0-9]*)?([eE][-+]?[0-9]+(\.[0-9]+)?)?)/u, @@ -111,11 +111,11 @@ export default class Tokenizer { '[0-9]*' ); this.IDENT_NAMED_PLACEHOLDER_REGEX = regexFactory.createPlaceholderRegex( - cfg.namedPlaceholderTypes, + cfg.namedPlaceholderTypes ?? [], '[a-zA-Z0-9._$]+' ); this.STRING_NAMED_PLACEHOLDER_REGEX = regexFactory.createPlaceholderRegex( - cfg.namedPlaceholderTypes, + cfg.namedPlaceholderTypes ?? [], regexFactory.createStringPattern(cfg.stringTypes) ); } diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index 5c8786bcf7..70b9cedc1f 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -835,17 +835,13 @@ export default class BigQueryFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: BigQueryFormatter.reservedLogicalOperators, reservedKeywords: dedupe([ ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), stringTypes: BigQueryFormatter.stringTypes, - blockStart: ['('], - blockEnd: [')'], indexedPlaceholderTypes: ['?'], - namedPlaceholderTypes: [], lineCommentTypes: ['--', '#'], specialWordChars: { any: '_@$-' }, operators: BigQueryFormatter.operators, diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index 97e2868c2b..c11fd52f19 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -868,18 +868,14 @@ export default class Db2Formatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: Db2Formatter.reservedLogicalOperators, reservedKeywords: dedupe([ ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), stringTypes: Db2Formatter.stringTypes, - blockStart: ['('], - blockEnd: [')'], indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: [':'], - lineCommentTypes: ['--'], specialWordChars: { any: '#@' }, operators: Db2Formatter.operators, }); diff --git a/src/languages/hive.formatter.ts b/src/languages/hive.formatter.ts index 63d11ff053..af25ade5c8 100644 --- a/src/languages/hive.formatter.ts +++ b/src/languages/hive.formatter.ts @@ -623,19 +623,13 @@ export default class HiveFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: HiveFormatter.reservedLogicalOperators, reservedKeywords: dedupe([ ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), stringTypes: HiveFormatter.stringTypes, - blockStart: ['('], - blockEnd: [')'], indexedPlaceholderTypes: ['?'], - namedPlaceholderTypes: [], - lineCommentTypes: ['--'], - specialWordChars: {}, operators: HiveFormatter.operators, }); } diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index 68f254055b..d1aa624002 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1165,14 +1165,10 @@ export default class MariaDbFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: MariaDbFormatter.reservedLogicalOperators, reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: MariaDbFormatter.stringTypes, - blockStart: ['('], - blockEnd: [')'], indexedPlaceholderTypes: ['?'], - namedPlaceholderTypes: [], lineCommentTypes: ['--', '#'], specialWordChars: { prefix: '@' }, operators: MariaDbFormatter.operators, diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index 3703c3b815..19df958df7 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1328,14 +1328,10 @@ export default class MySqlFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: MySqlFormatter.reservedLogicalOperators, reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: MySqlFormatter.stringTypes, - blockStart: ['('], - blockEnd: [')'], indexedPlaceholderTypes: ['?'], - namedPlaceholderTypes: [], lineCommentTypes: ['--', '#'], specialWordChars: { prefix: '@:' }, operators: MySqlFormatter.operators, diff --git a/src/languages/n1ql.formatter.ts b/src/languages/n1ql.formatter.ts index 53eb8eb3a3..afe4160f79 100644 --- a/src/languages/n1ql.formatter.ts +++ b/src/languages/n1ql.formatter.ts @@ -521,7 +521,6 @@ export default class N1qlFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: N1qlFormatter.reservedLogicalOperators, reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: N1qlFormatter.stringTypes, diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 7f96b340d8..8c0d21bbac 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -462,15 +462,11 @@ export default class PlSqlFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: PlSqlFormatter.reservedLogicalOperators, reservedKeywords: dedupe(reservedKeywords), stringTypes: PlSqlFormatter.stringTypes, - blockStart: ['('], - blockEnd: [')'], indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: [':'], - lineCommentTypes: ['--'], specialWordChars: { any: '_$#.@' }, operators: PlSqlFormatter.operators, preprocess, diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index c62be701ee..bbdd2c9433 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1678,18 +1678,14 @@ export default class PostgreSqlFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: PostgreSqlFormatter.reservedLogicalOperators, reservedKeywords: dedupe([ ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...reservedKeywords, ]), stringTypes: PostgreSqlFormatter.stringTypes, - blockStart: ['('], - blockEnd: [')'], indexedPlaceholderTypes: ['$'], namedPlaceholderTypes: [':'], - lineCommentTypes: ['--'], operators: PostgreSqlFormatter.operators, }); } diff --git a/src/languages/redshift.formatter.ts b/src/languages/redshift.formatter.ts index a2b3f38f5d..4c2df13f02 100644 --- a/src/languages/redshift.formatter.ts +++ b/src/languages/redshift.formatter.ts @@ -725,18 +725,14 @@ export default class RedshiftFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: RedshiftFormatter.reservedLogicalOperators, reservedKeywords: dedupe([ ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), stringTypes: RedshiftFormatter.stringTypes, - blockStart: ['('], - blockEnd: [')'], indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: ['@', '#', '$'], - lineCommentTypes: ['--'], operators: RedshiftFormatter.operators, }); } diff --git a/src/languages/spark.formatter.ts b/src/languages/spark.formatter.ts index cff2cf9b5a..907a9e555b 100644 --- a/src/languages/spark.formatter.ts +++ b/src/languages/spark.formatter.ts @@ -787,18 +787,14 @@ export default class SparkFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: SparkFormatter.reservedLogicalOperators, reservedKeywords: dedupe([ ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...reservedKeywords, ]), stringTypes: SparkFormatter.stringTypes, - blockStart: ['('], - blockEnd: [')'], indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: ['$'], - lineCommentTypes: ['--'], operators: SparkFormatter.operators, preprocess, }); diff --git a/src/languages/sql.formatter.ts b/src/languages/sql.formatter.ts index adb90151b6..7079212724 100644 --- a/src/languages/sql.formatter.ts +++ b/src/languages/sql.formatter.ts @@ -379,15 +379,10 @@ export default class SqlFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: SqlFormatter.reservedLogicalOperators, reservedKeywords: dedupe(reservedKeywords), stringTypes: SqlFormatter.stringTypes, - blockStart: ['('], - blockEnd: [')'], indexedPlaceholderTypes: ['?'], - namedPlaceholderTypes: [], - lineCommentTypes: ['--'], }); } } diff --git a/src/languages/sqlite.formatter.ts b/src/languages/sqlite.formatter.ts index ec0339ca44..5920fb6cf8 100644 --- a/src/languages/sqlite.formatter.ts +++ b/src/languages/sqlite.formatter.ts @@ -431,17 +431,13 @@ export default class SqliteFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: SqliteFormatter.reservedLogicalOperators, // https://www.sqlite.org/lang_keywords.html reservedKeywords: [...standardReservedWords, ...nonStandardSqliteReservedWords], stringTypes: SqliteFormatter.stringTypes, - blockStart: ['('], - blockEnd: [')'], // https://www.sqlite.org/lang_expr.html#parameters indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: [':', '@', '$'], - lineCommentTypes: ['--'], operators: SqliteFormatter.operators, }); } diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index 7f62a4a8f8..4f384464c4 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1241,18 +1241,13 @@ export default class TSqlFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedJoinConditions: ['ON', 'USING'], reservedLogicalOperators: TSqlFormatter.reservedLogicalOperators, reservedKeywords: dedupe([ ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), stringTypes: TSqlFormatter.stringTypes, - blockStart: ['('], - blockEnd: [')'], - indexedPlaceholderTypes: [], namedPlaceholderTypes: ['@'], - lineCommentTypes: ['--'], specialWordChars: { any: '#@' }, operators: TSqlFormatter.operators, // TODO: Support for money constants From 51bbeb0bb0a879efad43e72bd719bca1eb6dbba2 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 18 May 2022 22:09:58 +0300 Subject: [PATCH 014/334] Don't specify AND/OR operators for all dialects Only where XOR is also supported --- src/languages/bigquery.formatter.ts | 2 -- src/languages/db2.formatter.ts | 2 -- src/languages/hive.formatter.ts | 2 -- src/languages/mariadb.formatter.ts | 3 +-- src/languages/mysql.formatter.ts | 3 +-- src/languages/n1ql.formatter.ts | 3 +-- src/languages/plsql.formatter.ts | 3 +-- src/languages/postgresql.formatter.ts | 2 -- src/languages/redshift.formatter.ts | 2 -- src/languages/spark.formatter.ts | 3 +-- src/languages/sql.formatter.ts | 2 -- src/languages/sqlite.formatter.ts | 2 -- src/languages/tsql.formatter.ts | 2 -- test/bigquery.test.ts | 7 +------ test/db2.test.ts | 7 +------ test/features/operators.ts | 2 +- test/hive.test.ts | 7 +------ test/mariadb.test.ts | 7 +------ test/mysql.test.ts | 7 +------ test/n1ql.test.ts | 7 +------ test/plsql.test.ts | 7 +------ test/postgresql.test.ts | 7 +------ test/redshift.test.ts | 7 +------ test/spark.test.ts | 7 +------ test/sql.test.ts | 7 +------ test/sqlite.test.ts | 7 +------ test/tsql.test.ts | 7 +------ 27 files changed, 19 insertions(+), 105 deletions(-) diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index 70b9cedc1f..673bd88969 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -825,7 +825,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://cloud.google.com/bigquery/docs/reference/#standard-sql-reference export default class BigQueryFormatter extends Formatter { - static reservedLogicalOperators = ['AND', 'OR']; static stringTypes: StringPatternType[] = ['""', "''", '``']; // add: '''''', """""" ; prefixes: r, b static operators = ['>>', '<<', '||']; // TODO: handle trailing comma in select clause @@ -835,7 +834,6 @@ export default class BigQueryFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedLogicalOperators: BigQueryFormatter.reservedLogicalOperators, reservedKeywords: dedupe([ ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index c11fd52f19..f8ec66d284 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -859,7 +859,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE', 'ELSEIF']; // https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_72/db2/rbafzintro.htm export default class Db2Formatter extends Formatter { - static reservedLogicalOperators = ['AND', 'OR']; static stringTypes: StringPatternType[] = [`""`, "''", '``', '[]', "x''"]; static operators = ['**', '!>', '!<', '||']; @@ -868,7 +867,6 @@ export default class Db2Formatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedLogicalOperators: Db2Formatter.reservedLogicalOperators, reservedKeywords: dedupe([ ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), diff --git a/src/languages/hive.formatter.ts b/src/languages/hive.formatter.ts index af25ade5c8..ed25cb431d 100644 --- a/src/languages/hive.formatter.ts +++ b/src/languages/hive.formatter.ts @@ -614,7 +614,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://cwiki.apache.org/confluence/display/Hive/LanguageManual export default class HiveFormatter extends Formatter { - static reservedLogicalOperators = ['AND', 'OR']; static stringTypes: StringPatternType[] = ['""', "''", '``']; static operators = ['<=>', '==', '||']; @@ -623,7 +622,6 @@ export default class HiveFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedLogicalOperators: HiveFormatter.reservedLogicalOperators, reservedKeywords: dedupe([ ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index d1aa624002..f945eaf6fd 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1156,7 +1156,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE', 'ELSEIF', 'ELSIF']; // For reference: https://mariadb.com/kb/en/sql-statements-structure/ export default class MariaDbFormatter extends Formatter { - static reservedLogicalOperators = ['AND', 'OR', 'XOR']; static stringTypes: StringPatternType[] = ['``', "''", '""']; static operators = [':=', '<<', '>>', '<=>', '&&', '||']; @@ -1165,7 +1164,7 @@ export default class MariaDbFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedLogicalOperators: MariaDbFormatter.reservedLogicalOperators, + reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: MariaDbFormatter.stringTypes, indexedPlaceholderTypes: ['?'], diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index 19df958df7..3613f156d7 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1319,7 +1319,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE', 'ELSEIF']; // https://dev.mysql.com/doc/refman/8.0/en/ export default class MySqlFormatter extends Formatter { - static reservedLogicalOperators = ['AND', 'OR', 'XOR']; static stringTypes: StringPatternType[] = ['``', "''", '""']; static operators = [':=', '<<', '>>', '<=>', '&&', '||', '->', '->>']; @@ -1328,7 +1327,7 @@ export default class MySqlFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedLogicalOperators: MySqlFormatter.reservedLogicalOperators, + reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: MySqlFormatter.stringTypes, indexedPlaceholderTypes: ['?'], diff --git a/src/languages/n1ql.formatter.ts b/src/languages/n1ql.formatter.ts index afe4160f79..32e54b56a0 100644 --- a/src/languages/n1ql.formatter.ts +++ b/src/languages/n1ql.formatter.ts @@ -512,7 +512,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // For reference: http://docs.couchbase.com.s3-website-us-west-1.amazonaws.com/server/6.0/n1ql/n1ql-language-reference/index.html export default class N1qlFormatter extends Formatter { - static reservedLogicalOperators = ['AND', 'OR', 'XOR']; static stringTypes: StringPatternType[] = [`""`, "''", '``']; static operators = ['==']; @@ -521,7 +520,7 @@ export default class N1qlFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedLogicalOperators: N1qlFormatter.reservedLogicalOperators, + reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: N1qlFormatter.stringTypes, blockStart: ['(', '[', '{'], diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 8c0d21bbac..a18076abde 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -443,7 +443,6 @@ const reservedBinaryCommands = [ const reservedDependentClauses = ['WHEN', 'ELSE']; export default class PlSqlFormatter extends Formatter { - static reservedLogicalOperators = ['AND', 'OR', 'XOR']; static stringTypes: StringPatternType[] = [`""`, "N''", "''", '``']; static operators = [ '||', @@ -462,7 +461,7 @@ export default class PlSqlFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedLogicalOperators: PlSqlFormatter.reservedLogicalOperators, + reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe(reservedKeywords), stringTypes: PlSqlFormatter.stringTypes, indexedPlaceholderTypes: ['?'], diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index bbdd2c9433..bf839eae55 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1669,7 +1669,6 @@ const binaryOperators = [ // https://www.postgresql.org/docs/14/index.html export default class PostgreSqlFormatter extends Formatter { - static reservedLogicalOperators = ['AND', 'OR']; static stringTypes: StringPatternType[] = [`""`, "''", "U&''", 'U&""', '$$', '``', "E''"]; static operators = binaryOperators; @@ -1678,7 +1677,6 @@ export default class PostgreSqlFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedLogicalOperators: PostgreSqlFormatter.reservedLogicalOperators, reservedKeywords: dedupe([ ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...reservedKeywords, diff --git a/src/languages/redshift.formatter.ts b/src/languages/redshift.formatter.ts index 4c2df13f02..6871578c47 100644 --- a/src/languages/redshift.formatter.ts +++ b/src/languages/redshift.formatter.ts @@ -716,7 +716,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://docs.aws.amazon.com/redshift/latest/dg/cm_chap_SQLCommandRef.html export default class RedshiftFormatter extends Formatter { - static reservedLogicalOperators = ['AND', 'OR']; static stringTypes: StringPatternType[] = [`""`, "''", '``']; static operators = ['|/', '||/', '<<', '>>', '||']; @@ -725,7 +724,6 @@ export default class RedshiftFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedLogicalOperators: RedshiftFormatter.reservedLogicalOperators, reservedKeywords: dedupe([ ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), diff --git a/src/languages/spark.formatter.ts b/src/languages/spark.formatter.ts index 907a9e555b..129e7a8f89 100644 --- a/src/languages/spark.formatter.ts +++ b/src/languages/spark.formatter.ts @@ -778,7 +778,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // http://spark.apache.org/docs/latest/sql-programming-guide.html export default class SparkFormatter extends Formatter { - static reservedLogicalOperators = ['AND', 'OR', 'XOR']; static stringTypes: StringPatternType[] = [`""`, "''", '``', '{}']; static operators = ['<=>', '&&', '||', '==', '->']; @@ -787,7 +786,7 @@ export default class SparkFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedLogicalOperators: SparkFormatter.reservedLogicalOperators, + reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe([ ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...reservedKeywords, diff --git a/src/languages/sql.formatter.ts b/src/languages/sql.formatter.ts index 7079212724..9301b64d42 100644 --- a/src/languages/sql.formatter.ts +++ b/src/languages/sql.formatter.ts @@ -370,7 +370,6 @@ const reservedBinaryCommands = [ const reservedDependentClauses = ['WHEN', 'ELSE']; export default class SqlFormatter extends Formatter { - static reservedLogicalOperators = ['AND', 'OR']; static stringTypes: StringPatternType[] = [`""`, "''", '``']; static operators = []; @@ -379,7 +378,6 @@ export default class SqlFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedLogicalOperators: SqlFormatter.reservedLogicalOperators, reservedKeywords: dedupe(reservedKeywords), stringTypes: SqlFormatter.stringTypes, indexedPlaceholderTypes: ['?'], diff --git a/src/languages/sqlite.formatter.ts b/src/languages/sqlite.formatter.ts index 5920fb6cf8..ee2bd95b07 100644 --- a/src/languages/sqlite.formatter.ts +++ b/src/languages/sqlite.formatter.ts @@ -421,7 +421,6 @@ const reservedBinaryCommands = [ const reservedDependentClauses = ['WHEN', 'ELSE']; export default class SqliteFormatter extends Formatter { - static reservedLogicalOperators = ['AND', 'OR']; static stringTypes: StringPatternType[] = [`""`, "''", '``', '[]']; // https://www.sqlite.org/lang_expr.html static operators = ['||', '<<', '>>', '==', '!=']; @@ -431,7 +430,6 @@ export default class SqliteFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedLogicalOperators: SqliteFormatter.reservedLogicalOperators, // https://www.sqlite.org/lang_keywords.html reservedKeywords: [...standardReservedWords, ...nonStandardSqliteReservedWords], stringTypes: SqliteFormatter.stringTypes, diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index 4f384464c4..0db9b68c28 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1232,7 +1232,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://docs.microsoft.com/en-us/sql/t-sql/language-reference?view=sql-server-ver15 export default class TSqlFormatter extends Formatter { - static reservedLogicalOperators = ['AND', 'OR']; static stringTypes: StringPatternType[] = [`""`, "N''", "''", '[]', '``']; static operators = ['!<', '!>', '+=', '-=', '*=', '/=', '%=', '|=', '&=', '^=', '::']; @@ -1241,7 +1240,6 @@ export default class TSqlFormatter extends Formatter { reservedCommands, reservedBinaryCommands, reservedDependentClauses, - reservedLogicalOperators: TSqlFormatter.reservedLogicalOperators, reservedKeywords: dedupe([ ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), diff --git a/test/bigquery.test.ts b/test/bigquery.test.ts index 7aa6e7fc7a..89ef4431f4 100644 --- a/test/bigquery.test.ts +++ b/test/bigquery.test.ts @@ -22,12 +22,7 @@ describe('BigQueryFormatter', () => { supportsBetween(language, format); supportsSchema(language, format); supportsJoin(language, format, { without: ['NATURAL JOIN'] }); - supportsOperators( - language, - format, - BigQueryFormatter.operators, - BigQueryFormatter.reservedLogicalOperators - ); + supportsOperators(language, format, BigQueryFormatter.operators); it('supports # line comment', () => { const result = format('SELECT alpha # commment\nFROM beta'); diff --git a/test/db2.test.ts b/test/db2.test.ts index 3dae1270a4..0a7ef980d1 100644 --- a/test/db2.test.ts +++ b/test/db2.test.ts @@ -25,12 +25,7 @@ describe('Db2Formatter', () => { supportsStrings(language, format, Db2Formatter.stringTypes); supportsBetween(language, format); supportsSchema(language, format); - supportsOperators( - language, - format, - Db2Formatter.operators, - Db2Formatter.reservedLogicalOperators - ); + supportsOperators(language, format, Db2Formatter.operators); supportsJoin(language, format); it('formats FETCH FIRST like LIMIT', () => { diff --git a/test/features/operators.ts b/test/features/operators.ts index 0375f807fd..05d0ae1b3f 100644 --- a/test/features/operators.ts +++ b/test/features/operators.ts @@ -5,7 +5,7 @@ export default function supportsOperators( language: SqlLanguage, format: FormatFn, operators: string[], - logicalOperators: string[] + logicalOperators: string[] = ['AND', 'OR'] ) { operators.forEach(op => { it(`supports ${op} operator`, () => { diff --git a/test/hive.test.ts b/test/hive.test.ts index 5dfdc4a7f9..a8541e6ca3 100644 --- a/test/hive.test.ts +++ b/test/hive.test.ts @@ -22,11 +22,6 @@ describe('HiveFormatter', () => { supportsBetween(language, format); supportsSchema(language, format); supportsJoin(language, format, { without: ['NATURAL JOIN'] }); - supportsOperators( - language, - format, - HiveFormatter.operators, - HiveFormatter.reservedLogicalOperators - ); + supportsOperators(language, format, HiveFormatter.operators); supportsArray(language, format); }); diff --git a/test/mariadb.test.ts b/test/mariadb.test.ts index bc882cc335..e34a86b007 100644 --- a/test/mariadb.test.ts +++ b/test/mariadb.test.ts @@ -13,11 +13,6 @@ describe('MariaDbFormatter', () => { behavesLikeMariaDbFormatter(language, format); supportsStrings(language, format, MariaDbFormatter.stringTypes); - supportsOperators( - language, - format, - MariaDbFormatter.operators, - MariaDbFormatter.reservedLogicalOperators - ); + supportsOperators(language, format, MariaDbFormatter.operators, ['AND', 'OR', 'XOR']); supportsReturning(language, format); }); diff --git a/test/mysql.test.ts b/test/mysql.test.ts index 2683185b9f..d2019eaf1d 100644 --- a/test/mysql.test.ts +++ b/test/mysql.test.ts @@ -13,12 +13,7 @@ describe('MySqlFormatter', () => { behavesLikeMariaDbFormatter(language, format); supportsStrings(language, format, MySqlFormatter.stringTypes); - supportsOperators( - language, - format, - MySqlFormatter.operators, - MySqlFormatter.reservedLogicalOperators - ); + supportsOperators(language, format, MySqlFormatter.operators, ['AND', 'OR', 'XOR']); it('supports @@ system variables', () => { const result = format('SELECT @@GLOBAL.time, @@SYSTEM.date, @@hour FROM foo;'); diff --git a/test/n1ql.test.ts b/test/n1ql.test.ts index a7e5ef4cff..6f7dc14912 100644 --- a/test/n1ql.test.ts +++ b/test/n1ql.test.ts @@ -21,12 +21,7 @@ describe('N1qlFormatter', () => { supportsStrings(language, format, N1qlFormatter.stringTypes); supportsBetween(language, format); supportsSchema(language, format); - supportsOperators( - language, - format, - N1qlFormatter.operators, - N1qlFormatter.reservedLogicalOperators - ); + supportsOperators(language, format, N1qlFormatter.operators, ['AND', 'OR', 'XOR']); supportsArray(language, format); supportsJoin(language, format, { without: ['FULL', 'CROSS', 'NATURAL'] }); supportsReturning(language, format); diff --git a/test/plsql.test.ts b/test/plsql.test.ts index 9288fe351f..e438ade9d7 100644 --- a/test/plsql.test.ts +++ b/test/plsql.test.ts @@ -28,12 +28,7 @@ describe('PlSqlFormatter', () => { supportsStrings(language, format, PlSqlFormatter.stringTypes); supportsBetween(language, format); supportsSchema(language, format); - supportsOperators( - language, - format, - PlSqlFormatter.operators, - PlSqlFormatter.reservedLogicalOperators - ); + supportsOperators(language, format, PlSqlFormatter.operators, ['AND', 'OR', 'XOR']); supportsJoin(language, format); supportsReturning(language, format); diff --git a/test/postgresql.test.ts b/test/postgresql.test.ts index 528d63ce4a..11b79638cd 100644 --- a/test/postgresql.test.ts +++ b/test/postgresql.test.ts @@ -26,12 +26,7 @@ describe('PostgreSqlFormatter', () => { supportsStrings(language, format, PostgreSqlFormatter.stringTypes); supportsBetween(language, format); supportsSchema(language, format); - supportsOperators( - language, - format, - PostgreSqlFormatter.operators, - PostgreSqlFormatter.reservedLogicalOperators - ); + supportsOperators(language, format, PostgreSqlFormatter.operators); supportsJoin(language, format); supportsReturning(language, format); diff --git a/test/redshift.test.ts b/test/redshift.test.ts index 3abba348e6..b292dffe39 100644 --- a/test/redshift.test.ts +++ b/test/redshift.test.ts @@ -23,12 +23,7 @@ describe('RedshiftFormatter', () => { supportsDeleteFrom(language, format); supportsStrings(language, format, RedshiftFormatter.stringTypes); supportsSchema(language, format); - supportsOperators( - language, - format, - RedshiftFormatter.operators, - RedshiftFormatter.reservedLogicalOperators - ); + supportsOperators(language, format, RedshiftFormatter.operators); supportsJoin(language, format); it('formats LIMIT', () => { diff --git a/test/spark.test.ts b/test/spark.test.ts index 7a015cb01a..e10fc80efe 100644 --- a/test/spark.test.ts +++ b/test/spark.test.ts @@ -22,12 +22,7 @@ describe('SparkFormatter', () => { supportsStrings(language, format, SparkFormatter.stringTypes); supportsBetween(language, format); supportsSchema(language, format); - supportsOperators( - language, - format, - SparkFormatter.operators, - SparkFormatter.reservedLogicalOperators - ); + supportsOperators(language, format, SparkFormatter.operators, ['AND', 'OR', 'XOR']); supportsArray(language, format); supportsJoin(language, format, { additionally: [ diff --git a/test/sql.test.ts b/test/sql.test.ts index d79a8719e8..c44f754b84 100644 --- a/test/sql.test.ts +++ b/test/sql.test.ts @@ -26,12 +26,7 @@ describe('SqlFormatter', () => { supportsBetween(language, format); supportsSchema(language, format); supportsJoin(language, format); - supportsOperators( - language, - format, - SqlFormatter.operators, - SqlFormatter.reservedLogicalOperators - ); + supportsOperators(language, format, SqlFormatter.operators); it('replaces ? indexed placeholders with param values', () => { const result = format('SELECT ?, ?, ?;', { diff --git a/test/sqlite.test.ts b/test/sqlite.test.ts index 1a015f3c72..c4e44a0fe4 100644 --- a/test/sqlite.test.ts +++ b/test/sqlite.test.ts @@ -29,12 +29,7 @@ describe('SqliteFormatter', () => { without: ['FULL', 'RIGHT'], additionally: ['NATURAL LEFT JOIN', 'NATURAL LEFT OUTER JOIN'], }); - supportsOperators( - language, - format, - SqliteFormatter.operators, - SqliteFormatter.reservedLogicalOperators - ); + supportsOperators(language, format, SqliteFormatter.operators); it('replaces ? indexed placeholders with param values', () => { const result = format('SELECT ?, ?, ?;', { diff --git a/test/tsql.test.ts b/test/tsql.test.ts index d9b0adb468..eefdd1e9de 100644 --- a/test/tsql.test.ts +++ b/test/tsql.test.ts @@ -25,12 +25,7 @@ describe('TSqlFormatter', () => { supportsStrings(language, format, TSqlFormatter.stringTypes); supportsBetween(language, format); supportsSchema(language, format); - supportsOperators( - language, - format, - TSqlFormatter.operators, - TSqlFormatter.reservedLogicalOperators - ); + supportsOperators(language, format, TSqlFormatter.operators); supportsJoin(language, format, { without: ['NATURAL'] }); // TODO: The following are duplicated from StandardSQLFormatter test From 40cdf8f0b317409668b1387b6640909d7ccebb81 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 10:05:03 +0300 Subject: [PATCH 015/334] Refactor tests for ?-parameters --- test/behavesLikeMariaDbFormatter.ts | 2 + test/bigquery.test.ts | 2 + test/db2.test.ts | 2 + test/hive.test.ts | 2 + test/options/param.ts | 64 +++++++++++++++++++++++++++++ test/plsql.test.ts | 30 +------------- test/redshift.test.ts | 2 + test/spark.test.ts | 2 + test/sql.test.ts | 14 +------ test/sqlite.test.ts | 14 +------ 10 files changed, 82 insertions(+), 52 deletions(-) create mode 100644 test/options/param.ts diff --git a/test/behavesLikeMariaDbFormatter.ts b/test/behavesLikeMariaDbFormatter.ts index ff87fd7a15..5c50c725f3 100644 --- a/test/behavesLikeMariaDbFormatter.ts +++ b/test/behavesLikeMariaDbFormatter.ts @@ -8,6 +8,7 @@ import supportsBetween from './features/between'; import supportsJoin from './features/join'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; +import supportsParams from './options/param'; /** * Shared tests for MySQL and MariaDB @@ -29,6 +30,7 @@ export default function behavesLikeMariaDbFormatter(language: SqlLanguage, forma 'NATURAL RIGHT OUTER JOIN', ], }); + supportsParams(language, format, { indexed: ['?'] }); it('supports # comments', () => { expect(format('SELECT a # comment\nFROM b # comment')).toBe(dedent` diff --git a/test/bigquery.test.ts b/test/bigquery.test.ts index 89ef4431f4..b24222d823 100644 --- a/test/bigquery.test.ts +++ b/test/bigquery.test.ts @@ -10,6 +10,7 @@ import supportsBetween from './features/between'; import supportsJoin from './features/join'; import supportsOperators from './features/operators'; import supportsDeleteFrom from './features/deleteFrom'; +import supportsParams from './options/param'; describe('BigQueryFormatter', () => { const language = 'bigquery'; @@ -23,6 +24,7 @@ describe('BigQueryFormatter', () => { supportsSchema(language, format); supportsJoin(language, format, { without: ['NATURAL JOIN'] }); supportsOperators(language, format, BigQueryFormatter.operators); + supportsParams(language, format, { indexed: ['?'] }); it('supports # line comment', () => { const result = format('SELECT alpha # commment\nFROM beta'); diff --git a/test/db2.test.ts b/test/db2.test.ts index 0a7ef980d1..c00f4e22ce 100644 --- a/test/db2.test.ts +++ b/test/db2.test.ts @@ -12,6 +12,7 @@ import supportsSchema from './features/schema'; import supportsStrings from './features/strings'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; +import supportsParams from './options/param'; describe('Db2Formatter', () => { const language = 'db2'; @@ -27,6 +28,7 @@ describe('Db2Formatter', () => { supportsSchema(language, format); supportsOperators(language, format, Db2Formatter.operators); supportsJoin(language, format); + supportsParams(language, format, { indexed: ['?'] }); it('formats FETCH FIRST like LIMIT', () => { expect(format('SELECT col1 FROM tbl ORDER BY col2 DESC FETCH FIRST 20 ROWS ONLY;')).toBe(dedent` diff --git a/test/hive.test.ts b/test/hive.test.ts index a8541e6ca3..799fb39543 100644 --- a/test/hive.test.ts +++ b/test/hive.test.ts @@ -10,6 +10,7 @@ import supportsBetween from './features/between'; import supportsJoin from './features/join'; import supportsOperators from './features/operators'; import supportsArray from './features/array'; +import supportsParams from './options/param'; describe('HiveFormatter', () => { const language = 'hive'; @@ -24,4 +25,5 @@ describe('HiveFormatter', () => { supportsJoin(language, format, { without: ['NATURAL JOIN'] }); supportsOperators(language, format, HiveFormatter.operators); supportsArray(language, format); + supportsParams(language, format, { indexed: ['?'] }); }); diff --git a/test/options/param.ts b/test/options/param.ts new file mode 100644 index 0000000000..ed15491bbd --- /dev/null +++ b/test/options/param.ts @@ -0,0 +1,64 @@ +import dedent from 'dedent-js'; +import { SqlLanguage, FormatFn } from '../../src/sqlFormatter'; + +interface ParamsTypes { + indexed: '?'[]; +} + +export default function supportsParams( + language: SqlLanguage, + format: FormatFn, + params: ParamsTypes +) { + describe('supports params', () => { + if (params.indexed.includes('?')) { + it('leaves ? indexed placeholders as is when no params config provided', () => { + const result = format('SELECT ?, ?, ?;'); + expect(result).toBe(dedent` + SELECT + ?, + ?, + ?; + `); + }); + + it('replaces ? indexed placeholders with param values', () => { + const result = format('SELECT ?, ?, ?;', { + params: ['first', 'second', 'third'], + }); + expect(result).toBe(dedent` + SELECT + first, + second, + third; + `); + }); + + it('recognizes ?[0-9]* placeholders', () => { + const result = format('SELECT ?1, ?25, ?;'); + expect(result).toBe(dedent` + SELECT + ?1, + ?25, + ?; + `); + }); + + it('replaces ? numbered placeholders with param values', () => { + const result = format('SELECT ?1, ?2, ?0;', { + params: { + 0: 'first', + 1: 'second', + 2: 'third', + }, + }); + expect(result).toBe(dedent` + SELECT + second, + third, + first; + `); + }); + } + }); +} diff --git a/test/plsql.test.ts b/test/plsql.test.ts index e438ade9d7..1a572b5067 100644 --- a/test/plsql.test.ts +++ b/test/plsql.test.ts @@ -14,6 +14,7 @@ import supportsStrings from './features/strings'; import supportsReturning from './features/returning'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; +import supportsParams from './options/param'; describe('PlSqlFormatter', () => { const language = 'plsql'; @@ -31,6 +32,7 @@ describe('PlSqlFormatter', () => { supportsOperators(language, format, PlSqlFormatter.operators, ['AND', 'OR', 'XOR']); supportsJoin(language, format); supportsReturning(language, format); + supportsParams(language, format, { indexed: ['?'] }); it('formats FETCH FIRST like LIMIT', () => { expect(format('SELECT col1 FROM tbl ORDER BY col2 DESC FETCH FIRST 20 ROWS ONLY;')).toBe(dedent` @@ -82,34 +84,6 @@ describe('PlSqlFormatter', () => { `); }); - it('recognizes ?[0-9]* placeholders', () => { - const result = format('SELECT ?1, ?25, ?;'); - expect(result).toBe(dedent` - SELECT - ?1, - ?25, - ?; - `); - }); - - it('replaces ? numbered placeholders with param values', () => { - const result = format('SELECT ?1, ?2, ?0;', { - params: { - 0: 'first', - 1: 'second', - 2: 'third', - }, - }); - expect(result).toBe('SELECT\n' + ' second,\n' + ' third,\n' + ' first;'); - }); - - it('replaces ? indexed placeholders with param values', () => { - const result = format('SELECT ?, ?, ?;', { - params: ['first', 'second', 'third'], - }); - expect(result).toBe('SELECT\n' + ' first,\n' + ' second,\n' + ' third;'); - }); - it('formats SELECT query with CROSS APPLY', () => { const result = format('SELECT a, b FROM t CROSS APPLY fn(t.id)'); expect(result).toBe(dedent` diff --git a/test/redshift.test.ts b/test/redshift.test.ts index b292dffe39..1740522a38 100644 --- a/test/redshift.test.ts +++ b/test/redshift.test.ts @@ -11,6 +11,7 @@ import supportsOperators from './features/operators'; import supportsSchema from './features/schema'; import supportsStrings from './features/strings'; import supportsDeleteFrom from './features/deleteFrom'; +import supportsParams from './options/param'; describe('RedshiftFormatter', () => { const language = 'redshift'; @@ -25,6 +26,7 @@ describe('RedshiftFormatter', () => { supportsSchema(language, format); supportsOperators(language, format, RedshiftFormatter.operators); supportsJoin(language, format); + supportsParams(language, format, { indexed: ['?'] }); it('formats LIMIT', () => { expect(format('SELECT col1 FROM tbl ORDER BY col2 DESC LIMIT 10;')).toBe(dedent` diff --git a/test/spark.test.ts b/test/spark.test.ts index e10fc80efe..da0a7eacf9 100644 --- a/test/spark.test.ts +++ b/test/spark.test.ts @@ -11,6 +11,7 @@ import supportsOperators from './features/operators'; import supportsSchema from './features/schema'; import supportsStrings from './features/strings'; import supportsArray from './features/array'; +import supportsParams from './options/param'; describe('SparkFormatter', () => { const language = 'spark'; @@ -44,6 +45,7 @@ describe('SparkFormatter', () => { 'NATURAL SEMI JOIN', ], }); + supportsParams(language, format, { indexed: ['?'] }); it('formats WINDOW specification as top level', () => { const result = format( diff --git a/test/sql.test.ts b/test/sql.test.ts index c44f754b84..a948215992 100644 --- a/test/sql.test.ts +++ b/test/sql.test.ts @@ -12,6 +12,7 @@ import supportsJoin from './features/join'; import supportsOperators from './features/operators'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; +import supportsParams from './options/param'; describe('SqlFormatter', () => { const language = 'sql'; @@ -27,18 +28,7 @@ describe('SqlFormatter', () => { supportsSchema(language, format); supportsJoin(language, format); supportsOperators(language, format, SqlFormatter.operators); - - it('replaces ? indexed placeholders with param values', () => { - const result = format('SELECT ?, ?, ?;', { - params: ['first', 'second', 'third'], - }); - expect(result).toBe(dedent` - SELECT - first, - second, - third; - `); - }); + supportsParams(language, format, { indexed: ['?'] }); it('formats FETCH FIRST like LIMIT', () => { const result = format('SELECT * FETCH FIRST 2 ROWS ONLY;'); diff --git a/test/sqlite.test.ts b/test/sqlite.test.ts index c4e44a0fe4..cb13b07c3d 100644 --- a/test/sqlite.test.ts +++ b/test/sqlite.test.ts @@ -12,6 +12,7 @@ import supportsJoin from './features/join'; import supportsOperators from './features/operators'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; +import supportsParams from './options/param'; describe('SqliteFormatter', () => { const language = 'sqlite'; @@ -30,18 +31,7 @@ describe('SqliteFormatter', () => { additionally: ['NATURAL LEFT JOIN', 'NATURAL LEFT OUTER JOIN'], }); supportsOperators(language, format, SqliteFormatter.operators); - - it('replaces ? indexed placeholders with param values', () => { - const result = format('SELECT ?, ?, ?;', { - params: ['first', 'second', 'third'], - }); - expect(result).toBe(dedent` - SELECT - first, - second, - third; - `); - }); + supportsParams(language, format, { indexed: ['?'] }); it('formats FETCH FIRST like LIMIT', () => { const result = format('SELECT * FETCH FIRST 2 ROWS ONLY;'); From a2e8a4de70503b11fcbacff6dfa5d2f016f93f01 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 10:12:03 +0300 Subject: [PATCH 016/334] Move $-param tests also to the shared params test --- test/options/param.ts | 28 +++++++++++++++++++++++++++- test/postgresql.test.ts | 26 ++------------------------ 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/test/options/param.ts b/test/options/param.ts index ed15491bbd..a385c6b139 100644 --- a/test/options/param.ts +++ b/test/options/param.ts @@ -2,7 +2,7 @@ import dedent from 'dedent-js'; import { SqlLanguage, FormatFn } from '../../src/sqlFormatter'; interface ParamsTypes { - indexed: '?'[]; + indexed: ('?' | '$')[]; } export default function supportsParams( @@ -60,5 +60,31 @@ export default function supportsParams( `); }); } + + if (params.indexed.includes('$')) { + it('recognizes $n placeholders', () => { + const result = format('SELECT $1, $2 FROM tbl'); + expect(result).toBe(dedent` + SELECT + $1, + $2 + FROM + tbl + `); + }); + + it('replaces $n placeholders with param values', () => { + const result = format('SELECT $1, $2 FROM tbl', { + params: { 1: '"variable value"', 2: '"blah"' }, + }); + expect(result).toBe(dedent` + SELECT + "variable value", + "blah" + FROM + tbl + `); + }); + } }); } diff --git a/test/postgresql.test.ts b/test/postgresql.test.ts index 11b79638cd..1539dfa6ff 100644 --- a/test/postgresql.test.ts +++ b/test/postgresql.test.ts @@ -13,6 +13,7 @@ import supportsStrings from './features/strings'; import supportsReturning from './features/returning'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; +import supportsParams from './options/param'; describe('PostgreSqlFormatter', () => { const language = 'postgresql'; @@ -29,30 +30,7 @@ describe('PostgreSqlFormatter', () => { supportsOperators(language, format, PostgreSqlFormatter.operators); supportsJoin(language, format); supportsReturning(language, format); - - it('supports $n placeholders', () => { - const result = format('SELECT $1, $2 FROM tbl'); - expect(result).toBe(dedent` - SELECT - $1, - $2 - FROM - tbl - `); - }); - - it('replaces $n placeholders with param values', () => { - const result = format('SELECT $1, $2 FROM tbl', { - params: { 1: '"variable value"', 2: '"blah"' }, - }); - expect(result).toBe(dedent` - SELECT - "variable value", - "blah" - FROM - tbl - `); - }); + supportsParams(language, format, { indexed: ['$'] }); it('supports :name placeholders', () => { expect(format('foo = :bar')).toBe('foo = :bar'); From c4d9c7918d8cf1ece2c505606a71206ebe8a1bff Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 10:29:07 +0300 Subject: [PATCH 017/334] Refactor tests for :name parameters --- test/db2.test.ts | 19 +-------------- test/options/param.ts | 51 ++++++++++++++++++++++++++++++++++++++--- test/plsql.test.ts | 2 +- test/postgresql.test.ts | 19 +-------------- test/sqlite.test.ts | 2 +- 5 files changed, 52 insertions(+), 41 deletions(-) diff --git a/test/db2.test.ts b/test/db2.test.ts index c00f4e22ce..38ee399adb 100644 --- a/test/db2.test.ts +++ b/test/db2.test.ts @@ -28,7 +28,7 @@ describe('Db2Formatter', () => { supportsSchema(language, format); supportsOperators(language, format, Db2Formatter.operators); supportsJoin(language, format); - supportsParams(language, format, { indexed: ['?'] }); + supportsParams(language, format, { indexed: ['?'], named: [':'] }); it('formats FETCH FIRST like LIMIT', () => { expect(format('SELECT col1 FROM tbl ORDER BY col2 DESC FETCH FIRST 20 ROWS ONLY;')).toBe(dedent` @@ -68,21 +68,4 @@ describe('Db2Formatter', () => { tbl `); }); - - it('recognizes :variables', () => { - expect(format('SELECT :variable;')).toBe(dedent` - SELECT - :variable; - `); - }); - - it('replaces :variables with param values', () => { - const result = format('SELECT :variable', { - params: { variable: '"variable value"' }, - }); - expect(result).toBe(dedent` - SELECT - "variable value" - `); - }); }); diff --git a/test/options/param.ts b/test/options/param.ts index a385c6b139..ad2984e439 100644 --- a/test/options/param.ts +++ b/test/options/param.ts @@ -2,7 +2,8 @@ import dedent from 'dedent-js'; import { SqlLanguage, FormatFn } from '../../src/sqlFormatter'; interface ParamsTypes { - indexed: ('?' | '$')[]; + indexed?: ('?' | '$')[]; + named?: ':'[]; } export default function supportsParams( @@ -11,7 +12,7 @@ export default function supportsParams( params: ParamsTypes ) { describe('supports params', () => { - if (params.indexed.includes('?')) { + if (params.indexed?.includes('?')) { it('leaves ? indexed placeholders as is when no params config provided', () => { const result = format('SELECT ?, ?, ?;'); expect(result).toBe(dedent` @@ -61,7 +62,7 @@ export default function supportsParams( }); } - if (params.indexed.includes('$')) { + if (params.indexed?.includes('$')) { it('recognizes $n placeholders', () => { const result = format('SELECT $1, $2 FROM tbl'); expect(result).toBe(dedent` @@ -86,5 +87,49 @@ export default function supportsParams( `); }); } + + if (params.named?.includes(':')) { + it('recognizes :name placeholders', () => { + expect(format('SELECT :foo, :bar, :baz;')).toBe(dedent` + SELECT + :foo, + :bar, + :baz; + `); + }); + + it('replaces :name placeholders with param values', () => { + expect( + format(`WHERE name = :name AND age > :current_age;`, { + params: { name: "'John'", current_age: '10' }, + }) + ).toBe(dedent` + WHERE + name = 'John' + AND age > 10; + `); + }); + + it(`recognizes :'name' and :"name" placeholders`, () => { + expect(format(`SELECT :'foo', :"bar", :"baz";`)).toBe(dedent` + SELECT + :'foo', + :"bar", + :"baz"; + `); + }); + + it(`replaces :'name' and :"name" placeholders with param values`, () => { + expect( + format(`WHERE name = :"name" AND age > :'current_age';`, { + params: { name: "'John'", current_age: '10' }, + }) + ).toBe(dedent` + WHERE + name = 'John' + AND age > 10; + `); + }); + } }); } diff --git a/test/plsql.test.ts b/test/plsql.test.ts index 1a572b5067..8f4442c1b8 100644 --- a/test/plsql.test.ts +++ b/test/plsql.test.ts @@ -32,7 +32,7 @@ describe('PlSqlFormatter', () => { supportsOperators(language, format, PlSqlFormatter.operators, ['AND', 'OR', 'XOR']); supportsJoin(language, format); supportsReturning(language, format); - supportsParams(language, format, { indexed: ['?'] }); + supportsParams(language, format, { indexed: ['?'], named: [':'] }); it('formats FETCH FIRST like LIMIT', () => { expect(format('SELECT col1 FROM tbl ORDER BY col2 DESC FETCH FIRST 20 ROWS ONLY;')).toBe(dedent` diff --git a/test/postgresql.test.ts b/test/postgresql.test.ts index 1539dfa6ff..fc2cb42210 100644 --- a/test/postgresql.test.ts +++ b/test/postgresql.test.ts @@ -1,4 +1,3 @@ -import dedent from 'dedent-js'; import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; import PostgreSqlFormatter from '../src/languages/postgresql.formatter'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; @@ -30,21 +29,5 @@ describe('PostgreSqlFormatter', () => { supportsOperators(language, format, PostgreSqlFormatter.operators); supportsJoin(language, format); supportsReturning(language, format); - supportsParams(language, format, { indexed: ['$'] }); - - it('supports :name placeholders', () => { - expect(format('foo = :bar')).toBe('foo = :bar'); - }); - - it('replaces :name placeholders with param values', () => { - expect( - format(`foo = :bar AND :"field" = 10 OR col = :'val'`, { - params: { bar: "'Hello'", field: 'some_col', val: '7' }, - }) - ).toBe(dedent` - foo = 'Hello' - AND some_col = 10 - OR col = 7 - `); - }); + supportsParams(language, format, { indexed: ['$'], named: [':'] }); }); diff --git a/test/sqlite.test.ts b/test/sqlite.test.ts index cb13b07c3d..7726ecc73a 100644 --- a/test/sqlite.test.ts +++ b/test/sqlite.test.ts @@ -31,7 +31,7 @@ describe('SqliteFormatter', () => { additionally: ['NATURAL LEFT JOIN', 'NATURAL LEFT OUTER JOIN'], }); supportsOperators(language, format, SqliteFormatter.operators); - supportsParams(language, format, { indexed: ['?'] }); + supportsParams(language, format, { indexed: ['?'], named: [':'] }); it('formats FETCH FIRST like LIMIT', () => { const result = format('SELECT * FETCH FIRST 2 ROWS ONLY;'); From 55e5e30f095ce3a4d19ac1f67d6f00b884ef828e Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 10:54:00 +0300 Subject: [PATCH 018/334] Refactor $name parameter tests --- test/n1ql.test.ts | 45 +-------------------- test/options/param.ts | 92 ++++++++++++++++++++++++++++++++++++++++++- test/redshift.test.ts | 2 +- test/spark.test.ts | 28 +------------ test/sqlite.test.ts | 2 +- 5 files changed, 96 insertions(+), 73 deletions(-) diff --git a/test/n1ql.test.ts b/test/n1ql.test.ts index 6f7dc14912..5073326c51 100644 --- a/test/n1ql.test.ts +++ b/test/n1ql.test.ts @@ -11,6 +11,7 @@ import supportsStrings from './features/strings'; import supportsReturning from './features/returning'; import supportsDeleteFrom from './features/deleteFrom'; import supportsArray from './features/array'; +import supportsParams from './options/param'; describe('N1qlFormatter', () => { const language = 'n1ql'; @@ -25,6 +26,7 @@ describe('N1qlFormatter', () => { supportsArray(language, format); supportsJoin(language, format, { without: ['FULL', 'CROSS', 'NATURAL'] }); supportsReturning(language, format); + supportsParams(language, format, { named: ['$'] }); it('formats SELECT query with primary key querying', () => { const result = format("SELECT fname, email FROM tutorial USE KEYS ['dave', 'ian'];"); @@ -131,47 +133,4 @@ describe('N1qlFormatter', () => { type = 'actor' `); }); - - it('recognizes $variables', () => { - const result = format('SELECT $variable, $\'var name\', $"var name", $`var name`;'); - expect(result).toBe(dedent` - SELECT - $variable, - $'var name', - $"var name", - $\`var name\`; - `); - }); - - it('replaces $variables with param values', () => { - const result = format('SELECT $variable, $\'var name\', $"var name", $`var name`;', { - params: { - 'variable': '"variable value"', - 'var name': "'var value'", - }, - }); - expect(result).toBe(dedent` - SELECT - "variable value", - 'var value', - 'var value', - 'var value'; - `); - }); - - it('replaces $ numbered placeholders with param values', () => { - const result = format('SELECT $1, $2, $0;', { - params: { - 0: 'first', - 1: 'second', - 2: 'third', - }, - }); - expect(result).toBe(dedent` - SELECT - second, - third, - first; - `); - }); }); diff --git a/test/options/param.ts b/test/options/param.ts index ad2984e439..c8afe02772 100644 --- a/test/options/param.ts +++ b/test/options/param.ts @@ -3,7 +3,7 @@ import { SqlLanguage, FormatFn } from '../../src/sqlFormatter'; interface ParamsTypes { indexed?: ('?' | '$')[]; - named?: ':'[]; + named?: (':' | '$' | '${}')[]; } export default function supportsParams( @@ -131,5 +131,95 @@ export default function supportsParams( `); }); } + + if (params.named?.includes('$')) { + it('recognizes $name placeholders', () => { + expect(format('SELECT $foo, $bar, $baz;')).toBe(dedent` + SELECT + $foo, + $bar, + $baz; + `); + }); + + it('replaces $name placeholders with param values', () => { + expect( + format(`WHERE name = $name AND age > $current_age;`, { + params: { name: "'John'", current_age: '10' }, + }) + ).toBe(dedent` + WHERE + name = 'John' + AND age > 10; + `); + }); + + it(`recognizes $'name' and $"name" and $\`name\` placeholders`, () => { + expect(format(`SELECT $'foo', $"bar", $\`baz\`;`)).toBe(dedent` + SELECT + $'foo', + $"bar", + $\`baz\`; + `); + }); + + it(`replaces $'name' and $"name" and $\`name\` placeholders with param values`, () => { + expect( + format(`WHERE name = $"name" AND age > $'current_age' OR addr = $\`addr\`;`, { + params: { name: "'John'", current_age: '10', addr: "'Baker street'" }, + }) + ).toBe(dedent` + WHERE + name = 'John' + AND age > 10 + OR addr = 'Baker street'; + `); + }); + + it('replaces $n numbered placeholders with param values', () => { + const result = format('SELECT $1, $2, $0;', { + params: { + 0: 'first', + 1: 'second', + 2: 'third', + }, + }); + expect(result).toBe(dedent` + SELECT + second, + third, + first; + `); + }); + } + + if (params.named?.includes('${}')) { + // eslint-disable-next-line no-template-curly-in-string + it('recognizes ${name} placeholders', () => { + // eslint-disable-next-line no-template-curly-in-string + const result = format('SELECT ${var_name}, ${var name};'); + expect(result).toBe(dedent` + SELECT + \${var_name}, + \${var name}; + `); + }); + + // eslint-disable-next-line no-template-curly-in-string + it('replaces ${variables} with param values', () => { + // eslint-disable-next-line no-template-curly-in-string + const result = format('SELECT ${var 1}, ${var2};', { + params: { + 'var 1': "'var one'", + 'var2': "'var two'", + }, + }); + expect(result).toBe(dedent` + SELECT + 'var one', + 'var two'; + `); + }); + } }); } diff --git a/test/redshift.test.ts b/test/redshift.test.ts index 1740522a38..e59ce062c0 100644 --- a/test/redshift.test.ts +++ b/test/redshift.test.ts @@ -26,7 +26,7 @@ describe('RedshiftFormatter', () => { supportsSchema(language, format); supportsOperators(language, format, RedshiftFormatter.operators); supportsJoin(language, format); - supportsParams(language, format, { indexed: ['?'] }); + supportsParams(language, format, { indexed: ['?'], named: ['$'] }); it('formats LIMIT', () => { expect(format('SELECT col1 FROM tbl ORDER BY col2 DESC LIMIT 10;')).toBe(dedent` diff --git a/test/spark.test.ts b/test/spark.test.ts index da0a7eacf9..9e5dbf0b5a 100644 --- a/test/spark.test.ts +++ b/test/spark.test.ts @@ -45,7 +45,7 @@ describe('SparkFormatter', () => { 'NATURAL SEMI JOIN', ], }); - supportsParams(language, format, { indexed: ['?'] }); + supportsParams(language, format, { indexed: ['?'], named: ['$', '${}'] }); it('formats WINDOW specification as top level', () => { const result = format( @@ -79,30 +79,4 @@ describe('SparkFormatter', () => { tbl; `); }); - - // eslint-disable-next-line no-template-curly-in-string - it('does not add spaces around ${value} params', () => { - // eslint-disable-next-line no-template-curly-in-string - const result = format('SELECT ${var_name};'); - expect(result).toBe(dedent` - SELECT - \${var_name}; - `); - }); - - // eslint-disable-next-line no-template-curly-in-string - it('replaces $variables and ${variables} with param values', () => { - // eslint-disable-next-line no-template-curly-in-string - const result = format('SELECT $var1, ${var2};', { - params: { - var1: "'var one'", - var2: "'var two'", - }, - }); - expect(result).toBe(dedent` - SELECT - 'var one', - 'var two'; - `); - }); }); diff --git a/test/sqlite.test.ts b/test/sqlite.test.ts index 7726ecc73a..e140a8d183 100644 --- a/test/sqlite.test.ts +++ b/test/sqlite.test.ts @@ -31,7 +31,7 @@ describe('SqliteFormatter', () => { additionally: ['NATURAL LEFT JOIN', 'NATURAL LEFT OUTER JOIN'], }); supportsOperators(language, format, SqliteFormatter.operators); - supportsParams(language, format, { indexed: ['?'], named: [':'] }); + supportsParams(language, format, { indexed: ['?'], named: [':', '$'] }); it('formats FETCH FIRST like LIMIT', () => { const result = format('SELECT * FETCH FIRST 2 ROWS ONLY;'); From 762ad45b32dd5fc0f45c10d1df0c353ed968187e Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 11:07:01 +0300 Subject: [PATCH 019/334] Refactor @name parameter tests --- test/options/param.ts | 69 ++++++++++++++++++++++++++++++++++++++++++- test/redshift.test.ts | 12 +------- test/sqlite.test.ts | 2 +- test/tsql.test.ts | 28 ++---------------- 4 files changed, 72 insertions(+), 39 deletions(-) diff --git a/test/options/param.ts b/test/options/param.ts index c8afe02772..940b024b3d 100644 --- a/test/options/param.ts +++ b/test/options/param.ts @@ -3,7 +3,7 @@ import { SqlLanguage, FormatFn } from '../../src/sqlFormatter'; interface ParamsTypes { indexed?: ('?' | '$')[]; - named?: (':' | '$' | '${}')[]; + named?: (':' | '$' | '${}' | '@' | '@""' | '@[]')[]; } export default function supportsParams( @@ -222,4 +222,71 @@ export default function supportsParams( }); } }); + + if (params.named?.includes('@')) { + it('recognizes @name placeholders', () => { + expect(format('SELECT @foo, @bar, @baz;')).toBe(dedent` + SELECT + @foo, + @bar, + @baz; + `); + }); + + it('replaces @name placeholders with param values', () => { + expect( + format(`WHERE name = @name AND age > @current_age;`, { + params: { name: "'John'", current_age: '10' }, + }) + ).toBe(dedent` + WHERE + name = 'John' + AND age > 10; + `); + }); + } + + if (params.named?.includes('@""')) { + it(`recognizes @"name" placeholders`, () => { + expect(format(`SELECT @"foo", @"foo bar";`)).toBe(dedent` + SELECT + @"foo", + @"foo bar"; + `); + }); + + it(`replaces @"name" placeholders with param values`, () => { + expect( + format(`WHERE name = @"name" AND age > @"current age";`, { + params: { 'name': "'John'", 'current age': '10' }, + }) + ).toBe(dedent` + WHERE + name = 'John' + AND age > 10; + `); + }); + } + + if (params.named?.includes('@[]')) { + it(`recognizes @[name] placeholders`, () => { + expect(format(`SELECT @[foo], @[foo bar];`)).toBe(dedent` + SELECT + @[foo], + @[foo bar]; + `); + }); + + it(`replaces @[name] placeholders with param values`, () => { + expect( + format(`WHERE name = @[name] AND age > @[current age];`, { + params: { 'name': "'John'", 'current age': '10' }, + }) + ).toBe(dedent` + WHERE + name = 'John' + AND age > 10; + `); + }); + } } diff --git a/test/redshift.test.ts b/test/redshift.test.ts index e59ce062c0..1934a8b6f6 100644 --- a/test/redshift.test.ts +++ b/test/redshift.test.ts @@ -26,7 +26,7 @@ describe('RedshiftFormatter', () => { supportsSchema(language, format); supportsOperators(language, format, RedshiftFormatter.operators); supportsJoin(language, format); - supportsParams(language, format, { indexed: ['?'], named: ['$'] }); + supportsParams(language, format, { indexed: ['?'], named: ['$', '@', '@""'] }); it('formats LIMIT', () => { expect(format('SELECT col1 FROM tbl ORDER BY col2 DESC LIMIT 10;')).toBe(dedent` @@ -56,16 +56,6 @@ describe('RedshiftFormatter', () => { `); }); - it('recognizes @ as part of identifiers', () => { - const result = format('SELECT @col1 FROM tbl'); - expect(result).toBe(dedent` - SELECT - @col1 - FROM - tbl - `); - }); - it.skip('formats DISTKEY and SORTKEY after CREATE TABLE', () => { expect( format( diff --git a/test/sqlite.test.ts b/test/sqlite.test.ts index e140a8d183..ca95bb697c 100644 --- a/test/sqlite.test.ts +++ b/test/sqlite.test.ts @@ -31,7 +31,7 @@ describe('SqliteFormatter', () => { additionally: ['NATURAL LEFT JOIN', 'NATURAL LEFT OUTER JOIN'], }); supportsOperators(language, format, SqliteFormatter.operators); - supportsParams(language, format, { indexed: ['?'], named: [':', '$'] }); + supportsParams(language, format, { indexed: ['?'], named: [':', '$', '@', '@""'] }); it('formats FETCH FIRST like LIMIT', () => { const result = format('SELECT * FETCH FIRST 2 ROWS ONLY;'); diff --git a/test/tsql.test.ts b/test/tsql.test.ts index eefdd1e9de..5c92230c97 100644 --- a/test/tsql.test.ts +++ b/test/tsql.test.ts @@ -12,6 +12,7 @@ import supportsOperators from './features/operators'; import supportsJoin from './features/join'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; +import supportsParams from './options/param'; describe('TSqlFormatter', () => { const language = 'tsql'; @@ -27,6 +28,7 @@ describe('TSqlFormatter', () => { supportsSchema(language, format); supportsOperators(language, format, TSqlFormatter.operators); supportsJoin(language, format, { without: ['NATURAL'] }); + supportsParams(language, format, { named: ['@', '@""', '@[]'] }); // TODO: The following are duplicated from StandardSQLFormatter test @@ -42,32 +44,6 @@ describe('TSqlFormatter', () => { `); }); - it('recognizes @variables', () => { - const result = format('SELECT @variable, @"var name", @[var name];'); - expect(result).toBe(dedent` - SELECT - @variable, - @"var name", - @[var name]; - `); - }); - - it('replaces @variables with param values', () => { - const result = format('SELECT @variable, @"var name1", @[var name2];', { - params: { - 'variable': "'var value'", - 'var name1': "'var value1'", - 'var name2': "'var value2'", - }, - }); - expect(result).toBe(dedent` - SELECT - 'var value', - 'var value1', - 'var value2'; - `); - }); - it('formats SELECT query with CROSS JOIN', () => { const result = format('SELECT a, b FROM t CROSS JOIN t2 on t.id = t2.id_t'); expect(result).toBe(dedent` From 4c4de5ef209cc2332a5649b5b1bea2b41a051fdf Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 11:12:41 +0300 Subject: [PATCH 020/334] Looks like Redshift has incorrect parameter types --- src/languages/redshift.formatter.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/languages/redshift.formatter.ts b/src/languages/redshift.formatter.ts index 6871578c47..7391f0db6d 100644 --- a/src/languages/redshift.formatter.ts +++ b/src/languages/redshift.formatter.ts @@ -730,6 +730,9 @@ export default class RedshiftFormatter extends Formatter { ]), stringTypes: RedshiftFormatter.stringTypes, indexedPlaceholderTypes: ['?'], + // XXX: Seems like redshift only supports $1, $2, $3 parameters, + // but for some reason we list lots of types in here. + // https://docs.aws.amazon.com/redshift/latest/dg/r_PREPARE.html namedPlaceholderTypes: ['@', '#', '$'], operators: RedshiftFormatter.operators, }); From a29cea01b190e7c75ff6f5789449c8919434e2e6 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 11:24:52 +0300 Subject: [PATCH 021/334] Remove unused language parameter from all test helper functions Except supportsComments(), which still uses it. --- test/behavesLikeMariaDbFormatter.ts | 14 ++++++------ test/behavesLikeSqlFormatter.ts | 30 +++++++++++++------------- test/bigquery.test.ts | 16 +++++++------- test/db2.test.ts | 20 ++++++++--------- test/features/alterTable.ts | 4 ++-- test/features/alterTableModify.ts | 4 ++-- test/features/array.ts | 4 ++-- test/features/between.ts | 4 ++-- test/features/case.ts | 4 ++-- test/features/constraints.ts | 4 ++-- test/features/createTable.ts | 4 ++-- test/features/deleteFrom.ts | 4 ++-- test/features/join.ts | 8 ++----- test/features/operators.ts | 3 +-- test/features/returning.ts | 4 ++-- test/features/schema.ts | 4 ++-- test/features/strings.ts | 8 ++----- test/hive.test.ts | 18 ++++++++-------- test/mariadb.test.ts | 6 +++--- test/mysql.test.ts | 4 ++-- test/n1ql.test.ts | 18 ++++++++-------- test/options/aliasAs.ts | 4 ++-- test/options/commaPosition.ts | 4 ++-- test/options/expressionWidth.ts | 4 ++-- test/options/indentStyle.ts | 4 ++-- test/options/keywordCase.ts | 4 ++-- test/options/linesBetweenQueries.ts | 4 ++-- test/options/logicalOperatorNewline.ts | 4 ++-- test/options/multilineLists.ts | 4 ++-- test/options/newlineBeforeParen.ts | 4 ++-- test/options/newlineBeforeSemicolon.ts | 4 ++-- test/options/param.ts | 8 ++----- test/options/tabWidth.ts | 4 ++-- test/options/tabulateAlias.ts | 4 ++-- test/options/useTabs.ts | 4 ++-- test/plsql.test.ts | 24 ++++++++++----------- test/postgresql.test.ts | 22 +++++++++---------- test/redshift.test.ts | 18 ++++++++-------- test/spark.test.ts | 18 ++++++++-------- test/sql.test.ts | 20 ++++++++--------- test/sqlite.test.ts | 20 ++++++++--------- test/tsql.test.ts | 20 ++++++++--------- 42 files changed, 187 insertions(+), 200 deletions(-) diff --git a/test/behavesLikeMariaDbFormatter.ts b/test/behavesLikeMariaDbFormatter.ts index 5c50c725f3..db83ddcb09 100644 --- a/test/behavesLikeMariaDbFormatter.ts +++ b/test/behavesLikeMariaDbFormatter.ts @@ -15,12 +15,12 @@ import supportsParams from './options/param'; */ export default function behavesLikeMariaDbFormatter(language: SqlLanguage, format: FormatFn) { behavesLikeSqlFormatter(language, format); - supportsCreateTable(language, format); - supportsConstraints(language, format); - supportsAlterTable(language, format); - supportsDeleteFrom(language, format); - supportsBetween(language, format); - supportsJoin(language, format, { + supportsCreateTable(format); + supportsConstraints(format); + supportsAlterTable(format); + supportsDeleteFrom(format); + supportsBetween(format); + supportsJoin(format, { without: ['FULL'], additionally: [ 'STRAIGHT_JOIN', @@ -30,7 +30,7 @@ export default function behavesLikeMariaDbFormatter(language: SqlLanguage, forma 'NATURAL RIGHT OUTER JOIN', ], }); - supportsParams(language, format, { indexed: ['?'] }); + supportsParams(format, { indexed: ['?'] }); it('supports # comments', () => { expect(format('SELECT a # comment\nFROM b # comment')).toBe(dedent` diff --git a/test/behavesLikeSqlFormatter.ts b/test/behavesLikeSqlFormatter.ts index eb0990d686..a7d4c60b31 100644 --- a/test/behavesLikeSqlFormatter.ts +++ b/test/behavesLikeSqlFormatter.ts @@ -22,21 +22,21 @@ import supportsTabulateAlias from './options/tabulateAlias'; */ export default function behavesLikeSqlFormatter(language: SqlLanguage, format: FormatFn) { supportsComments(language, format); - supportsCase(language, format); - - supportsAliasAs(language, format); - supportsTabulateAlias(language, format); - supportsTabWidth(language, format); - supportsUseTabs(language, format); - supportsKeywordCase(language, format); - supportsIndentStyle(language, format); - supportsLinesBetweenQueries(language, format); - supportsMultilineLists(language, format); - supportsExpressionWidth(language, format); - supportsNewlineBeforeParen(language, format); - supportsNewlineBeforeSemicolon(language, format); - supportsCommaPosition(language, format); - supportsLogicalOperatorNewline(language, format); + supportsCase(format); + + supportsAliasAs(format); + supportsTabulateAlias(format); + supportsTabWidth(format); + supportsUseTabs(format); + supportsKeywordCase(format); + supportsIndentStyle(format); + supportsLinesBetweenQueries(format); + supportsMultilineLists(format); + supportsExpressionWidth(format); + supportsNewlineBeforeParen(format); + supportsNewlineBeforeSemicolon(format); + supportsCommaPosition(format); + supportsLogicalOperatorNewline(format); it('does nothing with empty input', () => { const result = format(''); diff --git a/test/bigquery.test.ts b/test/bigquery.test.ts index b24222d823..467dcdcbf1 100644 --- a/test/bigquery.test.ts +++ b/test/bigquery.test.ts @@ -17,14 +17,14 @@ describe('BigQueryFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(language, format); - supportsCreateTable(language, format); - supportsDeleteFrom(language, format); - supportsStrings(language, format, BigQueryFormatter.stringTypes); - supportsBetween(language, format); - supportsSchema(language, format); - supportsJoin(language, format, { without: ['NATURAL JOIN'] }); - supportsOperators(language, format, BigQueryFormatter.operators); - supportsParams(language, format, { indexed: ['?'] }); + supportsCreateTable(format); + supportsDeleteFrom(format); + supportsStrings(format, BigQueryFormatter.stringTypes); + supportsBetween(format); + supportsSchema(format); + supportsJoin(format, { without: ['NATURAL JOIN'] }); + supportsOperators(format, BigQueryFormatter.operators); + supportsParams(format, { indexed: ['?'] }); it('supports # line comment', () => { const result = format('SELECT alpha # commment\nFROM beta'); diff --git a/test/db2.test.ts b/test/db2.test.ts index 38ee399adb..9e6ab801a4 100644 --- a/test/db2.test.ts +++ b/test/db2.test.ts @@ -19,16 +19,16 @@ describe('Db2Formatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(language, format); - supportsCreateTable(language, format); - supportsConstraints(language, format); - supportsAlterTable(language, format); - supportsDeleteFrom(language, format); - supportsStrings(language, format, Db2Formatter.stringTypes); - supportsBetween(language, format); - supportsSchema(language, format); - supportsOperators(language, format, Db2Formatter.operators); - supportsJoin(language, format); - supportsParams(language, format, { indexed: ['?'], named: [':'] }); + supportsCreateTable(format); + supportsConstraints(format); + supportsAlterTable(format); + supportsDeleteFrom(format); + supportsStrings(format, Db2Formatter.stringTypes); + supportsBetween(format); + supportsSchema(format); + supportsOperators(format, Db2Formatter.operators); + supportsJoin(format); + supportsParams(format, { indexed: ['?'], named: [':'] }); it('formats FETCH FIRST like LIMIT', () => { expect(format('SELECT col1 FROM tbl ORDER BY col2 DESC FETCH FIRST 20 ROWS ONLY;')).toBe(dedent` diff --git a/test/features/alterTable.ts b/test/features/alterTable.ts index 0e123b6c48..6f894139eb 100644 --- a/test/features/alterTable.ts +++ b/test/features/alterTable.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { FormatFn, SqlLanguage } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsAlterTable(language: SqlLanguage, format: FormatFn) { +export default function supportsAlterTable(format: FormatFn) { it('formats ALTER TABLE ... ALTER COLUMN query', () => { const result = format('ALTER TABLE supplier ALTER COLUMN supplier_name VARCHAR(100) NOT NULL;'); expect(result).toBe(dedent` diff --git a/test/features/alterTableModify.ts b/test/features/alterTableModify.ts index c7b6746d59..c6f215a772 100644 --- a/test/features/alterTableModify.ts +++ b/test/features/alterTableModify.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { SqlLanguage, FormatFn } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsAlterTableModify(language: SqlLanguage, format: FormatFn) { +export default function supportsAlterTableModify(format: FormatFn) { it('formats ALTER TABLE ... MODIFY statement', () => { const result = format('ALTER TABLE supplier MODIFY supplier_name char(100) NOT NULL;'); expect(result).toBe(dedent` diff --git a/test/features/array.ts b/test/features/array.ts index 9539ecbe06..3ab15d2f87 100644 --- a/test/features/array.ts +++ b/test/features/array.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { SqlLanguage, FormatFn } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsArray(language: SqlLanguage, format: FormatFn) { +export default function supportsArray(format: FormatFn) { it('supports square brackets for array indexing', () => { const result = format(`SELECT order_lines[5].productId;`); expect(result).toBe(dedent` diff --git a/test/features/between.ts b/test/features/between.ts index a92421b93f..76ab10c2e5 100644 --- a/test/features/between.ts +++ b/test/features/between.ts @@ -1,6 +1,6 @@ -import { SqlLanguage, FormatFn } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsBetween(language: SqlLanguage, format: FormatFn) { +export default function supportsBetween(format: FormatFn) { it('formats BETWEEN _ AND _ on single line', () => { expect(format('foo BETWEEN bar AND baz')).toBe('foo BETWEEN bar AND baz'); }); diff --git a/test/features/case.ts b/test/features/case.ts index 08ccf35da1..41e77719d4 100644 --- a/test/features/case.ts +++ b/test/features/case.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { SqlLanguage, FormatFn } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsCase(language: SqlLanguage, format: FormatFn) { +export default function supportsCase(format: FormatFn) { it('formats CASE ... WHEN with a blank expression', () => { const result = format( "CASE WHEN option = 'foo' THEN 1 WHEN option = 'bar' THEN 2 WHEN option = 'baz' THEN 3 ELSE 4 END;" diff --git a/test/features/constraints.ts b/test/features/constraints.ts index 346a7b85e0..deb38c2748 100644 --- a/test/features/constraints.ts +++ b/test/features/constraints.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { SqlLanguage, FormatFn } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsConstraints(language: SqlLanguage, format: FormatFn) { +export default function supportsConstraints(format: FormatFn) { it('treats ON UPDATE & ON DELETE as distinct keywords from ON', () => { expect( format(` diff --git a/test/features/createTable.ts b/test/features/createTable.ts index a47f941800..bc23d0dfc5 100644 --- a/test/features/createTable.ts +++ b/test/features/createTable.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { SqlLanguage, FormatFn } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsCreateTable(language: SqlLanguage, format: FormatFn) { +export default function supportsCreateTable(format: FormatFn) { it('formats short CREATE TABLE', () => { expect(format('CREATE TABLE tbl (a INT PRIMARY KEY, b TEXT);')).toBe(dedent` CREATE TABLE diff --git a/test/features/deleteFrom.ts b/test/features/deleteFrom.ts index 85cfda6a67..78ab4224f8 100644 --- a/test/features/deleteFrom.ts +++ b/test/features/deleteFrom.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { FormatFn, SqlLanguage } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsDeleteFrom(language: SqlLanguage, format: FormatFn) { +export default function supportsDeleteFrom(format: FormatFn) { it('formats simple DELETE FROM statement', () => { const result = format("DELETE FROM Customers WHERE CustomerName='Alfred' AND Phone=5002132;"); expect(result).toBe(dedent` diff --git a/test/features/join.ts b/test/features/join.ts index 8405c83297..115e5b6a69 100644 --- a/test/features/join.ts +++ b/test/features/join.ts @@ -1,13 +1,9 @@ import dedent from 'dedent-js'; -import { SqlLanguage, FormatFn } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; type Options = { without?: string[]; additionally?: string[] }; -export default function supportsJoin( - language: SqlLanguage, - format: FormatFn, - { without, additionally }: Options = {} -) { +export default function supportsJoin(format: FormatFn, { without, additionally }: Options = {}) { const unsupportedJoinRegex = without ? new RegExp(without.join('|'), 'u') : /^whateve_!%&$/u; const isSupportedJoin = (join: string) => !unsupportedJoinRegex.test(join); diff --git a/test/features/operators.ts b/test/features/operators.ts index 05d0ae1b3f..1934732f2e 100644 --- a/test/features/operators.ts +++ b/test/features/operators.ts @@ -1,8 +1,7 @@ import dedent from 'dedent-js'; -import { SqlLanguage, FormatFn } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; export default function supportsOperators( - language: SqlLanguage, format: FormatFn, operators: string[], logicalOperators: string[] = ['AND', 'OR'] diff --git a/test/features/returning.ts b/test/features/returning.ts index 13029d1c87..3f3a2183aa 100644 --- a/test/features/returning.ts +++ b/test/features/returning.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { FormatFn, SqlLanguage } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsReturning(language: SqlLanguage, format: FormatFn) { +export default function supportsReturning(format: FormatFn) { it('places RETURNING to new line', () => { const result = format( "INSERT INTO users (firstname, lastname) VALUES ('Joe', 'Cool') RETURNING id, firstname;" diff --git a/test/features/schema.ts b/test/features/schema.ts index 88dc598596..2e53db8fee 100644 --- a/test/features/schema.ts +++ b/test/features/schema.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { SqlLanguage, FormatFn } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsSchema(language: SqlLanguage, format: FormatFn) { +export default function supportsSchema(format: FormatFn) { it('formats simple SET SCHEMA statements', () => { const result = format('SET SCHEMA schema1;'); expect(result).toBe(dedent` diff --git a/test/features/strings.ts b/test/features/strings.ts index 1d7def07f1..00d8113cc1 100644 --- a/test/features/strings.ts +++ b/test/features/strings.ts @@ -1,12 +1,8 @@ import { expect } from '@jest/globals'; import dedent from 'dedent-js'; -import { SqlLanguage, FormatFn } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsStrings( - language: SqlLanguage, - format: FormatFn, - stringTypes: string[] -) { +export default function supportsStrings(format: FormatFn, stringTypes: string[]) { if (stringTypes.includes('""')) { it('supports double-quoted strings', () => { expect(format('"foo JOIN bar"')).toBe('"foo JOIN bar"'); diff --git a/test/hive.test.ts b/test/hive.test.ts index 799fb39543..3b5befcc31 100644 --- a/test/hive.test.ts +++ b/test/hive.test.ts @@ -17,13 +17,13 @@ describe('HiveFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(language, format); - supportsCreateTable(language, format); - supportsAlterTable(language, format); - supportsStrings(language, format, HiveFormatter.stringTypes); - supportsBetween(language, format); - supportsSchema(language, format); - supportsJoin(language, format, { without: ['NATURAL JOIN'] }); - supportsOperators(language, format, HiveFormatter.operators); - supportsArray(language, format); - supportsParams(language, format, { indexed: ['?'] }); + supportsCreateTable(format); + supportsAlterTable(format); + supportsStrings(format, HiveFormatter.stringTypes); + supportsBetween(format); + supportsSchema(format); + supportsJoin(format, { without: ['NATURAL JOIN'] }); + supportsOperators(format, HiveFormatter.operators); + supportsArray(format); + supportsParams(format, { indexed: ['?'] }); }); diff --git a/test/mariadb.test.ts b/test/mariadb.test.ts index e34a86b007..7235c5ebe1 100644 --- a/test/mariadb.test.ts +++ b/test/mariadb.test.ts @@ -12,7 +12,7 @@ describe('MariaDbFormatter', () => { behavesLikeMariaDbFormatter(language, format); - supportsStrings(language, format, MariaDbFormatter.stringTypes); - supportsOperators(language, format, MariaDbFormatter.operators, ['AND', 'OR', 'XOR']); - supportsReturning(language, format); + supportsStrings(format, MariaDbFormatter.stringTypes); + supportsOperators(format, MariaDbFormatter.operators, ['AND', 'OR', 'XOR']); + supportsReturning(format); }); diff --git a/test/mysql.test.ts b/test/mysql.test.ts index d2019eaf1d..2f7af9d1c1 100644 --- a/test/mysql.test.ts +++ b/test/mysql.test.ts @@ -12,8 +12,8 @@ describe('MySqlFormatter', () => { behavesLikeMariaDbFormatter(language, format); - supportsStrings(language, format, MySqlFormatter.stringTypes); - supportsOperators(language, format, MySqlFormatter.operators, ['AND', 'OR', 'XOR']); + supportsStrings(format, MySqlFormatter.stringTypes); + supportsOperators(format, MySqlFormatter.operators, ['AND', 'OR', 'XOR']); it('supports @@ system variables', () => { const result = format('SELECT @@GLOBAL.time, @@SYSTEM.date, @@hour FROM foo;'); diff --git a/test/n1ql.test.ts b/test/n1ql.test.ts index 5073326c51..c7a2966617 100644 --- a/test/n1ql.test.ts +++ b/test/n1ql.test.ts @@ -18,15 +18,15 @@ describe('N1qlFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(language, format); - supportsDeleteFrom(language, format); - supportsStrings(language, format, N1qlFormatter.stringTypes); - supportsBetween(language, format); - supportsSchema(language, format); - supportsOperators(language, format, N1qlFormatter.operators, ['AND', 'OR', 'XOR']); - supportsArray(language, format); - supportsJoin(language, format, { without: ['FULL', 'CROSS', 'NATURAL'] }); - supportsReturning(language, format); - supportsParams(language, format, { named: ['$'] }); + supportsDeleteFrom(format); + supportsStrings(format, N1qlFormatter.stringTypes); + supportsBetween(format); + supportsSchema(format); + supportsOperators(format, N1qlFormatter.operators, ['AND', 'OR', 'XOR']); + supportsArray(format); + supportsJoin(format, { without: ['FULL', 'CROSS', 'NATURAL'] }); + supportsReturning(format); + supportsParams(format, { named: ['$'] }); it('formats SELECT query with primary key querying', () => { const result = format("SELECT fname, email FROM tutorial USE KEYS ['dave', 'ian'];"); diff --git a/test/options/aliasAs.ts b/test/options/aliasAs.ts index b2a3b1a36e..f1d06939ce 100644 --- a/test/options/aliasAs.ts +++ b/test/options/aliasAs.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { FormatFn, SqlLanguage } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsAliasAs(language: SqlLanguage, format: FormatFn) { +export default function supportsAliasAs(format: FormatFn) { describe('by default', () => { it('preserves original uses of AS', () => { expect( diff --git a/test/options/commaPosition.ts b/test/options/commaPosition.ts index ba94833c11..d7ce002438 100644 --- a/test/options/commaPosition.ts +++ b/test/options/commaPosition.ts @@ -1,8 +1,8 @@ import { expect } from '@jest/globals'; import dedent from 'dedent-js'; -import { FormatFn, SqlLanguage } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsCommaPosition(language: SqlLanguage, format: FormatFn) { +export default function supportsCommaPosition(format: FormatFn) { it('defaults to comma after column', () => { const result = format( 'SELECT alpha , MAX(beta) , delta AS d ,epsilon FROM gamma GROUP BY alpha , delta, epsilon' diff --git a/test/options/expressionWidth.ts b/test/options/expressionWidth.ts index c85e017f14..aceb7beb3f 100644 --- a/test/options/expressionWidth.ts +++ b/test/options/expressionWidth.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { FormatFn, SqlLanguage } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsExpressionWidth(language: SqlLanguage, format: FormatFn) { +export default function supportsExpressionWidth(format: FormatFn) { it('throws error when expressionWidth negative number', () => { expect(() => { format('SELECT *', { expressionWidth: -2 }); diff --git a/test/options/indentStyle.ts b/test/options/indentStyle.ts index 47040dc973..beb375072d 100644 --- a/test/options/indentStyle.ts +++ b/test/options/indentStyle.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { FormatFn, SqlLanguage } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsIndentStyle(language: SqlLanguage, format: FormatFn) { +export default function supportsIndentStyle(format: FormatFn) { const baseQuery = ` SELECT COUNT(a.column1), MAX(b.column2 + b.column3), b.column4 AS four FROM ( SELECT column1, column5 FROM table1 ) a diff --git a/test/options/keywordCase.ts b/test/options/keywordCase.ts index 4a2f53d5f9..84b398208a 100644 --- a/test/options/keywordCase.ts +++ b/test/options/keywordCase.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { FormatFn, SqlLanguage } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsKeywordCase(language: SqlLanguage, format: FormatFn) { +export default function supportsKeywordCase(format: FormatFn) { it('preserves keyword case by default', () => { const result = format('select distinct * frOM foo left JOIN bar WHERe cola > 1 and colb = 3'); expect(result).toBe(dedent` diff --git a/test/options/linesBetweenQueries.ts b/test/options/linesBetweenQueries.ts index ad0765edc5..adc18683e2 100644 --- a/test/options/linesBetweenQueries.ts +++ b/test/options/linesBetweenQueries.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { FormatFn, SqlLanguage } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsLinesBetweenQueries(language: SqlLanguage, format: FormatFn) { +export default function supportsLinesBetweenQueries(format: FormatFn) { it('defaults to single empty line between queries', () => { const result = format('SELECT * FROM foo; SELECT * FROM bar;'); expect(result).toBe(dedent` diff --git a/test/options/logicalOperatorNewline.ts b/test/options/logicalOperatorNewline.ts index f799248fd1..da820259c3 100644 --- a/test/options/logicalOperatorNewline.ts +++ b/test/options/logicalOperatorNewline.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { FormatFn, SqlLanguage } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsLogicalOperatorNewline(language: SqlLanguage, format: FormatFn) { +export default function supportsLogicalOperatorNewline(format: FormatFn) { it('by default adds newline before logical operator', () => { const result = format('SELECT a WHERE true AND false;'); expect(result).toBe(dedent` diff --git a/test/options/multilineLists.ts b/test/options/multilineLists.ts index d797240482..ece8c99f3e 100644 --- a/test/options/multilineLists.ts +++ b/test/options/multilineLists.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { FormatFn, SqlLanguage } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsMultilineLists(language: SqlLanguage, format: FormatFn) { +export default function supportsMultilineLists(format: FormatFn) { it('throws error when multilineLists is negative number', () => { expect(() => { format('SELECT *', { multilineLists: -1 }); diff --git a/test/options/newlineBeforeParen.ts b/test/options/newlineBeforeParen.ts index 34cd174971..6d68d1b8ef 100644 --- a/test/options/newlineBeforeParen.ts +++ b/test/options/newlineBeforeParen.ts @@ -1,8 +1,8 @@ import { expect } from '@jest/globals'; import dedent from 'dedent-js'; -import { FormatFn, SqlLanguage } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsNewlineBeforeParen(language: SqlLanguage, format: FormatFn) { +export default function supportsNewlineBeforeParen(format: FormatFn) { it('defaults to newline before opening and closing parenthesis', () => { const result = format('SELECT a FROM ( SELECT b FROM c );'); expect(result).toBe(dedent` diff --git a/test/options/newlineBeforeSemicolon.ts b/test/options/newlineBeforeSemicolon.ts index 32f16fe3ff..891cf298a7 100644 --- a/test/options/newlineBeforeSemicolon.ts +++ b/test/options/newlineBeforeSemicolon.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { FormatFn, SqlLanguage } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsNewlineBeforeSemicolon(language: SqlLanguage, format: FormatFn) { +export default function supportsNewlineBeforeSemicolon(format: FormatFn) { it('defaults to semicolon on end of last line', () => { const result = format(`SELECT a FROM b;`); expect(result).toBe(dedent` diff --git a/test/options/param.ts b/test/options/param.ts index 940b024b3d..881dfaa240 100644 --- a/test/options/param.ts +++ b/test/options/param.ts @@ -1,16 +1,12 @@ import dedent from 'dedent-js'; -import { SqlLanguage, FormatFn } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; interface ParamsTypes { indexed?: ('?' | '$')[]; named?: (':' | '$' | '${}' | '@' | '@""' | '@[]')[]; } -export default function supportsParams( - language: SqlLanguage, - format: FormatFn, - params: ParamsTypes -) { +export default function supportsParams(format: FormatFn, params: ParamsTypes) { describe('supports params', () => { if (params.indexed?.includes('?')) { it('leaves ? indexed placeholders as is when no params config provided', () => { diff --git a/test/options/tabWidth.ts b/test/options/tabWidth.ts index b8156d8152..e5d33d79d7 100644 --- a/test/options/tabWidth.ts +++ b/test/options/tabWidth.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { FormatFn, SqlLanguage } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsTabWidth(language: SqlLanguage, format: FormatFn) { +export default function supportsTabWidth(format: FormatFn) { it('indents with 2 spaces by default', () => { const result = format('SELECT count(*),Column1 FROM Table1;'); diff --git a/test/options/tabulateAlias.ts b/test/options/tabulateAlias.ts index 77fd2766b9..f4d20ddaa3 100644 --- a/test/options/tabulateAlias.ts +++ b/test/options/tabulateAlias.ts @@ -1,7 +1,7 @@ import dedent from 'dedent-js'; -import { FormatFn, SqlLanguage } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsTabulateAlias(language: SqlLanguage, format: FormatFn) { +export default function supportsTabulateAlias(format: FormatFn) { it('tabulates aliases which use AS keyword', () => { const result = format( 'SELECT alpha AS alp, MAX(beta), epsilon AS E FROM ( SELECT mu AS m, iota AS io FROM gamma );', diff --git a/test/options/useTabs.ts b/test/options/useTabs.ts index 63d839e47e..61c8c45c5a 100644 --- a/test/options/useTabs.ts +++ b/test/options/useTabs.ts @@ -1,6 +1,6 @@ -import { FormatFn, SqlLanguage } from '../../src/sqlFormatter'; +import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsUseTabs(language: SqlLanguage, format: FormatFn) { +export default function supportsUseTabs(format: FormatFn) { it('supports indenting with tabs', () => { const result = format('SELECT count(*),Column1 FROM Table1;', { useTabs: true, diff --git a/test/plsql.test.ts b/test/plsql.test.ts index 8f4442c1b8..e88ede9774 100644 --- a/test/plsql.test.ts +++ b/test/plsql.test.ts @@ -21,18 +21,18 @@ describe('PlSqlFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(language, format); - supportsCreateTable(language, format); - supportsConstraints(language, format); - supportsAlterTable(language, format); - supportsAlterTableModify(language, format); - supportsDeleteFrom(language, format); - supportsStrings(language, format, PlSqlFormatter.stringTypes); - supportsBetween(language, format); - supportsSchema(language, format); - supportsOperators(language, format, PlSqlFormatter.operators, ['AND', 'OR', 'XOR']); - supportsJoin(language, format); - supportsReturning(language, format); - supportsParams(language, format, { indexed: ['?'], named: [':'] }); + supportsCreateTable(format); + supportsConstraints(format); + supportsAlterTable(format); + supportsAlterTableModify(format); + supportsDeleteFrom(format); + supportsStrings(format, PlSqlFormatter.stringTypes); + supportsBetween(format); + supportsSchema(format); + supportsOperators(format, PlSqlFormatter.operators, ['AND', 'OR', 'XOR']); + supportsJoin(format); + supportsReturning(format); + supportsParams(format, { indexed: ['?'], named: [':'] }); it('formats FETCH FIRST like LIMIT', () => { expect(format('SELECT col1 FROM tbl ORDER BY col2 DESC FETCH FIRST 20 ROWS ONLY;')).toBe(dedent` diff --git a/test/postgresql.test.ts b/test/postgresql.test.ts index fc2cb42210..34ce88361d 100644 --- a/test/postgresql.test.ts +++ b/test/postgresql.test.ts @@ -19,15 +19,15 @@ describe('PostgreSqlFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(language, format); - supportsCreateTable(language, format); - supportsConstraints(language, format); - supportsAlterTable(language, format); - supportsDeleteFrom(language, format); - supportsStrings(language, format, PostgreSqlFormatter.stringTypes); - supportsBetween(language, format); - supportsSchema(language, format); - supportsOperators(language, format, PostgreSqlFormatter.operators); - supportsJoin(language, format); - supportsReturning(language, format); - supportsParams(language, format, { indexed: ['$'], named: [':'] }); + supportsCreateTable(format); + supportsConstraints(format); + supportsAlterTable(format); + supportsDeleteFrom(format); + supportsStrings(format, PostgreSqlFormatter.stringTypes); + supportsBetween(format); + supportsSchema(format); + supportsOperators(format, PostgreSqlFormatter.operators); + supportsJoin(format); + supportsReturning(format); + supportsParams(format, { indexed: ['$'], named: [':'] }); }); diff --git a/test/redshift.test.ts b/test/redshift.test.ts index 1934a8b6f6..f8f89f514a 100644 --- a/test/redshift.test.ts +++ b/test/redshift.test.ts @@ -18,15 +18,15 @@ describe('RedshiftFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(language, format); - supportsCreateTable(language, format); - supportsAlterTable(language, format); - supportsAlterTableModify(language, format); - supportsDeleteFrom(language, format); - supportsStrings(language, format, RedshiftFormatter.stringTypes); - supportsSchema(language, format); - supportsOperators(language, format, RedshiftFormatter.operators); - supportsJoin(language, format); - supportsParams(language, format, { indexed: ['?'], named: ['$', '@', '@""'] }); + supportsCreateTable(format); + supportsAlterTable(format); + supportsAlterTableModify(format); + supportsDeleteFrom(format); + supportsStrings(format, RedshiftFormatter.stringTypes); + supportsSchema(format); + supportsOperators(format, RedshiftFormatter.operators); + supportsJoin(format); + supportsParams(format, { indexed: ['?'], named: ['$', '@', '@""'] }); it('formats LIMIT', () => { expect(format('SELECT col1 FROM tbl ORDER BY col2 DESC LIMIT 10;')).toBe(dedent` diff --git a/test/spark.test.ts b/test/spark.test.ts index 9e5dbf0b5a..23af0c8cd5 100644 --- a/test/spark.test.ts +++ b/test/spark.test.ts @@ -18,14 +18,14 @@ describe('SparkFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(language, format); - supportsCreateTable(language, format); - supportsAlterTable(language, format); - supportsStrings(language, format, SparkFormatter.stringTypes); - supportsBetween(language, format); - supportsSchema(language, format); - supportsOperators(language, format, SparkFormatter.operators, ['AND', 'OR', 'XOR']); - supportsArray(language, format); - supportsJoin(language, format, { + supportsCreateTable(format); + supportsAlterTable(format); + supportsStrings(format, SparkFormatter.stringTypes); + supportsBetween(format); + supportsSchema(format); + supportsOperators(format, SparkFormatter.operators, ['AND', 'OR', 'XOR']); + supportsArray(format); + supportsJoin(format, { additionally: [ 'ANTI JOIN', 'SEMI JOIN', @@ -45,7 +45,7 @@ describe('SparkFormatter', () => { 'NATURAL SEMI JOIN', ], }); - supportsParams(language, format, { indexed: ['?'], named: ['$', '${}'] }); + supportsParams(format, { indexed: ['?'], named: ['$', '${}'] }); it('formats WINDOW specification as top level', () => { const result = format( diff --git a/test/sql.test.ts b/test/sql.test.ts index a948215992..4318daaa49 100644 --- a/test/sql.test.ts +++ b/test/sql.test.ts @@ -19,16 +19,16 @@ describe('SqlFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(language, format); - supportsCreateTable(language, format); - supportsConstraints(language, format); - supportsAlterTable(language, format); - supportsDeleteFrom(language, format); - supportsStrings(language, format, SqlFormatter.stringTypes); - supportsBetween(language, format); - supportsSchema(language, format); - supportsJoin(language, format); - supportsOperators(language, format, SqlFormatter.operators); - supportsParams(language, format, { indexed: ['?'] }); + supportsCreateTable(format); + supportsConstraints(format); + supportsAlterTable(format); + supportsDeleteFrom(format); + supportsStrings(format, SqlFormatter.stringTypes); + supportsBetween(format); + supportsSchema(format); + supportsJoin(format); + supportsOperators(format, SqlFormatter.operators); + supportsParams(format, { indexed: ['?'] }); it('formats FETCH FIRST like LIMIT', () => { const result = format('SELECT * FETCH FIRST 2 ROWS ONLY;'); diff --git a/test/sqlite.test.ts b/test/sqlite.test.ts index ca95bb697c..5ecc4e5926 100644 --- a/test/sqlite.test.ts +++ b/test/sqlite.test.ts @@ -19,19 +19,19 @@ describe('SqliteFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(language, format); - supportsCreateTable(language, format); - supportsConstraints(language, format); - supportsAlterTable(language, format); - supportsDeleteFrom(language, format); - supportsStrings(language, format, SqliteFormatter.stringTypes); - supportsBetween(language, format); - supportsSchema(language, format); - supportsJoin(language, format, { + supportsCreateTable(format); + supportsConstraints(format); + supportsAlterTable(format); + supportsDeleteFrom(format); + supportsStrings(format, SqliteFormatter.stringTypes); + supportsBetween(format); + supportsSchema(format); + supportsJoin(format, { without: ['FULL', 'RIGHT'], additionally: ['NATURAL LEFT JOIN', 'NATURAL LEFT OUTER JOIN'], }); - supportsOperators(language, format, SqliteFormatter.operators); - supportsParams(language, format, { indexed: ['?'], named: [':', '$', '@', '@""'] }); + supportsOperators(format, SqliteFormatter.operators); + supportsParams(format, { indexed: ['?'], named: [':', '$', '@', '@""'] }); it('formats FETCH FIRST like LIMIT', () => { const result = format('SELECT * FETCH FIRST 2 ROWS ONLY;'); diff --git a/test/tsql.test.ts b/test/tsql.test.ts index 5c92230c97..8803ba37c3 100644 --- a/test/tsql.test.ts +++ b/test/tsql.test.ts @@ -19,16 +19,16 @@ describe('TSqlFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(language, format); - supportsCreateTable(language, format); - supportsConstraints(language, format); - supportsAlterTable(language, format); - supportsDeleteFrom(language, format); - supportsStrings(language, format, TSqlFormatter.stringTypes); - supportsBetween(language, format); - supportsSchema(language, format); - supportsOperators(language, format, TSqlFormatter.operators); - supportsJoin(language, format, { without: ['NATURAL'] }); - supportsParams(language, format, { named: ['@', '@""', '@[]'] }); + supportsCreateTable(format); + supportsConstraints(format); + supportsAlterTable(format); + supportsDeleteFrom(format); + supportsStrings(format, TSqlFormatter.stringTypes); + supportsBetween(format); + supportsSchema(format); + supportsOperators(format, TSqlFormatter.operators); + supportsJoin(format, { without: ['NATURAL'] }); + supportsParams(format, { named: ['@', '@""', '@[]'] }); // TODO: The following are duplicated from StandardSQLFormatter test From 6bb00bc6f417c1b9590c5198e32a7fac76f651c5 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 11:29:59 +0300 Subject: [PATCH 022/334] Move supportsComments() out of behavesLikeSqlFormatter() Comments syntax varies a bit across dialects. --- test/behavesLikeMariaDbFormatter.ts | 4 +++- test/behavesLikeSqlFormatter.ts | 6 ++---- test/bigquery.test.ts | 4 +++- test/db2.test.ts | 4 +++- test/hive.test.ts | 4 +++- test/n1ql.test.ts | 4 +++- test/plsql.test.ts | 4 +++- test/postgresql.test.ts | 4 +++- test/redshift.test.ts | 4 +++- test/spark.test.ts | 4 +++- test/sql.test.ts | 4 +++- test/sqlite.test.ts | 4 +++- test/tsql.test.ts | 4 +++- 13 files changed, 38 insertions(+), 16 deletions(-) diff --git a/test/behavesLikeMariaDbFormatter.ts b/test/behavesLikeMariaDbFormatter.ts index db83ddcb09..8588611bc2 100644 --- a/test/behavesLikeMariaDbFormatter.ts +++ b/test/behavesLikeMariaDbFormatter.ts @@ -9,12 +9,14 @@ import supportsJoin from './features/join'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; +import supportsComments from './features/comments'; /** * Shared tests for MySQL and MariaDB */ export default function behavesLikeMariaDbFormatter(language: SqlLanguage, format: FormatFn) { - behavesLikeSqlFormatter(language, format); + behavesLikeSqlFormatter(format); + supportsComments(language, format); supportsCreateTable(format); supportsConstraints(format); supportsAlterTable(format); diff --git a/test/behavesLikeSqlFormatter.ts b/test/behavesLikeSqlFormatter.ts index a7d4c60b31..09fe10910e 100644 --- a/test/behavesLikeSqlFormatter.ts +++ b/test/behavesLikeSqlFormatter.ts @@ -1,7 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn, SqlLanguage } from '../src/sqlFormatter'; -import supportsComments from './features/comments'; +import { FormatFn } from '../src/sqlFormatter'; import supportsCase from './features/case'; import supportsTabWidth from './options/tabWidth'; import supportsUseTabs from './options/useTabs'; @@ -20,8 +19,7 @@ import supportsTabulateAlias from './options/tabulateAlias'; /** * Core tests for all SQL formatters */ -export default function behavesLikeSqlFormatter(language: SqlLanguage, format: FormatFn) { - supportsComments(language, format); +export default function behavesLikeSqlFormatter(format: FormatFn) { supportsCase(format); supportsAliasAs(format); diff --git a/test/bigquery.test.ts b/test/bigquery.test.ts index 467dcdcbf1..219c6976fc 100644 --- a/test/bigquery.test.ts +++ b/test/bigquery.test.ts @@ -11,12 +11,14 @@ import supportsJoin from './features/join'; import supportsOperators from './features/operators'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; +import supportsComments from './features/comments'; describe('BigQueryFormatter', () => { const language = 'bigquery'; const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); - behavesLikeSqlFormatter(language, format); + behavesLikeSqlFormatter(format); + supportsComments(language, format); supportsCreateTable(format); supportsDeleteFrom(format); supportsStrings(format, BigQueryFormatter.stringTypes); diff --git a/test/db2.test.ts b/test/db2.test.ts index 9e6ab801a4..417ca16fa1 100644 --- a/test/db2.test.ts +++ b/test/db2.test.ts @@ -13,12 +13,14 @@ import supportsStrings from './features/strings'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; +import supportsComments from './features/comments'; describe('Db2Formatter', () => { const language = 'db2'; const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); - behavesLikeSqlFormatter(language, format); + behavesLikeSqlFormatter(format); + supportsComments(language, format); supportsCreateTable(format); supportsConstraints(format); supportsAlterTable(format); diff --git a/test/hive.test.ts b/test/hive.test.ts index 3b5befcc31..e0ea6aaa7b 100644 --- a/test/hive.test.ts +++ b/test/hive.test.ts @@ -11,12 +11,14 @@ import supportsJoin from './features/join'; import supportsOperators from './features/operators'; import supportsArray from './features/array'; import supportsParams from './options/param'; +import supportsComments from './features/comments'; describe('HiveFormatter', () => { const language = 'hive'; const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); - behavesLikeSqlFormatter(language, format); + behavesLikeSqlFormatter(format); + supportsComments(language, format); supportsCreateTable(format); supportsAlterTable(format); supportsStrings(format, HiveFormatter.stringTypes); diff --git a/test/n1ql.test.ts b/test/n1ql.test.ts index c7a2966617..bfeffaa3a6 100644 --- a/test/n1ql.test.ts +++ b/test/n1ql.test.ts @@ -12,12 +12,14 @@ import supportsReturning from './features/returning'; import supportsDeleteFrom from './features/deleteFrom'; import supportsArray from './features/array'; import supportsParams from './options/param'; +import supportsComments from './features/comments'; describe('N1qlFormatter', () => { const language = 'n1ql'; const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); - behavesLikeSqlFormatter(language, format); + behavesLikeSqlFormatter(format); + supportsComments(language, format); supportsDeleteFrom(format); supportsStrings(format, N1qlFormatter.stringTypes); supportsBetween(format); diff --git a/test/plsql.test.ts b/test/plsql.test.ts index e88ede9774..beab7e3066 100644 --- a/test/plsql.test.ts +++ b/test/plsql.test.ts @@ -15,12 +15,14 @@ import supportsReturning from './features/returning'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; +import supportsComments from './features/comments'; describe('PlSqlFormatter', () => { const language = 'plsql'; const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); - behavesLikeSqlFormatter(language, format); + behavesLikeSqlFormatter(format); + supportsComments(language, format); supportsCreateTable(format); supportsConstraints(format); supportsAlterTable(format); diff --git a/test/postgresql.test.ts b/test/postgresql.test.ts index 34ce88361d..05cd97d221 100644 --- a/test/postgresql.test.ts +++ b/test/postgresql.test.ts @@ -13,12 +13,14 @@ import supportsReturning from './features/returning'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; +import supportsComments from './features/comments'; describe('PostgreSqlFormatter', () => { const language = 'postgresql'; const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); - behavesLikeSqlFormatter(language, format); + behavesLikeSqlFormatter(format); + supportsComments(language, format); supportsCreateTable(format); supportsConstraints(format); supportsAlterTable(format); diff --git a/test/redshift.test.ts b/test/redshift.test.ts index f8f89f514a..9419d77c93 100644 --- a/test/redshift.test.ts +++ b/test/redshift.test.ts @@ -12,12 +12,14 @@ import supportsSchema from './features/schema'; import supportsStrings from './features/strings'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; +import supportsComments from './features/comments'; describe('RedshiftFormatter', () => { const language = 'redshift'; const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); - behavesLikeSqlFormatter(language, format); + behavesLikeSqlFormatter(format); + supportsComments(language, format); supportsCreateTable(format); supportsAlterTable(format); supportsAlterTableModify(format); diff --git a/test/spark.test.ts b/test/spark.test.ts index 23af0c8cd5..2c1aaefea5 100644 --- a/test/spark.test.ts +++ b/test/spark.test.ts @@ -12,12 +12,14 @@ import supportsSchema from './features/schema'; import supportsStrings from './features/strings'; import supportsArray from './features/array'; import supportsParams from './options/param'; +import supportsComments from './features/comments'; describe('SparkFormatter', () => { const language = 'spark'; const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); - behavesLikeSqlFormatter(language, format); + behavesLikeSqlFormatter(format); + supportsComments(language, format); supportsCreateTable(format); supportsAlterTable(format); supportsStrings(format, SparkFormatter.stringTypes); diff --git a/test/sql.test.ts b/test/sql.test.ts index 4318daaa49..7c5a27f15c 100644 --- a/test/sql.test.ts +++ b/test/sql.test.ts @@ -13,12 +13,14 @@ import supportsOperators from './features/operators'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; +import supportsComments from './features/comments'; describe('SqlFormatter', () => { const language = 'sql'; const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); - behavesLikeSqlFormatter(language, format); + behavesLikeSqlFormatter(format); + supportsComments(language, format); supportsCreateTable(format); supportsConstraints(format); supportsAlterTable(format); diff --git a/test/sqlite.test.ts b/test/sqlite.test.ts index 5ecc4e5926..4576514095 100644 --- a/test/sqlite.test.ts +++ b/test/sqlite.test.ts @@ -13,12 +13,14 @@ import supportsOperators from './features/operators'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; +import supportsComments from './features/comments'; describe('SqliteFormatter', () => { const language = 'sqlite'; const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); - behavesLikeSqlFormatter(language, format); + behavesLikeSqlFormatter(format); + supportsComments(language, format); supportsCreateTable(format); supportsConstraints(format); supportsAlterTable(format); diff --git a/test/tsql.test.ts b/test/tsql.test.ts index 8803ba37c3..3ea8eadc0a 100644 --- a/test/tsql.test.ts +++ b/test/tsql.test.ts @@ -13,12 +13,14 @@ import supportsJoin from './features/join'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; +import supportsComments from './features/comments'; describe('TSqlFormatter', () => { const language = 'tsql'; const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); - behavesLikeSqlFormatter(language, format); + behavesLikeSqlFormatter(format); + supportsComments(language, format); supportsCreateTable(format); supportsConstraints(format); supportsAlterTable(format); From 4f9db8d05ce75ed2c1f2234064fcc67af8b6b417 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 11:41:50 +0300 Subject: [PATCH 023/334] Remove language param also from supportsComments() test Targeting this specific case with a sepatate flag instead. --- test/behavesLikeMariaDbFormatter.ts | 6 +++--- test/bigquery.test.ts | 2 +- test/db2.test.ts | 2 +- test/features/comments.ts | 13 +++++++++---- test/hive.test.ts | 2 +- test/mariadb.test.ts | 2 +- test/mysql.test.ts | 2 +- test/n1ql.test.ts | 2 +- test/plsql.test.ts | 2 +- test/postgresql.test.ts | 2 +- test/redshift.test.ts | 2 +- test/spark.test.ts | 2 +- test/sql.test.ts | 2 +- test/sqlite.test.ts | 2 +- test/tsql.test.ts | 2 +- 15 files changed, 25 insertions(+), 20 deletions(-) diff --git a/test/behavesLikeMariaDbFormatter.ts b/test/behavesLikeMariaDbFormatter.ts index 8588611bc2..81b5c457f8 100644 --- a/test/behavesLikeMariaDbFormatter.ts +++ b/test/behavesLikeMariaDbFormatter.ts @@ -1,6 +1,6 @@ import dedent from 'dedent-js'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; -import { FormatFn, SqlLanguage } from '../src/sqlFormatter'; +import { FormatFn } from '../src/sqlFormatter'; import supportsCreateTable from './features/createTable'; import supportsAlterTable from './features/alterTable'; @@ -14,9 +14,9 @@ import supportsComments from './features/comments'; /** * Shared tests for MySQL and MariaDB */ -export default function behavesLikeMariaDbFormatter(language: SqlLanguage, format: FormatFn) { +export default function behavesLikeMariaDbFormatter(format: FormatFn) { behavesLikeSqlFormatter(format); - supportsComments(language, format); + supportsComments(format); supportsCreateTable(format); supportsConstraints(format); supportsAlterTable(format); diff --git a/test/bigquery.test.ts b/test/bigquery.test.ts index 219c6976fc..faadab0e2b 100644 --- a/test/bigquery.test.ts +++ b/test/bigquery.test.ts @@ -18,7 +18,7 @@ describe('BigQueryFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(format); - supportsComments(language, format); + supportsComments(format, { skipTrickyCommentsTest: true }); supportsCreateTable(format); supportsDeleteFrom(format); supportsStrings(format, BigQueryFormatter.stringTypes); diff --git a/test/db2.test.ts b/test/db2.test.ts index 417ca16fa1..d562d59e0a 100644 --- a/test/db2.test.ts +++ b/test/db2.test.ts @@ -20,7 +20,7 @@ describe('Db2Formatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(format); - supportsComments(language, format); + supportsComments(format); supportsCreateTable(format); supportsConstraints(format); supportsAlterTable(format); diff --git a/test/features/comments.ts b/test/features/comments.ts index 5a2abc7806..4a2b369b06 100644 --- a/test/features/comments.ts +++ b/test/features/comments.ts @@ -1,9 +1,11 @@ import dedent from 'dedent-js'; -import { FormatFn, SqlLanguage } from '../../src/sqlFormatter'; - +import { FormatFn } from '../../src/sqlFormatter'; import { itIf } from '../utils'; -export default function supportsComments(language: SqlLanguage, format: FormatFn) { +export default function supportsComments( + format: FormatFn, + { skipTrickyCommentsTest }: { skipTrickyCommentsTest?: boolean } = {} +) { it('formats SELECT query with different comments', () => { const result = format(dedent` SELECT @@ -44,7 +46,10 @@ export default function supportsComments(language: SqlLanguage, format: FormatFn expect(format(sql)).toBe(sql); }); - itIf(language !== 'bigquery')('formats tricky line comments', () => { + // TODO: This currently fails for BigQuery + // BigQuery supports single dashes inside identifiers e.g. first-name, + // but we mistakenly support multiple dashes e.g. first--name + itIf(!skipTrickyCommentsTest)('formats tricky line comments', () => { expect(format('SELECT a--comment, here\nFROM b--comment')).toBe(dedent` SELECT a --comment, here diff --git a/test/hive.test.ts b/test/hive.test.ts index e0ea6aaa7b..8f0a2cd414 100644 --- a/test/hive.test.ts +++ b/test/hive.test.ts @@ -18,7 +18,7 @@ describe('HiveFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(format); - supportsComments(language, format); + supportsComments(format); supportsCreateTable(format); supportsAlterTable(format); supportsStrings(format, HiveFormatter.stringTypes); diff --git a/test/mariadb.test.ts b/test/mariadb.test.ts index 7235c5ebe1..455db797c7 100644 --- a/test/mariadb.test.ts +++ b/test/mariadb.test.ts @@ -10,7 +10,7 @@ describe('MariaDbFormatter', () => { const language = 'mariadb'; const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); - behavesLikeMariaDbFormatter(language, format); + behavesLikeMariaDbFormatter(format); supportsStrings(format, MariaDbFormatter.stringTypes); supportsOperators(format, MariaDbFormatter.operators, ['AND', 'OR', 'XOR']); diff --git a/test/mysql.test.ts b/test/mysql.test.ts index 2f7af9d1c1..5ee17ec8e3 100644 --- a/test/mysql.test.ts +++ b/test/mysql.test.ts @@ -10,7 +10,7 @@ describe('MySqlFormatter', () => { const language = 'mysql'; const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); - behavesLikeMariaDbFormatter(language, format); + behavesLikeMariaDbFormatter(format); supportsStrings(format, MySqlFormatter.stringTypes); supportsOperators(format, MySqlFormatter.operators, ['AND', 'OR', 'XOR']); diff --git a/test/n1ql.test.ts b/test/n1ql.test.ts index bfeffaa3a6..e30a724206 100644 --- a/test/n1ql.test.ts +++ b/test/n1ql.test.ts @@ -19,7 +19,7 @@ describe('N1qlFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(format); - supportsComments(language, format); + supportsComments(format); supportsDeleteFrom(format); supportsStrings(format, N1qlFormatter.stringTypes); supportsBetween(format); diff --git a/test/plsql.test.ts b/test/plsql.test.ts index beab7e3066..e1c624be2d 100644 --- a/test/plsql.test.ts +++ b/test/plsql.test.ts @@ -22,7 +22,7 @@ describe('PlSqlFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(format); - supportsComments(language, format); + supportsComments(format); supportsCreateTable(format); supportsConstraints(format); supportsAlterTable(format); diff --git a/test/postgresql.test.ts b/test/postgresql.test.ts index 05cd97d221..4b9be128a0 100644 --- a/test/postgresql.test.ts +++ b/test/postgresql.test.ts @@ -20,7 +20,7 @@ describe('PostgreSqlFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(format); - supportsComments(language, format); + supportsComments(format); supportsCreateTable(format); supportsConstraints(format); supportsAlterTable(format); diff --git a/test/redshift.test.ts b/test/redshift.test.ts index 9419d77c93..340e436038 100644 --- a/test/redshift.test.ts +++ b/test/redshift.test.ts @@ -19,7 +19,7 @@ describe('RedshiftFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(format); - supportsComments(language, format); + supportsComments(format); supportsCreateTable(format); supportsAlterTable(format); supportsAlterTableModify(format); diff --git a/test/spark.test.ts b/test/spark.test.ts index 2c1aaefea5..fb20ee1228 100644 --- a/test/spark.test.ts +++ b/test/spark.test.ts @@ -19,7 +19,7 @@ describe('SparkFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(format); - supportsComments(language, format); + supportsComments(format); supportsCreateTable(format); supportsAlterTable(format); supportsStrings(format, SparkFormatter.stringTypes); diff --git a/test/sql.test.ts b/test/sql.test.ts index 7c5a27f15c..efb4557567 100644 --- a/test/sql.test.ts +++ b/test/sql.test.ts @@ -20,7 +20,7 @@ describe('SqlFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(format); - supportsComments(language, format); + supportsComments(format); supportsCreateTable(format); supportsConstraints(format); supportsAlterTable(format); diff --git a/test/sqlite.test.ts b/test/sqlite.test.ts index 4576514095..1938d15c61 100644 --- a/test/sqlite.test.ts +++ b/test/sqlite.test.ts @@ -20,7 +20,7 @@ describe('SqliteFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(format); - supportsComments(language, format); + supportsComments(format); supportsCreateTable(format); supportsConstraints(format); supportsAlterTable(format); diff --git a/test/tsql.test.ts b/test/tsql.test.ts index 3ea8eadc0a..953f08bce3 100644 --- a/test/tsql.test.ts +++ b/test/tsql.test.ts @@ -20,7 +20,7 @@ describe('TSqlFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(format); - supportsComments(language, format); + supportsComments(format); supportsCreateTable(format); supportsConstraints(format); supportsAlterTable(format); From 80f663d5ba5611439bffa3b927d94a70c9cea0e0 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 11:46:13 +0300 Subject: [PATCH 024/334] Don't use double-dashes inside BigQuery identifier test --- test/bigquery.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/bigquery.test.ts b/test/bigquery.test.ts index faadab0e2b..0a4cd7c75f 100644 --- a/test/bigquery.test.ts +++ b/test/bigquery.test.ts @@ -38,16 +38,16 @@ describe('BigQueryFormatter', () => { `); }); - // Note: BigQuery supports dashes inside identifiers, so a--comment would be + // Note: BigQuery supports single dashes inside identifiers, so my-ident would be // detected as identifier, while other SQL dialects would detect it as - // identifier a followed by comment. + // "my" "ident" // https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical it('supports dashes inside identifiers', () => { - const result = format('SELECT alpha--foo, bar-foo\nFROM beta'); + const result = format('SELECT alpha-foo, some-long-identifier\nFROM beta'); expect(result).toBe(dedent` SELECT - alpha--foo, - bar-foo + alpha-foo, + some-long-identifier FROM beta `); From 0feaea2750c69c8f25a35876e5aaba04a97a6176 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 11:54:18 +0300 Subject: [PATCH 025/334] Refactor tests for #-comments --- test/behavesLikeMariaDbFormatter.ts | 11 +---------- test/bigquery.test.ts | 2 +- test/features/comments.ts | 24 +++++++++++++++++++----- test/n1ql.test.ts | 2 +- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/test/behavesLikeMariaDbFormatter.ts b/test/behavesLikeMariaDbFormatter.ts index 81b5c457f8..77b98374ad 100644 --- a/test/behavesLikeMariaDbFormatter.ts +++ b/test/behavesLikeMariaDbFormatter.ts @@ -16,7 +16,7 @@ import supportsComments from './features/comments'; */ export default function behavesLikeMariaDbFormatter(format: FormatFn) { behavesLikeSqlFormatter(format); - supportsComments(format); + supportsComments(format, { hashComments: true }); supportsCreateTable(format); supportsConstraints(format); supportsAlterTable(format); @@ -34,15 +34,6 @@ export default function behavesLikeMariaDbFormatter(format: FormatFn) { }); supportsParams(format, { indexed: ['?'] }); - it('supports # comments', () => { - expect(format('SELECT a # comment\nFROM b # comment')).toBe(dedent` - SELECT - a # comment - FROM - b # comment - `); - }); - it('supports @variables', () => { expect(format('SELECT @foo, @bar')).toBe(dedent` SELECT diff --git a/test/bigquery.test.ts b/test/bigquery.test.ts index 0a4cd7c75f..dfb0e65ca1 100644 --- a/test/bigquery.test.ts +++ b/test/bigquery.test.ts @@ -18,7 +18,7 @@ describe('BigQueryFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(format); - supportsComments(format, { skipTrickyCommentsTest: true }); + supportsComments(format, { hashComments: true, skipTrickyCommentsTest: true }); supportsCreateTable(format); supportsDeleteFrom(format); supportsStrings(format, BigQueryFormatter.stringTypes); diff --git a/test/features/comments.ts b/test/features/comments.ts index 4a2b369b06..2d0aeb92c8 100644 --- a/test/features/comments.ts +++ b/test/features/comments.ts @@ -2,10 +2,12 @@ import dedent from 'dedent-js'; import { FormatFn } from '../../src/sqlFormatter'; import { itIf } from '../utils'; -export default function supportsComments( - format: FormatFn, - { skipTrickyCommentsTest }: { skipTrickyCommentsTest?: boolean } = {} -) { +interface CommentsConfig { + hashComments?: boolean; + skipTrickyCommentsTest?: boolean; +} + +export default function supportsComments(format: FormatFn, opts: CommentsConfig = {}) { it('formats SELECT query with different comments', () => { const result = format(dedent` SELECT @@ -49,7 +51,7 @@ export default function supportsComments( // TODO: This currently fails for BigQuery // BigQuery supports single dashes inside identifiers e.g. first-name, // but we mistakenly support multiple dashes e.g. first--name - itIf(!skipTrickyCommentsTest)('formats tricky line comments', () => { + itIf(!opts.skipTrickyCommentsTest)('formats tricky line comments', () => { expect(format('SELECT a--comment, here\nFROM b--comment')).toBe(dedent` SELECT a --comment, here @@ -120,4 +122,16 @@ export default function supportsComments( /*Comment `); }); + + if (opts.hashComments) { + it('supports # line comment', () => { + const result = format('SELECT alpha # commment\nFROM beta'); + expect(result).toBe(dedent` + SELECT + alpha # commment + FROM + beta + `); + }); + } } diff --git a/test/n1ql.test.ts b/test/n1ql.test.ts index e30a724206..ff078c181f 100644 --- a/test/n1ql.test.ts +++ b/test/n1ql.test.ts @@ -19,7 +19,7 @@ describe('N1qlFormatter', () => { const format: FormatFn = (query, cfg = {}) => originalFormat(query, { ...cfg, language }); behavesLikeSqlFormatter(format); - supportsComments(format); + supportsComments(format, { hashComments: true }); supportsDeleteFrom(format); supportsStrings(format, N1qlFormatter.stringTypes); supportsBetween(format); From 2c80be60346dd00b9cbb2214900ff8e761be41eb Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 13:52:27 +0300 Subject: [PATCH 026/334] Document styles supported by various formatters --- sql/formatting.md | 47 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/sql/formatting.md b/sql/formatting.md index dabd73ff47..63f8ef24c7 100644 --- a/sql/formatting.md +++ b/sql/formatting.md @@ -17,13 +17,48 @@ Links to recources describing how to format SQL. Other tools that perform SQL formatting. -- [sqlparse](https://pypi.org/project/sqlparse/) Python library. [Online demo](https://sqlformat.org/) -- [Instant SQL formatter](https://www.dpriver.com/pp/sqlformat.htm) online tool and VS plugin. -- [Freeformatter.com](https://www.freeformatter.com/sql-formatter.html) a site with online formatters for many languages. -- [Code Beautify](https://codebeautify.org/sqlformatter) another site with multiple formatters. -- [SQL Complete](https://www.devart.com/dbforge/sql/sqlcomplete/) a proprietary tool from Devart. [Online version](https://sql-format.com/) +- [sqlparse](https://sqlformat.org/) Python library and online formatter.\ + (This one is really quite bad. The style is a bit like our tabularLeft, but with variable indentation. + The formatting of CREATE TABLE is exceptionally bad.) +- [Instant SQL formatter](https://www.dpriver.com/pp/sqlformat.htm) online tool and VS plugin.\ + Uses tabularLeft & tabularRight styles, but with 7 instead of 10 spaces. +- [Freeformatter.com](https://www.freeformatter.com/sql-formatter.html) a site with online formatters for many languages.\ + Uses our standard style. +- [Code Beautify](https://codebeautify.org/sqlformatter) another site with multiple formatters.\ + Uses our standard style. +- [SQL Complete](https://www.devart.com/dbforge/sql/sqlcomplete/) a proprietary tool from Devart. [Online version](https://sql-format.com/)\ + By default uses a compact version of our standard style, but has huge amount of configuration options. - [SQL Formatter](https://www.apexsql.com/sql-tools-refactor.aspx) a proprietary tool from ApexSQL. - [SQLinForm](https://www.sqlinform.com/) a proprietary tool (also free versions available) - [SQL Pretty Printer](https://www.dpriver.com/) a proprietary tool. - [SQL Fluff](https://docs.sqlfluff.com/en/stable/index.html) A linter for SQL (also has formatting rules). -- [SQL Prompt](https://www.red-gate.com/website/sql-formatter) A proprietary tool, has an online demo of the formatter. +- [SQL Prompt](https://www.red-gate.com/website/sql-formatter) A proprietary tool, has an online demo of the formatter.\ + Supports multiple distinct styles of formatting. + +Here's some example SQL to test out various formatters: + +```sql +SELECT + supplier_name, city -- inline comment + ,(select count(*) from people where supplier_id = s.id) as sup_count +FROM suppliers s left join addresses a on s.address_id=a.id +WHERE s.value>500 and a.city = 'New York' +ORDER BY supplier_name asc,city desc; + +/* another comment in here */ +INSERT INTO articles +(title, author, submission_date) +VALUES ('Learn SQL', 'John Doe', now()); + +UPDATE articles +SET author = 'Peter', submission_date = '2022-01-01' +WHERE title like '%by Peter'; + +CREATE TABLE articles ( + id int not null auto_increment, + title varchar(100) not null, + author varchar(40) not null, + submission_date date, + primary key ( id ) +); +``` From cc3a42c42ca60d73a2dcc70ce682b6203e75350f Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 15:32:57 +0300 Subject: [PATCH 027/334] Move some very generic tests to sqlFormatter test --- test/behavesLikeSqlFormatter.ts | 12 ------------ test/sqlFormatter.test.ts | 12 ++++++++++++ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/test/behavesLikeSqlFormatter.ts b/test/behavesLikeSqlFormatter.ts index 09fe10910e..d54cb2fa0a 100644 --- a/test/behavesLikeSqlFormatter.ts +++ b/test/behavesLikeSqlFormatter.ts @@ -36,18 +36,6 @@ export default function behavesLikeSqlFormatter(format: FormatFn) { supportsCommaPosition(format); supportsLogicalOperatorNewline(format); - it('does nothing with empty input', () => { - const result = format(''); - - expect(result).toBe(''); - }); - - it('throws error when query argument is not string', () => { - expect(() => format(undefined as unknown as string)).toThrow( - 'Invalid query argument. Expected string, instead got undefined' - ); - }); - it('formats lonely semicolon', () => { expect(format(';')).toBe(';'); }); diff --git a/test/sqlFormatter.test.ts b/test/sqlFormatter.test.ts index 1bb35ef510..ec17e0fb91 100644 --- a/test/sqlFormatter.test.ts +++ b/test/sqlFormatter.test.ts @@ -12,4 +12,16 @@ describe('sqlFormatter', () => { format('SELECT «weird-stuff»'); }).toThrow('Parse error: Unexpected "«weird-stuff»"'); }); + + it('does nothing with empty input', () => { + const result = format(''); + + expect(result).toBe(''); + }); + + it('throws error when query argument is not string', () => { + expect(() => format(undefined as unknown as string)).toThrow( + 'Invalid query argument. Expected string, instead got undefined' + ); + }); }); From b02fc3266a75c3cdb0c6f5dc5aafe64535e053d4 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 15:33:39 +0300 Subject: [PATCH 028/334] Move lonely semicolon test to newlineBeforeSemicolon test --- test/behavesLikeSqlFormatter.ts | 4 ---- test/options/newlineBeforeSemicolon.ts | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/behavesLikeSqlFormatter.ts b/test/behavesLikeSqlFormatter.ts index d54cb2fa0a..f21dd12f69 100644 --- a/test/behavesLikeSqlFormatter.ts +++ b/test/behavesLikeSqlFormatter.ts @@ -36,10 +36,6 @@ export default function behavesLikeSqlFormatter(format: FormatFn) { supportsCommaPosition(format); supportsLogicalOperatorNewline(format); - it('formats lonely semicolon', () => { - expect(format(';')).toBe(';'); - }); - it('formats simple SELECT query', () => { const result = format('SELECT count(*),Column1 FROM Table1;'); expect(result).toBe(dedent` diff --git a/test/options/newlineBeforeSemicolon.ts b/test/options/newlineBeforeSemicolon.ts index 891cf298a7..b7e6c5bc7a 100644 --- a/test/options/newlineBeforeSemicolon.ts +++ b/test/options/newlineBeforeSemicolon.ts @@ -2,6 +2,10 @@ import dedent from 'dedent-js'; import { FormatFn } from '../../src/sqlFormatter'; export default function supportsNewlineBeforeSemicolon(format: FormatFn) { + it('formats lonely semicolon', () => { + expect(format(';')).toBe(';'); + }); + it('defaults to semicolon on end of last line', () => { const result = format(`SELECT a FROM b;`); expect(result).toBe(dedent` From f5d4eca390f651e7322d603f1f3a2d3d26a54ff3 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 15:44:54 +0300 Subject: [PATCH 029/334] Don't add newline before semicolon when it's a lonely one --- src/core/StatementFormatter.ts | 9 ++++----- test/options/newlineBeforeSemicolon.ts | 4 ++++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 6d2178a988..051d6e42b9 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -400,11 +400,10 @@ export default class StatementFormatter { } private formatQuerySeparator(token: Token, query: string): string { - return [ - trimSpacesEnd(query), - this.cfg.newlineBeforeSemicolon ? '\n' : '', - this.show(token), - ].join(''); + return this.formatWithoutSpaces( + token, + this.cfg.newlineBeforeSemicolon ? this.addNewline(query) : query + ); } /** Converts token to string, uppercasing if enabled */ diff --git a/test/options/newlineBeforeSemicolon.ts b/test/options/newlineBeforeSemicolon.ts index b7e6c5bc7a..15a2ee8a56 100644 --- a/test/options/newlineBeforeSemicolon.ts +++ b/test/options/newlineBeforeSemicolon.ts @@ -6,6 +6,10 @@ export default function supportsNewlineBeforeSemicolon(format: FormatFn) { expect(format(';')).toBe(';'); }); + it('does not add newline before lonely semicolon when newlineBeforeSemicolon:true', () => { + expect(format(';', { newlineBeforeSemicolon: true })).toBe(';'); + }); + it('defaults to semicolon on end of last line', () => { const result = format(`SELECT a FROM b;`); expect(result).toBe(dedent` From 46e6e414b7c920eb4f8473c66df002baebf6f78b Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 15:49:26 +0300 Subject: [PATCH 030/334] Additional semicolon tests --- test/options/newlineBeforeSemicolon.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/options/newlineBeforeSemicolon.ts b/test/options/newlineBeforeSemicolon.ts index 15a2ee8a56..ed9f3d6235 100644 --- a/test/options/newlineBeforeSemicolon.ts +++ b/test/options/newlineBeforeSemicolon.ts @@ -30,4 +30,25 @@ export default function supportsNewlineBeforeSemicolon(format: FormatFn) { ; `); }); + + // the nr of empty lines here depends on linesBetweenQueries option + it('formats multiple lonely semicolons', () => { + expect(format(';;;')).toBe(dedent` + ; + + ; + + ; + `); + }); + + it('does not introduce extra empty lines between semicolons when newlineBeforeSemicolon:true', () => { + expect(format(';;;', { newlineBeforeSemicolon: true })).toBe(dedent` + ; + + ; + + ; + `); + }); } From bb4041a4bdcf0d54009b6cd0efea868d1cf889d8 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 16:00:56 +0300 Subject: [PATCH 031/334] Move tests for numbers to separate file --- test/behavesLikeSqlFormatter.ts | 51 ++----------------------------- test/features/numbers.ts | 53 +++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 49 deletions(-) create mode 100644 test/features/numbers.ts diff --git a/test/behavesLikeSqlFormatter.ts b/test/behavesLikeSqlFormatter.ts index f21dd12f69..6ca6a03004 100644 --- a/test/behavesLikeSqlFormatter.ts +++ b/test/behavesLikeSqlFormatter.ts @@ -15,12 +15,14 @@ import supportsLinesBetweenQueries from './options/linesBetweenQueries'; import supportsNewlineBeforeSemicolon from './options/newlineBeforeSemicolon'; import supportsLogicalOperatorNewline from './options/logicalOperatorNewline'; import supportsTabulateAlias from './options/tabulateAlias'; +import supportsNumbers from './features/numbers'; /** * Core tests for all SQL formatters */ export default function behavesLikeSqlFormatter(format: FormatFn) { supportsCase(format); + supportsNumbers(format); supportsAliasAs(format); supportsTabulateAlias(format); @@ -378,28 +380,6 @@ export default function behavesLikeSqlFormatter(format: FormatFn) { `); }); - it('supports decimal numbers', () => { - const result = format('SELECT 42, -35.04, 105., 2.53E+3, 1.085E-5;'); - expect(result).toBe(dedent` - SELECT - 42, - -35.04, - 105., - 2.53E+3, - 1.085E-5; - `); - }); - - it('supports hex and binary numbers', () => { - const result = format('SELECT 0xAE, 0x10F, 0b1010001;'); - expect(result).toBe(dedent` - SELECT - 0xAE, - 0x10F, - 0b1010001; - `); - }); - it('correctly indents create statement after select', () => { const result = format(` SELECT * FROM test; @@ -420,33 +400,6 @@ export default function behavesLikeSqlFormatter(format: FormatFn) { `); }); - it('correctly handles floats as single tokens', () => { - const result = format('SELECT 1e-9 AS a, 1.5e+10 AS b, 3.5E12 AS c, 3.5e12 AS d;'); - expect(result).toBe(dedent` - SELECT - 1e-9 AS a, - 1.5e+10 AS b, - 3.5E12 AS c, - 3.5e12 AS d; - `); - }); - - it('correctly handles floats with trailing point', () => { - let result = format('SELECT 1000. AS a;'); - expect(result).toBe(dedent` - SELECT - 1000. AS a; - `); - - result = format('SELECT a, b / 1000. AS a_s, 100. * b / SUM(a_s);'); - expect(result).toBe(dedent` - SELECT - a, - b / 1000. AS a_s, - 100. * b / SUM(a_s); - `); - }); - it('does not split UNION ALL in half', () => { const result = format(` SELECT * FROM tbl1 diff --git a/test/features/numbers.ts b/test/features/numbers.ts new file mode 100644 index 0000000000..8c03bc17d8 --- /dev/null +++ b/test/features/numbers.ts @@ -0,0 +1,53 @@ +import dedent from 'dedent-js'; +import { FormatFn } from '../../src/sqlFormatter'; + +export default function supportsNumbers(format: FormatFn) { + it('supports decimal numbers', () => { + const result = format('SELECT 42, -35.04, 105., 2.53E+3, 1.085E-5;'); + expect(result).toBe(dedent` + SELECT + 42, + -35.04, + 105., + 2.53E+3, + 1.085E-5; + `); + }); + + it('supports hex and binary numbers', () => { + const result = format('SELECT 0xAE, 0x10F, 0b1010001;'); + expect(result).toBe(dedent` + SELECT + 0xAE, + 0x10F, + 0b1010001; + `); + }); + + it('correctly handles floats as single tokens', () => { + const result = format('SELECT 1e-9 AS a, 1.5e+10 AS b, 3.5E12 AS c, 3.5e12 AS d;'); + expect(result).toBe(dedent` + SELECT + 1e-9 AS a, + 1.5e+10 AS b, + 3.5E12 AS c, + 3.5e12 AS d; + `); + }); + + it('correctly handles floats with trailing point', () => { + let result = format('SELECT 1000. AS a;'); + expect(result).toBe(dedent` + SELECT + 1000. AS a; + `); + + result = format('SELECT a, b / 1000. AS a_s, 100. * b / SUM(a_s);'); + expect(result).toBe(dedent` + SELECT + a, + b / 1000. AS a_s, + 100. * b / SUM(a_s); + `); + }); +} From 41bec91c6249768d1ed5ca0b5bf1232dd56efbe1 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 16:06:00 +0300 Subject: [PATCH 032/334] Delete redundant multi-statement tests These are already covered by tests for linesBetweenQueries --- test/behavesLikeSqlFormatter.ts | 44 --------------------------------- 1 file changed, 44 deletions(-) diff --git a/test/behavesLikeSqlFormatter.ts b/test/behavesLikeSqlFormatter.ts index 6ca6a03004..07ee56f8ed 100644 --- a/test/behavesLikeSqlFormatter.ts +++ b/test/behavesLikeSqlFormatter.ts @@ -345,30 +345,6 @@ export default function behavesLikeSqlFormatter(format: FormatFn) { expect(format('foo OR bar')).toBe('foo\nOR bar'); }); - it('keeps separation between multiple statements', () => { - expect(format('foo;bar;')).toBe('foo;\n\nbar;'); - expect(format('foo\n;bar;')).toBe('foo;\n\nbar;'); - expect(format('foo\n\n\n;bar;\n\n')).toBe('foo;\n\nbar;'); - - const result = format(` - SELECT count(*),Column1 FROM Table1; - SELECT count(*),Column1 FROM Table2; - `); - expect(result).toBe(dedent` - SELECT - count(*), - Column1 - FROM - Table1; - - SELECT - count(*), - Column1 - FROM - Table2; - `); - }); - it('formats unicode correctly', () => { const result = format('SELECT 结合使用, тест FROM töörõõm;'); expect(result).toBe(dedent` @@ -380,26 +356,6 @@ export default function behavesLikeSqlFormatter(format: FormatFn) { `); }); - it('correctly indents create statement after select', () => { - const result = format(` - SELECT * FROM test; - CREATE TABLE test(id NUMBER NOT NULL, col1 VARCHAR2(20), col2 VARCHAR2(20)); - `); - expect(result).toBe(dedent` - SELECT - * - FROM - test; - - CREATE TABLE - test( - id NUMBER NOT NULL, - col1 VARCHAR2(20), - col2 VARCHAR2(20) - ); - `); - }); - it('does not split UNION ALL in half', () => { const result = format(` SELECT * FROM tbl1 From 11cfc81af0375bba094b43086d1129953dee0643 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 16:08:20 +0300 Subject: [PATCH 033/334] Delete redundant AND/OR tests --- test/behavesLikeSqlFormatter.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/behavesLikeSqlFormatter.ts b/test/behavesLikeSqlFormatter.ts index 07ee56f8ed..4c3d94ab34 100644 --- a/test/behavesLikeSqlFormatter.ts +++ b/test/behavesLikeSqlFormatter.ts @@ -340,11 +340,6 @@ export default function behavesLikeSqlFormatter(format: FormatFn) { expect(format('UNIQUE foo')).toBe('UNIQUE foo'); }); - it('formats AND/OR operators', () => { - expect(format('foo AND bar')).toBe('foo\nAND bar'); - expect(format('foo OR bar')).toBe('foo\nOR bar'); - }); - it('formats unicode correctly', () => { const result = format('SELECT 结合使用, тест FROM töörõõm;'); expect(result).toBe(dedent` From a3c6354c8b1905c3c4e51762e0fe0e98a7aa581f Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 16:09:32 +0300 Subject: [PATCH 034/334] Move tests for set-operators to general operators test --- test/behavesLikeSqlFormatter.ts | 10 ---------- test/features/operators.ts | 10 ++++++++++ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/behavesLikeSqlFormatter.ts b/test/behavesLikeSqlFormatter.ts index 4c3d94ab34..1d096c9239 100644 --- a/test/behavesLikeSqlFormatter.ts +++ b/test/behavesLikeSqlFormatter.ts @@ -330,16 +330,6 @@ export default function behavesLikeSqlFormatter(format: FormatFn) { expect(result).toBe("((foo = 'bar'))"); }); - it('formats logical operators', () => { - expect(format('foo ALL bar')).toBe('foo ALL bar'); - expect(format('foo = ANY (1, 2, 3)')).toBe('foo = ANY (1, 2, 3)'); - expect(format('EXISTS bar')).toBe('EXISTS bar'); - expect(format('foo IN (1, 2, 3)')).toBe('foo IN (1, 2, 3)'); - expect(format("foo LIKE 'hello%'")).toBe("foo LIKE 'hello%'"); - expect(format('foo IS NULL')).toBe('foo IS NULL'); - expect(format('UNIQUE foo')).toBe('UNIQUE foo'); - }); - it('formats unicode correctly', () => { const result = format('SELECT 结合使用, тест FROM töörõõm;'); expect(result).toBe(dedent` diff --git a/test/features/operators.ts b/test/features/operators.ts index 1934732f2e..8b802f727d 100644 --- a/test/features/operators.ts +++ b/test/features/operators.ts @@ -48,4 +48,14 @@ export default function supportsOperators( $\{b}; `); }); + + it('supports set operators', () => { + expect(format('foo ALL bar')).toBe('foo ALL bar'); + expect(format('foo = ANY (1, 2, 3)')).toBe('foo = ANY (1, 2, 3)'); + expect(format('EXISTS bar')).toBe('EXISTS bar'); + expect(format('foo IN (1, 2, 3)')).toBe('foo IN (1, 2, 3)'); + expect(format("foo LIKE 'hello%'")).toBe("foo LIKE 'hello%'"); + expect(format('foo IS NULL')).toBe('foo IS NULL'); + expect(format('UNIQUE foo')).toBe('UNIQUE foo'); + }); } From 152b51aa9148db9670e1714d4128a723e2056b24 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 19:19:58 +0300 Subject: [PATCH 035/334] Move identifiers docs out of main syntax docs file --- sql/identifiers.md | 57 +++++++++++++++++++++++++++++++++++++++++++++ sql/syntax.md | 58 +--------------------------------------------- 2 files changed, 58 insertions(+), 57 deletions(-) create mode 100644 sql/identifiers.md diff --git a/sql/identifiers.md b/sql/identifiers.md new file mode 100644 index 0000000000..2ffa5a0f19 --- /dev/null +++ b/sql/identifiers.md @@ -0,0 +1,57 @@ +# Identifiers + +## Normal identifiers + +Most dialects support `[a-zA-Z_]` as first character and `[a-zA-Z0-9_]` as rest of the characters. +The differences from this are listed below: + +- [BigQuery][]: single dashes (`-`) can be used, but not at the beginning or end. +- [DB2][]: first char can only be a (uppercase) letter (a lowercase letter gets converted to uppercase). +- [Hive][]: _(no differences)_ +- [MariaDB][]: no first-letter restrictions. The characters `[a-zA-Z0-9_$]` and unicode letters are allowed everywhere. Can begin with digit, but can't only contain digits. +- [MySQL][]: same as MariaDB. +- [N1QL][]: _(no differences)_ +- [PL/SQL][]: can't start with `_`. Allows `$`, `#` in rest of the identifier. +- [PostgreSQL][]: additionally `$` after first char. Also unicode letters are allowed. +- [Redshift][]: also unicode letters are allowed. +- [Spark][]: _Seems like the usual syntax is allowed. But the docs are confusing._ +- [SQLite][sqlite-syntax-pdf]: _(no differences)_ +- [Transact-SQL][]: `@` and `#` are allowed as first chars plus `$` in the rest. Also unicode letters are allowed. + Though the beginning `@` signifies a local variable or parameter and `#` a temporary table or procedure. + +## Delimited identifiers + +SQL standard specifies double-quotes `".."` for delimited identifiers. +There is a considerable variation in implementations: + +- `` `..` `` [BigQuery][] +- `".."` [DB2][] +- `` `..` `` [Hive][] +- `` `..` ``, `".."`1, `[..]`2 [MariaDB][] +- `` `..` ``, `".."`1 [MySQL][] +- `` `..` `` [N1QL][] +- `".."` [PL/SQL][] +- `".."`, `U&".."` [PostgreSQL][] +- `".."` [Redshift][] +- `` `..` `` [Spark][] +- `".."`, `` `..` ``, `[..]` [SQLite][sqlite-keywords] +- `".."`, `[..]` [Transact-SQL][] + +Notes: + +1. when ANSI_QUOTES mode enabled +2. when MSSQL mode enabled + +[bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical +[db2]: https://www.ibm.com/docs/en/db2/9.7?topic=elements-identifiers +[hive]: https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362034#LanguageManualDDL-AlterColumn +[mariadb]: https://mariadb.com/kb/en/identifier-names/ +[mysql]: https://dev.mysql.com/doc/refman/8.0/en/identifiers.html +[n1ql]: https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/identifiers.html +[pl/sql]: https://docs.oracle.com/database/121/LNPLS/fundamentals.htm#LNPLS99973 +[postgresql]: https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS +[redshift]: https://docs.aws.amazon.com/redshift/latest/dg/r_names.html +[spark]: https://spark.apache.org/docs/latest/sql-ref-identifier.html +[sqlite-keywords]: https://www.sqlite.org/lang_keywords.html +[sqlite-syntax-pdf]: https://www.pearsonhighered.com/assets/samplechapter/0/6/7/2/067232685X.pdf +[transact-sql]: https://docs.microsoft.com/en-us/sql/relational-databases/databases/database-identifiers?view=sql-server-ver15 diff --git a/sql/syntax.md b/sql/syntax.md index ee758d14ca..2280b4fa7d 100644 --- a/sql/syntax.md +++ b/sql/syntax.md @@ -2,60 +2,4 @@ Reference of SQL syntax variations. -## Identifiers - -## Normal identifiers - -Most dialects support `[a-zA-Z_]` as first character and `[a-zA-Z0-9_]` as rest of the characters. -The differences from this are listed below: - -- [BigQuery][]: single dashes (`-`) can be used, but not at the beginning or end. -- [DB2][]: first char can only be a (uppercase) letter (a lowercase letter gets converted to uppercase). -- [Hive][]: _(no differences)_ -- [MariaDB][]: no first-letter restrictions. The characters `[a-zA-Z0-9_$]` and unicode letters are allowed everywhere. Can begin with digit, but can't only contain digits. -- [MySQL][]: same as MariaDB. -- [N1QL][]: _(no differences)_ -- [PL/SQL][]: can't start with `_`. Allows `$`, `#` in rest of the identifier. -- [PostgreSQL][]: additionally `$` after first char. Also unicode letters are allowed. -- [Redshift][]: also unicode letters are allowed. -- [Spark][]: _Seems like the usual syntax is allowed. But the docs are confusing._ -- [SQLite][sqlite-syntax-pdf]: _(no differences)_ -- [Transact-SQL][]: `@` and `#` are allowed as first chars plus `$` in the rest. Also unicode letters are allowed. - Though the beginning `@` signifies a local variable or parameter and `#` a temporary table or procedure. - -## Delimited identifiers - -SQL standard specifies double-quotes `".."` for delimited identifiers. -There is a considerable variation in implementations: - -- `` `..` `` [BigQuery][] -- `".."` [DB2][] -- `` `..` `` [Hive][] -- `` `..` ``, `".."`1, `[..]`2 [MariaDB][] -- `` `..` ``, `".."`1 [MySQL][] -- `` `..` `` [N1QL][] -- `".."` [PL/SQL][] -- `".."`, `U&".."` [PostgreSQL][] -- `".."` [Redshift][] -- `` `..` `` [Spark][] -- `".."`, `` `..` ``, `[..]` [SQLite][sqlite-keywords] -- `".."`, `[..]` [Transact-SQL][] - -Notes: - -1. when ANSI_QUOTES mode enabled -2. when MSSQL mode enabled - -[bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical -[db2]: https://www.ibm.com/docs/en/db2/9.7?topic=elements-identifiers -[hive]: https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362034#LanguageManualDDL-AlterColumn -[mariadb]: https://mariadb.com/kb/en/identifier-names/ -[mysql]: https://dev.mysql.com/doc/refman/8.0/en/identifiers.html -[n1ql]: https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/identifiers.html -[pl/sql]: https://docs.oracle.com/database/121/LNPLS/fundamentals.htm#LNPLS99973 -[postgresql]: https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS -[redshift]: https://docs.aws.amazon.com/redshift/latest/dg/r_names.html -[spark]: https://spark.apache.org/docs/latest/sql-ref-identifier.html -[sqlite-keywords]: https://www.sqlite.org/lang_keywords.html -[sqlite-syntax-pdf]: https://www.pearsonhighered.com/assets/samplechapter/0/6/7/2/067232685X.pdf -[transact-sql]: https://docs.microsoft.com/en-us/sql/relational-databases/databases/database-identifiers?view=sql-server-ver15 +- [Identifiers](./identifiers.md) From 9e8323dafae1e7219bea833dfbd15d176ecdf135 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 19:46:11 +0300 Subject: [PATCH 036/334] Links to SELECT syntax in all dialects --- sql/select.md | 27 +++++++++++++++++++++++++++ sql/syntax.md | 1 + 2 files changed, 28 insertions(+) create mode 100644 sql/select.md diff --git a/sql/select.md b/sql/select.md new file mode 100644 index 0000000000..9a113dd6b9 --- /dev/null +++ b/sql/select.md @@ -0,0 +1,27 @@ +# SELECT statement + +- [BigQuery][] +- [DB2][] +- [Hive][] +- [MariaDB][] +- [MySQL][] +- [N1QL][] +- [PL/SQL][] +- [PostgreSQL][] +- [Redshift][] +- [Spark][] +- [SQLite][] +- [Transact-SQL][] + +[bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax +[db2]: https://www.ibm.com/docs/en/db2/9.7?topic=queries-select-statement +[hive]: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Select +[mariadb]: https://mariadb.com/kb/en/select/ +[mysql]: https://dev.mysql.com/doc/refman/8.0/en/select.html +[n1ql]: https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/select-syntax.html +[pl/sql]: https://docs.oracle.com/database/121/SQLRF/queries001.htm#SQLRF52327 +[postgresql]: https://www.postgresql.org/docs/current/queries.html +[redshift]: https://docs.aws.amazon.com/redshift/latest/dg/r_SELECT_synopsis.html +[spark]: https://spark.apache.org/docs/latest/sql-ref-syntax-qry-select.html +[sqlite]: https://www.sqlite.org/lang_select.html +[transact-sql]: https://docs.microsoft.com/en-US/sql/t-sql/queries/select-transact-sql?view=sql-server-ver15 diff --git a/sql/syntax.md b/sql/syntax.md index 2280b4fa7d..759a9612fc 100644 --- a/sql/syntax.md +++ b/sql/syntax.md @@ -3,3 +3,4 @@ Reference of SQL syntax variations. - [Identifiers](./identifiers.md) +- [SELECT](./select.md) From 86f6c2541c1b019ea33cada6e373563551304f78 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 21:08:32 +0300 Subject: [PATCH 037/334] One-line refactor to use formatWithSpaceAfter() --- src/core/StatementFormatter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 051d6e42b9..1ab16c84db 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -369,7 +369,7 @@ export default class StatementFormatter { * Formats a comma Operator onto query, ending line unless in an Inline Block */ private formatComma(token: Token, query: string): string { - query = trimSpacesEnd(query) + this.show(token) + ' '; + query = this.formatWithSpaceAfter(token, query); if (this.inlineBlock.isActive()) { return query; From f76bab839aa342592f1827dd151251254e4e0ff6 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 19 May 2022 22:35:59 +0300 Subject: [PATCH 038/334] Build the SQL string through separate Builder object --- src/core/StatementFormatter.ts | 227 ++++++++++++++++----------------- src/core/StringBuilder.ts | 40 ++++++ 2 files changed, 150 insertions(+), 117 deletions(-) create mode 100644 src/core/StringBuilder.ts diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 1ab16c84db..bf5716ad30 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -1,7 +1,7 @@ import Indentation from './Indentation'; import InlineBlock from './InlineBlock'; import Params from './Params'; -import { equalizeWhitespace, trimSpacesEnd } from '../utils'; +import { equalizeWhitespace } from '../utils'; import { isReserved, isCommand, isToken, Token, TokenType, EOF_TOKEN } from './token'; import { FormatOptions } from '../types'; import { toTabularToken, replaceTabularPlaceholders } from './tabularStyle'; @@ -9,6 +9,7 @@ import AliasAs from './AliasAs'; import AsTokenFactory from './AsTokenFactory'; import { Statement } from './Parser'; import { indentString, isTabularStyle } from './config'; +import StringBuilder from './StringBuilder'; /** Formats single SQL statement */ export default class StatementFormatter { @@ -18,6 +19,7 @@ export default class StatementFormatter { private aliasAs: AliasAs; private params: Params; private asTokenFactory: AsTokenFactory; + private query: StringBuilder; private currentNewline = true; private previousReservedToken: Token = EOF_TOKEN; @@ -32,11 +34,11 @@ export default class StatementFormatter { this.aliasAs = new AliasAs(this.cfg.aliasAs, this); this.params = params; this.asTokenFactory = asTokenFactory; + this.query = new StringBuilder(this.indentation); } public format(statement: Statement): string { this.tokens = statement.tokens; - let formattedQuery = ''; for (this.index = 0; this.index < this.tokens.length; this.index++) { let token = this.tokens[this.index]; @@ -58,57 +60,54 @@ export default class StatementFormatter { } if (token.type === TokenType.LINE_COMMENT) { - formattedQuery = this.formatLineComment(token, formattedQuery); + this.formatLineComment(token); } else if (token.type === TokenType.BLOCK_COMMENT) { - formattedQuery = this.formatBlockComment(token, formattedQuery); + this.formatBlockComment(token); } else if (token.type === TokenType.RESERVED_COMMAND) { this.currentNewline = this.checkNewline(token); - formattedQuery = this.formatCommand(token, formattedQuery); + this.formatCommand(token); } else if (token.type === TokenType.RESERVED_BINARY_COMMAND) { - formattedQuery = this.formatBinaryCommand(token, formattedQuery); + this.formatBinaryCommand(token); } else if (token.type === TokenType.RESERVED_DEPENDENT_CLAUSE) { - formattedQuery = this.formatDependentClause(token, formattedQuery); + this.formatDependentClause(token); } else if (token.type === TokenType.RESERVED_JOIN_CONDITION) { - formattedQuery = this.formatJoinCondition(token, formattedQuery); + this.formatJoinCondition(token); } else if (token.type === TokenType.RESERVED_LOGICAL_OPERATOR) { - formattedQuery = this.formatLogicalOperator(token, formattedQuery); + this.formatLogicalOperator(token); } else if (token.type === TokenType.RESERVED_KEYWORD) { - formattedQuery = this.formatKeyword(token, formattedQuery); + this.formatKeyword(token); } else if (token.type === TokenType.BLOCK_START) { - formattedQuery = this.formatBlockStart(token, formattedQuery); + this.formatBlockStart(token); } else if (token.type === TokenType.BLOCK_END) { - formattedQuery = this.formatBlockEnd(token, formattedQuery); + this.formatBlockEnd(token); } else if (token.type === TokenType.RESERVED_CASE_START) { - formattedQuery = this.formatCaseStart(token, formattedQuery); + this.formatCaseStart(token); } else if (token.type === TokenType.RESERVED_CASE_END) { - formattedQuery = this.formatCaseEnd(token, formattedQuery); + this.formatCaseEnd(token); } else if (token.type === TokenType.PLACEHOLDER) { - formattedQuery = this.formatPlaceholder(token, formattedQuery); + this.formatPlaceholder(token); } else if (token.type === TokenType.OPERATOR) { - formattedQuery = this.formatOperator(token, formattedQuery); + this.formatOperator(token); } else { - formattedQuery = this.formatWord(token, formattedQuery); + this.formatWord(token); } } - return replaceTabularPlaceholders(formattedQuery); + return replaceTabularPlaceholders(this.query.toString()); } /** * Formats word tokens + any potential AS tokens for aliases */ - private formatWord(token: Token, query: string): string { - let finalQuery = query; + private formatWord(token: Token) { if (this.aliasAs.shouldAddBefore(token)) { - finalQuery = this.formatWithSpaces(this.asTokenFactory.token(), finalQuery); + this.query.addWithSpaces(this.show(this.asTokenFactory.token())); } - finalQuery = this.formatWithSpaces(token, finalQuery); + this.query.addWithSpaces(this.show(token)); if (this.aliasAs.shouldAddAfter()) { - finalQuery = this.formatWithSpaces(this.asTokenFactory.token(), finalQuery); + this.query.addWithSpaces(this.show(this.asTokenFactory.token())); } - - return finalQuery; } /** @@ -173,13 +172,16 @@ export default class StatementFormatter { } /** Formats a line comment onto query */ - private formatLineComment(token: Token, query: string): string { - return this.addNewline(query + this.show(token)); + private formatLineComment(token: Token) { + this.query.addWithSpaceBefore(this.show(token)); + this.query.addNewline(); } /** Formats a block comment onto query */ - private formatBlockComment(token: Token, query: string): string { - return this.addNewline(this.addNewline(query) + this.indentComment(token.value)); + private formatBlockComment(token: Token) { + this.query.addNewline(); + this.query.addWithSpaceBefore(this.indentComment(token.value)); + this.query.addNewline(); } /** Aligns comment to current indentation level */ @@ -190,10 +192,10 @@ export default class StatementFormatter { /** * Formats a Reserved Command onto query, increasing indentation level where necessary */ - private formatCommand(token: Token, query: string): string { + private formatCommand(token: Token) { this.indentation.decreaseTopLevel(); - query = this.addNewline(query); + this.query.addNewline(); // indent tabular formats, except when preceding a ( if (isTabularStyle(this.cfg)) { @@ -204,83 +206,95 @@ export default class StatementFormatter { this.indentation.increaseTopLevel(); } - query += this.show(token); // print token onto query + this.query.addWithSpaceBefore(this.show(token)); // print token onto query if (this.currentNewline && !isTabularStyle(this.cfg)) { - query = this.addNewline(query); + this.query.addNewline(); } else { - query += ' '; + this.query.addWithSpaceBefore(' '); } - return query; } /** * Formats a Reserved Binary Command onto query, joining neighbouring tokens */ - private formatBinaryCommand(token: Token, query: string): string { + private formatBinaryCommand(token: Token) { const isJoin = /JOIN/i.test(token.value); // check if token contains JOIN if (!isJoin || isTabularStyle(this.cfg)) { // decrease for boolean set operators or in tabular mode this.indentation.decreaseTopLevel(); } - query = this.addNewline(query) + this.show(token); - return isJoin ? query + ' ' : this.addNewline(query); + this.query.addNewline(); + this.query.addWithSpaceBefore(this.show(token)); + if (isJoin) { + this.query.addWithSpaceBefore(' '); + } else { + this.query.addNewline(); + } } /** * Formats a Reserved Keyword onto query, skipping AS if disabled */ - private formatKeyword(token: Token, query: string): string { + private formatKeyword(token: Token) { if (isToken.AS(token) && this.aliasAs.shouldRemove()) { - return query; + return; } - return this.formatWithSpaces(token, query); + this.query.addWithSpaces(this.show(token)); } /** * Formats a Reserved Dependent Clause token onto query, supporting the keyword that precedes it */ - private formatDependentClause(token: Token, query: string): string { - return this.addNewline(query) + this.show(token) + ' '; + private formatDependentClause(token: Token) { + this.query.addNewline(); + this.query.addWithSpaces(this.show(token)); } // Formats ON and USING keywords - private formatJoinCondition(token: Token, query: string): string { - return query + this.show(token) + ' '; + private formatJoinCondition(token: Token) { + this.query.addWithSpaces(this.show(token)); } /** * Formats an Operator onto query, following rules for specific characters */ - private formatOperator(token: Token, query: string): string { + private formatOperator(token: Token) { // special operator if (token.value === ',') { - return this.formatComma(token, query); + this.formatComma(token); + return; } else if (token.value === ';') { - return this.formatQuerySeparator(token, query); + this.formatQuerySeparator(token); + return; } else if (['$', '['].includes(token.value)) { - return this.formatWithSpaceBefore(token, query); + this.query.addWithSpaceBefore(this.show(token)); + return; } else if ([':', ']'].includes(token.value)) { - return this.formatWithSpaceAfter(token, query); + this.query.addWithSpaceAfter(this.show(token)); + return; } else if (['.', '{', '}', '`'].includes(token.value)) { - return this.formatWithoutSpaces(token, query); + this.query.addWithoutSpaces(this.show(token)); + return; } // regular operator if (this.cfg.denseOperators && this.tokenLookBehind().type !== TokenType.RESERVED_COMMAND) { // do not trim whitespace if SELECT * - return this.formatWithoutSpaces(token, query); + this.query.addWithoutSpaces(this.show(token)); + return; } - return this.formatWithSpaces(token, query); + this.query.addWithSpaces(this.show(token)); } /** * Formats a Logical Operator onto query, joining boolean conditions */ - private formatLogicalOperator(token: Token, query: string): string { + private formatLogicalOperator(token: Token) { // ignore AND when BETWEEN x [AND] y if (isToken.AND(token) && isToken.BETWEEN(this.tokenLookBehind(2))) { - return this.formatWithSpaces(token, query); + this.query.addWithSpaces(this.show(token)); + return; } if (isTabularStyle(this.cfg)) { @@ -288,14 +302,19 @@ export default class StatementFormatter { } if (this.cfg.logicalOperatorNewline === 'before') { - return (this.currentNewline ? this.addNewline(query) : query) + this.show(token) + ' '; + if (this.currentNewline) { + this.query.addNewline(); + } + this.query.addWithSpaces(this.show(token)); } else { - query += this.show(token); - return this.currentNewline ? this.addNewline(query) : query; + this.query.addWithSpaceBefore(this.show(token)); + if (this.currentNewline) { + this.query.addNewline(); + } } } - private formatBlockStart(token: Token, query: string): string { + private formatBlockStart(token: Token) { // Take out the preceding space unless there was whitespace there in the original query // or another opening parens or line comment const preserveWhitespaceFor = [ @@ -307,103 +326,86 @@ export default class StatementFormatter { token.whitespaceBefore?.length === 0 && !preserveWhitespaceFor.includes(this.tokenLookBehind().type) ) { - query = trimSpacesEnd(query); + this.query.addWithoutSpaces(this.show(token)); } else if (!this.cfg.newlineBeforeOpenParen) { - query = query.trimEnd() + ' '; + this.query.addWithoutNewlinesBefore(this.show(token)); + } else { + this.query.addWithSpaceBefore(this.show(token)); } - query += this.show(token); this.inlineBlock.beginIfPossible(this.tokens, this.index); if (!this.inlineBlock.isActive()) { this.indentation.increaseBlockLevel(); - query = this.addNewline(query); + this.query.addNewline(); } - return query; } - private formatBlockEnd(token: Token, query: string): string { + private formatBlockEnd(token: Token) { if (this.inlineBlock.isActive()) { this.inlineBlock.end(); - return this.formatWithSpaceAfter(token, query); // do not add space before ) + this.query.addWithSpaceAfter(this.show(token)); // do not add space before ) } else { - return this.formatMultilineBlockEnd(token, query); + this.formatMultilineBlockEnd(token); } } - private formatCaseStart(token: Token, query: string): string { - query = this.formatWithSpaces(token, query); + private formatCaseStart(token: Token) { + this.query.addWithSpaces(this.show(token)); this.indentation.increaseBlockLevel(); if (this.cfg.multilineLists === 'always') { - query = this.addNewline(query); + this.query.addNewline(); } - return query; } - private formatCaseEnd(token: Token, query: string): string { - return this.formatMultilineBlockEnd(token, query); + private formatCaseEnd(token: Token) { + this.formatMultilineBlockEnd(token); } - private formatMultilineBlockEnd(token: Token, query: string): string { + private formatMultilineBlockEnd(token: Token) { this.indentation.decreaseBlockLevel(); if (isTabularStyle(this.cfg)) { // +1 extra indentation step for the closing paren - query = this.addNewline(query) + this.indentation.getSingleIndent(); + this.query.addNewline(); + this.query.addWithSpaceBefore(this.indentation.getSingleIndent()); } else if (this.cfg.newlineBeforeCloseParen) { - query = this.addNewline(query); + this.query.addNewline(); } else { - query = query.trimEnd() + ' '; + this.query.addWithoutNewlinesBefore(''); } - return this.formatWithSpaces(token, query); + this.query.addWithSpaces(this.show(token)); } /** * Formats a Placeholder item onto query, to be replaced with the value of the placeholder */ - formatPlaceholder(token: Token, query: string): string { - return query + this.params.get(token) + ' '; + formatPlaceholder(token: Token) { + this.query.addWithSpaces(this.params.get(token)); } /** * Formats a comma Operator onto query, ending line unless in an Inline Block */ - private formatComma(token: Token, query: string): string { - query = this.formatWithSpaceAfter(token, query); + private formatComma(token: Token) { + this.query.addWithSpaceAfter(this.show(token)); if (this.inlineBlock.isActive()) { - return query; + // nothing } else if (isToken.LIMIT(this.getPreviousReservedToken())) { - return query; + // nothing } else if (this.currentNewline) { - return this.addNewline(query); + this.query.addNewline(); } else { - return query; + // nothing } } - /** Simple append of token onto query */ - private formatWithoutSpaces(token: Token, query: string): string { - return trimSpacesEnd(query) + this.show(token); - } - - private formatWithSpaces(token: Token, query: string): string { - return query + this.show(token) + ' '; - } - - private formatWithSpaceBefore(token: Token, query: string) { - return query + this.show(token); - } - - private formatWithSpaceAfter(token: Token, query: string) { - return trimSpacesEnd(query) + this.show(token) + ' '; - } - - private formatQuerySeparator(token: Token, query: string): string { - return this.formatWithoutSpaces( - token, - this.cfg.newlineBeforeSemicolon ? this.addNewline(query) : query - ); + private formatQuerySeparator(token: Token) { + if (this.cfg.newlineBeforeSemicolon) { + this.query.addNewline(); + } + this.query.addWithoutSpaces(this.show(token)); } /** Converts token to string, uppercasing if enabled */ @@ -422,15 +424,6 @@ export default class StatementFormatter { } } - /** Inserts a newline onto the query */ - private addNewline(query: string): string { - query = trimSpacesEnd(query); - if (!query.endsWith('\n') && query !== '') { - query += '\n'; - } - return query + this.indentation.getIndent(); - } - /** Returns the latest encountered reserved keyword token */ public getPreviousReservedToken(): Token { return this.previousReservedToken; diff --git a/src/core/StringBuilder.ts b/src/core/StringBuilder.ts new file mode 100644 index 0000000000..14c74c95a0 --- /dev/null +++ b/src/core/StringBuilder.ts @@ -0,0 +1,40 @@ +import { trimSpacesEnd } from '../utils'; +import Indentation from './Indentation'; + +export default class StringBuilder { + private query = ''; + + constructor(private indentation: Indentation) {} + + public addWithoutSpaces(text: string) { + this.query = trimSpacesEnd(this.query) + text; + } + + public addWithSpaces(text: string) { + this.query += text + ' '; + } + + public addWithSpaceBefore(text: string) { + this.query += text; + } + + public addWithSpaceAfter(text: string) { + this.query = trimSpacesEnd(this.query) + text + ' '; + } + + public addNewline() { + this.query = trimSpacesEnd(this.query); + if (!this.query.endsWith('\n') && this.query !== '') { + this.query += '\n'; + } + this.query += this.indentation.getIndent(); + } + + public addWithoutNewlinesBefore(text: string) { + this.query = this.query.trimEnd() + ' ' + text; + } + + public toString(): string { + return this.query; + } +} From 219dc6509e6f8cf8f4252f4a25033ff2c931612d Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 20 May 2022 11:17:03 +0300 Subject: [PATCH 039/334] Eliminate odd addWithSpaceBefore(' ') --- src/core/StatementFormatter.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index bf5716ad30..30ba2df1db 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -206,11 +206,11 @@ export default class StatementFormatter { this.indentation.increaseTopLevel(); } - this.query.addWithSpaceBefore(this.show(token)); // print token onto query if (this.currentNewline && !isTabularStyle(this.cfg)) { + this.query.addWithSpaceBefore(this.show(token)); this.query.addNewline(); } else { - this.query.addWithSpaceBefore(' '); + this.query.addWithSpaces(this.show(token)); } } @@ -224,10 +224,10 @@ export default class StatementFormatter { this.indentation.decreaseTopLevel(); } this.query.addNewline(); - this.query.addWithSpaceBefore(this.show(token)); if (isJoin) { - this.query.addWithSpaceBefore(' '); + this.query.addWithSpaces(this.show(token)); } else { + this.query.addWithSpaceBefore(this.show(token)); this.query.addNewline(); } } From e21bbb9005ec61b464a62668e70b7b05640a21de Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 20 May 2022 11:56:31 +0300 Subject: [PATCH 040/334] New StringBuilder API with just one add() method --- src/core/StatementFormatter.ts | 96 +++++++++++++++++----------------- src/core/StringBuilder.ts | 51 +++++++++++------- 2 files changed, 79 insertions(+), 68 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 30ba2df1db..d3c46fd829 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -9,7 +9,7 @@ import AliasAs from './AliasAs'; import AsTokenFactory from './AsTokenFactory'; import { Statement } from './Parser'; import { indentString, isTabularStyle } from './config'; -import StringBuilder from './StringBuilder'; +import StringBuilder, { WS } from './StringBuilder'; /** Formats single SQL statement */ export default class StatementFormatter { @@ -100,13 +100,13 @@ export default class StatementFormatter { */ private formatWord(token: Token) { if (this.aliasAs.shouldAddBefore(token)) { - this.query.addWithSpaces(this.show(this.asTokenFactory.token())); + this.query.add(this.show(this.asTokenFactory.token()), WS.SPACE); } - this.query.addWithSpaces(this.show(token)); + this.query.add(this.show(token), WS.SPACE); if (this.aliasAs.shouldAddAfter()) { - this.query.addWithSpaces(this.show(this.asTokenFactory.token())); + this.query.add(this.show(this.asTokenFactory.token()), WS.SPACE); } } @@ -173,15 +173,15 @@ export default class StatementFormatter { /** Formats a line comment onto query */ private formatLineComment(token: Token) { - this.query.addWithSpaceBefore(this.show(token)); - this.query.addNewline(); + this.query.add(this.show(token)); + this.query.add(WS.NEWLINE, WS.INDENT); } /** Formats a block comment onto query */ private formatBlockComment(token: Token) { - this.query.addNewline(); - this.query.addWithSpaceBefore(this.indentComment(token.value)); - this.query.addNewline(); + this.query.add(WS.NEWLINE, WS.INDENT); + this.query.add(this.indentComment(token.value)); + this.query.add(WS.NEWLINE, WS.INDENT); } /** Aligns comment to current indentation level */ @@ -195,7 +195,7 @@ export default class StatementFormatter { private formatCommand(token: Token) { this.indentation.decreaseTopLevel(); - this.query.addNewline(); + this.query.add(WS.NEWLINE, WS.INDENT); // indent tabular formats, except when preceding a ( if (isTabularStyle(this.cfg)) { @@ -207,10 +207,10 @@ export default class StatementFormatter { } if (this.currentNewline && !isTabularStyle(this.cfg)) { - this.query.addWithSpaceBefore(this.show(token)); - this.query.addNewline(); + this.query.add(this.show(token)); + this.query.add(WS.NEWLINE, WS.INDENT); } else { - this.query.addWithSpaces(this.show(token)); + this.query.add(this.show(token), WS.SPACE); } } @@ -223,12 +223,12 @@ export default class StatementFormatter { // decrease for boolean set operators or in tabular mode this.indentation.decreaseTopLevel(); } - this.query.addNewline(); + this.query.add(WS.NEWLINE, WS.INDENT); if (isJoin) { - this.query.addWithSpaces(this.show(token)); + this.query.add(this.show(token), WS.SPACE); } else { - this.query.addWithSpaceBefore(this.show(token)); - this.query.addNewline(); + this.query.add(this.show(token)); + this.query.add(WS.NEWLINE, WS.INDENT); } } @@ -240,20 +240,20 @@ export default class StatementFormatter { return; } - this.query.addWithSpaces(this.show(token)); + this.query.add(this.show(token), WS.SPACE); } /** * Formats a Reserved Dependent Clause token onto query, supporting the keyword that precedes it */ private formatDependentClause(token: Token) { - this.query.addNewline(); - this.query.addWithSpaces(this.show(token)); + this.query.add(WS.NEWLINE, WS.INDENT); + this.query.add(this.show(token), WS.SPACE); } // Formats ON and USING keywords private formatJoinCondition(token: Token) { - this.query.addWithSpaces(this.show(token)); + this.query.add(this.show(token), WS.SPACE); } /** @@ -268,23 +268,23 @@ export default class StatementFormatter { this.formatQuerySeparator(token); return; } else if (['$', '['].includes(token.value)) { - this.query.addWithSpaceBefore(this.show(token)); + this.query.add(this.show(token)); return; } else if ([':', ']'].includes(token.value)) { - this.query.addWithSpaceAfter(this.show(token)); + this.query.add(WS.NO_SPACE, this.show(token), WS.SPACE); return; } else if (['.', '{', '}', '`'].includes(token.value)) { - this.query.addWithoutSpaces(this.show(token)); + this.query.add(WS.NO_SPACE, this.show(token)); return; } // regular operator if (this.cfg.denseOperators && this.tokenLookBehind().type !== TokenType.RESERVED_COMMAND) { // do not trim whitespace if SELECT * - this.query.addWithoutSpaces(this.show(token)); + this.query.add(WS.NO_SPACE, this.show(token)); return; } - this.query.addWithSpaces(this.show(token)); + this.query.add(this.show(token), WS.SPACE); } /** @@ -293,7 +293,7 @@ export default class StatementFormatter { private formatLogicalOperator(token: Token) { // ignore AND when BETWEEN x [AND] y if (isToken.AND(token) && isToken.BETWEEN(this.tokenLookBehind(2))) { - this.query.addWithSpaces(this.show(token)); + this.query.add(this.show(token), WS.SPACE); return; } @@ -303,13 +303,13 @@ export default class StatementFormatter { if (this.cfg.logicalOperatorNewline === 'before') { if (this.currentNewline) { - this.query.addNewline(); + this.query.add(WS.NEWLINE, WS.INDENT); } - this.query.addWithSpaces(this.show(token)); + this.query.add(this.show(token), WS.SPACE); } else { - this.query.addWithSpaceBefore(this.show(token)); + this.query.add(this.show(token)); if (this.currentNewline) { - this.query.addNewline(); + this.query.add(WS.NEWLINE, WS.INDENT); } } } @@ -326,34 +326,34 @@ export default class StatementFormatter { token.whitespaceBefore?.length === 0 && !preserveWhitespaceFor.includes(this.tokenLookBehind().type) ) { - this.query.addWithoutSpaces(this.show(token)); + this.query.add(WS.NO_SPACE, this.show(token)); } else if (!this.cfg.newlineBeforeOpenParen) { - this.query.addWithoutNewlinesBefore(this.show(token)); + this.query.add(WS.NO_NEWLINE, WS.SPACE, this.show(token)); } else { - this.query.addWithSpaceBefore(this.show(token)); + this.query.add(this.show(token)); } this.inlineBlock.beginIfPossible(this.tokens, this.index); if (!this.inlineBlock.isActive()) { this.indentation.increaseBlockLevel(); - this.query.addNewline(); + this.query.add(WS.NEWLINE, WS.INDENT); } } private formatBlockEnd(token: Token) { if (this.inlineBlock.isActive()) { this.inlineBlock.end(); - this.query.addWithSpaceAfter(this.show(token)); // do not add space before ) + this.query.add(WS.NO_SPACE, this.show(token), WS.SPACE); } else { this.formatMultilineBlockEnd(token); } } private formatCaseStart(token: Token) { - this.query.addWithSpaces(this.show(token)); + this.query.add(this.show(token), WS.SPACE); this.indentation.increaseBlockLevel(); if (this.cfg.multilineLists === 'always') { - this.query.addNewline(); + this.query.add(WS.NEWLINE, WS.INDENT); } } @@ -366,36 +366,36 @@ export default class StatementFormatter { if (isTabularStyle(this.cfg)) { // +1 extra indentation step for the closing paren - this.query.addNewline(); - this.query.addWithSpaceBefore(this.indentation.getSingleIndent()); + this.query.add(WS.NEWLINE, WS.INDENT); + this.query.add(this.indentation.getSingleIndent()); } else if (this.cfg.newlineBeforeCloseParen) { - this.query.addNewline(); + this.query.add(WS.NEWLINE, WS.INDENT); } else { - this.query.addWithoutNewlinesBefore(''); + this.query.add(WS.NO_NEWLINE, WS.SPACE); } - this.query.addWithSpaces(this.show(token)); + this.query.add(this.show(token), WS.SPACE); } /** * Formats a Placeholder item onto query, to be replaced with the value of the placeholder */ formatPlaceholder(token: Token) { - this.query.addWithSpaces(this.params.get(token)); + this.query.add(this.params.get(token), WS.SPACE); } /** * Formats a comma Operator onto query, ending line unless in an Inline Block */ private formatComma(token: Token) { - this.query.addWithSpaceAfter(this.show(token)); + this.query.add(WS.NO_SPACE, this.show(token), WS.SPACE); if (this.inlineBlock.isActive()) { // nothing } else if (isToken.LIMIT(this.getPreviousReservedToken())) { // nothing } else if (this.currentNewline) { - this.query.addNewline(); + this.query.add(WS.NEWLINE, WS.INDENT); } else { // nothing } @@ -403,9 +403,9 @@ export default class StatementFormatter { private formatQuerySeparator(token: Token) { if (this.cfg.newlineBeforeSemicolon) { - this.query.addNewline(); + this.query.add(WS.NEWLINE, WS.INDENT); } - this.query.addWithoutSpaces(this.show(token)); + this.query.add(WS.NO_SPACE, this.show(token)); } /** Converts token to string, uppercasing if enabled */ diff --git a/src/core/StringBuilder.ts b/src/core/StringBuilder.ts index 14c74c95a0..b1af70c053 100644 --- a/src/core/StringBuilder.ts +++ b/src/core/StringBuilder.ts @@ -1,37 +1,48 @@ import { trimSpacesEnd } from '../utils'; import Indentation from './Indentation'; +export enum WS { + SPACE = 1, + NO_SPACE = 2, + NEWLINE = 3, + NO_NEWLINE = 4, + INDENT = 5, +} + export default class StringBuilder { private query = ''; constructor(private indentation: Indentation) {} - public addWithoutSpaces(text: string) { - this.query = trimSpacesEnd(this.query) + text; - } - - public addWithSpaces(text: string) { - this.query += text + ' '; - } - - public addWithSpaceBefore(text: string) { - this.query += text; - } - - public addWithSpaceAfter(text: string) { - this.query = trimSpacesEnd(this.query) + text + ' '; + public add(...items: (WS | string)[]) { + for (const item of items) { + switch (item) { + case WS.SPACE: + this.query += ' '; + break; + case WS.NO_SPACE: + this.query = trimSpacesEnd(this.query); + break; + case WS.NEWLINE: + this.addNewline(); + break; + case WS.NO_NEWLINE: + this.query = this.query.trimEnd(); + break; + case WS.INDENT: + this.query += this.indentation.getIndent(); + break; + default: + this.query += item; + } + } } - public addNewline() { + private addNewline() { this.query = trimSpacesEnd(this.query); if (!this.query.endsWith('\n') && this.query !== '') { this.query += '\n'; } - this.query += this.indentation.getIndent(); - } - - public addWithoutNewlinesBefore(text: string) { - this.query = this.query.trimEnd() + ' ' + text; } public toString(): string { From 42b66974f6ff395f4d54b58018c7d34abe7db9cd Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 20 May 2022 12:02:19 +0300 Subject: [PATCH 041/334] Combine consequitive add() calls --- src/core/StatementFormatter.ts | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index d3c46fd829..ab1c3d4766 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -173,15 +173,12 @@ export default class StatementFormatter { /** Formats a line comment onto query */ private formatLineComment(token: Token) { - this.query.add(this.show(token)); - this.query.add(WS.NEWLINE, WS.INDENT); + this.query.add(this.show(token), WS.NEWLINE, WS.INDENT); } /** Formats a block comment onto query */ private formatBlockComment(token: Token) { - this.query.add(WS.NEWLINE, WS.INDENT); - this.query.add(this.indentComment(token.value)); - this.query.add(WS.NEWLINE, WS.INDENT); + this.query.add(WS.NEWLINE, WS.INDENT, this.indentComment(token.value), WS.NEWLINE, WS.INDENT); } /** Aligns comment to current indentation level */ @@ -207,8 +204,7 @@ export default class StatementFormatter { } if (this.currentNewline && !isTabularStyle(this.cfg)) { - this.query.add(this.show(token)); - this.query.add(WS.NEWLINE, WS.INDENT); + this.query.add(this.show(token), WS.NEWLINE, WS.INDENT); } else { this.query.add(this.show(token), WS.SPACE); } @@ -223,12 +219,10 @@ export default class StatementFormatter { // decrease for boolean set operators or in tabular mode this.indentation.decreaseTopLevel(); } - this.query.add(WS.NEWLINE, WS.INDENT); if (isJoin) { - this.query.add(this.show(token), WS.SPACE); + this.query.add(WS.NEWLINE, WS.INDENT, this.show(token), WS.SPACE); } else { - this.query.add(this.show(token)); - this.query.add(WS.NEWLINE, WS.INDENT); + this.query.add(WS.NEWLINE, WS.INDENT, this.show(token), WS.NEWLINE, WS.INDENT); } } @@ -247,8 +241,7 @@ export default class StatementFormatter { * Formats a Reserved Dependent Clause token onto query, supporting the keyword that precedes it */ private formatDependentClause(token: Token) { - this.query.add(WS.NEWLINE, WS.INDENT); - this.query.add(this.show(token), WS.SPACE); + this.query.add(WS.NEWLINE, WS.INDENT, this.show(token), WS.SPACE); } // Formats ON and USING keywords @@ -366,8 +359,7 @@ export default class StatementFormatter { if (isTabularStyle(this.cfg)) { // +1 extra indentation step for the closing paren - this.query.add(WS.NEWLINE, WS.INDENT); - this.query.add(this.indentation.getSingleIndent()); + this.query.add(WS.NEWLINE, WS.INDENT, this.indentation.getSingleIndent()); } else if (this.cfg.newlineBeforeCloseParen) { this.query.add(WS.NEWLINE, WS.INDENT); } else { From d636b07b4964aa1099f535a32109493d22396a85 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 20 May 2022 12:03:51 +0300 Subject: [PATCH 042/334] Convert long if-elseif block to single if --- src/core/StatementFormatter.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index ab1c3d4766..1e25d36713 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -382,14 +382,12 @@ export default class StatementFormatter { private formatComma(token: Token) { this.query.add(WS.NO_SPACE, this.show(token), WS.SPACE); - if (this.inlineBlock.isActive()) { - // nothing - } else if (isToken.LIMIT(this.getPreviousReservedToken())) { - // nothing - } else if (this.currentNewline) { + if ( + !this.inlineBlock.isActive() && + !isToken.LIMIT(this.getPreviousReservedToken()) && + this.currentNewline + ) { this.query.add(WS.NEWLINE, WS.INDENT); - } else { - // nothing } } From f4f613ec6f73f2fe3016613ae01f1b3c1cf3c675 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 20 May 2022 12:20:24 +0300 Subject: [PATCH 043/334] Write some docs for StringBuilder class --- src/core/StringBuilder.ts | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/core/StringBuilder.ts b/src/core/StringBuilder.ts index b1af70c053..6889d97984 100644 --- a/src/core/StringBuilder.ts +++ b/src/core/StringBuilder.ts @@ -1,19 +1,29 @@ import { trimSpacesEnd } from '../utils'; import Indentation from './Indentation'; +/** Whitespace modifiers to be used with add() method */ export enum WS { - SPACE = 1, - NO_SPACE = 2, - NEWLINE = 3, - NO_NEWLINE = 4, - INDENT = 5, + SPACE = 1, // Adds single space + NO_SPACE = 2, // Removes preceding spaces (if any) + NEWLINE = 3, // Adds single newline + NO_NEWLINE = 4, // Removes all preceding whitespace (including newlines) + INDENT = 5, // Adds indentation (as much as needed for current indentation level) } +/** + * API for constructing SQL string (especially the whitespace part). + * + * It hides the internal implementation, so it can be rewritten to + * use something more efficient than current string concatenation. + */ export default class StringBuilder { private query = ''; constructor(private indentation: Indentation) {} + /** + * Appends token strings and whitespace modifications to SQL string. + */ public add(...items: (WS | string)[]) { for (const item of items) { switch (item) { @@ -45,6 +55,9 @@ export default class StringBuilder { } } + /** + * Returns the final SQL string. + */ public toString(): string { return this.query; } From 2a8173bedf9d562469bc66a850fbb8a3b51cefb6 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 20 May 2022 12:21:36 +0300 Subject: [PATCH 044/334] Rename StringBuilder to WhitespaceBuilder --- src/core/StatementFormatter.ts | 6 +++--- src/core/{StringBuilder.ts => WhitespaceBuilder.ts} | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/core/{StringBuilder.ts => WhitespaceBuilder.ts} (97%) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 1e25d36713..0d806ea159 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -9,7 +9,7 @@ import AliasAs from './AliasAs'; import AsTokenFactory from './AsTokenFactory'; import { Statement } from './Parser'; import { indentString, isTabularStyle } from './config'; -import StringBuilder, { WS } from './StringBuilder'; +import WhitespaceBuilder, { WS } from './WhitespaceBuilder'; /** Formats single SQL statement */ export default class StatementFormatter { @@ -19,7 +19,7 @@ export default class StatementFormatter { private aliasAs: AliasAs; private params: Params; private asTokenFactory: AsTokenFactory; - private query: StringBuilder; + private query: WhitespaceBuilder; private currentNewline = true; private previousReservedToken: Token = EOF_TOKEN; @@ -34,7 +34,7 @@ export default class StatementFormatter { this.aliasAs = new AliasAs(this.cfg.aliasAs, this); this.params = params; this.asTokenFactory = asTokenFactory; - this.query = new StringBuilder(this.indentation); + this.query = new WhitespaceBuilder(this.indentation); } public format(statement: Statement): string { diff --git a/src/core/StringBuilder.ts b/src/core/WhitespaceBuilder.ts similarity index 97% rename from src/core/StringBuilder.ts rename to src/core/WhitespaceBuilder.ts index 6889d97984..18b810fba9 100644 --- a/src/core/StringBuilder.ts +++ b/src/core/WhitespaceBuilder.ts @@ -16,7 +16,7 @@ export enum WS { * It hides the internal implementation, so it can be rewritten to * use something more efficient than current string concatenation. */ -export default class StringBuilder { +export default class WhitespaceBuilder { private query = ''; constructor(private indentation: Indentation) {} From 0c9ef1268643e5517fe6b7f6075a2d68ce73dd57 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 20 May 2022 12:25:27 +0300 Subject: [PATCH 045/334] Simplify formatQuerySeparator --- src/core/StatementFormatter.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 0d806ea159..a4cacbd9a8 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -393,9 +393,10 @@ export default class StatementFormatter { private formatQuerySeparator(token: Token) { if (this.cfg.newlineBeforeSemicolon) { - this.query.add(WS.NEWLINE, WS.INDENT); + this.query.add(WS.NEWLINE, this.show(token)); + } else { + this.query.add(WS.NO_SPACE, this.show(token)); } - this.query.add(WS.NO_SPACE, this.show(token)); } /** Converts token to string, uppercasing if enabled */ From 2f5c6d41b726a826bb99e841411e1a4dc8215271 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 20 May 2022 12:26:59 +0300 Subject: [PATCH 046/334] Simplify formatComma --- src/core/StatementFormatter.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index a4cacbd9a8..97a94749f5 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -380,14 +380,14 @@ export default class StatementFormatter { * Formats a comma Operator onto query, ending line unless in an Inline Block */ private formatComma(token: Token) { - this.query.add(WS.NO_SPACE, this.show(token), WS.SPACE); - if ( !this.inlineBlock.isActive() && !isToken.LIMIT(this.getPreviousReservedToken()) && this.currentNewline ) { - this.query.add(WS.NEWLINE, WS.INDENT); + this.query.add(WS.NO_SPACE, this.show(token), WS.NEWLINE, WS.INDENT); + } else { + this.query.add(WS.NO_SPACE, this.show(token), WS.SPACE); } } From 506e35de0207024214d063b19cb30f4a0fd1791d Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 20 May 2022 12:29:09 +0300 Subject: [PATCH 047/334] Simplify formatMultilineBlockEnd --- src/core/StatementFormatter.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 97a94749f5..f4872d3843 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -359,14 +359,18 @@ export default class StatementFormatter { if (isTabularStyle(this.cfg)) { // +1 extra indentation step for the closing paren - this.query.add(WS.NEWLINE, WS.INDENT, this.indentation.getSingleIndent()); + this.query.add( + WS.NEWLINE, + WS.INDENT, + this.indentation.getSingleIndent(), + this.show(token), + WS.SPACE + ); } else if (this.cfg.newlineBeforeCloseParen) { - this.query.add(WS.NEWLINE, WS.INDENT); + this.query.add(WS.NEWLINE, WS.INDENT, this.show(token), WS.SPACE); } else { - this.query.add(WS.NO_NEWLINE, WS.SPACE); + this.query.add(WS.NO_NEWLINE, WS.SPACE, this.show(token), WS.SPACE); } - - this.query.add(this.show(token), WS.SPACE); } /** From 420b88f90a89d30f76d75c14833eb43efcde32fd Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 20 May 2022 12:31:06 +0300 Subject: [PATCH 048/334] Add SINGLE_INDENT type of WS --- src/core/StatementFormatter.ts | 8 +------- src/core/WhitespaceBuilder.ts | 4 ++++ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index f4872d3843..06d0168a9e 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -359,13 +359,7 @@ export default class StatementFormatter { if (isTabularStyle(this.cfg)) { // +1 extra indentation step for the closing paren - this.query.add( - WS.NEWLINE, - WS.INDENT, - this.indentation.getSingleIndent(), - this.show(token), - WS.SPACE - ); + this.query.add(WS.NEWLINE, WS.INDENT, WS.SINGLE_INDENT, this.show(token), WS.SPACE); } else if (this.cfg.newlineBeforeCloseParen) { this.query.add(WS.NEWLINE, WS.INDENT, this.show(token), WS.SPACE); } else { diff --git a/src/core/WhitespaceBuilder.ts b/src/core/WhitespaceBuilder.ts index 18b810fba9..55a34bed52 100644 --- a/src/core/WhitespaceBuilder.ts +++ b/src/core/WhitespaceBuilder.ts @@ -8,6 +8,7 @@ export enum WS { NEWLINE = 3, // Adds single newline NO_NEWLINE = 4, // Removes all preceding whitespace (including newlines) INDENT = 5, // Adds indentation (as much as needed for current indentation level) + SINGLE_INDENT = 6, // Adds whitespace for single indentation step } /** @@ -42,6 +43,9 @@ export default class WhitespaceBuilder { case WS.INDENT: this.query += this.indentation.getIndent(); break; + case WS.SINGLE_INDENT: + this.query += this.indentation.getSingleIndent(); + break; default: this.query += item; } From 135b1246a466353633f26f6a226d38200613f74d Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 20 May 2022 12:33:39 +0300 Subject: [PATCH 049/334] Simplify formatCaseStart --- src/core/StatementFormatter.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 06d0168a9e..33e8238f42 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -343,10 +343,11 @@ export default class StatementFormatter { } private formatCaseStart(token: Token) { - this.query.add(this.show(token), WS.SPACE); this.indentation.increaseBlockLevel(); if (this.cfg.multilineLists === 'always') { - this.query.add(WS.NEWLINE, WS.INDENT); + this.query.add(this.show(token), WS.NEWLINE, WS.INDENT); + } else { + this.query.add(this.show(token), WS.SPACE); } } From 92566a6fe8e178dbda3476b348cc0017513daa3f Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 20 May 2022 12:38:29 +0300 Subject: [PATCH 050/334] Simplify formatLogicalOperator --- src/core/StatementFormatter.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 33e8238f42..0ba8c9f1da 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -296,13 +296,16 @@ export default class StatementFormatter { if (this.cfg.logicalOperatorNewline === 'before') { if (this.currentNewline) { - this.query.add(WS.NEWLINE, WS.INDENT); + this.query.add(WS.NEWLINE, WS.INDENT, this.show(token), WS.SPACE); + } else { + this.query.add(this.show(token), WS.SPACE); } - this.query.add(this.show(token), WS.SPACE); } else { - this.query.add(this.show(token)); + // eslint-disable-next-line no-lonely-if if (this.currentNewline) { - this.query.add(WS.NEWLINE, WS.INDENT); + this.query.add(this.show(token), WS.NEWLINE, WS.INDENT); + } else { + this.query.add(this.show(token)); } } } From 0b45326ea5a59e20978c687beffcd9d610fc80b3 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 20 May 2022 12:42:08 +0300 Subject: [PATCH 051/334] Clarify formatOperator --- src/core/StatementFormatter.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 0ba8c9f1da..f330696c89 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -271,13 +271,13 @@ export default class StatementFormatter { return; } - // regular operator + // other operators + // in dense operators mode do not trim whitespace if SELECT * if (this.cfg.denseOperators && this.tokenLookBehind().type !== TokenType.RESERVED_COMMAND) { - // do not trim whitespace if SELECT * this.query.add(WS.NO_SPACE, this.show(token)); - return; + } else { + this.query.add(this.show(token), WS.SPACE); } - this.query.add(this.show(token), WS.SPACE); } /** From 62f3574b57275ffed4408c8b506b3a2df9ddaec1 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 20 May 2022 13:17:24 +0300 Subject: [PATCH 052/334] Rewrite WhitespaceBuilder to not use string concatenation Should be more optimal. The tests now run about 2x faster. --- src/core/Indentation.ts | 7 ++++ src/core/WhitespaceBuilder.ts | 63 +++++++++++++++++++++++++++-------- 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/src/core/Indentation.ts b/src/core/Indentation.ts index 8e5a0033e6..cf27972ec2 100644 --- a/src/core/Indentation.ts +++ b/src/core/Indentation.ts @@ -34,6 +34,13 @@ export default class Indentation { return this.indent.repeat(this.indentTypes.length); } + /** + * Returns current indentation level + */ + getLevel(): number { + return this.indentTypes.length; + } + /** * Increases indentation by one top-level indent. */ diff --git a/src/core/WhitespaceBuilder.ts b/src/core/WhitespaceBuilder.ts index 55a34bed52..2658735862 100644 --- a/src/core/WhitespaceBuilder.ts +++ b/src/core/WhitespaceBuilder.ts @@ -1,4 +1,3 @@ -import { trimSpacesEnd } from '../utils'; import Indentation from './Indentation'; /** Whitespace modifiers to be used with add() method */ @@ -14,11 +13,12 @@ export enum WS { /** * API for constructing SQL string (especially the whitespace part). * - * It hides the internal implementation, so it can be rewritten to - * use something more efficient than current string concatenation. + * It hides the internal implementation. + * Originally it used plain string concatenation, which was expensive. + * Now it's storing items to array and builds the string only in the end. */ export default class WhitespaceBuilder { - private query = ''; + private query: (WS.SPACE | WS.SINGLE_INDENT | WS.NEWLINE | string)[] = []; constructor(private indentation: Indentation) {} @@ -29,33 +29,47 @@ export default class WhitespaceBuilder { for (const item of items) { switch (item) { case WS.SPACE: - this.query += ' '; + this.query.push(WS.SPACE); break; case WS.NO_SPACE: - this.query = trimSpacesEnd(this.query); + this.trimHorizontalWhitespace(); break; case WS.NEWLINE: + this.trimHorizontalWhitespace(); this.addNewline(); break; case WS.NO_NEWLINE: - this.query = this.query.trimEnd(); + this.trimAllWhitespace(); break; case WS.INDENT: - this.query += this.indentation.getIndent(); + for (let i = 0; i < this.indentation.getLevel(); i++) { + this.query.push(WS.SINGLE_INDENT); + } break; case WS.SINGLE_INDENT: - this.query += this.indentation.getSingleIndent(); + this.query.push(WS.SINGLE_INDENT); break; default: - this.query += item; + this.query.push(item); } } } + private trimHorizontalWhitespace() { + while (isHorizontalWhitespace(last(this.query))) { + this.query.pop(); + } + } + + private trimAllWhitespace() { + while (isWhitespace(last(this.query))) { + this.query.pop(); + } + } + private addNewline() { - this.query = trimSpacesEnd(this.query); - if (!this.query.endsWith('\n') && this.query !== '') { - this.query += '\n'; + if (this.query.length > 0 && last(this.query) !== WS.NEWLINE) { + this.query.push(WS.NEWLINE); } } @@ -63,6 +77,27 @@ export default class WhitespaceBuilder { * Returns the final SQL string. */ public toString(): string { - return this.query; + return this.query.map(item => this.itemToString(item)).join(''); + } + + private itemToString(item: WS | string) { + switch (item) { + case WS.SPACE: + return ' '; + case WS.NEWLINE: + return '\n'; + case WS.SINGLE_INDENT: + return this.indentation.getSingleIndent(); + default: + return item; + } } } + +const isHorizontalWhitespace = (item: WS | string | undefined) => + item === WS.SPACE || item === WS.SINGLE_INDENT; + +const isWhitespace = (item: WS | string | undefined) => + item === WS.SPACE || item === WS.SINGLE_INDENT || item === WS.NEWLINE; + +const last = (arr: T[]): T | undefined => arr[arr.length - 1]; From 77ba363953fe59f1df0dad078cb4197903b175c3 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 20 May 2022 13:20:10 +0300 Subject: [PATCH 053/334] Delete unused trimSpacesEnd() --- src/utils.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index ca4638a51f..ca7f82b278 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,8 +1,5 @@ export const dedupe = (arr: string[]) => [...new Set(arr)]; -// Only removes spaces, not newlines -export const trimSpacesEnd = (str: string) => str.replace(/[ \t]+$/u, ''); - // Last element from array export const last = (arr: T[]) => arr[arr.length - 1]; From 94491ad73a3b453e7ce5660e3cb8d2b800073eb4 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Sat, 21 May 2022 10:11:51 +0300 Subject: [PATCH 054/334] Use already existing last() func from utils --- src/core/WhitespaceBuilder.ts | 3 +-- src/utils.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/core/WhitespaceBuilder.ts b/src/core/WhitespaceBuilder.ts index 2658735862..2f4cae4800 100644 --- a/src/core/WhitespaceBuilder.ts +++ b/src/core/WhitespaceBuilder.ts @@ -1,3 +1,4 @@ +import { last } from '../utils'; import Indentation from './Indentation'; /** Whitespace modifiers to be used with add() method */ @@ -99,5 +100,3 @@ const isHorizontalWhitespace = (item: WS | string | undefined) => const isWhitespace = (item: WS | string | undefined) => item === WS.SPACE || item === WS.SINGLE_INDENT || item === WS.NEWLINE; - -const last = (arr: T[]): T | undefined => arr[arr.length - 1]; diff --git a/src/utils.ts b/src/utils.ts index ca7f82b278..df8154d6f1 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,7 @@ export const dedupe = (arr: string[]) => [...new Set(arr)]; // Last element from array -export const last = (arr: T[]) => arr[arr.length - 1]; +export const last = (arr: T[]): T | undefined => arr[arr.length - 1]; // True array is empty, or it's not an array at all export const isEmpty = (arr: any[]) => !Array.isArray(arr) || arr.length === 0; From a4ff7f45c17294d91e8557679942a99e7be53e30 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Sat, 21 May 2022 10:56:58 +0300 Subject: [PATCH 055/334] Remove ZWS-replacement from tabular token formatting Instead of adding ZeroWidthSpace chars and replacing them later with normal spaces, the spaces are now added immediately and the formatting itself no more modifies Token objects, but happens inside show() method. This was made possible by the earlier WhitespaceBuilder refactor, which now no more trims trailing spaces, so we don't lose these trailing spaces we insert for tabular formatted keywords. --- src/core/StatementFormatter.ts | 34 ++++++++++++++++++++++------------ src/core/tabularStyle.ts | 34 ++++++++-------------------------- src/core/token.ts | 3 --- 3 files changed, 30 insertions(+), 41 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index f330696c89..21468befb2 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -4,7 +4,7 @@ import Params from './Params'; import { equalizeWhitespace } from '../utils'; import { isReserved, isCommand, isToken, Token, TokenType, EOF_TOKEN } from './token'; import { FormatOptions } from '../types'; -import { toTabularToken, replaceTabularPlaceholders } from './tabularStyle'; +import toTabularFormat from './tabularStyle'; import AliasAs from './AliasAs'; import AsTokenFactory from './AsTokenFactory'; import { Statement } from './Parser'; @@ -41,19 +41,11 @@ export default class StatementFormatter { this.tokens = statement.tokens; for (this.index = 0; this.index < this.tokens.length; this.index++) { - let token = this.tokens[this.index]; + const token = this.tokens[this.index]; // if token is a Reserved Keyword, Command, Binary Command, Dependent Clause, Logical Operator, CASE, END if (isReserved(token)) { this.previousReservedToken = token; - if ( - token.type === TokenType.RESERVED_LOGICAL_OPERATOR || - token.type === TokenType.RESERVED_DEPENDENT_CLAUSE || - token.type === TokenType.RESERVED_COMMAND || - token.type === TokenType.RESERVED_BINARY_COMMAND - ) { - token = toTabularToken(token, this.cfg.indentStyle); - } if (token.type === TokenType.RESERVED_COMMAND) { this.previousCommandToken = token; } @@ -92,7 +84,7 @@ export default class StatementFormatter { this.formatWord(token); } } - return replaceTabularPlaceholders(this.query.toString()); + return this.query.toString(); } /** @@ -401,8 +393,26 @@ export default class StatementFormatter { } } - /** Converts token to string, uppercasing if enabled */ private show(token: Token): string { + if (this.isTabularToken(token)) { + return toTabularFormat(this.showToken(token), this.cfg.indentStyle); + } else { + return this.showToken(token); + } + } + + // These token types can be formatted in tabular style + private isTabularToken(token: Token): boolean { + return ( + token.type === TokenType.RESERVED_LOGICAL_OPERATOR || + token.type === TokenType.RESERVED_DEPENDENT_CLAUSE || + token.type === TokenType.RESERVED_COMMAND || + token.type === TokenType.RESERVED_BINARY_COMMAND + ); + } + + // don't call this directly, always use show() instead. + private showToken(token: Token): string { if (isReserved(token)) { switch (this.cfg.keywordCase) { case 'preserve': diff --git a/src/core/tabularStyle.ts b/src/core/tabularStyle.ts index 205b448462..0ddfa71f83 100644 --- a/src/core/tabularStyle.ts +++ b/src/core/tabularStyle.ts @@ -1,43 +1,25 @@ import { IndentStyle } from '../types'; -import { Token, ZWS } from './token'; /** * When tabular style enabled, - * produces a 10-char wide version of reserved token. - * - * It'll be padded by zero-width space characters - * instead of normal spaces, so that these spaces will survive - * trimming of spaces in other parts of formatter. - * They'll be converted to normal spaces in the end of - * all the normal formatting with the replaceTabularPlaceholders() + * produces a 10-char wide version of token text. */ -export function toTabularToken(token: Token, indentStyle: IndentStyle): Token { +export default function toTabularFormat(tokenText: string, indentStyle: IndentStyle): string { if (indentStyle === 'standard') { - return token; + return tokenText; } - let bufferItem = token.text; // store which part of keyword receives 10-space buffer let tail = [] as string[]; // rest of keyword - if (bufferItem.length >= 10 && bufferItem.includes(' ')) { + if (tokenText.length >= 10 && tokenText.includes(' ')) { // split for long keywords like INNER JOIN or UNION DISTINCT - [bufferItem, ...tail] = bufferItem.split(' '); + [tokenText, ...tail] = tokenText.split(' '); } if (indentStyle === 'tabularLeft') { - bufferItem = bufferItem.padEnd(9, ZWS); + tokenText = tokenText.padEnd(9, ' '); } else { - bufferItem = bufferItem.padStart(9, ZWS); + tokenText = tokenText.padStart(9, ' '); } - return { - ...token, - text: bufferItem + ['', ...tail].join(' '), - }; -} - -/** - * Replaces zero-width-spaces added by the above function - */ -export function replaceTabularPlaceholders(query: string): string { - return query.replace(new RegExp(ZWS, 'ugim'), ' '); + return tokenText + ['', ...tail].join(' '); } diff --git a/src/core/token.ts b/src/core/token.ts index 9ef22229b6..de20c15bc4 100644 --- a/src/core/token.ts +++ b/src/core/token.ts @@ -35,9 +35,6 @@ export interface Token { */ export const EOF_TOKEN = { type: TokenType.EOF, text: '«EOF»', value: '«EOF»' }; -/** Special Unicode character to serve as a placeholder for tabular formats as \w whitespace is unavailable */ -export const ZWS = '​'; // uses zero-width space (​ / U+200B) - /** Checks if two tokens are equivalent */ export const testToken = (compareToken: { type: TokenType; value: string }) => From fffe1a7b5778a585b00718922ca66086b34bb69f Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Sat, 21 May 2022 11:03:30 +0300 Subject: [PATCH 056/334] Add unit tests for toTabularFormat() function --- test/unit/tabularStyle.test.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 test/unit/tabularStyle.test.ts diff --git a/test/unit/tabularStyle.test.ts b/test/unit/tabularStyle.test.ts new file mode 100644 index 0000000000..429e6b974e --- /dev/null +++ b/test/unit/tabularStyle.test.ts @@ -0,0 +1,21 @@ +import toTabularFormat from '../../src/core/tabularStyle'; + +describe('toTabularFormat()', () => { + it('does nothing in standard style', () => { + expect(toTabularFormat('FROM', 'standard')).toBe('FROM'); + expect(toTabularFormat('INNER JOIN', 'standard')).toBe('INNER JOIN'); + expect(toTabularFormat('INSERT INTO', 'standard')).toBe('INSERT INTO'); + }); + + it('formats in tabularLeft style', () => { + expect(toTabularFormat('FROM', 'tabularLeft')).toBe('FROM '); + expect(toTabularFormat('INNER JOIN', 'tabularLeft')).toBe('INNER JOIN'); + expect(toTabularFormat('INSERT INTO', 'tabularLeft')).toBe('INSERT INTO'); + }); + + it('formats in tabularRight style', () => { + expect(toTabularFormat('FROM', 'tabularRight')).toBe(' FROM'); + expect(toTabularFormat('INNER JOIN', 'tabularRight')).toBe(' INNER JOIN'); + expect(toTabularFormat('INSERT INTO', 'tabularRight')).toBe(' INSERT INTO'); + }); +}); From 120651e4b0c88f5cb1d7add1b1eb9f0b01e72ef5 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Sat, 21 May 2022 11:05:50 +0300 Subject: [PATCH 057/334] Skip equalizeWhitespace() when upper/lower-casing Now that Token.text is no more formatted for tabular format, we can simply use Token.value, which is already in uppercase and without extra whitespace. --- src/core/StatementFormatter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 21468befb2..91f3f8ef6b 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -418,9 +418,9 @@ export default class StatementFormatter { case 'preserve': return equalizeWhitespace(token.text); case 'upper': - return equalizeWhitespace(token.text.toUpperCase()); + return token.value; case 'lower': - return equalizeWhitespace(token.text.toLowerCase()); + return token.value.toLowerCase(); } } else { return token.value; From c9b2b4dfc2c908972a55b552b5e01742ce8f62a1 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Mon, 23 May 2022 11:36:07 +0300 Subject: [PATCH 058/334] Document query parameter syntax --- sql/parameters.md | 56 +++++++++++++++++++++++++++++++++++++++++++++++ sql/syntax.md | 1 + 2 files changed, 57 insertions(+) create mode 100644 sql/parameters.md diff --git a/sql/parameters.md b/sql/parameters.md new file mode 100644 index 0000000000..4322996262 --- /dev/null +++ b/sql/parameters.md @@ -0,0 +1,56 @@ +# Parameters + +Parameter placeholder markers used in prepared statements. + +## Positional parameters + +- [BigQuery][]: `?` +- [DB2][]: `?` +- Hive: — +- [MariaDB][]: `?` +- [MySQL][]: `?` +- [N1QL][]: `?` +- PL/SQL: — +- PostgreSQL: — +- Redshift: — +- Spark: — +- [SQLite][]: `?` +- [Transact-SQL][]: `?` + +## Numbered parameters + +- [MariaDB][]: `:1`, `:2`, ...1 +- [N1QL][]: `$1`, `$2`, ... +- [PL/SQL][]: `:1`, `:2`, ... +- [PostgreSQL][]: `$1`, `$2`, ... +- [Redshift][]: `$1`, `$2`, ... +- [SQLite][]: `?1`, `?2`, ... + +1. When SQL_MODE=ORACLE enabled. + +## Named parameters + +- [BigQuery][]: `@` followed by [identifier][] (either quoted or unquoted) +- [DB2][]: colon (`:`) followed by name (the name can include letters, numbers, and the symbols `@`, `#`, `$`, and `_`) +- Hive: — +- MariaDB: — +- MySQL: — +- [N1QL][]: `$` followed by unquoted [identifier][] +- [PL/SQL][]: colon (`:`) followed by name (`[a-zA-Z][a-zA-Z0-9_]*`) +- PostgreSQL: — +- Redshift: — +- Spark: — +- [SQLite][]: `$`, `@` or `:` followed by unquoted [identifier][] +- [Transact-SQL][]: `@` or `:` followed by name (see also [identifier][] syntax) + +[identifier]: ./identifiers.md +[bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#query_parameters +[db2]: https://www.ibm.com/docs/en/db2/9.7?topic=statements-prepare#r0000975__l975 +[mariadb]: https://mariadb.com/kb/en/prepare-statement/ +[mysql]: https://dev.mysql.com/doc/refman/8.0/en/prepare.html +[n1ql]: https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/prepare.html#parameters +[pl/sql]: https://docs.oracle.com/en/database/oracle/oracle-database/21/lnoci/using-sql_statements-in-oci.html#GUID-8D6FD01B-5B8A-49A2-BFD8-71B404529F07 +[postgresql]: https://www.postgresql.org/docs/14/sql-prepare.html +[redshift]: https://docs.aws.amazon.com/redshift/latest/dg/r_PREPARE.html +[sqlite]: https://sqlite.org/c3ref/bind_blob.html +[transact-sql]: https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/configuring-parameters-and-parameter-data-types diff --git a/sql/syntax.md b/sql/syntax.md index 759a9612fc..3cee32b58a 100644 --- a/sql/syntax.md +++ b/sql/syntax.md @@ -3,4 +3,5 @@ Reference of SQL syntax variations. - [Identifiers](./identifiers.md) +- [Parameters](./parameters.md) - [SELECT](./select.md) From 39a1ab9c044c89091492ff07b39592a37c025b54 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Mon, 23 May 2022 11:40:10 +0300 Subject: [PATCH 059/334] Additional notes for T-sql parameter types --- sql/parameters.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sql/parameters.md b/sql/parameters.md index 4322996262..9706a6461e 100644 --- a/sql/parameters.md +++ b/sql/parameters.md @@ -15,19 +15,17 @@ Parameter placeholder markers used in prepared statements. - Redshift: — - Spark: — - [SQLite][]: `?` -- [Transact-SQL][]: `?` +- [Transact-SQL][]: `?`1 ## Numbered parameters -- [MariaDB][]: `:1`, `:2`, ...1 +- [MariaDB][]: `:1`, `:2`, ...2 - [N1QL][]: `$1`, `$2`, ... - [PL/SQL][]: `:1`, `:2`, ... - [PostgreSQL][]: `$1`, `$2`, ... - [Redshift][]: `$1`, `$2`, ... - [SQLite][]: `?1`, `?2`, ... -1. When SQL_MODE=ORACLE enabled. - ## Named parameters - [BigQuery][]: `@` followed by [identifier][] (either quoted or unquoted) @@ -41,7 +39,13 @@ Parameter placeholder markers used in prepared statements. - Redshift: — - Spark: — - [SQLite][]: `$`, `@` or `:` followed by unquoted [identifier][] -- [Transact-SQL][]: `@` or `:` followed by name (see also [identifier][] syntax) +- [Transact-SQL][]: `@` or `:`3 followed by name (see also [identifier][] syntax) + +### Notes: + +1. When using ODBC or OLE DB driver +2. When SQL_MODE=ORACLE enabled. +3. When using Oracle driver. [identifier]: ./identifiers.md [bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#query_parameters From d0ea62fd2ec4eff906771172e01c0f6f177cbd92 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Mon, 23 May 2022 11:47:14 +0300 Subject: [PATCH 060/334] Don't list dialects not supporting parameters --- sql/parameters.md | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/sql/parameters.md b/sql/parameters.md index 9706a6461e..769c228343 100644 --- a/sql/parameters.md +++ b/sql/parameters.md @@ -2,20 +2,19 @@ Parameter placeholder markers used in prepared statements. +**Note:** Apache Hive and Spark don't support prepared statements. + ## Positional parameters -- [BigQuery][]: `?` -- [DB2][]: `?` -- Hive: — -- [MariaDB][]: `?` -- [MySQL][]: `?` -- [N1QL][]: `?` -- PL/SQL: — -- PostgreSQL: — -- Redshift: — -- Spark: — -- [SQLite][]: `?` -- [Transact-SQL][]: `?`1 +These come in the form of single question mark (`?`), supported by: + +- [BigQuery][] +- [DB2][] +- [MariaDB][] +- [MySQL][] +- [N1QL][] +- [SQLite][] +- [Transact-SQL][]1 ## Numbered parameters @@ -30,14 +29,8 @@ Parameter placeholder markers used in prepared statements. - [BigQuery][]: `@` followed by [identifier][] (either quoted or unquoted) - [DB2][]: colon (`:`) followed by name (the name can include letters, numbers, and the symbols `@`, `#`, `$`, and `_`) -- Hive: — -- MariaDB: — -- MySQL: — - [N1QL][]: `$` followed by unquoted [identifier][] - [PL/SQL][]: colon (`:`) followed by name (`[a-zA-Z][a-zA-Z0-9_]*`) -- PostgreSQL: — -- Redshift: — -- Spark: — - [SQLite][]: `$`, `@` or `:` followed by unquoted [identifier][] - [Transact-SQL][]: `@` or `:`3 followed by name (see also [identifier][] syntax) From c7f88fe945d410e262cee53a9c160193a7710ca6 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Mon, 23 May 2022 21:13:37 +0300 Subject: [PATCH 061/334] Document string literal syntax --- sql/identifiers.md | 3 +- sql/strings.md | 69 ++++++++++++++++++++++++++++++++++++++++++++++ sql/syntax.md | 1 + 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 sql/strings.md diff --git a/sql/identifiers.md b/sql/identifiers.md index 2ffa5a0f19..10ceea66a4 100644 --- a/sql/identifiers.md +++ b/sql/identifiers.md @@ -35,12 +35,13 @@ There is a considerable variation in implementations: - `".."` [Redshift][] - `` `..` `` [Spark][] - `".."`, `` `..` ``, `[..]` [SQLite][sqlite-keywords] -- `".."`, `[..]` [Transact-SQL][] +- `".."`3, `[..]` [Transact-SQL][] Notes: 1. when ANSI_QUOTES mode enabled 2. when MSSQL mode enabled +3. unless QUOTED_IDENTIFIER option has been set OFF [bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical [db2]: https://www.ibm.com/docs/en/db2/9.7?topic=elements-identifiers diff --git a/sql/strings.md b/sql/strings.md new file mode 100644 index 0000000000..123fb2eb3e --- /dev/null +++ b/sql/strings.md @@ -0,0 +1,69 @@ +# Strings + +SQL standard supports single-quoted strings `'..'` with repeated quote `''` used for escaping. +The real world implementations have lots of variation: + +- [BigQuery][]: + - `".."`, `'..'`, `"""..."""`, `'''..'''` (backslash `\` used for escaping) + - `R".."`, `r'''..'''` the same as above, but with `r` or `R` prefix (backlashes not used for escaping) + - `B".."`, `b'''..'''` the same as above, but with `b` or `B` prefix (backlashes not used for escaping) + - `RB".."`, `br'''..'''` the same as above, but with additional `r` or `R` prefix (backlashes not used for escaping) +- [DB2][]: + - `'..'` (two single quotes `''` are used for escaping) + - `X'..'` a hex string (no escaping) + - `U&'..'` an unicode string (two single quotes `''` are used for escaping) + - `G'..'`, `N'..'` a graphic string + - `GX'..'` a graphic hex string (no escaping) + - `UX'..'` an UCS-2 graphic string (no escaping) +- [Hive][]: `'..'`, `".."` (backslash `\` used for escaping) +- [MariaDB][]: + - `'..'` (backslash `\`1 or repeated single-quote `''` used for escaping) + - `x'..'`, `X'..'` [hex string][mariadb-hex] +- [MySQL][]: + - `'..'`, `".."`2 (backslash `\`1 or repeated quote (`''` or `""`) used for escaping) + - `x'..'`, `X'..'` [hex string][mysql-hex] +- [N1QL][]: `".."` (backslash `\` used for escaping) +- [PL/SQL][]: + - `'..'` (two single quotes `''` are used for escaping) + - `N'..'`, `n'..'` a string using a natural character set + - `Q'x..x'`, `q'x..x'` where `x` is a custom delimiter character + - `q'{..}'`, `q'[..]'`, `q'<..>'`, `q'(..)'` special handling for certain delimiters in above syntax +- [PostgreSQL][]: + - `'..'` (two single quotes `''` are used for escaping) + - `E'..'`, `e'..'` string with C-style escapes (backslash `\` or repeated single-quote `''` used for escaping) + - `U&'..'`, `u&'..'` string with unicode escapes + - `$$..$$`, `$delim$..$delim$` dollar-quoted string with optional custom delimiters + - `B'..'`, `b'..'` bit string + - `X'..'`, `x'..'` hex string +- [Redshift][]: `'..'` +- [Spark][]: + - `'..'` (backslash `\` used for escaping) + - `X'..'` hex string +- [SQLite][]: + - `'..'` (two single quotes `''` are used for escaping) + - `X'..'`, `x'..'` hex string +- [Transact-SQL][]: + - `'..'` (two single quotes `''` are used for escaping) + - (`".."`3) + - `N'..'` (`N".."`3) unicode strings + +### Notes: + +1. unless the SQL_MODE has been set to NO_BACKSLASH_ESCAPES. +2. unless ANSI_QUOTES mode is enabled. +3. if the QUOTED_IDENTIFIER option has been set OFF. + +[bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#string_and_bytes_literals +[db2]: https://www.ibm.com/docs/en/db2/9.7?topic=elements-constants +[hive]: https://cwiki.apache.org/confluence/display/hive/languagemanual%20types#LanguageManualTypes-StringsstringStrings +[mariadb]: https://mariadb.com/kb/en/string-literals/ +[mariadb-hex]: https://mariadb.com/kb/en/hexadecimal-literals/ +[mysql]: https://dev.mysql.com/doc/refman/8.0/en/string-literals.html +[mysql-hex]: https://dev.mysql.com/doc/refman/8.0/en/hexadecimal-literals.html +[n1ql]: https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/literals.html#strings +[pl/sql]: https://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements003.htm#i42617 +[postgresql]: https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS +[redshift]: https://docs.aws.amazon.com/redshift/latest/dg/r_Examples_with_character_types.html +[spark]: https://spark.apache.org/docs/latest/sql-ref-literals.html#string-literal +[sqlite]: https://www.sqlite.org/lang_expr.html#literal_values_constants_ +[transact-sql]: https://docs.microsoft.com/en-us/sql/t-sql/data-types/constants-transact-sql?view=sql-server-ver15 diff --git a/sql/syntax.md b/sql/syntax.md index 3cee32b58a..683afec472 100644 --- a/sql/syntax.md +++ b/sql/syntax.md @@ -4,4 +4,5 @@ Reference of SQL syntax variations. - [Identifiers](./identifiers.md) - [Parameters](./parameters.md) +- [Strings](./strings.md) - [SELECT](./select.md) From 84f5b1cae724c6e15b47d51b62999cb04ecf407c Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 24 May 2022 10:33:58 +0300 Subject: [PATCH 062/334] Add missing PostgreSQL JSON operators --- src/languages/postgresql.formatter.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index bf839eae55..05df3a908f 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1631,6 +1631,8 @@ const binaryOperators = [ ':=', '->>', '->', + '#>>', + '#>', '=>', '~~*', '~~', From 2b045e526aade5e3da91d6df6d4fdb193548d4de Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 24 May 2022 10:36:29 +0300 Subject: [PATCH 063/334] Release v6.1.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9e18ba8dfc..b0584cb4b6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sql-formatter", - "version": "6.1.1", + "version": "6.1.2", "description": "Format whitespace in a SQL query to make it more readable", "license": "MIT", "main": "lib/index.js", From 7cc38187086e81509c5eba1d02a7a4abfc9e6adf Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 10:39:48 +0300 Subject: [PATCH 064/334] Remove redundant PL/SQL tests --- test/plsql.test.ts | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/test/plsql.test.ts b/test/plsql.test.ts index e1c624be2d..b1bb4c8c66 100644 --- a/test/plsql.test.ts +++ b/test/plsql.test.ts @@ -49,17 +49,6 @@ describe('PlSqlFormatter', () => { `); }); - it('formats only -- as a line comment', () => { - const result = format('SELECT col FROM\n-- This is a comment\nMyTable;\n'); - expect(result).toBe(dedent` - SELECT - col - FROM - -- This is a comment - MyTable; - `); - }); - it('recognizes _, $, #, . and @ as part of identifiers', () => { const result = format('SELECT my_col$1#, col.2@, type#, procedure$, user# FROM tbl\n'); expect(result).toBe(dedent` @@ -99,17 +88,6 @@ describe('PlSqlFormatter', () => { `); }); - it('formats simple SELECT', () => { - const result = format('SELECT N, M FROM t'); - expect(result).toBe(dedent` - SELECT - N, - M - FROM - t - `); - }); - it('formats simple SELECT with national characters', () => { const result = format("SELECT N'value'"); expect(result).toBe(dedent` From 0107ec351e4534a326033262e5494438a5c11ee8 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 10:48:48 +0300 Subject: [PATCH 065/334] Drop . and @ from PL/SQL identifiers According to PL/SQL docs, these aren't supported. --- src/languages/plsql.formatter.ts | 2 +- test/plsql.test.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index a18076abde..4558255803 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -466,7 +466,7 @@ export default class PlSqlFormatter extends Formatter { stringTypes: PlSqlFormatter.stringTypes, indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: [':'], - specialWordChars: { any: '_$#.@' }, + specialWordChars: { any: '_$#' }, operators: PlSqlFormatter.operators, preprocess, }); diff --git a/test/plsql.test.ts b/test/plsql.test.ts index b1bb4c8c66..d2f80db172 100644 --- a/test/plsql.test.ts +++ b/test/plsql.test.ts @@ -49,17 +49,17 @@ describe('PlSqlFormatter', () => { `); }); - it('recognizes _, $, #, . and @ as part of identifiers', () => { - const result = format('SELECT my_col$1#, col.2@, type#, procedure$, user# FROM tbl\n'); + it('recognizes _, $, # as part of identifiers', () => { + const result = format('SELECT my_col$1#, col.a$, type#, procedure$, user# FROM tbl;'); expect(result).toBe(dedent` SELECT my_col$1#, - col.2@, + col.a$, type#, procedure$, user# FROM - tbl + tbl; `); }); From dde3c234e3e9f33dc0c6093a1ae07c36a3c161c3 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 11:39:33 +0300 Subject: [PATCH 066/334] Separate quoted identifiers from strings New token type: IDENT --- src/core/Tokenizer.ts | 8 +++- src/core/token.ts | 1 + src/languages/bigquery.formatter.ts | 4 +- src/languages/db2.formatter.ts | 4 +- src/languages/hive.formatter.ts | 4 +- src/languages/mariadb.formatter.ts | 4 +- src/languages/mysql.formatter.ts | 4 +- src/languages/n1ql.formatter.ts | 4 +- src/languages/plsql.formatter.ts | 4 +- src/languages/postgresql.formatter.ts | 4 +- src/languages/redshift.formatter.ts | 4 +- src/languages/spark.formatter.ts | 4 +- src/languages/sql.formatter.ts | 4 +- src/languages/sqlite.formatter.ts | 4 +- src/languages/tsql.formatter.ts | 4 +- test/bigquery.test.ts | 2 + test/db2.test.ts | 2 + test/features/identifiers.ts | 67 +++++++++++++++++++++++++++ test/features/operators.ts | 10 ---- test/features/strings.ts | 26 ----------- test/hive.test.ts | 2 + test/mariadb.test.ts | 2 + test/mysql.test.ts | 2 + test/n1ql.test.ts | 2 + test/options/param.ts | 43 ----------------- test/plsql.test.ts | 2 + test/postgresql.test.ts | 2 + test/redshift.test.ts | 2 + test/spark.test.ts | 2 + test/sql.test.ts | 2 + test/sqlite.test.ts | 2 + test/tsql.test.ts | 2 + 32 files changed, 139 insertions(+), 94 deletions(-) create mode 100644 test/features/identifiers.ts diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 66caad1fc9..bdd0fc33ae 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -16,6 +16,7 @@ interface TokenizerOptions { reservedBinaryCommands: string[]; reservedJoinConditions?: string[]; stringTypes: regexFactory.StringPatternType[]; + identifierTypes: regexFactory.StringPatternType[]; blockStart?: string[]; blockEnd?: string[]; indexedPlaceholderTypes?: string[]; @@ -44,7 +45,8 @@ export default class Tokenizer { * @param {string[]} cfg.reservedCommands - Words that are set to new line separately * @param {string[]} cfg.reservedBinaryCommands - Words that are top level but have no indentation * @param {string[]} cfg.reservedJoinConditions - ON and USING - * @param {string[]} cfg.stringTypes - string types to enable - "", '', ``, [], N'' + * @param {string[]} cfg.stringTypes - string types to enable - '', "", N'', ... + * @param {string[]} cfg.identifierTypes - identifier types to enable - "", ``, [], ... * @param {string[]} cfg.blockStart - Opening parentheses to enable, like (, [ * @param {string[]} cfg.blockEnd - Closing parentheses to enable, like ), ] * @param {string[]} cfg.indexedPlaceholderTypes - Prefixes for indexed placeholders, like ? @@ -62,6 +64,7 @@ export default class Tokenizer { const specialWordCharsAll = Object.values(cfg.specialWordChars ?? {}).join(''); this.REGEX_MAP = { [TokenType.WORD]: regexFactory.createWordRegex(cfg.specialWordChars), + [TokenType.IDENT]: regexFactory.createStringRegex(cfg.identifierTypes), [TokenType.STRING]: regexFactory.createStringRegex(cfg.stringTypes), [TokenType.RESERVED_KEYWORD]: regexFactory.createReservedWordRegex( cfg.reservedKeywords, @@ -116,7 +119,7 @@ export default class Tokenizer { ); this.STRING_NAMED_PLACEHOLDER_REGEX = regexFactory.createPlaceholderRegex( cfg.namedPlaceholderTypes ?? [], - regexFactory.createStringPattern(cfg.stringTypes) + regexFactory.createStringPattern(cfg.identifierTypes) ); } @@ -175,6 +178,7 @@ export default class Tokenizer { this.matchToken(TokenType.LINE_COMMENT)(input) || this.matchToken(TokenType.BLOCK_COMMENT)(input) || this.matchToken(TokenType.STRING)(input) || + this.matchToken(TokenType.IDENT)(input) || this.matchToken(TokenType.BLOCK_START)(input) || this.matchToken(TokenType.BLOCK_END)(input) || this.getPlaceholderToken(input) || diff --git a/src/core/token.ts b/src/core/token.ts index de20c15bc4..50fa62bfcb 100644 --- a/src/core/token.ts +++ b/src/core/token.ts @@ -1,6 +1,7 @@ /** Token type enum for all possible Token categories */ export enum TokenType { WORD = 'WORD', + IDENT = 'IDENT', STRING = 'STRING', RESERVED_KEYWORD = 'RESERVED_KEYWORD', RESERVED_LOGICAL_OPERATOR = 'RESERVED_LOGICAL_OPERATOR', diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index 673bd88969..b4ea87f76d 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -825,7 +825,8 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://cloud.google.com/bigquery/docs/reference/#standard-sql-reference export default class BigQueryFormatter extends Formatter { - static stringTypes: StringPatternType[] = ['""', "''", '``']; // add: '''''', """""" ; prefixes: r, b + static stringTypes: StringPatternType[] = ['""', "''"]; // add: '''''', """""" ; prefixes: r, b + static identifierTypes: StringPatternType[] = ['``']; static operators = ['>>', '<<', '||']; // TODO: handle trailing comma in select clause @@ -839,6 +840,7 @@ export default class BigQueryFormatter extends Formatter { ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), stringTypes: BigQueryFormatter.stringTypes, + identifierTypes: BigQueryFormatter.identifierTypes, indexedPlaceholderTypes: ['?'], lineCommentTypes: ['--', '#'], specialWordChars: { any: '_@$-' }, diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index f8ec66d284..409201de87 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -859,7 +859,8 @@ const reservedDependentClauses = ['WHEN', 'ELSE', 'ELSEIF']; // https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_72/db2/rbafzintro.htm export default class Db2Formatter extends Formatter { - static stringTypes: StringPatternType[] = [`""`, "''", '``', '[]', "x''"]; + static stringTypes: StringPatternType[] = ["''", "x''"]; + static identifierTypes: StringPatternType[] = [`""`, '``', '[]']; static operators = ['**', '!>', '!<', '||']; tokenizer() { @@ -872,6 +873,7 @@ export default class Db2Formatter extends Formatter { ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), stringTypes: Db2Formatter.stringTypes, + identifierTypes: Db2Formatter.identifierTypes, indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: [':'], specialWordChars: { any: '#@' }, diff --git a/src/languages/hive.formatter.ts b/src/languages/hive.formatter.ts index ed25cb431d..8332cd83af 100644 --- a/src/languages/hive.formatter.ts +++ b/src/languages/hive.formatter.ts @@ -614,7 +614,8 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://cwiki.apache.org/confluence/display/Hive/LanguageManual export default class HiveFormatter extends Formatter { - static stringTypes: StringPatternType[] = ['""', "''", '``']; + static stringTypes: StringPatternType[] = ['""', "''"]; + static identifierTypes: StringPatternType[] = ['``']; static operators = ['<=>', '==', '||']; tokenizer() { @@ -627,6 +628,7 @@ export default class HiveFormatter extends Formatter { ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), stringTypes: HiveFormatter.stringTypes, + identifierTypes: HiveFormatter.identifierTypes, indexedPlaceholderTypes: ['?'], operators: HiveFormatter.operators, }); diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index f945eaf6fd..dcd0345084 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1156,7 +1156,8 @@ const reservedDependentClauses = ['WHEN', 'ELSE', 'ELSEIF', 'ELSIF']; // For reference: https://mariadb.com/kb/en/sql-statements-structure/ export default class MariaDbFormatter extends Formatter { - static stringTypes: StringPatternType[] = ['``', "''", '""']; + static stringTypes: StringPatternType[] = ["''"]; + static identifierTypes: StringPatternType[] = ['``', '""']; static operators = [':=', '<<', '>>', '<=>', '&&', '||']; tokenizer() { @@ -1167,6 +1168,7 @@ export default class MariaDbFormatter extends Formatter { reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: MariaDbFormatter.stringTypes, + identifierTypes: MariaDbFormatter.identifierTypes, indexedPlaceholderTypes: ['?'], lineCommentTypes: ['--', '#'], specialWordChars: { prefix: '@' }, diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index 3613f156d7..7f1f96729a 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1319,7 +1319,8 @@ const reservedDependentClauses = ['WHEN', 'ELSE', 'ELSEIF']; // https://dev.mysql.com/doc/refman/8.0/en/ export default class MySqlFormatter extends Formatter { - static stringTypes: StringPatternType[] = ['``', "''", '""']; + static stringTypes: StringPatternType[] = ["''"]; + static identifierTypes: StringPatternType[] = ['``', '""']; static operators = [':=', '<<', '>>', '<=>', '&&', '||', '->', '->>']; tokenizer() { @@ -1330,6 +1331,7 @@ export default class MySqlFormatter extends Formatter { reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: MySqlFormatter.stringTypes, + identifierTypes: MySqlFormatter.identifierTypes, indexedPlaceholderTypes: ['?'], lineCommentTypes: ['--', '#'], specialWordChars: { prefix: '@:' }, diff --git a/src/languages/n1ql.formatter.ts b/src/languages/n1ql.formatter.ts index 32e54b56a0..1a5d6d4487 100644 --- a/src/languages/n1ql.formatter.ts +++ b/src/languages/n1ql.formatter.ts @@ -512,7 +512,8 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // For reference: http://docs.couchbase.com.s3-website-us-west-1.amazonaws.com/server/6.0/n1ql/n1ql-language-reference/index.html export default class N1qlFormatter extends Formatter { - static stringTypes: StringPatternType[] = [`""`, "''", '``']; + static stringTypes: StringPatternType[] = [`""`, "''"]; + static identifierTypes: StringPatternType[] = ['``']; static operators = ['==']; tokenizer() { @@ -523,6 +524,7 @@ export default class N1qlFormatter extends Formatter { reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: N1qlFormatter.stringTypes, + identifierTypes: N1qlFormatter.identifierTypes, blockStart: ['(', '[', '{'], blockEnd: [')', ']', '}'], namedPlaceholderTypes: ['$'], diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 4558255803..aa703b26bb 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -443,7 +443,8 @@ const reservedBinaryCommands = [ const reservedDependentClauses = ['WHEN', 'ELSE']; export default class PlSqlFormatter extends Formatter { - static stringTypes: StringPatternType[] = [`""`, "N''", "''", '``']; + static stringTypes: StringPatternType[] = ["N''", "''"]; + static identifierTypes: StringPatternType[] = [`""`, '``']; static operators = [ '||', '**', @@ -464,6 +465,7 @@ export default class PlSqlFormatter extends Formatter { reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe(reservedKeywords), stringTypes: PlSqlFormatter.stringTypes, + identifierTypes: PlSqlFormatter.identifierTypes, indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: [':'], specialWordChars: { any: '_$#' }, diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index 05df3a908f..3927db4a54 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1671,7 +1671,8 @@ const binaryOperators = [ // https://www.postgresql.org/docs/14/index.html export default class PostgreSqlFormatter extends Formatter { - static stringTypes: StringPatternType[] = [`""`, "''", "U&''", 'U&""', '$$', '``', "E''"]; + static stringTypes: StringPatternType[] = ["''", "U&''", '$$', "E''"]; + static identifierTypes: StringPatternType[] = [`""`, 'U&""', '``']; static operators = binaryOperators; tokenizer() { @@ -1684,6 +1685,7 @@ export default class PostgreSqlFormatter extends Formatter { ...reservedKeywords, ]), stringTypes: PostgreSqlFormatter.stringTypes, + identifierTypes: PostgreSqlFormatter.identifierTypes, indexedPlaceholderTypes: ['$'], namedPlaceholderTypes: [':'], operators: PostgreSqlFormatter.operators, diff --git a/src/languages/redshift.formatter.ts b/src/languages/redshift.formatter.ts index 7391f0db6d..faca3e9f8d 100644 --- a/src/languages/redshift.formatter.ts +++ b/src/languages/redshift.formatter.ts @@ -716,7 +716,8 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://docs.aws.amazon.com/redshift/latest/dg/cm_chap_SQLCommandRef.html export default class RedshiftFormatter extends Formatter { - static stringTypes: StringPatternType[] = [`""`, "''", '``']; + static stringTypes: StringPatternType[] = ["''"]; + static identifierTypes: StringPatternType[] = [`""`, '``']; static operators = ['|/', '||/', '<<', '>>', '||']; tokenizer() { @@ -729,6 +730,7 @@ export default class RedshiftFormatter extends Formatter { ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), stringTypes: RedshiftFormatter.stringTypes, + identifierTypes: RedshiftFormatter.identifierTypes, indexedPlaceholderTypes: ['?'], // XXX: Seems like redshift only supports $1, $2, $3 parameters, // but for some reason we list lots of types in here. diff --git a/src/languages/spark.formatter.ts b/src/languages/spark.formatter.ts index 129e7a8f89..57d66237e1 100644 --- a/src/languages/spark.formatter.ts +++ b/src/languages/spark.formatter.ts @@ -778,7 +778,8 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // http://spark.apache.org/docs/latest/sql-programming-guide.html export default class SparkFormatter extends Formatter { - static stringTypes: StringPatternType[] = [`""`, "''", '``', '{}']; + static stringTypes: StringPatternType[] = [`""`, "''"]; + static identifierTypes: StringPatternType[] = ['``', '{}']; static operators = ['<=>', '&&', '||', '==', '->']; tokenizer() { @@ -792,6 +793,7 @@ export default class SparkFormatter extends Formatter { ...reservedKeywords, ]), stringTypes: SparkFormatter.stringTypes, + identifierTypes: SparkFormatter.identifierTypes, indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: ['$'], operators: SparkFormatter.operators, diff --git a/src/languages/sql.formatter.ts b/src/languages/sql.formatter.ts index 9301b64d42..f9f4975346 100644 --- a/src/languages/sql.formatter.ts +++ b/src/languages/sql.formatter.ts @@ -370,7 +370,8 @@ const reservedBinaryCommands = [ const reservedDependentClauses = ['WHEN', 'ELSE']; export default class SqlFormatter extends Formatter { - static stringTypes: StringPatternType[] = [`""`, "''", '``']; + static stringTypes: StringPatternType[] = ["''"]; + static identifierTypes: StringPatternType[] = [`""`, '``']; static operators = []; tokenizer() { @@ -380,6 +381,7 @@ export default class SqlFormatter extends Formatter { reservedDependentClauses, reservedKeywords: dedupe(reservedKeywords), stringTypes: SqlFormatter.stringTypes, + identifierTypes: SqlFormatter.identifierTypes, indexedPlaceholderTypes: ['?'], }); } diff --git a/src/languages/sqlite.formatter.ts b/src/languages/sqlite.formatter.ts index ee2bd95b07..355c559b52 100644 --- a/src/languages/sqlite.formatter.ts +++ b/src/languages/sqlite.formatter.ts @@ -421,7 +421,8 @@ const reservedBinaryCommands = [ const reservedDependentClauses = ['WHEN', 'ELSE']; export default class SqliteFormatter extends Formatter { - static stringTypes: StringPatternType[] = [`""`, "''", '``', '[]']; + static stringTypes: StringPatternType[] = ["''"]; + static identifierTypes: StringPatternType[] = [`""`, '``', '[]']; // https://www.sqlite.org/lang_expr.html static operators = ['||', '<<', '>>', '==', '!=']; @@ -433,6 +434,7 @@ export default class SqliteFormatter extends Formatter { // https://www.sqlite.org/lang_keywords.html reservedKeywords: [...standardReservedWords, ...nonStandardSqliteReservedWords], stringTypes: SqliteFormatter.stringTypes, + identifierTypes: SqliteFormatter.identifierTypes, // https://www.sqlite.org/lang_expr.html#parameters indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: [':', '@', '$'], diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index 0db9b68c28..bc5515c9b9 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1232,7 +1232,8 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://docs.microsoft.com/en-us/sql/t-sql/language-reference?view=sql-server-ver15 export default class TSqlFormatter extends Formatter { - static stringTypes: StringPatternType[] = [`""`, "N''", "''", '[]', '``']; + static stringTypes: StringPatternType[] = ["N''", "''"]; + static identifierTypes: StringPatternType[] = [`""`, '[]', '``']; static operators = ['!<', '!>', '+=', '-=', '*=', '/=', '%=', '|=', '&=', '^=', '::']; tokenizer() { @@ -1245,6 +1246,7 @@ export default class TSqlFormatter extends Formatter { ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), stringTypes: TSqlFormatter.stringTypes, + identifierTypes: TSqlFormatter.identifierTypes, namedPlaceholderTypes: ['@'], specialWordChars: { any: '#@' }, operators: TSqlFormatter.operators, diff --git a/test/bigquery.test.ts b/test/bigquery.test.ts index dfb0e65ca1..32bd0a1dcb 100644 --- a/test/bigquery.test.ts +++ b/test/bigquery.test.ts @@ -12,6 +12,7 @@ import supportsOperators from './features/operators'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsIdentifiers from './features/identifiers'; describe('BigQueryFormatter', () => { const language = 'bigquery'; @@ -22,6 +23,7 @@ describe('BigQueryFormatter', () => { supportsCreateTable(format); supportsDeleteFrom(format); supportsStrings(format, BigQueryFormatter.stringTypes); + supportsIdentifiers(format, BigQueryFormatter.identifierTypes); supportsBetween(format); supportsSchema(format); supportsJoin(format, { without: ['NATURAL JOIN'] }); diff --git a/test/db2.test.ts b/test/db2.test.ts index d562d59e0a..984f956f75 100644 --- a/test/db2.test.ts +++ b/test/db2.test.ts @@ -14,6 +14,7 @@ import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsIdentifiers from './features/identifiers'; describe('Db2Formatter', () => { const language = 'db2'; @@ -26,6 +27,7 @@ describe('Db2Formatter', () => { supportsAlterTable(format); supportsDeleteFrom(format); supportsStrings(format, Db2Formatter.stringTypes); + supportsIdentifiers(format, Db2Formatter.identifierTypes); supportsBetween(format); supportsSchema(format); supportsOperators(format, Db2Formatter.operators); diff --git a/test/features/identifiers.ts b/test/features/identifiers.ts new file mode 100644 index 0000000000..f3e647b0f6 --- /dev/null +++ b/test/features/identifiers.ts @@ -0,0 +1,67 @@ +import { expect } from '@jest/globals'; +import dedent from 'dedent-js'; +import { FormatFn } from '../../src/sqlFormatter'; + +export default function supportsIdentifiers(format: FormatFn, identifierTypes: string[]) { + if (identifierTypes.includes('""')) { + it('supports double-quoted identifiers', () => { + expect(format('"foo JOIN bar"')).toBe('"foo JOIN bar"'); + expect(format('"foo \\" JOIN bar"')).toBe('"foo \\" JOIN bar"'); + expect(format('SELECT "where" FROM "update"')).toBe(dedent` + SELECT + "where" + FROM + "update" + `); + }); + } + + if (identifierTypes.includes('``')) { + it('supports backtick-quoted identifiers', () => { + expect(format('`foo JOIN bar`')).toBe('`foo JOIN bar`'); + expect(format('`foo `` JOIN bar`')).toBe('`foo `` JOIN bar`'); + expect(format('SELECT `where` FROM `update`')).toBe(dedent` + SELECT + \`where\` + FROM + \`update\` + `); + }); + + it('supports backticks', () => { + const result = format(`SELECT \`a\`.\`b\` FROM \`c\`.\`d\`;`); + expect(result).toBe(dedent` + SELECT + \`a\`.\`b\` + FROM + \`c\`.\`d\`; + `); + }); + } + + if (identifierTypes.includes('U&""')) { + it('supports unicode double-quoted identifiers', () => { + expect(format('U&"foo JOIN bar"')).toBe('U&"foo JOIN bar"'); + expect(format('U&"foo \\" JOIN bar"')).toBe('U&"foo \\" JOIN bar"'); + expect(format('SELECT U&"where" FROM U&"update"')).toBe(dedent` + SELECT + U&"where" + FROM + U&"update" + `); + }); + } + + if (identifierTypes.includes('[]')) { + it('supports [bracket-quoted identifiers]', () => { + expect(format('[foo JOIN bar]')).toBe('[foo JOIN bar]'); + expect(format('[foo ]] JOIN bar]')).toBe('[foo ]] JOIN bar]'); + expect(format('SELECT [where] FROM [update]')).toBe(dedent` + SELECT + [where] + FROM + [update] + `); + }); + } +} diff --git a/test/features/operators.ts b/test/features/operators.ts index 8b802f727d..6db6bb900d 100644 --- a/test/features/operators.ts +++ b/test/features/operators.ts @@ -29,16 +29,6 @@ export default function supportsOperators( }); }); - it('supports backticks', () => { - const result = format(`SELECT \`a\`.\`b\` FROM \`c\`.\`d\`;`); - expect(result).toBe(dedent` - SELECT - \`a\`.\`b\` - FROM - \`c\`.\`d\`; - `); - }); - it('supports braces', () => { const result = format(`SELECT $\{a} FROM $\{b};`); expect(result).toBe(dedent` diff --git a/test/features/strings.ts b/test/features/strings.ts index 00d8113cc1..aad9031594 100644 --- a/test/features/strings.ts +++ b/test/features/strings.ts @@ -29,19 +29,6 @@ export default function supportsStrings(format: FormatFn, stringTypes: string[]) }); } - if (stringTypes.includes('``')) { - it('supports backtick-quoted strings', () => { - expect(format('`foo JOIN bar`')).toBe('`foo JOIN bar`'); - expect(format('`foo `` JOIN bar`')).toBe('`foo `` JOIN bar`'); - expect(format('SELECT `where` FROM `update`')).toBe(dedent` - SELECT - \`where\` - FROM - \`update\` - `); - }); - } - if (stringTypes.includes('U&""')) { it('supports unicode double-quoted strings', () => { expect(format('U&"foo JOIN bar"')).toBe('U&"foo JOIN bar"'); @@ -85,19 +72,6 @@ export default function supportsStrings(format: FormatFn, stringTypes: string[]) }); } - if (stringTypes.includes('[]')) { - it('supports [bracket-quoted identifiers]', () => { - expect(format('[foo JOIN bar]')).toBe('[foo JOIN bar]'); - expect(format('[foo ]] JOIN bar]')).toBe('[foo ]] JOIN bar]'); - expect(format('SELECT [where] FROM [update]')).toBe(dedent` - SELECT - [where] - FROM - [update] - `); - }); - } - if (stringTypes.includes("N''")) { it('supports T-SQL unicode strings', () => { expect(format("N'foo JOIN bar'")).toBe("N'foo JOIN bar'"); diff --git a/test/hive.test.ts b/test/hive.test.ts index 8f0a2cd414..d62f4edb76 100644 --- a/test/hive.test.ts +++ b/test/hive.test.ts @@ -12,6 +12,7 @@ import supportsOperators from './features/operators'; import supportsArray from './features/array'; import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsIdentifiers from './features/identifiers'; describe('HiveFormatter', () => { const language = 'hive'; @@ -22,6 +23,7 @@ describe('HiveFormatter', () => { supportsCreateTable(format); supportsAlterTable(format); supportsStrings(format, HiveFormatter.stringTypes); + supportsIdentifiers(format, HiveFormatter.identifierTypes); supportsBetween(format); supportsSchema(format); supportsJoin(format, { without: ['NATURAL JOIN'] }); diff --git a/test/mariadb.test.ts b/test/mariadb.test.ts index 455db797c7..4b14e51d0a 100644 --- a/test/mariadb.test.ts +++ b/test/mariadb.test.ts @@ -5,6 +5,7 @@ import behavesLikeMariaDbFormatter from './behavesLikeMariaDbFormatter'; import supportsStrings from './features/strings'; import supportsOperators from './features/operators'; import supportsReturning from './features/returning'; +import supportsIdentifiers from './features/identifiers'; describe('MariaDbFormatter', () => { const language = 'mariadb'; @@ -13,6 +14,7 @@ describe('MariaDbFormatter', () => { behavesLikeMariaDbFormatter(format); supportsStrings(format, MariaDbFormatter.stringTypes); + supportsIdentifiers(format, MariaDbFormatter.identifierTypes); supportsOperators(format, MariaDbFormatter.operators, ['AND', 'OR', 'XOR']); supportsReturning(format); }); diff --git a/test/mysql.test.ts b/test/mysql.test.ts index 5ee17ec8e3..4e093b04b0 100644 --- a/test/mysql.test.ts +++ b/test/mysql.test.ts @@ -5,6 +5,7 @@ import behavesLikeMariaDbFormatter from './behavesLikeMariaDbFormatter'; import supportsStrings from './features/strings'; import supportsOperators from './features/operators'; +import supportsIdentifiers from './features/identifiers'; describe('MySqlFormatter', () => { const language = 'mysql'; @@ -13,6 +14,7 @@ describe('MySqlFormatter', () => { behavesLikeMariaDbFormatter(format); supportsStrings(format, MySqlFormatter.stringTypes); + supportsIdentifiers(format, MySqlFormatter.identifierTypes); supportsOperators(format, MySqlFormatter.operators, ['AND', 'OR', 'XOR']); it('supports @@ system variables', () => { diff --git a/test/n1ql.test.ts b/test/n1ql.test.ts index ff078c181f..269b0910ed 100644 --- a/test/n1ql.test.ts +++ b/test/n1ql.test.ts @@ -13,6 +13,7 @@ import supportsDeleteFrom from './features/deleteFrom'; import supportsArray from './features/array'; import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsIdentifiers from './features/identifiers'; describe('N1qlFormatter', () => { const language = 'n1ql'; @@ -22,6 +23,7 @@ describe('N1qlFormatter', () => { supportsComments(format, { hashComments: true }); supportsDeleteFrom(format); supportsStrings(format, N1qlFormatter.stringTypes); + supportsIdentifiers(format, N1qlFormatter.identifierTypes); supportsBetween(format); supportsSchema(format); supportsOperators(format, N1qlFormatter.operators, ['AND', 'OR', 'XOR']); diff --git a/test/options/param.ts b/test/options/param.ts index 881dfaa240..b28ff17956 100644 --- a/test/options/param.ts +++ b/test/options/param.ts @@ -105,27 +105,6 @@ export default function supportsParams(format: FormatFn, params: ParamsTypes) { AND age > 10; `); }); - - it(`recognizes :'name' and :"name" placeholders`, () => { - expect(format(`SELECT :'foo', :"bar", :"baz";`)).toBe(dedent` - SELECT - :'foo', - :"bar", - :"baz"; - `); - }); - - it(`replaces :'name' and :"name" placeholders with param values`, () => { - expect( - format(`WHERE name = :"name" AND age > :'current_age';`, { - params: { name: "'John'", current_age: '10' }, - }) - ).toBe(dedent` - WHERE - name = 'John' - AND age > 10; - `); - }); } if (params.named?.includes('$')) { @@ -150,28 +129,6 @@ export default function supportsParams(format: FormatFn, params: ParamsTypes) { `); }); - it(`recognizes $'name' and $"name" and $\`name\` placeholders`, () => { - expect(format(`SELECT $'foo', $"bar", $\`baz\`;`)).toBe(dedent` - SELECT - $'foo', - $"bar", - $\`baz\`; - `); - }); - - it(`replaces $'name' and $"name" and $\`name\` placeholders with param values`, () => { - expect( - format(`WHERE name = $"name" AND age > $'current_age' OR addr = $\`addr\`;`, { - params: { name: "'John'", current_age: '10', addr: "'Baker street'" }, - }) - ).toBe(dedent` - WHERE - name = 'John' - AND age > 10 - OR addr = 'Baker street'; - `); - }); - it('replaces $n numbered placeholders with param values', () => { const result = format('SELECT $1, $2, $0;', { params: { diff --git a/test/plsql.test.ts b/test/plsql.test.ts index d2f80db172..6d297b197c 100644 --- a/test/plsql.test.ts +++ b/test/plsql.test.ts @@ -16,6 +16,7 @@ import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsIdentifiers from './features/identifiers'; describe('PlSqlFormatter', () => { const language = 'plsql'; @@ -29,6 +30,7 @@ describe('PlSqlFormatter', () => { supportsAlterTableModify(format); supportsDeleteFrom(format); supportsStrings(format, PlSqlFormatter.stringTypes); + supportsIdentifiers(format, PlSqlFormatter.identifierTypes); supportsBetween(format); supportsSchema(format); supportsOperators(format, PlSqlFormatter.operators, ['AND', 'OR', 'XOR']); diff --git a/test/postgresql.test.ts b/test/postgresql.test.ts index 4b9be128a0..657001918b 100644 --- a/test/postgresql.test.ts +++ b/test/postgresql.test.ts @@ -14,6 +14,7 @@ import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsIdentifiers from './features/identifiers'; describe('PostgreSqlFormatter', () => { const language = 'postgresql'; @@ -26,6 +27,7 @@ describe('PostgreSqlFormatter', () => { supportsAlterTable(format); supportsDeleteFrom(format); supportsStrings(format, PostgreSqlFormatter.stringTypes); + supportsIdentifiers(format, PostgreSqlFormatter.identifierTypes); supportsBetween(format); supportsSchema(format); supportsOperators(format, PostgreSqlFormatter.operators); diff --git a/test/redshift.test.ts b/test/redshift.test.ts index 340e436038..90b5cabbd2 100644 --- a/test/redshift.test.ts +++ b/test/redshift.test.ts @@ -13,6 +13,7 @@ import supportsStrings from './features/strings'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsIdentifiers from './features/identifiers'; describe('RedshiftFormatter', () => { const language = 'redshift'; @@ -25,6 +26,7 @@ describe('RedshiftFormatter', () => { supportsAlterTableModify(format); supportsDeleteFrom(format); supportsStrings(format, RedshiftFormatter.stringTypes); + supportsIdentifiers(format, RedshiftFormatter.identifierTypes); supportsSchema(format); supportsOperators(format, RedshiftFormatter.operators); supportsJoin(format); diff --git a/test/spark.test.ts b/test/spark.test.ts index fb20ee1228..0f4239a589 100644 --- a/test/spark.test.ts +++ b/test/spark.test.ts @@ -13,6 +13,7 @@ import supportsStrings from './features/strings'; import supportsArray from './features/array'; import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsIdentifiers from './features/identifiers'; describe('SparkFormatter', () => { const language = 'spark'; @@ -23,6 +24,7 @@ describe('SparkFormatter', () => { supportsCreateTable(format); supportsAlterTable(format); supportsStrings(format, SparkFormatter.stringTypes); + supportsIdentifiers(format, SparkFormatter.identifierTypes); supportsBetween(format); supportsSchema(format); supportsOperators(format, SparkFormatter.operators, ['AND', 'OR', 'XOR']); diff --git a/test/sql.test.ts b/test/sql.test.ts index efb4557567..f6ba307339 100644 --- a/test/sql.test.ts +++ b/test/sql.test.ts @@ -14,6 +14,7 @@ import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsIdentifiers from './features/identifiers'; describe('SqlFormatter', () => { const language = 'sql'; @@ -26,6 +27,7 @@ describe('SqlFormatter', () => { supportsAlterTable(format); supportsDeleteFrom(format); supportsStrings(format, SqlFormatter.stringTypes); + supportsIdentifiers(format, SqlFormatter.identifierTypes); supportsBetween(format); supportsSchema(format); supportsJoin(format); diff --git a/test/sqlite.test.ts b/test/sqlite.test.ts index 1938d15c61..be6448be3c 100644 --- a/test/sqlite.test.ts +++ b/test/sqlite.test.ts @@ -14,6 +14,7 @@ import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsIdentifiers from './features/identifiers'; describe('SqliteFormatter', () => { const language = 'sqlite'; @@ -26,6 +27,7 @@ describe('SqliteFormatter', () => { supportsAlterTable(format); supportsDeleteFrom(format); supportsStrings(format, SqliteFormatter.stringTypes); + supportsIdentifiers(format, SqliteFormatter.identifierTypes); supportsBetween(format); supportsSchema(format); supportsJoin(format, { diff --git a/test/tsql.test.ts b/test/tsql.test.ts index 953f08bce3..54309cf4c7 100644 --- a/test/tsql.test.ts +++ b/test/tsql.test.ts @@ -14,6 +14,7 @@ import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsIdentifiers from './features/identifiers'; describe('TSqlFormatter', () => { const language = 'tsql'; @@ -26,6 +27,7 @@ describe('TSqlFormatter', () => { supportsAlterTable(format); supportsDeleteFrom(format); supportsStrings(format, TSqlFormatter.stringTypes); + supportsIdentifiers(format, TSqlFormatter.identifierTypes); supportsBetween(format); supportsSchema(format); supportsOperators(format, TSqlFormatter.operators); From 09425299af1dce50b0c24dd81fa8028297100079 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 11:51:25 +0300 Subject: [PATCH 067/334] Place by-default-disabled quotes in parenthesis --- sql/identifiers.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/identifiers.md b/sql/identifiers.md index 10ceea66a4..2b5f946a49 100644 --- a/sql/identifiers.md +++ b/sql/identifiers.md @@ -27,8 +27,8 @@ There is a considerable variation in implementations: - `` `..` `` [BigQuery][] - `".."` [DB2][] - `` `..` `` [Hive][] -- `` `..` ``, `".."`1, `[..]`2 [MariaDB][] -- `` `..` ``, `".."`1 [MySQL][] +- `` `..` ``, (`".."`1, `[..]`2) [MariaDB][] +- `` `..` ``, (`".."`1) [MySQL][] - `` `..` `` [N1QL][] - `".."` [PL/SQL][] - `".."`, `U&".."` [PostgreSQL][] From 9379e59f6ddcf168bc28dc9979e220cdecf2cd72 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 12:09:44 +0300 Subject: [PATCH 068/334] Remove unsupported identifier and string types --- src/languages/db2.formatter.ts | 2 +- src/languages/mariadb.formatter.ts | 4 ++-- src/languages/mysql.formatter.ts | 4 ++-- src/languages/n1ql.formatter.ts | 2 +- src/languages/plsql.formatter.ts | 4 ++-- src/languages/postgresql.formatter.ts | 2 +- src/languages/redshift.formatter.ts | 2 +- src/languages/spark.formatter.ts | 4 ++-- src/languages/tsql.formatter.ts | 2 +- test/options/keywordCase.ts | 4 ++-- test/spark.test.ts | 6 +++--- 11 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index 409201de87..107b46f182 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -860,7 +860,7 @@ const reservedDependentClauses = ['WHEN', 'ELSE', 'ELSEIF']; // https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_72/db2/rbafzintro.htm export default class Db2Formatter extends Formatter { static stringTypes: StringPatternType[] = ["''", "x''"]; - static identifierTypes: StringPatternType[] = [`""`, '``', '[]']; + static identifierTypes: StringPatternType[] = [`""`]; static operators = ['**', '!>', '!<', '||']; tokenizer() { diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index dcd0345084..51d568962a 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1156,8 +1156,8 @@ const reservedDependentClauses = ['WHEN', 'ELSE', 'ELSEIF', 'ELSIF']; // For reference: https://mariadb.com/kb/en/sql-statements-structure/ export default class MariaDbFormatter extends Formatter { - static stringTypes: StringPatternType[] = ["''"]; - static identifierTypes: StringPatternType[] = ['``', '""']; + static stringTypes: StringPatternType[] = ["''", '""']; + static identifierTypes: StringPatternType[] = ['``']; static operators = [':=', '<<', '>>', '<=>', '&&', '||']; tokenizer() { diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index 7f1f96729a..f4de1507e5 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1319,8 +1319,8 @@ const reservedDependentClauses = ['WHEN', 'ELSE', 'ELSEIF']; // https://dev.mysql.com/doc/refman/8.0/en/ export default class MySqlFormatter extends Formatter { - static stringTypes: StringPatternType[] = ["''"]; - static identifierTypes: StringPatternType[] = ['``', '""']; + static stringTypes: StringPatternType[] = ["''", '""']; + static identifierTypes: StringPatternType[] = ['``']; static operators = [':=', '<<', '>>', '<=>', '&&', '||', '->', '->>']; tokenizer() { diff --git a/src/languages/n1ql.formatter.ts b/src/languages/n1ql.formatter.ts index 1a5d6d4487..6c388586cd 100644 --- a/src/languages/n1ql.formatter.ts +++ b/src/languages/n1ql.formatter.ts @@ -512,7 +512,7 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // For reference: http://docs.couchbase.com.s3-website-us-west-1.amazonaws.com/server/6.0/n1ql/n1ql-language-reference/index.html export default class N1qlFormatter extends Formatter { - static stringTypes: StringPatternType[] = [`""`, "''"]; + static stringTypes: StringPatternType[] = [`""`, "''"]; // TODO: single quotes actually not supported in N1QL static identifierTypes: StringPatternType[] = ['``']; static operators = ['==']; diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index aa703b26bb..d666407b45 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -443,8 +443,8 @@ const reservedBinaryCommands = [ const reservedDependentClauses = ['WHEN', 'ELSE']; export default class PlSqlFormatter extends Formatter { - static stringTypes: StringPatternType[] = ["N''", "''"]; - static identifierTypes: StringPatternType[] = [`""`, '``']; + static stringTypes: StringPatternType[] = ["''", "N''"]; + static identifierTypes: StringPatternType[] = [`""`]; static operators = [ '||', '**', diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index 3927db4a54..c93b884f0b 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1672,7 +1672,7 @@ const binaryOperators = [ // https://www.postgresql.org/docs/14/index.html export default class PostgreSqlFormatter extends Formatter { static stringTypes: StringPatternType[] = ["''", "U&''", '$$', "E''"]; - static identifierTypes: StringPatternType[] = [`""`, 'U&""', '``']; + static identifierTypes: StringPatternType[] = [`""`, 'U&""']; static operators = binaryOperators; tokenizer() { diff --git a/src/languages/redshift.formatter.ts b/src/languages/redshift.formatter.ts index faca3e9f8d..61c57ee77d 100644 --- a/src/languages/redshift.formatter.ts +++ b/src/languages/redshift.formatter.ts @@ -717,7 +717,7 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://docs.aws.amazon.com/redshift/latest/dg/cm_chap_SQLCommandRef.html export default class RedshiftFormatter extends Formatter { static stringTypes: StringPatternType[] = ["''"]; - static identifierTypes: StringPatternType[] = [`""`, '``']; + static identifierTypes: StringPatternType[] = [`""`]; static operators = ['|/', '||/', '<<', '>>', '||']; tokenizer() { diff --git a/src/languages/spark.formatter.ts b/src/languages/spark.formatter.ts index 57d66237e1..8d2546e9cb 100644 --- a/src/languages/spark.formatter.ts +++ b/src/languages/spark.formatter.ts @@ -778,8 +778,8 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // http://spark.apache.org/docs/latest/sql-programming-guide.html export default class SparkFormatter extends Formatter { - static stringTypes: StringPatternType[] = [`""`, "''"]; - static identifierTypes: StringPatternType[] = ['``', '{}']; + static stringTypes: StringPatternType[] = ["''"]; + static identifierTypes: StringPatternType[] = ['``', '{}']; // TODO: the ${} syntax is currently used for placeholders, but prepared statements are actually not supported in Spark static operators = ['<=>', '&&', '||', '==', '->']; tokenizer() { diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index bc5515c9b9..ae862c2251 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1233,7 +1233,7 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://docs.microsoft.com/en-us/sql/t-sql/language-reference?view=sql-server-ver15 export default class TSqlFormatter extends Formatter { static stringTypes: StringPatternType[] = ["N''", "''"]; - static identifierTypes: StringPatternType[] = [`""`, '[]', '``']; + static identifierTypes: StringPatternType[] = [`""`, '[]']; static operators = ['!<', '!>', '+=', '-=', '*=', '/=', '%=', '|=', '&=', '^=', '::']; tokenizer() { diff --git a/test/options/keywordCase.ts b/test/options/keywordCase.ts index 84b398208a..f9a5f4f571 100644 --- a/test/options/keywordCase.ts +++ b/test/options/keywordCase.ts @@ -49,12 +49,12 @@ export default function supportsKeywordCase(format: FormatFn) { }); it('does not uppercase keywords inside strings', () => { - const result = format('select "distinct" as foo', { + const result = format(`select 'distinct' as foo`, { keywordCase: 'upper', }); expect(result).toBe(dedent` SELECT - "distinct" AS foo + 'distinct' AS foo `); }); } diff --git a/test/spark.test.ts b/test/spark.test.ts index 0f4239a589..2b42eb2daa 100644 --- a/test/spark.test.ts +++ b/test/spark.test.ts @@ -73,12 +73,12 @@ describe('SparkFormatter', () => { it('formats window function and end as inline', () => { const result = format( - 'SELECT window(time, "1 hour").start AS window_start, window(time, "1 hour").end AS window_end FROM tbl;' + `SELECT window(time, '1 hour').start AS window_start, window(time, '1 hour').end AS window_end FROM tbl;` ); expect(result).toBe(dedent` SELECT - window(time, "1 hour").start AS window_start, - window(time, "1 hour").end AS window_end + window(time, '1 hour').start AS window_start, + window(time, '1 hour').end AS window_end FROM tbl; `); From d1083d17a42a8dfeedf6b71ced53aff4c67125cb Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 12:16:33 +0300 Subject: [PATCH 069/334] Document single quotes support in N1QL --- src/languages/n1ql.formatter.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/languages/n1ql.formatter.ts b/src/languages/n1ql.formatter.ts index 6c388586cd..5e0c37f053 100644 --- a/src/languages/n1ql.formatter.ts +++ b/src/languages/n1ql.formatter.ts @@ -512,7 +512,10 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // For reference: http://docs.couchbase.com.s3-website-us-west-1.amazonaws.com/server/6.0/n1ql/n1ql-language-reference/index.html export default class N1qlFormatter extends Formatter { - static stringTypes: StringPatternType[] = [`""`, "''"]; // TODO: single quotes actually not supported in N1QL + // NOTE: single quotes are actually not supported in N1QL, + // but we support them anyway as all other SQL dialects do, + // which simplifies writing tests that are shared between all dialects. + static stringTypes: StringPatternType[] = [`""`, "''"]; static identifierTypes: StringPatternType[] = ['``']; static operators = ['==']; From 5cfe38b07073d605f96094c97a48f74c143698b2 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 12:23:34 +0300 Subject: [PATCH 070/334] Drop placeholder support from Hive and Spark Completely removing the ${} type of placeholders --- src/core/regexFactory.ts | 1 - src/languages/hive.formatter.ts | 1 - src/languages/spark.formatter.ts | 4 +--- test/hive.test.ts | 2 -- test/options/param.ts | 31 +------------------------------ test/spark.test.ts | 2 -- 6 files changed, 2 insertions(+), 39 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index b5f790d3aa..09a006de43 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -79,7 +79,6 @@ export const createWordRegex = ( // 8. PostgreSQL dollar-quoted strings const patterns = { '``': '((`[^`]*($|`))+)', - '{}': '((\\{[^\\}]*($|\\}))+)', '[]': '((\\[[^\\]]*($|\\]))(\\][^\\]]*($|\\]))*)', '""': '(("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+)', "''": "(('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+)", diff --git a/src/languages/hive.formatter.ts b/src/languages/hive.formatter.ts index 8332cd83af..36199d23c9 100644 --- a/src/languages/hive.formatter.ts +++ b/src/languages/hive.formatter.ts @@ -629,7 +629,6 @@ export default class HiveFormatter extends Formatter { ]), stringTypes: HiveFormatter.stringTypes, identifierTypes: HiveFormatter.identifierTypes, - indexedPlaceholderTypes: ['?'], operators: HiveFormatter.operators, }); } diff --git a/src/languages/spark.formatter.ts b/src/languages/spark.formatter.ts index 8d2546e9cb..8fe2f1b722 100644 --- a/src/languages/spark.formatter.ts +++ b/src/languages/spark.formatter.ts @@ -779,7 +779,7 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // http://spark.apache.org/docs/latest/sql-programming-guide.html export default class SparkFormatter extends Formatter { static stringTypes: StringPatternType[] = ["''"]; - static identifierTypes: StringPatternType[] = ['``', '{}']; // TODO: the ${} syntax is currently used for placeholders, but prepared statements are actually not supported in Spark + static identifierTypes: StringPatternType[] = ['``']; static operators = ['<=>', '&&', '||', '==', '->']; tokenizer() { @@ -794,8 +794,6 @@ export default class SparkFormatter extends Formatter { ]), stringTypes: SparkFormatter.stringTypes, identifierTypes: SparkFormatter.identifierTypes, - indexedPlaceholderTypes: ['?'], - namedPlaceholderTypes: ['$'], operators: SparkFormatter.operators, preprocess, }); diff --git a/test/hive.test.ts b/test/hive.test.ts index d62f4edb76..43ba8fbd15 100644 --- a/test/hive.test.ts +++ b/test/hive.test.ts @@ -10,7 +10,6 @@ import supportsBetween from './features/between'; import supportsJoin from './features/join'; import supportsOperators from './features/operators'; import supportsArray from './features/array'; -import supportsParams from './options/param'; import supportsComments from './features/comments'; import supportsIdentifiers from './features/identifiers'; @@ -29,5 +28,4 @@ describe('HiveFormatter', () => { supportsJoin(format, { without: ['NATURAL JOIN'] }); supportsOperators(format, HiveFormatter.operators); supportsArray(format); - supportsParams(format, { indexed: ['?'] }); }); diff --git a/test/options/param.ts b/test/options/param.ts index b28ff17956..bd3e8fcd90 100644 --- a/test/options/param.ts +++ b/test/options/param.ts @@ -3,7 +3,7 @@ import { FormatFn } from '../../src/sqlFormatter'; interface ParamsTypes { indexed?: ('?' | '$')[]; - named?: (':' | '$' | '${}' | '@' | '@""' | '@[]')[]; + named?: (':' | '$' | '@' | '@""' | '@[]')[]; } export default function supportsParams(format: FormatFn, params: ParamsTypes) { @@ -145,35 +145,6 @@ export default function supportsParams(format: FormatFn, params: ParamsTypes) { `); }); } - - if (params.named?.includes('${}')) { - // eslint-disable-next-line no-template-curly-in-string - it('recognizes ${name} placeholders', () => { - // eslint-disable-next-line no-template-curly-in-string - const result = format('SELECT ${var_name}, ${var name};'); - expect(result).toBe(dedent` - SELECT - \${var_name}, - \${var name}; - `); - }); - - // eslint-disable-next-line no-template-curly-in-string - it('replaces ${variables} with param values', () => { - // eslint-disable-next-line no-template-curly-in-string - const result = format('SELECT ${var 1}, ${var2};', { - params: { - 'var 1': "'var one'", - 'var2': "'var two'", - }, - }); - expect(result).toBe(dedent` - SELECT - 'var one', - 'var two'; - `); - }); - } }); if (params.named?.includes('@')) { diff --git a/test/spark.test.ts b/test/spark.test.ts index 2b42eb2daa..d6826f96b3 100644 --- a/test/spark.test.ts +++ b/test/spark.test.ts @@ -11,7 +11,6 @@ import supportsOperators from './features/operators'; import supportsSchema from './features/schema'; import supportsStrings from './features/strings'; import supportsArray from './features/array'; -import supportsParams from './options/param'; import supportsComments from './features/comments'; import supportsIdentifiers from './features/identifiers'; @@ -49,7 +48,6 @@ describe('SparkFormatter', () => { 'NATURAL SEMI JOIN', ], }); - supportsParams(format, { indexed: ['?'], named: ['$', '${}'] }); it('formats WINDOW specification as top level', () => { const result = format( From 2ec0a3879543037b1c27fcf3d36cc1fed333e19a Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 12:32:11 +0300 Subject: [PATCH 071/334] Throw error when params option used with Hive or Spark --- src/sqlFormatter.ts | 12 ++++++++++++ test/hive.test.ts | 6 ++++++ test/spark.test.ts | 6 ++++++ 3 files changed, 24 insertions(+) diff --git a/src/sqlFormatter.ts b/src/sqlFormatter.ts index e6febe62f9..4ef7e7aa49 100644 --- a/src/sqlFormatter.ts +++ b/src/sqlFormatter.ts @@ -98,6 +98,18 @@ function validateConfig(cfg: FormatFnOptions): FormatFnOptions { ); } + if (cfg.language === 'hive' && cfg.params !== undefined) { + throw new ConfigError( + 'Unexpected "params" option. Prepared statement placeholders not supported for Hive.' + ); + } + + if (cfg.language === 'spark' && cfg.params !== undefined) { + throw new ConfigError( + 'Unexpected "params" option. Prepared statement placeholders not supported for Spark.' + ); + } + return cfg; } diff --git a/test/hive.test.ts b/test/hive.test.ts index 43ba8fbd15..546b5c25d1 100644 --- a/test/hive.test.ts +++ b/test/hive.test.ts @@ -28,4 +28,10 @@ describe('HiveFormatter', () => { supportsJoin(format, { without: ['NATURAL JOIN'] }); supportsOperators(format, HiveFormatter.operators); supportsArray(format); + + it('throws error when params option used', () => { + expect(() => format('SELECT *', { params: ['1', '2', '3'] })).toThrow( + 'Unexpected "params" option. Prepared statement placeholders not supported for Hive.' + ); + }); }); diff --git a/test/spark.test.ts b/test/spark.test.ts index d6826f96b3..58da7edf08 100644 --- a/test/spark.test.ts +++ b/test/spark.test.ts @@ -81,4 +81,10 @@ describe('SparkFormatter', () => { tbl; `); }); + + it('throws error when params option used', () => { + expect(() => format('SELECT *', { params: ['1', '2', '3'] })).toThrow( + 'Unexpected "params" option. Prepared statement placeholders not supported for Spark.' + ); + }); }); From c777fa5fced3d856748a2d7943523a79f8d46d8f Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 12:33:53 +0300 Subject: [PATCH 072/334] Drop PL/SQL backtick-handling code No backtick-quoted identifiers available in PL/SQL any more. --- src/languages/plsql.formatter.ts | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index d666407b45..0b74352af3 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -478,16 +478,7 @@ export default class PlSqlFormatter extends Formatter { function preprocess(tokens: Token[]) { let previousReservedToken: Token = EOF_TOKEN; - return tokens.map((token, i) => { - const prevToken = tokens[i - 1] || EOF_TOKEN; - const nextToken = tokens[i + 1] || EOF_TOKEN; - - // `table`[.]`column` - if (token.value === '.' && nextToken.value.startsWith('`') && prevToken.value.endsWith('`')) { - // This is an operator, do not insert spaces - return { ...token, type: TokenType.OPERATOR }; - } - + return tokens.map(token => { // BY [SET] if (isToken.SET(token) && isToken.BY(previousReservedToken)) { return { ...token, type: TokenType.RESERVED_KEYWORD }; From d0b61ee79b9a6a557886140f59d5883111ab1efc Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 12:40:44 +0300 Subject: [PATCH 073/334] Repeat the dot-between-identifiers test for all quote types --- test/features/identifiers.ts | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/test/features/identifiers.ts b/test/features/identifiers.ts index f3e647b0f6..b33ddef9b6 100644 --- a/test/features/identifiers.ts +++ b/test/features/identifiers.ts @@ -14,6 +14,14 @@ export default function supportsIdentifiers(format: FormatFn, identifierTypes: s "update" `); }); + + it('no space around dot between two double-quoted identifiers', () => { + const result = format(`SELECT "my table"."col name";`); + expect(result).toBe(dedent` + SELECT + "my table"."col name"; + `); + }); } if (identifierTypes.includes('``')) { @@ -28,13 +36,11 @@ export default function supportsIdentifiers(format: FormatFn, identifierTypes: s `); }); - it('supports backticks', () => { - const result = format(`SELECT \`a\`.\`b\` FROM \`c\`.\`d\`;`); + it('no space around dot between two backtick-quoted identifiers', () => { + const result = format(`SELECT \`my table\`.\`col name\`;`); expect(result).toBe(dedent` SELECT - \`a\`.\`b\` - FROM - \`c\`.\`d\`; + \`my table\`.\`col name\`; `); }); } @@ -50,6 +56,14 @@ export default function supportsIdentifiers(format: FormatFn, identifierTypes: s U&"update" `); }); + + it('no space around dot between unicode double-quoted identifiers', () => { + const result = format(`SELECT U&"my table".U&"col name";`); + expect(result).toBe(dedent` + SELECT + U&"my table".U&"col name"; + `); + }); } if (identifierTypes.includes('[]')) { @@ -63,5 +77,13 @@ export default function supportsIdentifiers(format: FormatFn, identifierTypes: s [update] `); }); + + it('no space around dot between two [bracket-quoted identifiers]', () => { + const result = format(`SELECT [my table].[col name];`); + expect(result).toBe(dedent` + SELECT + [my table].[col name]; + `); + }); } } From 7454308b5b4f1de7f7a6ff5d16f01ed12f345d3b Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 12:52:37 +0300 Subject: [PATCH 074/334] Replace long token-type if-else with switch --- src/core/StatementFormatter.ts | 83 +++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 31 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 91f3f8ef6b..d211f95085 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -51,37 +51,58 @@ export default class StatementFormatter { } } - if (token.type === TokenType.LINE_COMMENT) { - this.formatLineComment(token); - } else if (token.type === TokenType.BLOCK_COMMENT) { - this.formatBlockComment(token); - } else if (token.type === TokenType.RESERVED_COMMAND) { - this.currentNewline = this.checkNewline(token); - this.formatCommand(token); - } else if (token.type === TokenType.RESERVED_BINARY_COMMAND) { - this.formatBinaryCommand(token); - } else if (token.type === TokenType.RESERVED_DEPENDENT_CLAUSE) { - this.formatDependentClause(token); - } else if (token.type === TokenType.RESERVED_JOIN_CONDITION) { - this.formatJoinCondition(token); - } else if (token.type === TokenType.RESERVED_LOGICAL_OPERATOR) { - this.formatLogicalOperator(token); - } else if (token.type === TokenType.RESERVED_KEYWORD) { - this.formatKeyword(token); - } else if (token.type === TokenType.BLOCK_START) { - this.formatBlockStart(token); - } else if (token.type === TokenType.BLOCK_END) { - this.formatBlockEnd(token); - } else if (token.type === TokenType.RESERVED_CASE_START) { - this.formatCaseStart(token); - } else if (token.type === TokenType.RESERVED_CASE_END) { - this.formatCaseEnd(token); - } else if (token.type === TokenType.PLACEHOLDER) { - this.formatPlaceholder(token); - } else if (token.type === TokenType.OPERATOR) { - this.formatOperator(token); - } else { - this.formatWord(token); + switch (token.type) { + case TokenType.LINE_COMMENT: + this.formatLineComment(token); + break; + case TokenType.BLOCK_COMMENT: + this.formatBlockComment(token); + break; + case TokenType.RESERVED_COMMAND: + this.currentNewline = this.checkNewline(token); + this.formatCommand(token); + break; + case TokenType.RESERVED_BINARY_COMMAND: + this.formatBinaryCommand(token); + break; + case TokenType.RESERVED_DEPENDENT_CLAUSE: + this.formatDependentClause(token); + break; + case TokenType.RESERVED_JOIN_CONDITION: + this.formatJoinCondition(token); + break; + case TokenType.RESERVED_LOGICAL_OPERATOR: + this.formatLogicalOperator(token); + break; + case TokenType.RESERVED_KEYWORD: + this.formatKeyword(token); + break; + case TokenType.BLOCK_START: + this.formatBlockStart(token); + break; + case TokenType.BLOCK_END: + this.formatBlockEnd(token); + break; + case TokenType.RESERVED_CASE_START: + this.formatCaseStart(token); + break; + case TokenType.RESERVED_CASE_END: + this.formatCaseEnd(token); + break; + case TokenType.PLACEHOLDER: + this.formatPlaceholder(token); + break; + case TokenType.OPERATOR: + this.formatOperator(token); + break; + case TokenType.WORD: + case TokenType.IDENT: + case TokenType.STRING: + case TokenType.NUMBER: + this.formatWord(token); + break; + default: + throw new Error(`Unexpected token type: ${token.type}`); } } return this.query.toString(); From 48fc357c9d9a9822aff895e4f20779471ea0fa96 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 12:54:37 +0300 Subject: [PATCH 075/334] Extract the long switch to separate method --- src/core/StatementFormatter.ts | 95 +++++++++++++++------------------- 1 file changed, 42 insertions(+), 53 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index d211f95085..5f4fe88ab5 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -51,63 +51,52 @@ export default class StatementFormatter { } } - switch (token.type) { - case TokenType.LINE_COMMENT: - this.formatLineComment(token); - break; - case TokenType.BLOCK_COMMENT: - this.formatBlockComment(token); - break; - case TokenType.RESERVED_COMMAND: - this.currentNewline = this.checkNewline(token); - this.formatCommand(token); - break; - case TokenType.RESERVED_BINARY_COMMAND: - this.formatBinaryCommand(token); - break; - case TokenType.RESERVED_DEPENDENT_CLAUSE: - this.formatDependentClause(token); - break; - case TokenType.RESERVED_JOIN_CONDITION: - this.formatJoinCondition(token); - break; - case TokenType.RESERVED_LOGICAL_OPERATOR: - this.formatLogicalOperator(token); - break; - case TokenType.RESERVED_KEYWORD: - this.formatKeyword(token); - break; - case TokenType.BLOCK_START: - this.formatBlockStart(token); - break; - case TokenType.BLOCK_END: - this.formatBlockEnd(token); - break; - case TokenType.RESERVED_CASE_START: - this.formatCaseStart(token); - break; - case TokenType.RESERVED_CASE_END: - this.formatCaseEnd(token); - break; - case TokenType.PLACEHOLDER: - this.formatPlaceholder(token); - break; - case TokenType.OPERATOR: - this.formatOperator(token); - break; - case TokenType.WORD: - case TokenType.IDENT: - case TokenType.STRING: - case TokenType.NUMBER: - this.formatWord(token); - break; - default: - throw new Error(`Unexpected token type: ${token.type}`); - } + this.formatToken(token); } return this.query.toString(); } + private formatToken(token: Token): void { + switch (token.type) { + case TokenType.LINE_COMMENT: + return this.formatLineComment(token); + case TokenType.BLOCK_COMMENT: + return this.formatBlockComment(token); + case TokenType.RESERVED_COMMAND: + this.currentNewline = this.checkNewline(token); + return this.formatCommand(token); + case TokenType.RESERVED_BINARY_COMMAND: + return this.formatBinaryCommand(token); + case TokenType.RESERVED_DEPENDENT_CLAUSE: + return this.formatDependentClause(token); + case TokenType.RESERVED_JOIN_CONDITION: + return this.formatJoinCondition(token); + case TokenType.RESERVED_LOGICAL_OPERATOR: + return this.formatLogicalOperator(token); + case TokenType.RESERVED_KEYWORD: + return this.formatKeyword(token); + case TokenType.BLOCK_START: + return this.formatBlockStart(token); + case TokenType.BLOCK_END: + return this.formatBlockEnd(token); + case TokenType.RESERVED_CASE_START: + return this.formatCaseStart(token); + case TokenType.RESERVED_CASE_END: + return this.formatCaseEnd(token); + case TokenType.PLACEHOLDER: + return this.formatPlaceholder(token); + case TokenType.OPERATOR: + return this.formatOperator(token); + case TokenType.WORD: + case TokenType.IDENT: + case TokenType.STRING: + case TokenType.NUMBER: + return this.formatWord(token); + default: + throw new Error(`Unexpected token type: ${token.type}`); + } + } + /** * Formats word tokens + any potential AS tokens for aliases */ From a44de04b6c103ad82fc986480f8175b6502b9623 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 14:25:50 +0300 Subject: [PATCH 076/334] Extract extra pair of parens out of string regexes --- src/core/regexFactory.ts | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 09a006de43..3d5a0d50bf 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -78,25 +78,27 @@ export const createWordRegex = ( // 7. Unicode double-quoted string using \" to escape // 8. PostgreSQL dollar-quoted strings const patterns = { - '``': '((`[^`]*($|`))+)', - '[]': '((\\[[^\\]]*($|\\]))(\\][^\\]]*($|\\]))*)', - '""': '(("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+)', - "''": "(('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+)", - "N''": "((N'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+)", - "x''": "(([xX]'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+)", - "E''": "((E'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+)", - "U&''": "((U&'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+)", - 'U&""': '((U&"[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+)', - '$$': '((?\\$\\w*\\$)[\\s\\S]*?(?:\\k|$))', + '``': '(`[^`]*($|`))+', + '[]': '(\\[[^\\]]*($|\\]))(\\][^\\]]*($|\\]))*', + '""': '("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+', + "''": "('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", + "N''": "(N'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", + "x''": "([xX]'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", + "E''": "(E'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", + "U&''": "(U&'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", + 'U&""': '(U&"[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+', + '$$': '(?\\$\\w*\\$)[\\s\\S]*?(?:\\k|$)', }; export type StringPatternType = keyof typeof patterns; +const createQuotePattern = (type: StringPatternType): string => '(' + patterns[type] + ')'; + /** * Builds a string pattern for matching string patterns for all given string types * @param {StringPatternType[]} stringTypes - list of strings that denote string patterns */ export const createStringPattern = (stringTypes: StringPatternType[]): string => - stringTypes.map(t => patterns[t]).join('|'); + stringTypes.map(createQuotePattern).join('|'); /** * Builds a RegExp for matching string patterns using `createStringPattern` From 738cfb80eee2fb479feda668aef516b35315f074 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 14:29:31 +0300 Subject: [PATCH 077/334] Rename x'' to X'' The uppercase version is the one defined by SQL standard. --- src/core/regexFactory.ts | 2 +- src/languages/db2.formatter.ts | 2 +- test/features/strings.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 3d5a0d50bf..93c6895a17 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -83,7 +83,7 @@ const patterns = { '""': '("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+', "''": "('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", "N''": "(N'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", - "x''": "([xX]'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", + "X''": "([xX]'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", "E''": "(E'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", "U&''": "(U&'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", 'U&""': '(U&"[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+', diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index 107b46f182..7fe08a546c 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -859,7 +859,7 @@ const reservedDependentClauses = ['WHEN', 'ELSE', 'ELSEIF']; // https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_72/db2/rbafzintro.htm export default class Db2Formatter extends Formatter { - static stringTypes: StringPatternType[] = ["''", "x''"]; + static stringTypes: StringPatternType[] = ["''", "X''"]; static identifierTypes: StringPatternType[] = [`""`]; static operators = ['**', '!>', '!<', '||']; diff --git a/test/features/strings.ts b/test/features/strings.ts index aad9031594..7653e740b0 100644 --- a/test/features/strings.ts +++ b/test/features/strings.ts @@ -85,7 +85,7 @@ export default function supportsStrings(format: FormatFn, stringTypes: string[]) }); } - if (stringTypes.includes("x''")) { + if (stringTypes.includes("X''")) { it('supports hex byte sequences', () => { expect(format("x'0E'")).toBe("x'0E'"); expect(format("X'1F0A89C3'")).toBe("X'1F0A89C3'"); From 5a151df0f85902c9b9e773b8dbfb1afad61ede65 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 14:35:39 +0300 Subject: [PATCH 078/334] Move prefixes in front of string patterns This fixes #211, which caused detecting the following as single string: U'blah'U'zah' --- src/core/regexFactory.ts | 10 +++++----- test/features/identifiers.ts | 8 ++++++++ test/features/strings.ts | 24 ++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 93c6895a17..d618f802fe 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -82,11 +82,11 @@ const patterns = { '[]': '(\\[[^\\]]*($|\\]))(\\][^\\]]*($|\\]))*', '""': '("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+', "''": "('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", - "N''": "(N'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", - "X''": "([xX]'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", - "E''": "(E'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", - "U&''": "(U&'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", - 'U&""': '(U&"[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+', + "N''": "N('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", + "X''": "[xX]('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", + "E''": "E('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", + "U&''": "U&('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", + 'U&""': 'U&("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+', '$$': '(?\\$\\w*\\$)[\\s\\S]*?(?:\\k|$)', }; export type StringPatternType = keyof typeof patterns; diff --git a/test/features/identifiers.ts b/test/features/identifiers.ts index b33ddef9b6..f4821f3b66 100644 --- a/test/features/identifiers.ts +++ b/test/features/identifiers.ts @@ -22,6 +22,10 @@ export default function supportsIdentifiers(format: FormatFn, identifierTypes: s "my table"."col name"; `); }); + + it('supports escaping double-quote by doubling it', () => { + expect(format('"foo""bar"')).toBe('"foo""bar"'); + }); } if (identifierTypes.includes('``')) { @@ -64,6 +68,10 @@ export default function supportsIdentifiers(format: FormatFn, identifierTypes: s U&"my table".U&"col name"; `); }); + + it('detects consequitive U&"" identifiers as separate ones', () => { + expect(format('U&"foo"U&"bar"')).toBe('U&"foo" U&"bar"'); + }); } if (identifierTypes.includes('[]')) { diff --git a/test/features/strings.ts b/test/features/strings.ts index 7653e740b0..d569e045a3 100644 --- a/test/features/strings.ts +++ b/test/features/strings.ts @@ -14,6 +14,10 @@ export default function supportsStrings(format: FormatFn, stringTypes: string[]) "update" `); }); + + it('supports escaping double-quote by doubling it', () => { + expect(format('"foo""bar"')).toBe('"foo""bar"'); + }); } if (stringTypes.includes("''")) { @@ -27,6 +31,10 @@ export default function supportsStrings(format: FormatFn, stringTypes: string[]) 'update' `); }); + + it('supports escaping single-quote by doubling it', () => { + expect(format("'foo''bar'")).toBe("'foo''bar'"); + }); } if (stringTypes.includes('U&""')) { @@ -40,6 +48,10 @@ export default function supportsStrings(format: FormatFn, stringTypes: string[]) U&"update" `); }); + + it("detects consequitive U&'' strings as separate ones", () => { + expect(format("U&'foo'U&'bar'")).toBe("U&'foo' U&'bar'"); + }); } if (stringTypes.includes("U&''")) { @@ -83,6 +95,10 @@ export default function supportsStrings(format: FormatFn, stringTypes: string[]) N'update' `); }); + + it("detects consequitive N'' strings as separate ones", () => { + expect(format("N'foo'N'bar'")).toBe("N'foo' N'bar'"); + }); } if (stringTypes.includes("X''")) { @@ -96,6 +112,10 @@ export default function supportsStrings(format: FormatFn, stringTypes: string[]) foo `); }); + + it("detects consequitive X'' strings as separate ones", () => { + expect(format("X'AE01'X'01F6'")).toBe("X'AE01' X'01F6'"); + }); } if (stringTypes.includes("E''")) { @@ -109,5 +129,9 @@ export default function supportsStrings(format: FormatFn, stringTypes: string[]) foo `); }); + + it("detects consequitive E'' strings as separate ones", () => { + expect(format("E'foo'E'bar'")).toBe("E'foo' E'bar'"); + }); } } From 10c9102396014b43421010964fb8c3f08cec336e Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 15:34:31 +0300 Subject: [PATCH 079/334] Decouple string/identifier tests from implementation It's a bit of duplication, but allows us to have different test logic from implementation logic. Already making use of this difference in N1QL tests where we don't actually need to test for single-quotes support, as N1QL doesn't support it, but for simplicity our implementation does. This will also open door to writing tests before implementation. --- test/bigquery.test.ts | 4 ++-- test/db2.test.ts | 4 ++-- test/hive.test.ts | 4 ++-- test/mariadb.test.ts | 4 ++-- test/mysql.test.ts | 4 ++-- test/n1ql.test.ts | 4 ++-- test/plsql.test.ts | 4 ++-- test/postgresql.test.ts | 4 ++-- test/redshift.test.ts | 4 ++-- test/spark.test.ts | 4 ++-- test/sql.test.ts | 4 ++-- test/sqlite.test.ts | 4 ++-- test/tsql.test.ts | 4 ++-- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/test/bigquery.test.ts b/test/bigquery.test.ts index 32bd0a1dcb..8aef9f42dd 100644 --- a/test/bigquery.test.ts +++ b/test/bigquery.test.ts @@ -22,8 +22,8 @@ describe('BigQueryFormatter', () => { supportsComments(format, { hashComments: true, skipTrickyCommentsTest: true }); supportsCreateTable(format); supportsDeleteFrom(format); - supportsStrings(format, BigQueryFormatter.stringTypes); - supportsIdentifiers(format, BigQueryFormatter.identifierTypes); + supportsStrings(format, ['""', "''"]); + supportsIdentifiers(format, ['``']); supportsBetween(format); supportsSchema(format); supportsJoin(format, { without: ['NATURAL JOIN'] }); diff --git a/test/db2.test.ts b/test/db2.test.ts index 984f956f75..7d36c9a3ea 100644 --- a/test/db2.test.ts +++ b/test/db2.test.ts @@ -26,8 +26,8 @@ describe('Db2Formatter', () => { supportsConstraints(format); supportsAlterTable(format); supportsDeleteFrom(format); - supportsStrings(format, Db2Formatter.stringTypes); - supportsIdentifiers(format, Db2Formatter.identifierTypes); + supportsStrings(format, ["''", "X''"]); + supportsIdentifiers(format, [`""`]); supportsBetween(format); supportsSchema(format); supportsOperators(format, Db2Formatter.operators); diff --git a/test/hive.test.ts b/test/hive.test.ts index 546b5c25d1..a515ca61c7 100644 --- a/test/hive.test.ts +++ b/test/hive.test.ts @@ -21,8 +21,8 @@ describe('HiveFormatter', () => { supportsComments(format); supportsCreateTable(format); supportsAlterTable(format); - supportsStrings(format, HiveFormatter.stringTypes); - supportsIdentifiers(format, HiveFormatter.identifierTypes); + supportsStrings(format, ['""', "''"]); + supportsIdentifiers(format, ['``']); supportsBetween(format); supportsSchema(format); supportsJoin(format, { without: ['NATURAL JOIN'] }); diff --git a/test/mariadb.test.ts b/test/mariadb.test.ts index 4b14e51d0a..e6dfbd8312 100644 --- a/test/mariadb.test.ts +++ b/test/mariadb.test.ts @@ -13,8 +13,8 @@ describe('MariaDbFormatter', () => { behavesLikeMariaDbFormatter(format); - supportsStrings(format, MariaDbFormatter.stringTypes); - supportsIdentifiers(format, MariaDbFormatter.identifierTypes); + supportsStrings(format, ["''", '""']); + supportsIdentifiers(format, ['``']); supportsOperators(format, MariaDbFormatter.operators, ['AND', 'OR', 'XOR']); supportsReturning(format); }); diff --git a/test/mysql.test.ts b/test/mysql.test.ts index 4e093b04b0..25e20352b7 100644 --- a/test/mysql.test.ts +++ b/test/mysql.test.ts @@ -13,8 +13,8 @@ describe('MySqlFormatter', () => { behavesLikeMariaDbFormatter(format); - supportsStrings(format, MySqlFormatter.stringTypes); - supportsIdentifiers(format, MySqlFormatter.identifierTypes); + supportsStrings(format, ["''", '""']); + supportsIdentifiers(format, ['``']); supportsOperators(format, MySqlFormatter.operators, ['AND', 'OR', 'XOR']); it('supports @@ system variables', () => { diff --git a/test/n1ql.test.ts b/test/n1ql.test.ts index 269b0910ed..1c7adbd46e 100644 --- a/test/n1ql.test.ts +++ b/test/n1ql.test.ts @@ -22,8 +22,8 @@ describe('N1qlFormatter', () => { behavesLikeSqlFormatter(format); supportsComments(format, { hashComments: true }); supportsDeleteFrom(format); - supportsStrings(format, N1qlFormatter.stringTypes); - supportsIdentifiers(format, N1qlFormatter.identifierTypes); + supportsStrings(format, [`""`]); + supportsIdentifiers(format, ['``']); supportsBetween(format); supportsSchema(format); supportsOperators(format, N1qlFormatter.operators, ['AND', 'OR', 'XOR']); diff --git a/test/plsql.test.ts b/test/plsql.test.ts index 6d297b197c..fbff3a9844 100644 --- a/test/plsql.test.ts +++ b/test/plsql.test.ts @@ -29,8 +29,8 @@ describe('PlSqlFormatter', () => { supportsAlterTable(format); supportsAlterTableModify(format); supportsDeleteFrom(format); - supportsStrings(format, PlSqlFormatter.stringTypes); - supportsIdentifiers(format, PlSqlFormatter.identifierTypes); + supportsStrings(format, ["''", "N''"]); + supportsIdentifiers(format, [`""`]); supportsBetween(format); supportsSchema(format); supportsOperators(format, PlSqlFormatter.operators, ['AND', 'OR', 'XOR']); diff --git a/test/postgresql.test.ts b/test/postgresql.test.ts index 657001918b..a0bcf2c3ed 100644 --- a/test/postgresql.test.ts +++ b/test/postgresql.test.ts @@ -26,8 +26,8 @@ describe('PostgreSqlFormatter', () => { supportsConstraints(format); supportsAlterTable(format); supportsDeleteFrom(format); - supportsStrings(format, PostgreSqlFormatter.stringTypes); - supportsIdentifiers(format, PostgreSqlFormatter.identifierTypes); + supportsStrings(format, ["''", "U&''", '$$', "E''"]); + supportsIdentifiers(format, [`""`, 'U&""']); supportsBetween(format); supportsSchema(format); supportsOperators(format, PostgreSqlFormatter.operators); diff --git a/test/redshift.test.ts b/test/redshift.test.ts index 90b5cabbd2..7d577dd445 100644 --- a/test/redshift.test.ts +++ b/test/redshift.test.ts @@ -25,8 +25,8 @@ describe('RedshiftFormatter', () => { supportsAlterTable(format); supportsAlterTableModify(format); supportsDeleteFrom(format); - supportsStrings(format, RedshiftFormatter.stringTypes); - supportsIdentifiers(format, RedshiftFormatter.identifierTypes); + supportsStrings(format, ["''"]); + supportsIdentifiers(format, [`""`]); supportsSchema(format); supportsOperators(format, RedshiftFormatter.operators); supportsJoin(format); diff --git a/test/spark.test.ts b/test/spark.test.ts index 58da7edf08..2568f703d2 100644 --- a/test/spark.test.ts +++ b/test/spark.test.ts @@ -22,8 +22,8 @@ describe('SparkFormatter', () => { supportsComments(format); supportsCreateTable(format); supportsAlterTable(format); - supportsStrings(format, SparkFormatter.stringTypes); - supportsIdentifiers(format, SparkFormatter.identifierTypes); + supportsStrings(format, ["''"]); + supportsIdentifiers(format, ['``']); supportsBetween(format); supportsSchema(format); supportsOperators(format, SparkFormatter.operators, ['AND', 'OR', 'XOR']); diff --git a/test/sql.test.ts b/test/sql.test.ts index f6ba307339..f69a2368a4 100644 --- a/test/sql.test.ts +++ b/test/sql.test.ts @@ -26,8 +26,8 @@ describe('SqlFormatter', () => { supportsConstraints(format); supportsAlterTable(format); supportsDeleteFrom(format); - supportsStrings(format, SqlFormatter.stringTypes); - supportsIdentifiers(format, SqlFormatter.identifierTypes); + supportsStrings(format, ["''"]); + supportsIdentifiers(format, [`""`, '``']); supportsBetween(format); supportsSchema(format); supportsJoin(format); diff --git a/test/sqlite.test.ts b/test/sqlite.test.ts index be6448be3c..ee69d504b4 100644 --- a/test/sqlite.test.ts +++ b/test/sqlite.test.ts @@ -26,8 +26,8 @@ describe('SqliteFormatter', () => { supportsConstraints(format); supportsAlterTable(format); supportsDeleteFrom(format); - supportsStrings(format, SqliteFormatter.stringTypes); - supportsIdentifiers(format, SqliteFormatter.identifierTypes); + supportsStrings(format, ["''"]); + supportsIdentifiers(format, [`""`, '``', '[]']); supportsBetween(format); supportsSchema(format); supportsJoin(format, { diff --git a/test/tsql.test.ts b/test/tsql.test.ts index 54309cf4c7..fbe8a8ad30 100644 --- a/test/tsql.test.ts +++ b/test/tsql.test.ts @@ -26,8 +26,8 @@ describe('TSqlFormatter', () => { supportsConstraints(format); supportsAlterTable(format); supportsDeleteFrom(format); - supportsStrings(format, TSqlFormatter.stringTypes); - supportsIdentifiers(format, TSqlFormatter.identifierTypes); + supportsStrings(format, ["N''", "''"]); + supportsIdentifiers(format, [`""`, '[]']); supportsBetween(format); supportsSchema(format); supportsOperators(format, TSqlFormatter.operators); From b1042f21e4e69ce0d3ee67db418fcf34f63a69c1 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 15:42:20 +0300 Subject: [PATCH 080/334] Better types for identifier and string tests --- test/features/identifiers.ts | 4 +++- test/features/strings.ts | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/test/features/identifiers.ts b/test/features/identifiers.ts index f4821f3b66..8c0267defa 100644 --- a/test/features/identifiers.ts +++ b/test/features/identifiers.ts @@ -2,7 +2,9 @@ import { expect } from '@jest/globals'; import dedent from 'dedent-js'; import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsIdentifiers(format: FormatFn, identifierTypes: string[]) { +type IdentType = '""' | '``' | '[]' | 'U&""'; + +export default function supportsIdentifiers(format: FormatFn, identifierTypes: IdentType[]) { if (identifierTypes.includes('""')) { it('supports double-quoted identifiers', () => { expect(format('"foo JOIN bar"')).toBe('"foo JOIN bar"'); diff --git a/test/features/strings.ts b/test/features/strings.ts index d569e045a3..f6c1938a51 100644 --- a/test/features/strings.ts +++ b/test/features/strings.ts @@ -2,7 +2,9 @@ import { expect } from '@jest/globals'; import dedent from 'dedent-js'; import { FormatFn } from '../../src/sqlFormatter'; -export default function supportsStrings(format: FormatFn, stringTypes: string[]) { +type StringType = '""' | "''" | 'U&""' | "U&''" | '$$' | "N''" | "X''" | "E''"; + +export default function supportsStrings(format: FormatFn, stringTypes: StringType[]) { if (stringTypes.includes('""')) { it('supports double-quoted strings', () => { expect(format('"foo JOIN bar"')).toBe('"foo JOIN bar"'); From 7bc8d1d0ee0f8e19093925d929adbe4b0bcd21a3 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 15:50:22 +0300 Subject: [PATCH 081/334] Inline string/ident static fields in *Formatter classes --- src/languages/bigquery.formatter.ts | 7 ++----- src/languages/db2.formatter.ts | 7 ++----- src/languages/hive.formatter.ts | 7 ++----- src/languages/mariadb.formatter.ts | 7 ++----- src/languages/mysql.formatter.ts | 7 ++----- src/languages/n1ql.formatter.ts | 13 +++++-------- src/languages/plsql.formatter.ts | 7 ++----- src/languages/postgresql.formatter.ts | 7 ++----- src/languages/redshift.formatter.ts | 7 ++----- src/languages/spark.formatter.ts | 7 ++----- src/languages/sql.formatter.ts | 7 ++----- src/languages/sqlite.formatter.ts | 7 ++----- src/languages/tsql.formatter.ts | 7 ++----- 13 files changed, 29 insertions(+), 68 deletions(-) diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index b4ea87f76d..a624fb9391 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -1,6 +1,5 @@ import Formatter from '../core/Formatter'; import Tokenizer from '../core/Tokenizer'; -import type { StringPatternType } from '../core/regexFactory'; import { EOF_TOKEN, Token } from '../core/token'; import { dedupe } from '../utils'; @@ -825,8 +824,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://cloud.google.com/bigquery/docs/reference/#standard-sql-reference export default class BigQueryFormatter extends Formatter { - static stringTypes: StringPatternType[] = ['""', "''"]; // add: '''''', """""" ; prefixes: r, b - static identifierTypes: StringPatternType[] = ['``']; static operators = ['>>', '<<', '||']; // TODO: handle trailing comma in select clause @@ -839,8 +836,8 @@ export default class BigQueryFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), - stringTypes: BigQueryFormatter.stringTypes, - identifierTypes: BigQueryFormatter.identifierTypes, + stringTypes: ['""', "''"], // add: '''''', """""" ; prefixes: r, b + identifierTypes: ['``'], indexedPlaceholderTypes: ['?'], lineCommentTypes: ['--', '#'], specialWordChars: { any: '_@$-' }, diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index 7fe08a546c..eb8e61fc0e 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -1,6 +1,5 @@ import Formatter from '../core/Formatter'; import Tokenizer from '../core/Tokenizer'; -import type { StringPatternType } from '../core/regexFactory'; import { dedupe } from '../utils'; /** @@ -859,8 +858,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE', 'ELSEIF']; // https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_72/db2/rbafzintro.htm export default class Db2Formatter extends Formatter { - static stringTypes: StringPatternType[] = ["''", "X''"]; - static identifierTypes: StringPatternType[] = [`""`]; static operators = ['**', '!>', '!<', '||']; tokenizer() { @@ -872,8 +869,8 @@ export default class Db2Formatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), - stringTypes: Db2Formatter.stringTypes, - identifierTypes: Db2Formatter.identifierTypes, + stringTypes: ["''", "X''"], + identifierTypes: [`""`], indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: [':'], specialWordChars: { any: '#@' }, diff --git a/src/languages/hive.formatter.ts b/src/languages/hive.formatter.ts index 36199d23c9..edf072fa43 100644 --- a/src/languages/hive.formatter.ts +++ b/src/languages/hive.formatter.ts @@ -1,6 +1,5 @@ import Formatter from '../core/Formatter'; import Tokenizer from '../core/Tokenizer'; -import type { StringPatternType } from '../core/regexFactory'; import { dedupe } from '../utils'; /** @@ -614,8 +613,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://cwiki.apache.org/confluence/display/Hive/LanguageManual export default class HiveFormatter extends Formatter { - static stringTypes: StringPatternType[] = ['""', "''"]; - static identifierTypes: StringPatternType[] = ['``']; static operators = ['<=>', '==', '||']; tokenizer() { @@ -627,8 +624,8 @@ export default class HiveFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), - stringTypes: HiveFormatter.stringTypes, - identifierTypes: HiveFormatter.identifierTypes, + stringTypes: ['""', "''"], + identifierTypes: ['``'], operators: HiveFormatter.operators, }); } diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index 51d568962a..028ca91328 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1,7 +1,6 @@ import Formatter from '../core/Formatter'; import Tokenizer from '../core/Tokenizer'; import { EOF_TOKEN, isToken, Token, TokenType } from '../core/token'; -import type { StringPatternType } from '../core/regexFactory'; import { dedupe } from '../utils'; /** @@ -1156,8 +1155,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE', 'ELSEIF', 'ELSIF']; // For reference: https://mariadb.com/kb/en/sql-statements-structure/ export default class MariaDbFormatter extends Formatter { - static stringTypes: StringPatternType[] = ["''", '""']; - static identifierTypes: StringPatternType[] = ['``']; static operators = [':=', '<<', '>>', '<=>', '&&', '||']; tokenizer() { @@ -1167,8 +1164,8 @@ export default class MariaDbFormatter extends Formatter { reservedDependentClauses, reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), - stringTypes: MariaDbFormatter.stringTypes, - identifierTypes: MariaDbFormatter.identifierTypes, + stringTypes: ["''", '""'], + identifierTypes: ['``'], indexedPlaceholderTypes: ['?'], lineCommentTypes: ['--', '#'], specialWordChars: { prefix: '@' }, diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index f4de1507e5..c97519c1be 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1,7 +1,6 @@ import Formatter from '../core/Formatter'; import Tokenizer from '../core/Tokenizer'; import { EOF_TOKEN, isToken, Token, TokenType } from '../core/token'; -import type { StringPatternType } from '../core/regexFactory'; import { dedupe } from '../utils'; // TODO: split this into object with function categories @@ -1319,8 +1318,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE', 'ELSEIF']; // https://dev.mysql.com/doc/refman/8.0/en/ export default class MySqlFormatter extends Formatter { - static stringTypes: StringPatternType[] = ["''", '""']; - static identifierTypes: StringPatternType[] = ['``']; static operators = [':=', '<<', '>>', '<=>', '&&', '||', '->', '->>']; tokenizer() { @@ -1330,8 +1327,8 @@ export default class MySqlFormatter extends Formatter { reservedDependentClauses, reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), - stringTypes: MySqlFormatter.stringTypes, - identifierTypes: MySqlFormatter.identifierTypes, + stringTypes: ["''", '""'], + identifierTypes: ['``'], indexedPlaceholderTypes: ['?'], lineCommentTypes: ['--', '#'], specialWordChars: { prefix: '@:' }, diff --git a/src/languages/n1ql.formatter.ts b/src/languages/n1ql.formatter.ts index 5e0c37f053..25de59c2bf 100644 --- a/src/languages/n1ql.formatter.ts +++ b/src/languages/n1ql.formatter.ts @@ -1,6 +1,5 @@ import Formatter from '../core/Formatter'; import Tokenizer from '../core/Tokenizer'; -import type { StringPatternType } from '../core/regexFactory'; import { dedupe } from '../utils'; // TODO: split this into object with function categories @@ -512,11 +511,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // For reference: http://docs.couchbase.com.s3-website-us-west-1.amazonaws.com/server/6.0/n1ql/n1ql-language-reference/index.html export default class N1qlFormatter extends Formatter { - // NOTE: single quotes are actually not supported in N1QL, - // but we support them anyway as all other SQL dialects do, - // which simplifies writing tests that are shared between all dialects. - static stringTypes: StringPatternType[] = [`""`, "''"]; - static identifierTypes: StringPatternType[] = ['``']; static operators = ['==']; tokenizer() { @@ -526,8 +520,11 @@ export default class N1qlFormatter extends Formatter { reservedDependentClauses, reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), - stringTypes: N1qlFormatter.stringTypes, - identifierTypes: N1qlFormatter.identifierTypes, + // NOTE: single quotes are actually not supported in N1QL, + // but we support them anyway as all other SQL dialects do, + // which simplifies writing tests that are shared between all dialects. + stringTypes: [`""`, "''"], + identifierTypes: ['``'], blockStart: ['(', '[', '{'], blockEnd: [')', ']', '}'], namedPlaceholderTypes: ['$'], diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 0b74352af3..1b33d0ccfa 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -1,7 +1,6 @@ import Formatter from '../core/Formatter'; import Tokenizer from '../core/Tokenizer'; import { EOF_TOKEN, isReserved, isToken, Token, TokenType } from '../core/token'; // convert to partial type import in TS 4.5 -import type { StringPatternType } from '../core/regexFactory'; import { dedupe } from '../utils'; /** @@ -443,8 +442,6 @@ const reservedBinaryCommands = [ const reservedDependentClauses = ['WHEN', 'ELSE']; export default class PlSqlFormatter extends Formatter { - static stringTypes: StringPatternType[] = ["''", "N''"]; - static identifierTypes: StringPatternType[] = [`""`]; static operators = [ '||', '**', @@ -464,8 +461,8 @@ export default class PlSqlFormatter extends Formatter { reservedDependentClauses, reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe(reservedKeywords), - stringTypes: PlSqlFormatter.stringTypes, - identifierTypes: PlSqlFormatter.identifierTypes, + stringTypes: ["''", "N''"], + identifierTypes: [`""`], indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: [':'], specialWordChars: { any: '_$#' }, diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index c93b884f0b..fe91d43131 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1,6 +1,5 @@ import Formatter from '../core/Formatter'; import Tokenizer from '../core/Tokenizer'; -import type { StringPatternType } from '../core/regexFactory'; import { dedupe } from '../utils'; /** @@ -1671,8 +1670,6 @@ const binaryOperators = [ // https://www.postgresql.org/docs/14/index.html export default class PostgreSqlFormatter extends Formatter { - static stringTypes: StringPatternType[] = ["''", "U&''", '$$', "E''"]; - static identifierTypes: StringPatternType[] = [`""`, 'U&""']; static operators = binaryOperators; tokenizer() { @@ -1684,8 +1681,8 @@ export default class PostgreSqlFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...reservedKeywords, ]), - stringTypes: PostgreSqlFormatter.stringTypes, - identifierTypes: PostgreSqlFormatter.identifierTypes, + stringTypes: ["''", "U&''", '$$', "E''"], + identifierTypes: [`""`, 'U&""'], indexedPlaceholderTypes: ['$'], namedPlaceholderTypes: [':'], operators: PostgreSqlFormatter.operators, diff --git a/src/languages/redshift.formatter.ts b/src/languages/redshift.formatter.ts index 61c57ee77d..805c0cf3e3 100644 --- a/src/languages/redshift.formatter.ts +++ b/src/languages/redshift.formatter.ts @@ -1,6 +1,5 @@ import Formatter from '../core/Formatter'; import Tokenizer from '../core/Tokenizer'; -import type { StringPatternType } from '../core/regexFactory'; import { dedupe } from '../utils'; /** @@ -716,8 +715,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://docs.aws.amazon.com/redshift/latest/dg/cm_chap_SQLCommandRef.html export default class RedshiftFormatter extends Formatter { - static stringTypes: StringPatternType[] = ["''"]; - static identifierTypes: StringPatternType[] = [`""`]; static operators = ['|/', '||/', '<<', '>>', '||']; tokenizer() { @@ -729,8 +726,8 @@ export default class RedshiftFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), - stringTypes: RedshiftFormatter.stringTypes, - identifierTypes: RedshiftFormatter.identifierTypes, + stringTypes: ["''"], + identifierTypes: [`""`], indexedPlaceholderTypes: ['?'], // XXX: Seems like redshift only supports $1, $2, $3 parameters, // but for some reason we list lots of types in here. diff --git a/src/languages/spark.formatter.ts b/src/languages/spark.formatter.ts index 8fe2f1b722..2f47de4d24 100644 --- a/src/languages/spark.formatter.ts +++ b/src/languages/spark.formatter.ts @@ -1,7 +1,6 @@ import Formatter from '../core/Formatter'; import Tokenizer from '../core/Tokenizer'; import { EOF_TOKEN, isToken, Token, TokenType } from '../core/token'; // convert to partial type import in TS 4.5 -import type { StringPatternType } from '../core/regexFactory'; import { dedupe } from '../utils'; /** @@ -778,8 +777,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // http://spark.apache.org/docs/latest/sql-programming-guide.html export default class SparkFormatter extends Formatter { - static stringTypes: StringPatternType[] = ["''"]; - static identifierTypes: StringPatternType[] = ['``']; static operators = ['<=>', '&&', '||', '==', '->']; tokenizer() { @@ -792,8 +789,8 @@ export default class SparkFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...reservedKeywords, ]), - stringTypes: SparkFormatter.stringTypes, - identifierTypes: SparkFormatter.identifierTypes, + stringTypes: ["''"], + identifierTypes: ['``'], operators: SparkFormatter.operators, preprocess, }); diff --git a/src/languages/sql.formatter.ts b/src/languages/sql.formatter.ts index f9f4975346..737ab16f53 100644 --- a/src/languages/sql.formatter.ts +++ b/src/languages/sql.formatter.ts @@ -1,6 +1,5 @@ import Formatter from '../core/Formatter'; import Tokenizer from '../core/Tokenizer'; -import type { StringPatternType } from '../core/regexFactory'; import { dedupe } from '../utils'; /** @@ -370,8 +369,6 @@ const reservedBinaryCommands = [ const reservedDependentClauses = ['WHEN', 'ELSE']; export default class SqlFormatter extends Formatter { - static stringTypes: StringPatternType[] = ["''"]; - static identifierTypes: StringPatternType[] = [`""`, '``']; static operators = []; tokenizer() { @@ -380,8 +377,8 @@ export default class SqlFormatter extends Formatter { reservedBinaryCommands, reservedDependentClauses, reservedKeywords: dedupe(reservedKeywords), - stringTypes: SqlFormatter.stringTypes, - identifierTypes: SqlFormatter.identifierTypes, + stringTypes: ["''"], + identifierTypes: [`""`, '``'], indexedPlaceholderTypes: ['?'], }); } diff --git a/src/languages/sqlite.formatter.ts b/src/languages/sqlite.formatter.ts index 355c559b52..0c5896f93c 100644 --- a/src/languages/sqlite.formatter.ts +++ b/src/languages/sqlite.formatter.ts @@ -1,5 +1,4 @@ import Formatter from '../core/Formatter'; -import { StringPatternType } from '../core/regexFactory'; import Tokenizer from '../core/Tokenizer'; // https://jakewheat.github.io/sql-overview/sql-2008-foundation-grammar.html#reserved-word @@ -421,8 +420,6 @@ const reservedBinaryCommands = [ const reservedDependentClauses = ['WHEN', 'ELSE']; export default class SqliteFormatter extends Formatter { - static stringTypes: StringPatternType[] = ["''"]; - static identifierTypes: StringPatternType[] = [`""`, '``', '[]']; // https://www.sqlite.org/lang_expr.html static operators = ['||', '<<', '>>', '==', '!=']; @@ -433,8 +430,8 @@ export default class SqliteFormatter extends Formatter { reservedDependentClauses, // https://www.sqlite.org/lang_keywords.html reservedKeywords: [...standardReservedWords, ...nonStandardSqliteReservedWords], - stringTypes: SqliteFormatter.stringTypes, - identifierTypes: SqliteFormatter.identifierTypes, + stringTypes: ["''"], + identifierTypes: [`""`, '``', '[]'], // https://www.sqlite.org/lang_expr.html#parameters indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: [':', '@', '$'], diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index ae862c2251..4ab1ed07e2 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1,6 +1,5 @@ import Formatter from '../core/Formatter'; import Tokenizer from '../core/Tokenizer'; -import type { StringPatternType } from '../core/regexFactory'; import { dedupe } from '../utils'; /** @@ -1232,8 +1231,6 @@ const reservedDependentClauses = ['WHEN', 'ELSE']; // https://docs.microsoft.com/en-us/sql/t-sql/language-reference?view=sql-server-ver15 export default class TSqlFormatter extends Formatter { - static stringTypes: StringPatternType[] = ["N''", "''"]; - static identifierTypes: StringPatternType[] = [`""`, '[]']; static operators = ['!<', '!>', '+=', '-=', '*=', '/=', '%=', '|=', '&=', '^=', '::']; tokenizer() { @@ -1245,8 +1242,8 @@ export default class TSqlFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), - stringTypes: TSqlFormatter.stringTypes, - identifierTypes: TSqlFormatter.identifierTypes, + stringTypes: ["N''", "''"], + identifierTypes: [`""`, '[]'], namedPlaceholderTypes: ['@'], specialWordChars: { any: '#@' }, operators: TSqlFormatter.operators, From 540e5ff0506ecda5bc69f4b41262c2b4c130d3c7 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 16:05:57 +0300 Subject: [PATCH 082/334] Generalize quote prefixes for strings/identifiers This eliminates the duplication reported in #211 Also makes it possible to more easily add new string prefixes. --- src/core/regexFactory.ts | 34 ++++++++++++++++++--------- src/languages/db2.formatter.ts | 2 +- src/languages/plsql.formatter.ts | 2 +- src/languages/postgresql.formatter.ts | 4 ++-- src/languages/tsql.formatter.ts | 2 +- 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index d618f802fe..0a0e593485 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -73,25 +73,37 @@ export const createWordRegex = ( // 2. square bracket quoted string (SQL Server) using ]] to escape // 3. double quoted string using "" or \" to escape // 4. single quoted string using '' or \' to escape -// 5. national character quoted string using N'' or N\' to escape -// 6. Unicode single-quoted string using \' to escape -// 7. Unicode double-quoted string using \" to escape -// 8. PostgreSQL dollar-quoted strings +// 5. PostgreSQL dollar-quoted strings const patterns = { '``': '(`[^`]*($|`))+', '[]': '(\\[[^\\]]*($|\\]))(\\][^\\]]*($|\\]))*', '""': '("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+', "''": "('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", - "N''": "N('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", - "X''": "[xX]('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", - "E''": "E('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", - "U&''": "U&('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", - 'U&""': 'U&("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+', '$$': '(?\\$\\w*\\$)[\\s\\S]*?(?:\\k|$)', }; -export type StringPatternType = keyof typeof patterns; +export type PlainQuoteType = keyof typeof patterns; -const createQuotePattern = (type: StringPatternType): string => '(' + patterns[type] + ')'; +export type PrefixedQuoteType = { + quote: PlainQuoteType; + prefix: string; +}; + +export type StringPatternType = PlainQuoteType | PrefixedQuoteType; + +// Converts "ab" to "[Aa][Bb]" +const toCaseInsensitivePattern = (prefix: string): string => + prefix + .split('') + .map(char => '[' + char.toUpperCase() + char.toLowerCase() + ']') + .join(''); + +const createQuotePattern = (type: StringPatternType): string => { + if (typeof type === 'string') { + return '(' + patterns[type] + ')'; + } else { + return '(' + toCaseInsensitivePattern(type.prefix) + patterns[type.quote] + ')'; + } +}; /** * Builds a string pattern for matching string patterns for all given string types diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index eb8e61fc0e..b4f2bff255 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -869,7 +869,7 @@ export default class Db2Formatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), - stringTypes: ["''", "X''"], + stringTypes: ["''", { prefix: 'X', quote: "''" }], identifierTypes: [`""`], indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: [':'], diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 1b33d0ccfa..c0544b6d36 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -461,7 +461,7 @@ export default class PlSqlFormatter extends Formatter { reservedDependentClauses, reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe(reservedKeywords), - stringTypes: ["''", "N''"], + stringTypes: ["''", { prefix: 'N', quote: "''" }], identifierTypes: [`""`], indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: [':'], diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index fe91d43131..388d80403d 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1681,8 +1681,8 @@ export default class PostgreSqlFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...reservedKeywords, ]), - stringTypes: ["''", "U&''", '$$', "E''"], - identifierTypes: [`""`, 'U&""'], + stringTypes: ["''", '$$', { prefix: 'U&', quote: "''" }, { prefix: 'E', quote: "''" }], + identifierTypes: [`""`, { prefix: 'U&', quote: '""' }], indexedPlaceholderTypes: ['$'], namedPlaceholderTypes: [':'], operators: PostgreSqlFormatter.operators, diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index 4ab1ed07e2..1abe40767b 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1242,7 +1242,7 @@ export default class TSqlFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), - stringTypes: ["N''", "''"], + stringTypes: ["''", { prefix: 'N', quote: "''" }], identifierTypes: [`""`, '[]'], namedPlaceholderTypes: ['@'], specialWordChars: { any: '#@' }, From 36218ca62328f0468796451f0d40a252aaee6318 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 16:08:38 +0300 Subject: [PATCH 083/334] Rename StringPatternType to QuoteType --- src/core/Tokenizer.ts | 4 ++-- src/core/regexFactory.ts | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index bdd0fc33ae..9ed566aa5a 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -15,8 +15,8 @@ interface TokenizerOptions { reservedDependentClauses: string[]; reservedBinaryCommands: string[]; reservedJoinConditions?: string[]; - stringTypes: regexFactory.StringPatternType[]; - identifierTypes: regexFactory.StringPatternType[]; + stringTypes: regexFactory.QuoteType[]; + identifierTypes: regexFactory.QuoteType[]; blockStart?: string[]; blockEnd?: string[]; indexedPlaceholderTypes?: string[]; diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 0a0e593485..1738a0dedf 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -88,7 +88,7 @@ export type PrefixedQuoteType = { prefix: string; }; -export type StringPatternType = PlainQuoteType | PrefixedQuoteType; +export type QuoteType = PlainQuoteType | PrefixedQuoteType; // Converts "ab" to "[Aa][Bb]" const toCaseInsensitivePattern = (prefix: string): string => @@ -97,7 +97,7 @@ const toCaseInsensitivePattern = (prefix: string): string => .map(char => '[' + char.toUpperCase() + char.toLowerCase() + ']') .join(''); -const createQuotePattern = (type: StringPatternType): string => { +const createQuotePattern = (type: QuoteType): string => { if (typeof type === 'string') { return '(' + patterns[type] + ')'; } else { @@ -107,16 +107,16 @@ const createQuotePattern = (type: StringPatternType): string => { /** * Builds a string pattern for matching string patterns for all given string types - * @param {StringPatternType[]} stringTypes - list of strings that denote string patterns + * @param {QuoteType[]} stringTypes - list of strings that denote string patterns */ -export const createStringPattern = (stringTypes: StringPatternType[]): string => +export const createStringPattern = (stringTypes: QuoteType[]): string => stringTypes.map(createQuotePattern).join('|'); /** * Builds a RegExp for matching string patterns using `createStringPattern` - * @param {StringPatternType[]} stringTypes - list of strings that denote string patterns + * @param {QuoteType[]} stringTypes - list of strings that denote string patterns */ -export const createStringRegex = (stringTypes: StringPatternType[]): RegExp => +export const createStringRegex = (stringTypes: QuoteType[]): RegExp => new RegExp('^(' + createStringPattern(stringTypes) + ')', 'u'); /** Escapes paren characters for RegExp patterns */ From 01b98df304549bf7537d648b1e787e0a9d1af0de Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 16:13:40 +0300 Subject: [PATCH 084/334] Rename stringRegex functions to quoteRegex --- src/core/Tokenizer.ts | 6 +++--- src/core/regexFactory.ts | 20 +++++++------------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 9ed566aa5a..dce7d19d1f 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -64,8 +64,8 @@ export default class Tokenizer { const specialWordCharsAll = Object.values(cfg.specialWordChars ?? {}).join(''); this.REGEX_MAP = { [TokenType.WORD]: regexFactory.createWordRegex(cfg.specialWordChars), - [TokenType.IDENT]: regexFactory.createStringRegex(cfg.identifierTypes), - [TokenType.STRING]: regexFactory.createStringRegex(cfg.stringTypes), + [TokenType.IDENT]: regexFactory.createQuoteRegex(cfg.identifierTypes), + [TokenType.STRING]: regexFactory.createQuoteRegex(cfg.stringTypes), [TokenType.RESERVED_KEYWORD]: regexFactory.createReservedWordRegex( cfg.reservedKeywords, specialWordCharsAll @@ -119,7 +119,7 @@ export default class Tokenizer { ); this.STRING_NAMED_PLACEHOLDER_REGEX = regexFactory.createPlaceholderRegex( cfg.namedPlaceholderTypes ?? [], - regexFactory.createStringPattern(cfg.identifierTypes) + regexFactory.createQuotePattern(cfg.identifierTypes) ); } diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 1738a0dedf..0f81b377b8 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -97,7 +97,7 @@ const toCaseInsensitivePattern = (prefix: string): string => .map(char => '[' + char.toUpperCase() + char.toLowerCase() + ']') .join(''); -const createQuotePattern = (type: QuoteType): string => { +const createSingleQuotePattern = (type: QuoteType): string => { if (typeof type === 'string') { return '(' + patterns[type] + ')'; } else { @@ -105,19 +105,13 @@ const createQuotePattern = (type: QuoteType): string => { } }; -/** - * Builds a string pattern for matching string patterns for all given string types - * @param {QuoteType[]} stringTypes - list of strings that denote string patterns - */ -export const createStringPattern = (stringTypes: QuoteType[]): string => - stringTypes.map(createQuotePattern).join('|'); +/** Builds a quote-delimited pattern for matching all given quote types */ +export const createQuotePattern = (quoteTypes: QuoteType[]): string => + quoteTypes.map(createSingleQuotePattern).join('|'); -/** - * Builds a RegExp for matching string patterns using `createStringPattern` - * @param {QuoteType[]} stringTypes - list of strings that denote string patterns - */ -export const createStringRegex = (stringTypes: QuoteType[]): RegExp => - new RegExp('^(' + createStringPattern(stringTypes) + ')', 'u'); +/** Builds a RegExp for matching quote-delimited patterns */ +export const createQuoteRegex = (quoteTypes: QuoteType[]): RegExp => + new RegExp('^(' + createQuotePattern(quoteTypes) + ')', 'u'); /** Escapes paren characters for RegExp patterns */ const escapeParen = (paren: string): string => { From 20f5a432e589c520436610888a4da2186a3442b5 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 16:16:13 +0300 Subject: [PATCH 085/334] Rename patterns to quotePatterns and update docs --- src/core/regexFactory.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 0f81b377b8..3e2581ec8e 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -68,20 +68,20 @@ export const createWordRegex = ( ); }; -// This enables the following string patterns: -// 1. backtick quoted string using `` to escape -// 2. square bracket quoted string (SQL Server) using ]] to escape -// 3. double quoted string using "" or \" to escape -// 4. single quoted string using '' or \' to escape -// 5. PostgreSQL dollar-quoted strings -const patterns = { +// This enables the following quote styles: +// 1. backtick quoted using `` to escape +// 2. square bracket quoted (SQL Server) using ]] to escape +// 3. double quoted using "" or \" to escape +// 4. single quoted using '' or \' to escape +// 5. PostgreSQL dollar-quoted +const quotePatterns = { '``': '(`[^`]*($|`))+', '[]': '(\\[[^\\]]*($|\\]))(\\][^\\]]*($|\\]))*', '""': '("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+', "''": "('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", '$$': '(?\\$\\w*\\$)[\\s\\S]*?(?:\\k|$)', }; -export type PlainQuoteType = keyof typeof patterns; +export type PlainQuoteType = keyof typeof quotePatterns; export type PrefixedQuoteType = { quote: PlainQuoteType; @@ -99,9 +99,9 @@ const toCaseInsensitivePattern = (prefix: string): string => const createSingleQuotePattern = (type: QuoteType): string => { if (typeof type === 'string') { - return '(' + patterns[type] + ')'; + return '(' + quotePatterns[type] + ')'; } else { - return '(' + toCaseInsensitivePattern(type.prefix) + patterns[type.quote] + ')'; + return '(' + toCaseInsensitivePattern(type.prefix) + quotePatterns[type.quote] + ')'; } }; From b11e2c4d9669b09b08601d423272f23347cde329 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 16:29:38 +0300 Subject: [PATCH 086/334] Add RB-prefixed strings to BigQuery --- src/languages/bigquery.formatter.ts | 14 +++++++++++++- test/bigquery.test.ts | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index a624fb9391..97e1dff77a 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -836,7 +836,19 @@ export default class BigQueryFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), - stringTypes: ['""', "''"], // add: '''''', """""" ; prefixes: r, b + // TODO: add '''''', """""" + stringTypes: [ + '""', + { prefix: 'R', quote: '""' }, + { prefix: 'B', quote: '""' }, + { prefix: 'RB', quote: '""' }, + { prefix: 'BR', quote: '""' }, + "''", + { prefix: 'R', quote: "''" }, + { prefix: 'B', quote: "''" }, + { prefix: 'RB', quote: "''" }, + { prefix: 'BR', quote: "''" }, + ], identifierTypes: ['``'], indexedPlaceholderTypes: ['?'], lineCommentTypes: ['--', '#'], diff --git a/test/bigquery.test.ts b/test/bigquery.test.ts index 8aef9f42dd..43fd099002 100644 --- a/test/bigquery.test.ts +++ b/test/bigquery.test.ts @@ -55,6 +55,22 @@ describe('BigQueryFormatter', () => { `); }); + // BigQuery-specific string types + it('supports strings with r, b and rb prefixes', () => { + expect(format(`SELECT R'blah', B'sah', rb"huh", br'bulu bulu', r"haha", BR'la la' FROM foo`)) + .toBe(dedent` + SELECT + R'blah', + B'sah', + rb"huh", + br'bulu bulu', + r"haha", + BR'la la' + FROM + foo + `); + }); + it('supports STRUCT types', () => { const result = format( 'SELECT STRUCT("Alpha" as name, [23.4, 26.3, 26.4, 26.1] as splits) FROM beta' From db60e3c82f478f1d7a3b07f3cbaf7177e7ef4b43 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 16:39:23 +0300 Subject: [PATCH 087/334] Add missing string types for DB2 --- src/languages/db2.formatter.ts | 10 +++++++++- test/db2.test.ts | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index b4f2bff255..6727a12b15 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -869,7 +869,15 @@ export default class Db2Formatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), - stringTypes: ["''", { prefix: 'X', quote: "''" }], + stringTypes: [ + "''", + { prefix: 'X', quote: "''" }, + { prefix: 'G', quote: "''" }, + { prefix: 'N', quote: "''" }, + { prefix: 'GX', quote: "''" }, + { prefix: 'UX', quote: "''" }, + { prefix: 'U&', quote: "''" }, + ], identifierTypes: [`""`], indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: [':'], diff --git a/test/db2.test.ts b/test/db2.test.ts index 7d36c9a3ea..5a1d99f981 100644 --- a/test/db2.test.ts +++ b/test/db2.test.ts @@ -26,7 +26,7 @@ describe('Db2Formatter', () => { supportsConstraints(format); supportsAlterTable(format); supportsDeleteFrom(format); - supportsStrings(format, ["''", "X''"]); + supportsStrings(format, ["''", "X''", "U&''"]); supportsIdentifiers(format, [`""`]); supportsBetween(format); supportsSchema(format); @@ -72,4 +72,17 @@ describe('Db2Formatter', () => { tbl `); }); + + // DB2-specific string types + it('supports strings with G, N, GX, UX prefixes', () => { + expect(format(`SELECT G'blah blah', N'hah haa', GX'01AC', UX'CCF239' FROM foo`)).toBe(dedent` + SELECT + G'blah blah', + N'hah haa', + GX'01AC', + UX'CCF239' + FROM + foo + `); + }); }); From c015859170c60a3588a219bc46e9474e275e5eb5 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 16:42:09 +0300 Subject: [PATCH 088/334] Document double-quoted string for MariaDB --- sql/strings.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/strings.md b/sql/strings.md index 123fb2eb3e..4cb4efb584 100644 --- a/sql/strings.md +++ b/sql/strings.md @@ -17,7 +17,7 @@ The real world implementations have lots of variation: - `UX'..'` an UCS-2 graphic string (no escaping) - [Hive][]: `'..'`, `".."` (backslash `\` used for escaping) - [MariaDB][]: - - `'..'` (backslash `\`1 or repeated single-quote `''` used for escaping) + - `'..'`, `".."`2 (backslash `\`1 or repeated single-quote `''` used for escaping) - `x'..'`, `X'..'` [hex string][mariadb-hex] - [MySQL][]: - `'..'`, `".."`2 (backslash `\`1 or repeated quote (`''` or `""`) used for escaping) From bf9dada9237eeae81679b2e843037b9991546b12 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 16:46:03 +0300 Subject: [PATCH 089/334] Support hex strings for MariaDB and MySQL --- src/languages/mariadb.formatter.ts | 2 +- src/languages/mysql.formatter.ts | 2 +- test/mariadb.test.ts | 2 +- test/mysql.test.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index 028ca91328..fff6351c1b 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1164,7 +1164,7 @@ export default class MariaDbFormatter extends Formatter { reservedDependentClauses, reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), - stringTypes: ["''", '""'], + stringTypes: ["''", '""', { prefix: 'X', quote: "''" }], identifierTypes: ['``'], indexedPlaceholderTypes: ['?'], lineCommentTypes: ['--', '#'], diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index c97519c1be..18b740a002 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1327,7 +1327,7 @@ export default class MySqlFormatter extends Formatter { reservedDependentClauses, reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), - stringTypes: ["''", '""'], + stringTypes: ["''", '""', { prefix: 'X', quote: "''" }], identifierTypes: ['``'], indexedPlaceholderTypes: ['?'], lineCommentTypes: ['--', '#'], diff --git a/test/mariadb.test.ts b/test/mariadb.test.ts index e6dfbd8312..672dae939e 100644 --- a/test/mariadb.test.ts +++ b/test/mariadb.test.ts @@ -13,7 +13,7 @@ describe('MariaDbFormatter', () => { behavesLikeMariaDbFormatter(format); - supportsStrings(format, ["''", '""']); + supportsStrings(format, ["''", '""', "X''"]); supportsIdentifiers(format, ['``']); supportsOperators(format, MariaDbFormatter.operators, ['AND', 'OR', 'XOR']); supportsReturning(format); diff --git a/test/mysql.test.ts b/test/mysql.test.ts index 25e20352b7..aa9e56cf30 100644 --- a/test/mysql.test.ts +++ b/test/mysql.test.ts @@ -13,7 +13,7 @@ describe('MySqlFormatter', () => { behavesLikeMariaDbFormatter(format); - supportsStrings(format, ["''", '""']); + supportsStrings(format, ["''", '""', "X''"]); supportsIdentifiers(format, ['``']); supportsOperators(format, MySqlFormatter.operators, ['AND', 'OR', 'XOR']); From 47ba47c5c700b9985c87d54d5d774e138491ea20 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 16:48:04 +0300 Subject: [PATCH 090/334] Move MariaDB and MySQL string/ident tests to behavesLike file --- test/behavesLikeMariaDbFormatter.ts | 4 ++++ test/mariadb.test.ts | 4 ---- test/mysql.test.ts | 4 ---- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/test/behavesLikeMariaDbFormatter.ts b/test/behavesLikeMariaDbFormatter.ts index 77b98374ad..185a2d33fd 100644 --- a/test/behavesLikeMariaDbFormatter.ts +++ b/test/behavesLikeMariaDbFormatter.ts @@ -10,6 +10,8 @@ import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsStrings from './features/strings'; +import supportsIdentifiers from './features/identifiers'; /** * Shared tests for MySQL and MariaDB @@ -17,6 +19,8 @@ import supportsComments from './features/comments'; export default function behavesLikeMariaDbFormatter(format: FormatFn) { behavesLikeSqlFormatter(format); supportsComments(format, { hashComments: true }); + supportsStrings(format, ["''", '""', "X''"]); + supportsIdentifiers(format, ['``']); supportsCreateTable(format); supportsConstraints(format); supportsAlterTable(format); diff --git a/test/mariadb.test.ts b/test/mariadb.test.ts index 672dae939e..651610b38f 100644 --- a/test/mariadb.test.ts +++ b/test/mariadb.test.ts @@ -2,10 +2,8 @@ import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; import MariaDbFormatter from '../src/languages/mariadb.formatter'; import behavesLikeMariaDbFormatter from './behavesLikeMariaDbFormatter'; -import supportsStrings from './features/strings'; import supportsOperators from './features/operators'; import supportsReturning from './features/returning'; -import supportsIdentifiers from './features/identifiers'; describe('MariaDbFormatter', () => { const language = 'mariadb'; @@ -13,8 +11,6 @@ describe('MariaDbFormatter', () => { behavesLikeMariaDbFormatter(format); - supportsStrings(format, ["''", '""', "X''"]); - supportsIdentifiers(format, ['``']); supportsOperators(format, MariaDbFormatter.operators, ['AND', 'OR', 'XOR']); supportsReturning(format); }); diff --git a/test/mysql.test.ts b/test/mysql.test.ts index aa9e56cf30..f4e0600224 100644 --- a/test/mysql.test.ts +++ b/test/mysql.test.ts @@ -3,9 +3,7 @@ import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; import MySqlFormatter from '../src/languages/mysql.formatter'; import behavesLikeMariaDbFormatter from './behavesLikeMariaDbFormatter'; -import supportsStrings from './features/strings'; import supportsOperators from './features/operators'; -import supportsIdentifiers from './features/identifiers'; describe('MySqlFormatter', () => { const language = 'mysql'; @@ -13,8 +11,6 @@ describe('MySqlFormatter', () => { behavesLikeMariaDbFormatter(format); - supportsStrings(format, ["''", '""', "X''"]); - supportsIdentifiers(format, ['``']); supportsOperators(format, MySqlFormatter.operators, ['AND', 'OR', 'XOR']); it('supports @@ system variables', () => { From eee0ea32218b0fcfe7247bf0cf4b049841d732ef Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 17:23:00 +0300 Subject: [PATCH 091/334] Use generic string tests for DB2 N'' strings --- test/db2.test.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/db2.test.ts b/test/db2.test.ts index 5a1d99f981..9dae01e4bd 100644 --- a/test/db2.test.ts +++ b/test/db2.test.ts @@ -26,7 +26,7 @@ describe('Db2Formatter', () => { supportsConstraints(format); supportsAlterTable(format); supportsDeleteFrom(format); - supportsStrings(format, ["''", "X''", "U&''"]); + supportsStrings(format, ["''", "X''", "U&''", "N''"]); supportsIdentifiers(format, [`""`]); supportsBetween(format); supportsSchema(format); @@ -74,11 +74,10 @@ describe('Db2Formatter', () => { }); // DB2-specific string types - it('supports strings with G, N, GX, UX prefixes', () => { - expect(format(`SELECT G'blah blah', N'hah haa', GX'01AC', UX'CCF239' FROM foo`)).toBe(dedent` + it('supports strings with G, GX, UX prefixes', () => { + expect(format(`SELECT G'blah blah', GX'01AC', UX'CCF239' FROM foo`)).toBe(dedent` SELECT G'blah blah', - N'hah haa', GX'01AC', UX'CCF239' FROM From 48e5b178fd54f17f613e378c404ba047664437be Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 17:28:03 +0300 Subject: [PATCH 092/334] Support hex strings for PostgreSQL --- src/languages/postgresql.formatter.ts | 8 +++++++- test/postgresql.test.ts | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index 388d80403d..4af8fa026e 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1681,7 +1681,13 @@ export default class PostgreSqlFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...reservedKeywords, ]), - stringTypes: ["''", '$$', { prefix: 'U&', quote: "''" }, { prefix: 'E', quote: "''" }], + stringTypes: [ + "''", + '$$', + { prefix: 'U&', quote: "''" }, + { prefix: 'E', quote: "''" }, + { prefix: 'X', quote: "''" }, + ], identifierTypes: [`""`, { prefix: 'U&', quote: '""' }], indexedPlaceholderTypes: ['$'], namedPlaceholderTypes: [':'], diff --git a/test/postgresql.test.ts b/test/postgresql.test.ts index a0bcf2c3ed..967ef46301 100644 --- a/test/postgresql.test.ts +++ b/test/postgresql.test.ts @@ -26,7 +26,7 @@ describe('PostgreSqlFormatter', () => { supportsConstraints(format); supportsAlterTable(format); supportsDeleteFrom(format); - supportsStrings(format, ["''", "U&''", '$$', "E''"]); + supportsStrings(format, ["''", "U&''", '$$', "E''", "X''"]); supportsIdentifiers(format, [`""`, 'U&""']); supportsBetween(format); supportsSchema(format); From ac3c8de8634119f0d6879e540b603c9b6f79f202 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 17:35:04 +0300 Subject: [PATCH 093/334] Support postgres bit-strings --- src/languages/postgresql.formatter.ts | 1 + test/postgresql.test.ts | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index 4af8fa026e..f907abe9c6 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1687,6 +1687,7 @@ export default class PostgreSqlFormatter extends Formatter { { prefix: 'U&', quote: "''" }, { prefix: 'E', quote: "''" }, { prefix: 'X', quote: "''" }, + { prefix: 'B', quote: "''" }, ], identifierTypes: [`""`, { prefix: 'U&', quote: '""' }], indexedPlaceholderTypes: ['$'], diff --git a/test/postgresql.test.ts b/test/postgresql.test.ts index 967ef46301..0f216564b8 100644 --- a/test/postgresql.test.ts +++ b/test/postgresql.test.ts @@ -1,3 +1,4 @@ +import dedent from 'dedent-js'; import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; import PostgreSqlFormatter from '../src/languages/postgresql.formatter'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; @@ -34,4 +35,13 @@ describe('PostgreSqlFormatter', () => { supportsJoin(format); supportsReturning(format); supportsParams(format, { indexed: ['$'], named: [':'] }); + + // Postgres-specific string types + it('supports bit strings', () => { + expect(format(`SELECT B'0110010', B'1101000';`)).toBe(dedent` + SELECT + B'0110010', + B'1101000'; + `); + }); }); From 4e99de6b490f9550b22049ef67beb5eac40659c1 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 17:37:59 +0300 Subject: [PATCH 094/334] Move postgres-specific string tests to postgres test --- test/features/strings.ts | 36 +----------------------------------- test/postgresql.test.ts | 28 +++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 36 deletions(-) diff --git a/test/features/strings.ts b/test/features/strings.ts index f6c1938a51..638d9fe719 100644 --- a/test/features/strings.ts +++ b/test/features/strings.ts @@ -2,7 +2,7 @@ import { expect } from '@jest/globals'; import dedent from 'dedent-js'; import { FormatFn } from '../../src/sqlFormatter'; -type StringType = '""' | "''" | 'U&""' | "U&''" | '$$' | "N''" | "X''" | "E''"; +type StringType = '""' | "''" | 'U&""' | "U&''" | "N''" | "X''"; export default function supportsStrings(format: FormatFn, stringTypes: StringType[]) { if (stringTypes.includes('""')) { @@ -69,23 +69,6 @@ export default function supportsStrings(format: FormatFn, stringTypes: StringTyp }); } - if (stringTypes.includes('$$')) { - it('supports dollar-quoted strings', () => { - expect(format('$xxx$foo $$ LEFT JOIN $yyy$ bar$xxx$')).toBe( - '$xxx$foo $$ LEFT JOIN $yyy$ bar$xxx$' - ); - expect(format('$$foo JOIN bar$$')).toBe('$$foo JOIN bar$$'); - expect(format('$$foo $ JOIN bar$$')).toBe('$$foo $ JOIN bar$$'); - expect(format('$$foo \n bar$$')).toBe('$$foo \n bar$$'); - expect(format('SELECT $$where$$ FROM $$update$$')).toBe(dedent` - SELECT - $$where$$ - FROM - $$update$$ - `); - }); - } - if (stringTypes.includes("N''")) { it('supports T-SQL unicode strings', () => { expect(format("N'foo JOIN bar'")).toBe("N'foo JOIN bar'"); @@ -119,21 +102,4 @@ export default function supportsStrings(format: FormatFn, stringTypes: StringTyp expect(format("X'AE01'X'01F6'")).toBe("X'AE01' X'01F6'"); }); } - - if (stringTypes.includes("E''")) { - it('supports strings with C-style escapes', () => { - expect(format("E'blah blah'")).toBe("E'blah blah'"); - expect(format("E'some \\' FROM escapes'")).toBe("E'some \\' FROM escapes'"); - expect(format("SELECT E'blah' FROM foo")).toBe(dedent` - SELECT - E'blah' - FROM - foo - `); - }); - - it("detects consequitive E'' strings as separate ones", () => { - expect(format("E'foo'E'bar'")).toBe("E'foo' E'bar'"); - }); - } } diff --git a/test/postgresql.test.ts b/test/postgresql.test.ts index 0f216564b8..ca92fbdbbb 100644 --- a/test/postgresql.test.ts +++ b/test/postgresql.test.ts @@ -27,7 +27,7 @@ describe('PostgreSqlFormatter', () => { supportsConstraints(format); supportsAlterTable(format); supportsDeleteFrom(format); - supportsStrings(format, ["''", "U&''", '$$', "E''", "X''"]); + supportsStrings(format, ["''", "U&''", "X''"]); supportsIdentifiers(format, [`""`, 'U&""']); supportsBetween(format); supportsSchema(format); @@ -44,4 +44,30 @@ describe('PostgreSqlFormatter', () => { B'1101000'; `); }); + + it("supports E'' strings with C-style escapes", () => { + expect(format("E'blah blah'")).toBe("E'blah blah'"); + expect(format("E'some \\' FROM escapes'")).toBe("E'some \\' FROM escapes'"); + expect(format("SELECT E'blah' FROM foo")).toBe(dedent` + SELECT + E'blah' + FROM + foo + `); + }); + + it('supports dollar-quoted strings', () => { + expect(format('$xxx$foo $$ LEFT JOIN $yyy$ bar$xxx$')).toBe( + '$xxx$foo $$ LEFT JOIN $yyy$ bar$xxx$' + ); + expect(format('$$foo JOIN bar$$')).toBe('$$foo JOIN bar$$'); + expect(format('$$foo $ JOIN bar$$')).toBe('$$foo $ JOIN bar$$'); + expect(format('$$foo \n bar$$')).toBe('$$foo \n bar$$'); + expect(format('SELECT $$where$$ FROM $$update$$')).toBe(dedent` + SELECT + $$where$$ + FROM + $$update$$ + `); + }); }); From 142734f495a804868bd9ea420e8eba19d6dafb14 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 17:41:03 +0300 Subject: [PATCH 095/334] Add hex-strings support to Spark --- src/languages/spark.formatter.ts | 2 +- test/spark.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/languages/spark.formatter.ts b/src/languages/spark.formatter.ts index 2f47de4d24..c7269d5d79 100644 --- a/src/languages/spark.formatter.ts +++ b/src/languages/spark.formatter.ts @@ -789,7 +789,7 @@ export default class SparkFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...reservedKeywords, ]), - stringTypes: ["''"], + stringTypes: ["''", { prefix: 'X', quote: "''" }], identifierTypes: ['``'], operators: SparkFormatter.operators, preprocess, diff --git a/test/spark.test.ts b/test/spark.test.ts index 2568f703d2..1aa20d907b 100644 --- a/test/spark.test.ts +++ b/test/spark.test.ts @@ -22,7 +22,7 @@ describe('SparkFormatter', () => { supportsComments(format); supportsCreateTable(format); supportsAlterTable(format); - supportsStrings(format, ["''"]); + supportsStrings(format, ["''", "X''"]); supportsIdentifiers(format, ['``']); supportsBetween(format); supportsSchema(format); From 41ec0a4c1d7449bcd78d5c2677339dadc2242f93 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 17:42:59 +0300 Subject: [PATCH 096/334] Support hex-strings in SQLite --- src/languages/sqlite.formatter.ts | 2 +- test/sqlite.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/languages/sqlite.formatter.ts b/src/languages/sqlite.formatter.ts index 0c5896f93c..0d53279d9e 100644 --- a/src/languages/sqlite.formatter.ts +++ b/src/languages/sqlite.formatter.ts @@ -430,7 +430,7 @@ export default class SqliteFormatter extends Formatter { reservedDependentClauses, // https://www.sqlite.org/lang_keywords.html reservedKeywords: [...standardReservedWords, ...nonStandardSqliteReservedWords], - stringTypes: ["''"], + stringTypes: ["''", { prefix: 'X', quote: "''" }], identifierTypes: [`""`, '``', '[]'], // https://www.sqlite.org/lang_expr.html#parameters indexedPlaceholderTypes: ['?'], diff --git a/test/sqlite.test.ts b/test/sqlite.test.ts index ee69d504b4..c2e1845691 100644 --- a/test/sqlite.test.ts +++ b/test/sqlite.test.ts @@ -26,7 +26,7 @@ describe('SqliteFormatter', () => { supportsConstraints(format); supportsAlterTable(format); supportsDeleteFrom(format); - supportsStrings(format, ["''"]); + supportsStrings(format, ["''", "X''"]); supportsIdentifiers(format, [`""`, '``', '[]']); supportsBetween(format); supportsSchema(format); From 65b135c7708a4ea3bb46bc1dc58769c3160ec42f Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 17:45:54 +0300 Subject: [PATCH 097/334] Add hex-strings to standard SQL formatter --- src/languages/sql.formatter.ts | 2 +- test/sql.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/languages/sql.formatter.ts b/src/languages/sql.formatter.ts index 737ab16f53..7f7200c022 100644 --- a/src/languages/sql.formatter.ts +++ b/src/languages/sql.formatter.ts @@ -377,7 +377,7 @@ export default class SqlFormatter extends Formatter { reservedBinaryCommands, reservedDependentClauses, reservedKeywords: dedupe(reservedKeywords), - stringTypes: ["''"], + stringTypes: ["''", { prefix: 'X', quote: "''" }], identifierTypes: [`""`, '``'], indexedPlaceholderTypes: ['?'], }); diff --git a/test/sql.test.ts b/test/sql.test.ts index f69a2368a4..5b583f63c1 100644 --- a/test/sql.test.ts +++ b/test/sql.test.ts @@ -26,7 +26,7 @@ describe('SqlFormatter', () => { supportsConstraints(format); supportsAlterTable(format); supportsDeleteFrom(format); - supportsStrings(format, ["''"]); + supportsStrings(format, ["''", "X''"]); supportsIdentifiers(format, [`""`, '``']); supportsBetween(format); supportsSchema(format); From 5a468a79b0e574f3050d17961e1073224cdd96a8 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 18:36:40 +0300 Subject: [PATCH 098/334] Triple-quoted strings support for BigQuery --- src/core/regexFactory.ts | 4 ++++ src/languages/bigquery.formatter.ts | 13 +++++++++++- test/bigquery.test.ts | 31 +++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 3e2581ec8e..fb18e055d2 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -74,12 +74,16 @@ export const createWordRegex = ( // 3. double quoted using "" or \" to escape // 4. single quoted using '' or \' to escape // 5. PostgreSQL dollar-quoted +// 6. BigQuery '''triple-quoted''' +// 7. BigQuery """triple-quoted""" const quotePatterns = { '``': '(`[^`]*($|`))+', '[]': '(\\[[^\\]]*($|\\]))(\\][^\\]]*($|\\]))*', '""': '("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+', "''": "('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", '$$': '(?\\$\\w*\\$)[\\s\\S]*?(?:\\k|$)', + "'''..'''": "'''[^\\\\]*?(?:\\\\.[^\\\\]*?)*?('''|$)", + '""".."""': '"""[^\\\\]*?(?:\\\\.[^\\\\]*?)*?("""|$)', }; export type PlainQuoteType = keyof typeof quotePatterns; diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index 97e1dff77a..7897fa948d 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -836,8 +836,19 @@ export default class BigQueryFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), - // TODO: add '''''', """""" stringTypes: [ + // The triple-quoted strings are listed first, so they get matched first. + // Otherwise the first two quotes of """ will get matched as an empty "" string. + '""".."""', + { prefix: 'R', quote: '""".."""' }, + { prefix: 'B', quote: '""".."""' }, + { prefix: 'RB', quote: '""".."""' }, + { prefix: 'BR', quote: '""".."""' }, + "'''..'''", + { prefix: 'R', quote: "'''..'''" }, + { prefix: 'B', quote: "'''..'''" }, + { prefix: 'RB', quote: "'''..'''" }, + { prefix: 'BR', quote: "'''..'''" }, '""', { prefix: 'R', quote: '""' }, { prefix: 'B', quote: '""' }, diff --git a/test/bigquery.test.ts b/test/bigquery.test.ts index 43fd099002..c414b55248 100644 --- a/test/bigquery.test.ts +++ b/test/bigquery.test.ts @@ -71,6 +71,37 @@ describe('BigQueryFormatter', () => { `); }); + it('supports triple-quoted strings', () => { + expect( + format(`SELECT '''hello 'my' world''', """hello "my" world""", """\\"quoted\\"""" FROM foo`) + ).toBe(dedent` + SELECT + '''hello 'my' world''', + """hello "my" world""", + """\\"quoted\\"""" + FROM + foo + `); + }); + + it('supports strings with r, b and rb prefixes with triple-quoted strings', () => { + expect( + format( + `SELECT R'''blah''', B'''sah''', rb"""hu"h""", br'''bulu bulu''', r"""haha""", BR'''la' la''' FROM foo` + ) + ).toBe(dedent` + SELECT + R'''blah''', + B'''sah''', + rb"""hu"h""", + br'''bulu bulu''', + r"""haha""", + BR'''la' la''' + FROM + foo + `); + }); + it('supports STRUCT types', () => { const result = format( 'SELECT STRUCT("Alpha" as name, [23.4, 26.3, 26.4, 26.1] as splits) FROM beta' From 89e45046c7352e3d75db0d834af7fce904540161 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 20:28:52 +0300 Subject: [PATCH 099/334] Separate positional ? placeholders from indexed ones --- src/core/Tokenizer.ts | 20 ++++++++++++++++---- src/languages/bigquery.formatter.ts | 2 +- src/languages/db2.formatter.ts | 2 +- src/languages/mariadb.formatter.ts | 2 +- src/languages/mysql.formatter.ts | 2 +- src/languages/n1ql.formatter.ts | 1 + src/languages/plsql.formatter.ts | 2 +- src/languages/redshift.formatter.ts | 1 - src/languages/sql.formatter.ts | 2 +- src/languages/sqlite.formatter.ts | 1 + test/behavesLikeMariaDbFormatter.ts | 2 +- test/bigquery.test.ts | 2 +- test/db2.test.ts | 2 +- test/n1ql.test.ts | 2 +- test/options/param.ts | 15 +++++++++------ test/plsql.test.ts | 2 +- test/redshift.test.ts | 2 +- test/sql.test.ts | 2 +- test/sqlite.test.ts | 2 +- 19 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index dce7d19d1f..3f3180eef1 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -19,6 +19,7 @@ interface TokenizerOptions { identifierTypes: regexFactory.QuoteType[]; blockStart?: string[]; blockEnd?: string[]; + positionalPlaceholders?: boolean; indexedPlaceholderTypes?: string[]; namedPlaceholderTypes?: string[]; lineCommentTypes?: string[]; @@ -31,6 +32,7 @@ interface TokenizerOptions { export default class Tokenizer { REGEX_MAP: { [tokenType in TokenType]: RegExp }; + POSITIONAL_PLACEHOLDER_REGEX?: RegExp; INDEXED_PLACEHOLDER_REGEX?: RegExp; IDENT_NAMED_PLACEHOLDER_REGEX?: RegExp; STRING_NAMED_PLACEHOLDER_REGEX?: RegExp; @@ -49,6 +51,7 @@ export default class Tokenizer { * @param {string[]} cfg.identifierTypes - identifier types to enable - "", ``, [], ... * @param {string[]} cfg.blockStart - Opening parentheses to enable, like (, [ * @param {string[]} cfg.blockEnd - Closing parentheses to enable, like ), ] + * @param {boolean} cfg.positionalPlaceholders - True to enable positional placeholders "?" * @param {string[]} cfg.indexedPlaceholderTypes - Prefixes for indexed placeholders, like ? * @param {string[]} cfg.namedPlaceholderTypes - Prefixes for named placeholders, like @ and : * @param {string[]} cfg.lineCommentTypes - Line comments to enable, like # and -- @@ -109,9 +112,10 @@ export default class Tokenizer { [TokenType.EOF]: NULL_REGEX, // matches nothing }; + this.POSITIONAL_PLACEHOLDER_REGEX = cfg.positionalPlaceholders ? /^(\?)/ : undefined; this.INDEXED_PLACEHOLDER_REGEX = regexFactory.createPlaceholderRegex( cfg.indexedPlaceholderTypes ?? [], - '[0-9]*' + '[0-9]+' ); this.IDENT_NAMED_PLACEHOLDER_REGEX = regexFactory.createPlaceholderRegex( cfg.namedPlaceholderTypes ?? [], @@ -211,17 +215,25 @@ export default class Tokenizer { regex: this.INDEXED_PLACEHOLDER_REGEX ?? NULL_REGEX, parseKey: v => v.slice(1), }, + // pattern for positional placeholder + { + regex: this.POSITIONAL_PLACEHOLDER_REGEX ?? NULL_REGEX, + parseKey: v => v.slice(1), + }, ]; - return placeholderTokenRegexMap.reduce((acc, { regex, parseKey }) => { + for (const { regex, parseKey } of placeholderTokenRegexMap) { const token = this.getTokenOnFirstMatch({ input, regex, type: TokenType.PLACEHOLDER, transform: id, }); - return token ? { ...token, key: parseKey(token.value) } : acc; - }, undefined as Token | undefined); + if (token) { + return { ...token, key: parseKey(token.value) }; + } + } + return undefined; } getEscapedPlaceholderKey({ key, quoteChar }: { key: string; quoteChar: string }): string { diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index 7897fa948d..b0806da3a9 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -861,7 +861,7 @@ export default class BigQueryFormatter extends Formatter { { prefix: 'BR', quote: "''" }, ], identifierTypes: ['``'], - indexedPlaceholderTypes: ['?'], + positionalPlaceholders: true, lineCommentTypes: ['--', '#'], specialWordChars: { any: '_@$-' }, operators: BigQueryFormatter.operators, diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index 6727a12b15..d52b770b16 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -879,7 +879,7 @@ export default class Db2Formatter extends Formatter { { prefix: 'U&', quote: "''" }, ], identifierTypes: [`""`], - indexedPlaceholderTypes: ['?'], + positionalPlaceholders: true, namedPlaceholderTypes: [':'], specialWordChars: { any: '#@' }, operators: Db2Formatter.operators, diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index fff6351c1b..3fd56fc3aa 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1166,7 +1166,7 @@ export default class MariaDbFormatter extends Formatter { reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: ["''", '""', { prefix: 'X', quote: "''" }], identifierTypes: ['``'], - indexedPlaceholderTypes: ['?'], + positionalPlaceholders: true, lineCommentTypes: ['--', '#'], specialWordChars: { prefix: '@' }, operators: MariaDbFormatter.operators, diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index 18b740a002..8b9763081f 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1329,7 +1329,7 @@ export default class MySqlFormatter extends Formatter { reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: ["''", '""', { prefix: 'X', quote: "''" }], identifierTypes: ['``'], - indexedPlaceholderTypes: ['?'], + positionalPlaceholders: true, lineCommentTypes: ['--', '#'], specialWordChars: { prefix: '@:' }, operators: MySqlFormatter.operators, diff --git a/src/languages/n1ql.formatter.ts b/src/languages/n1ql.formatter.ts index 25de59c2bf..ee369f2fc2 100644 --- a/src/languages/n1ql.formatter.ts +++ b/src/languages/n1ql.formatter.ts @@ -527,6 +527,7 @@ export default class N1qlFormatter extends Formatter { identifierTypes: ['``'], blockStart: ['(', '[', '{'], blockEnd: [')', ']', '}'], + positionalPlaceholders: true, namedPlaceholderTypes: ['$'], lineCommentTypes: ['#', '--'], operators: N1qlFormatter.operators, diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index c0544b6d36..0e5b362134 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -461,9 +461,9 @@ export default class PlSqlFormatter extends Formatter { reservedDependentClauses, reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe(reservedKeywords), + // TODO: support custom-delimited strings: Q'{..}' q'<..>' etc stringTypes: ["''", { prefix: 'N', quote: "''" }], identifierTypes: [`""`], - indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: [':'], specialWordChars: { any: '_$#' }, operators: PlSqlFormatter.operators, diff --git a/src/languages/redshift.formatter.ts b/src/languages/redshift.formatter.ts index 805c0cf3e3..5d360f1dc9 100644 --- a/src/languages/redshift.formatter.ts +++ b/src/languages/redshift.formatter.ts @@ -728,7 +728,6 @@ export default class RedshiftFormatter extends Formatter { ]), stringTypes: ["''"], identifierTypes: [`""`], - indexedPlaceholderTypes: ['?'], // XXX: Seems like redshift only supports $1, $2, $3 parameters, // but for some reason we list lots of types in here. // https://docs.aws.amazon.com/redshift/latest/dg/r_PREPARE.html diff --git a/src/languages/sql.formatter.ts b/src/languages/sql.formatter.ts index 7f7200c022..a6e2308a36 100644 --- a/src/languages/sql.formatter.ts +++ b/src/languages/sql.formatter.ts @@ -379,7 +379,7 @@ export default class SqlFormatter extends Formatter { reservedKeywords: dedupe(reservedKeywords), stringTypes: ["''", { prefix: 'X', quote: "''" }], identifierTypes: [`""`, '``'], - indexedPlaceholderTypes: ['?'], + positionalPlaceholders: true, }); } } diff --git a/src/languages/sqlite.formatter.ts b/src/languages/sqlite.formatter.ts index 0d53279d9e..ea21a6d714 100644 --- a/src/languages/sqlite.formatter.ts +++ b/src/languages/sqlite.formatter.ts @@ -433,6 +433,7 @@ export default class SqliteFormatter extends Formatter { stringTypes: ["''", { prefix: 'X', quote: "''" }], identifierTypes: [`""`, '``', '[]'], // https://www.sqlite.org/lang_expr.html#parameters + positionalPlaceholders: true, indexedPlaceholderTypes: ['?'], namedPlaceholderTypes: [':', '@', '$'], operators: SqliteFormatter.operators, diff --git a/test/behavesLikeMariaDbFormatter.ts b/test/behavesLikeMariaDbFormatter.ts index 185a2d33fd..41bc683bfc 100644 --- a/test/behavesLikeMariaDbFormatter.ts +++ b/test/behavesLikeMariaDbFormatter.ts @@ -36,7 +36,7 @@ export default function behavesLikeMariaDbFormatter(format: FormatFn) { 'NATURAL RIGHT OUTER JOIN', ], }); - supportsParams(format, { indexed: ['?'] }); + supportsParams(format, { positional: true }); it('supports @variables', () => { expect(format('SELECT @foo, @bar')).toBe(dedent` diff --git a/test/bigquery.test.ts b/test/bigquery.test.ts index c414b55248..0843fa75c4 100644 --- a/test/bigquery.test.ts +++ b/test/bigquery.test.ts @@ -28,7 +28,7 @@ describe('BigQueryFormatter', () => { supportsSchema(format); supportsJoin(format, { without: ['NATURAL JOIN'] }); supportsOperators(format, BigQueryFormatter.operators); - supportsParams(format, { indexed: ['?'] }); + supportsParams(format, { positional: true }); it('supports # line comment', () => { const result = format('SELECT alpha # commment\nFROM beta'); diff --git a/test/db2.test.ts b/test/db2.test.ts index 9dae01e4bd..fda2cb0d9d 100644 --- a/test/db2.test.ts +++ b/test/db2.test.ts @@ -32,7 +32,7 @@ describe('Db2Formatter', () => { supportsSchema(format); supportsOperators(format, Db2Formatter.operators); supportsJoin(format); - supportsParams(format, { indexed: ['?'], named: [':'] }); + supportsParams(format, { positional: true, named: [':'] }); it('formats FETCH FIRST like LIMIT', () => { expect(format('SELECT col1 FROM tbl ORDER BY col2 DESC FETCH FIRST 20 ROWS ONLY;')).toBe(dedent` diff --git a/test/n1ql.test.ts b/test/n1ql.test.ts index 1c7adbd46e..b3a69b9ae6 100644 --- a/test/n1ql.test.ts +++ b/test/n1ql.test.ts @@ -30,7 +30,7 @@ describe('N1qlFormatter', () => { supportsArray(format); supportsJoin(format, { without: ['FULL', 'CROSS', 'NATURAL'] }); supportsReturning(format); - supportsParams(format, { named: ['$'] }); + supportsParams(format, { positional: true, named: ['$'] }); it('formats SELECT query with primary key querying', () => { const result = format("SELECT fname, email FROM tutorial USE KEYS ['dave', 'ian'];"); diff --git a/test/options/param.ts b/test/options/param.ts index bd3e8fcd90..3033675ab4 100644 --- a/test/options/param.ts +++ b/test/options/param.ts @@ -2,14 +2,15 @@ import dedent from 'dedent-js'; import { FormatFn } from '../../src/sqlFormatter'; interface ParamsTypes { + positional?: boolean; indexed?: ('?' | '$')[]; named?: (':' | '$' | '@' | '@""' | '@[]')[]; } export default function supportsParams(format: FormatFn, params: ParamsTypes) { describe('supports params', () => { - if (params.indexed?.includes('?')) { - it('leaves ? indexed placeholders as is when no params config provided', () => { + if (params.positional) { + it('leaves ? positional placeholders as is when no params config provided', () => { const result = format('SELECT ?, ?, ?;'); expect(result).toBe(dedent` SELECT @@ -19,7 +20,7 @@ export default function supportsParams(format: FormatFn, params: ParamsTypes) { `); }); - it('replaces ? indexed placeholders with param values', () => { + it('replaces ? positional placeholders with param values', () => { const result = format('SELECT ?, ?, ?;', { params: ['first', 'second', 'third'], }); @@ -30,14 +31,16 @@ export default function supportsParams(format: FormatFn, params: ParamsTypes) { third; `); }); + } - it('recognizes ?[0-9]* placeholders', () => { - const result = format('SELECT ?1, ?25, ?;'); + if (params.indexed?.includes('?')) { + it('recognizes ? numbered placeholders', () => { + const result = format('SELECT ?1, ?25, ?2;'); expect(result).toBe(dedent` SELECT ?1, ?25, - ?; + ?2; `); }); diff --git a/test/plsql.test.ts b/test/plsql.test.ts index fbff3a9844..0d522d5c86 100644 --- a/test/plsql.test.ts +++ b/test/plsql.test.ts @@ -36,7 +36,7 @@ describe('PlSqlFormatter', () => { supportsOperators(format, PlSqlFormatter.operators, ['AND', 'OR', 'XOR']); supportsJoin(format); supportsReturning(format); - supportsParams(format, { indexed: ['?'], named: [':'] }); + supportsParams(format, { named: [':'] }); it('formats FETCH FIRST like LIMIT', () => { expect(format('SELECT col1 FROM tbl ORDER BY col2 DESC FETCH FIRST 20 ROWS ONLY;')).toBe(dedent` diff --git a/test/redshift.test.ts b/test/redshift.test.ts index 7d577dd445..35d6887f1d 100644 --- a/test/redshift.test.ts +++ b/test/redshift.test.ts @@ -30,7 +30,7 @@ describe('RedshiftFormatter', () => { supportsSchema(format); supportsOperators(format, RedshiftFormatter.operators); supportsJoin(format); - supportsParams(format, { indexed: ['?'], named: ['$', '@', '@""'] }); + supportsParams(format, { named: ['$', '@', '@""'] }); it('formats LIMIT', () => { expect(format('SELECT col1 FROM tbl ORDER BY col2 DESC LIMIT 10;')).toBe(dedent` diff --git a/test/sql.test.ts b/test/sql.test.ts index 5b583f63c1..714cc094d2 100644 --- a/test/sql.test.ts +++ b/test/sql.test.ts @@ -32,7 +32,7 @@ describe('SqlFormatter', () => { supportsSchema(format); supportsJoin(format); supportsOperators(format, SqlFormatter.operators); - supportsParams(format, { indexed: ['?'] }); + supportsParams(format, { positional: true }); it('formats FETCH FIRST like LIMIT', () => { const result = format('SELECT * FETCH FIRST 2 ROWS ONLY;'); diff --git a/test/sqlite.test.ts b/test/sqlite.test.ts index c2e1845691..3c5bd99d80 100644 --- a/test/sqlite.test.ts +++ b/test/sqlite.test.ts @@ -35,7 +35,7 @@ describe('SqliteFormatter', () => { additionally: ['NATURAL LEFT JOIN', 'NATURAL LEFT OUTER JOIN'], }); supportsOperators(format, SqliteFormatter.operators); - supportsParams(format, { indexed: ['?'], named: [':', '$', '@', '@""'] }); + supportsParams(format, { positional: true, indexed: ['?'], named: [':', '$', '@', '@""'] }); it('formats FETCH FIRST like LIMIT', () => { const result = format('SELECT * FETCH FIRST 2 ROWS ONLY;'); From 1a0d9045e58eaa22e3b23bcfbd9716306bac0e91 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 26 May 2022 20:52:32 +0300 Subject: [PATCH 100/334] Extract placeholder patterns array from getPlaceholderToken() --- src/core/Tokenizer.ts | 81 +++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 42 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 3f3180eef1..2612e017ff 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -28,14 +28,13 @@ interface TokenizerOptions { preprocess?: (tokens: Token[]) => Token[]; } +type PlaceholderPattern = { regex: RegExp; parseKey: (s: string) => string }; + /** Converts SQL language string into a token stream */ export default class Tokenizer { REGEX_MAP: { [tokenType in TokenType]: RegExp }; - POSITIONAL_PLACEHOLDER_REGEX?: RegExp; - INDEXED_PLACEHOLDER_REGEX?: RegExp; - IDENT_NAMED_PLACEHOLDER_REGEX?: RegExp; - STRING_NAMED_PLACEHOLDER_REGEX?: RegExp; + private placeholderPatterns: PlaceholderPattern[]; private preprocess = (tokens: Token[]) => tokens; @@ -112,19 +111,41 @@ export default class Tokenizer { [TokenType.EOF]: NULL_REGEX, // matches nothing }; - this.POSITIONAL_PLACEHOLDER_REGEX = cfg.positionalPlaceholders ? /^(\?)/ : undefined; - this.INDEXED_PLACEHOLDER_REGEX = regexFactory.createPlaceholderRegex( - cfg.indexedPlaceholderTypes ?? [], - '[0-9]+' - ); - this.IDENT_NAMED_PLACEHOLDER_REGEX = regexFactory.createPlaceholderRegex( - cfg.namedPlaceholderTypes ?? [], - '[a-zA-Z0-9._$]+' - ); - this.STRING_NAMED_PLACEHOLDER_REGEX = regexFactory.createPlaceholderRegex( - cfg.namedPlaceholderTypes ?? [], - regexFactory.createQuotePattern(cfg.identifierTypes) - ); + this.placeholderPatterns = this.excludePatternsWithoutRegexes([ + { + // :name placeholders + regex: regexFactory.createPlaceholderRegex( + cfg.namedPlaceholderTypes ?? [], + '[a-zA-Z0-9._$]+' + ), + parseKey: v => v.slice(1), + }, + { + // :"name" placeholders + regex: regexFactory.createPlaceholderRegex( + cfg.namedPlaceholderTypes ?? [], + regexFactory.createQuotePattern(cfg.identifierTypes) + ), + parseKey: v => + this.getEscapedPlaceholderKey({ key: v.slice(2, -1), quoteChar: v.slice(-1) }), + }, + { + // :1, :2, :3 placeholders + regex: regexFactory.createPlaceholderRegex(cfg.indexedPlaceholderTypes ?? [], '[0-9]+'), + parseKey: v => v.slice(1), + }, + { + // ? placeholders + regex: cfg.positionalPlaceholders ? /^(\?)/ : undefined, + parseKey: v => v.slice(1), + }, + ]); + } + + private excludePatternsWithoutRegexes( + patterns: { regex?: RegExp; parseKey: (s: string) => string }[] + ) { + return patterns.filter((p): p is PlaceholderPattern => p.regex !== undefined); } /** @@ -198,31 +219,7 @@ export default class Tokenizer { * @return {Token | undefined} - The placeholder token if found, otherwise undefined */ getPlaceholderToken(input: string): Token | undefined { - const placeholderTokenRegexMap: { regex: RegExp; parseKey: (s: string) => string }[] = [ - // pattern for placeholder with identifier name - { - regex: this.IDENT_NAMED_PLACEHOLDER_REGEX ?? NULL_REGEX, - parseKey: v => v.slice(1), - }, - // pattern for placeholder with string name - { - regex: this.STRING_NAMED_PLACEHOLDER_REGEX ?? NULL_REGEX, - parseKey: v => - this.getEscapedPlaceholderKey({ key: v.slice(2, -1), quoteChar: v.slice(-1) }), - }, - // pattern for placeholder with numeric index - { - regex: this.INDEXED_PLACEHOLDER_REGEX ?? NULL_REGEX, - parseKey: v => v.slice(1), - }, - // pattern for positional placeholder - { - regex: this.POSITIONAL_PLACEHOLDER_REGEX ?? NULL_REGEX, - parseKey: v => v.slice(1), - }, - ]; - - for (const { regex, parseKey } of placeholderTokenRegexMap) { + for (const { regex, parseKey } of this.placeholderPatterns) { const token = this.getTokenOnFirstMatch({ input, regex, From 0c1b578d53d5fc13875645029d14f31e668f47e5 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 10:05:49 +0300 Subject: [PATCH 101/334] Add indexed placeholders to N1QL --- src/languages/n1ql.formatter.ts | 1 + test/n1ql.test.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/languages/n1ql.formatter.ts b/src/languages/n1ql.formatter.ts index ee369f2fc2..ed2ef73c0d 100644 --- a/src/languages/n1ql.formatter.ts +++ b/src/languages/n1ql.formatter.ts @@ -528,6 +528,7 @@ export default class N1qlFormatter extends Formatter { blockStart: ['(', '[', '{'], blockEnd: [')', ']', '}'], positionalPlaceholders: true, + indexedPlaceholderTypes: ['$'], namedPlaceholderTypes: ['$'], lineCommentTypes: ['#', '--'], operators: N1qlFormatter.operators, diff --git a/test/n1ql.test.ts b/test/n1ql.test.ts index b3a69b9ae6..34d62f3e0c 100644 --- a/test/n1ql.test.ts +++ b/test/n1ql.test.ts @@ -30,7 +30,7 @@ describe('N1qlFormatter', () => { supportsArray(format); supportsJoin(format, { without: ['FULL', 'CROSS', 'NATURAL'] }); supportsReturning(format); - supportsParams(format, { positional: true, named: ['$'] }); + supportsParams(format, { positional: true, indexed: ['$'], named: ['$'] }); it('formats SELECT query with primary key querying', () => { const result = format("SELECT fname, email FROM tutorial USE KEYS ['dave', 'ian'];"); From ef43d946dbbed0c4d899e538144830ad22c0f745 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 10:10:48 +0300 Subject: [PATCH 102/334] Add indexed placeholders to PL/SQL --- src/languages/plsql.formatter.ts | 1 + test/options/param.ts | 28 +++++++++++++++++++++++++++- test/plsql.test.ts | 2 +- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 0e5b362134..4e58cc6d9e 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -464,6 +464,7 @@ export default class PlSqlFormatter extends Formatter { // TODO: support custom-delimited strings: Q'{..}' q'<..>' etc stringTypes: ["''", { prefix: 'N', quote: "''" }], identifierTypes: [`""`], + indexedPlaceholderTypes: [':'], namedPlaceholderTypes: [':'], specialWordChars: { any: '_$#' }, operators: PlSqlFormatter.operators, diff --git a/test/options/param.ts b/test/options/param.ts index 3033675ab4..332dfe1309 100644 --- a/test/options/param.ts +++ b/test/options/param.ts @@ -3,7 +3,7 @@ import { FormatFn } from '../../src/sqlFormatter'; interface ParamsTypes { positional?: boolean; - indexed?: ('?' | '$')[]; + indexed?: ('?' | '$' | ':')[]; named?: (':' | '$' | '@' | '@""' | '@[]')[]; } @@ -87,6 +87,32 @@ export default function supportsParams(format: FormatFn, params: ParamsTypes) { }); } + if (params.indexed?.includes(':')) { + it('recognizes :n placeholders', () => { + const result = format('SELECT :1, :2 FROM tbl'); + expect(result).toBe(dedent` + SELECT + :1, + :2 + FROM + tbl + `); + }); + + it('replaces :n placeholders with param values', () => { + const result = format('SELECT :1, :2 FROM tbl', { + params: { 1: '"variable value"', 2: '"blah"' }, + }); + expect(result).toBe(dedent` + SELECT + "variable value", + "blah" + FROM + tbl + `); + }); + } + if (params.named?.includes(':')) { it('recognizes :name placeholders', () => { expect(format('SELECT :foo, :bar, :baz;')).toBe(dedent` diff --git a/test/plsql.test.ts b/test/plsql.test.ts index 0d522d5c86..45466bc50a 100644 --- a/test/plsql.test.ts +++ b/test/plsql.test.ts @@ -36,7 +36,7 @@ describe('PlSqlFormatter', () => { supportsOperators(format, PlSqlFormatter.operators, ['AND', 'OR', 'XOR']); supportsJoin(format); supportsReturning(format); - supportsParams(format, { named: [':'] }); + supportsParams(format, { indexed: [':'], named: [':'] }); it('formats FETCH FIRST like LIMIT', () => { expect(format('SELECT col1 FROM tbl ORDER BY col2 DESC FETCH FIRST 20 ROWS ONLY;')).toBe(dedent` From 05402e231d2a25275968ada2ec9d10d793fa1f01 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 10:12:34 +0300 Subject: [PATCH 103/334] Replace named placeholders with indexed in Redshift --- src/languages/redshift.formatter.ts | 5 +---- test/redshift.test.ts | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/languages/redshift.formatter.ts b/src/languages/redshift.formatter.ts index 5d360f1dc9..38bc6338ea 100644 --- a/src/languages/redshift.formatter.ts +++ b/src/languages/redshift.formatter.ts @@ -728,10 +728,7 @@ export default class RedshiftFormatter extends Formatter { ]), stringTypes: ["''"], identifierTypes: [`""`], - // XXX: Seems like redshift only supports $1, $2, $3 parameters, - // but for some reason we list lots of types in here. - // https://docs.aws.amazon.com/redshift/latest/dg/r_PREPARE.html - namedPlaceholderTypes: ['@', '#', '$'], + indexedPlaceholderTypes: ['$'], operators: RedshiftFormatter.operators, }); } diff --git a/test/redshift.test.ts b/test/redshift.test.ts index 35d6887f1d..dfb4771826 100644 --- a/test/redshift.test.ts +++ b/test/redshift.test.ts @@ -30,7 +30,7 @@ describe('RedshiftFormatter', () => { supportsSchema(format); supportsOperators(format, RedshiftFormatter.operators); supportsJoin(format); - supportsParams(format, { named: ['$', '@', '@""'] }); + supportsParams(format, { indexed: ['$'] }); it('formats LIMIT', () => { expect(format('SELECT col1 FROM tbl ORDER BY col2 DESC LIMIT 10;')).toBe(dedent` From 28d8e22a7bb5cc034fc33cc428172307967fa8e4 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 10:17:26 +0300 Subject: [PATCH 104/334] Rename indexed- to numbered-placeholders --- src/core/Tokenizer.ts | 6 +++--- src/languages/n1ql.formatter.ts | 2 +- src/languages/plsql.formatter.ts | 2 +- src/languages/postgresql.formatter.ts | 2 +- src/languages/redshift.formatter.ts | 2 +- src/languages/sqlite.formatter.ts | 2 +- test/n1ql.test.ts | 2 +- test/options/param.ts | 8 ++++---- test/plsql.test.ts | 2 +- test/postgresql.test.ts | 2 +- test/redshift.test.ts | 2 +- test/sqlite.test.ts | 2 +- 12 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 2612e017ff..b36165163d 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -20,7 +20,7 @@ interface TokenizerOptions { blockStart?: string[]; blockEnd?: string[]; positionalPlaceholders?: boolean; - indexedPlaceholderTypes?: string[]; + numberedPlaceholderTypes?: string[]; namedPlaceholderTypes?: string[]; lineCommentTypes?: string[]; specialWordChars?: { prefix?: string; any?: string; suffix?: string }; @@ -51,7 +51,7 @@ export default class Tokenizer { * @param {string[]} cfg.blockStart - Opening parentheses to enable, like (, [ * @param {string[]} cfg.blockEnd - Closing parentheses to enable, like ), ] * @param {boolean} cfg.positionalPlaceholders - True to enable positional placeholders "?" - * @param {string[]} cfg.indexedPlaceholderTypes - Prefixes for indexed placeholders, like ? + * @param {string[]} cfg.numberedPlaceholderTypes - Prefixes for numbered placeholders, like ":" for :1, :2, :3 * @param {string[]} cfg.namedPlaceholderTypes - Prefixes for named placeholders, like @ and : * @param {string[]} cfg.lineCommentTypes - Line comments to enable, like # and -- * @param {string[]} cfg.specialWordChars - Special chars that can be found inside of words, like @ and # @@ -131,7 +131,7 @@ export default class Tokenizer { }, { // :1, :2, :3 placeholders - regex: regexFactory.createPlaceholderRegex(cfg.indexedPlaceholderTypes ?? [], '[0-9]+'), + regex: regexFactory.createPlaceholderRegex(cfg.numberedPlaceholderTypes ?? [], '[0-9]+'), parseKey: v => v.slice(1), }, { diff --git a/src/languages/n1ql.formatter.ts b/src/languages/n1ql.formatter.ts index ed2ef73c0d..25a1d762f7 100644 --- a/src/languages/n1ql.formatter.ts +++ b/src/languages/n1ql.formatter.ts @@ -528,7 +528,7 @@ export default class N1qlFormatter extends Formatter { blockStart: ['(', '[', '{'], blockEnd: [')', ']', '}'], positionalPlaceholders: true, - indexedPlaceholderTypes: ['$'], + numberedPlaceholderTypes: ['$'], namedPlaceholderTypes: ['$'], lineCommentTypes: ['#', '--'], operators: N1qlFormatter.operators, diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 4e58cc6d9e..4bb6ebf7e8 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -464,7 +464,7 @@ export default class PlSqlFormatter extends Formatter { // TODO: support custom-delimited strings: Q'{..}' q'<..>' etc stringTypes: ["''", { prefix: 'N', quote: "''" }], identifierTypes: [`""`], - indexedPlaceholderTypes: [':'], + numberedPlaceholderTypes: [':'], namedPlaceholderTypes: [':'], specialWordChars: { any: '_$#' }, operators: PlSqlFormatter.operators, diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index f907abe9c6..161282103f 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1690,7 +1690,7 @@ export default class PostgreSqlFormatter extends Formatter { { prefix: 'B', quote: "''" }, ], identifierTypes: [`""`, { prefix: 'U&', quote: '""' }], - indexedPlaceholderTypes: ['$'], + numberedPlaceholderTypes: ['$'], namedPlaceholderTypes: [':'], operators: PostgreSqlFormatter.operators, }); diff --git a/src/languages/redshift.formatter.ts b/src/languages/redshift.formatter.ts index 38bc6338ea..843d2396a7 100644 --- a/src/languages/redshift.formatter.ts +++ b/src/languages/redshift.formatter.ts @@ -728,7 +728,7 @@ export default class RedshiftFormatter extends Formatter { ]), stringTypes: ["''"], identifierTypes: [`""`], - indexedPlaceholderTypes: ['$'], + numberedPlaceholderTypes: ['$'], operators: RedshiftFormatter.operators, }); } diff --git a/src/languages/sqlite.formatter.ts b/src/languages/sqlite.formatter.ts index ea21a6d714..0d35f1160e 100644 --- a/src/languages/sqlite.formatter.ts +++ b/src/languages/sqlite.formatter.ts @@ -434,7 +434,7 @@ export default class SqliteFormatter extends Formatter { identifierTypes: [`""`, '``', '[]'], // https://www.sqlite.org/lang_expr.html#parameters positionalPlaceholders: true, - indexedPlaceholderTypes: ['?'], + numberedPlaceholderTypes: ['?'], namedPlaceholderTypes: [':', '@', '$'], operators: SqliteFormatter.operators, }); diff --git a/test/n1ql.test.ts b/test/n1ql.test.ts index 34d62f3e0c..edcbb75294 100644 --- a/test/n1ql.test.ts +++ b/test/n1ql.test.ts @@ -30,7 +30,7 @@ describe('N1qlFormatter', () => { supportsArray(format); supportsJoin(format, { without: ['FULL', 'CROSS', 'NATURAL'] }); supportsReturning(format); - supportsParams(format, { positional: true, indexed: ['$'], named: ['$'] }); + supportsParams(format, { positional: true, numbered: ['$'], named: ['$'] }); it('formats SELECT query with primary key querying', () => { const result = format("SELECT fname, email FROM tutorial USE KEYS ['dave', 'ian'];"); diff --git a/test/options/param.ts b/test/options/param.ts index 332dfe1309..6c1f4255ed 100644 --- a/test/options/param.ts +++ b/test/options/param.ts @@ -3,7 +3,7 @@ import { FormatFn } from '../../src/sqlFormatter'; interface ParamsTypes { positional?: boolean; - indexed?: ('?' | '$' | ':')[]; + numbered?: ('?' | '$' | ':')[]; named?: (':' | '$' | '@' | '@""' | '@[]')[]; } @@ -33,7 +33,7 @@ export default function supportsParams(format: FormatFn, params: ParamsTypes) { }); } - if (params.indexed?.includes('?')) { + if (params.numbered?.includes('?')) { it('recognizes ? numbered placeholders', () => { const result = format('SELECT ?1, ?25, ?2;'); expect(result).toBe(dedent` @@ -61,7 +61,7 @@ export default function supportsParams(format: FormatFn, params: ParamsTypes) { }); } - if (params.indexed?.includes('$')) { + if (params.numbered?.includes('$')) { it('recognizes $n placeholders', () => { const result = format('SELECT $1, $2 FROM tbl'); expect(result).toBe(dedent` @@ -87,7 +87,7 @@ export default function supportsParams(format: FormatFn, params: ParamsTypes) { }); } - if (params.indexed?.includes(':')) { + if (params.numbered?.includes(':')) { it('recognizes :n placeholders', () => { const result = format('SELECT :1, :2 FROM tbl'); expect(result).toBe(dedent` diff --git a/test/plsql.test.ts b/test/plsql.test.ts index 45466bc50a..3b73611f97 100644 --- a/test/plsql.test.ts +++ b/test/plsql.test.ts @@ -36,7 +36,7 @@ describe('PlSqlFormatter', () => { supportsOperators(format, PlSqlFormatter.operators, ['AND', 'OR', 'XOR']); supportsJoin(format); supportsReturning(format); - supportsParams(format, { indexed: [':'], named: [':'] }); + supportsParams(format, { numbered: [':'], named: [':'] }); it('formats FETCH FIRST like LIMIT', () => { expect(format('SELECT col1 FROM tbl ORDER BY col2 DESC FETCH FIRST 20 ROWS ONLY;')).toBe(dedent` diff --git a/test/postgresql.test.ts b/test/postgresql.test.ts index ca92fbdbbb..7e41954e47 100644 --- a/test/postgresql.test.ts +++ b/test/postgresql.test.ts @@ -34,7 +34,7 @@ describe('PostgreSqlFormatter', () => { supportsOperators(format, PostgreSqlFormatter.operators); supportsJoin(format); supportsReturning(format); - supportsParams(format, { indexed: ['$'], named: [':'] }); + supportsParams(format, { numbered: ['$'], named: [':'] }); // Postgres-specific string types it('supports bit strings', () => { diff --git a/test/redshift.test.ts b/test/redshift.test.ts index dfb4771826..b97fe63fa6 100644 --- a/test/redshift.test.ts +++ b/test/redshift.test.ts @@ -30,7 +30,7 @@ describe('RedshiftFormatter', () => { supportsSchema(format); supportsOperators(format, RedshiftFormatter.operators); supportsJoin(format); - supportsParams(format, { indexed: ['$'] }); + supportsParams(format, { numbered: ['$'] }); it('formats LIMIT', () => { expect(format('SELECT col1 FROM tbl ORDER BY col2 DESC LIMIT 10;')).toBe(dedent` diff --git a/test/sqlite.test.ts b/test/sqlite.test.ts index 3c5bd99d80..1c96621ba3 100644 --- a/test/sqlite.test.ts +++ b/test/sqlite.test.ts @@ -35,7 +35,7 @@ describe('SqliteFormatter', () => { additionally: ['NATURAL LEFT JOIN', 'NATURAL LEFT OUTER JOIN'], }); supportsOperators(format, SqliteFormatter.operators); - supportsParams(format, { positional: true, indexed: ['?'], named: [':', '$', '@', '@""'] }); + supportsParams(format, { positional: true, numbered: ['?'], named: [':', '$', '@', '@""'] }); it('formats FETCH FIRST like LIMIT', () => { const result = format('SELECT * FETCH FIRST 2 ROWS ONLY;'); From 513e4727eeb2f4df8fd9d73baad1e5a9ac018745 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 10:31:26 +0300 Subject: [PATCH 105/334] Remove named placeholders from Postgres --- src/languages/postgresql.formatter.ts | 1 - test/postgresql.test.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index 161282103f..4f6c5caf6d 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1691,7 +1691,6 @@ export default class PostgreSqlFormatter extends Formatter { ], identifierTypes: [`""`, { prefix: 'U&', quote: '""' }], numberedPlaceholderTypes: ['$'], - namedPlaceholderTypes: [':'], operators: PostgreSqlFormatter.operators, }); } diff --git a/test/postgresql.test.ts b/test/postgresql.test.ts index 7e41954e47..3e8e827345 100644 --- a/test/postgresql.test.ts +++ b/test/postgresql.test.ts @@ -34,7 +34,7 @@ describe('PostgreSqlFormatter', () => { supportsOperators(format, PostgreSqlFormatter.operators); supportsJoin(format); supportsReturning(format); - supportsParams(format, { numbered: ['$'], named: [':'] }); + supportsParams(format, { numbered: ['$'] }); // Postgres-specific string types it('supports bit strings', () => { From 9750aac98628bd0bde7b3115290d5a29a45caf3f Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 10:33:49 +0300 Subject: [PATCH 106/334] Drop @".." placeholder support from SQLite This commit just drops the tests, the next commit will drop the actual support. --- test/sqlite.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sqlite.test.ts b/test/sqlite.test.ts index 1c96621ba3..53a45acff9 100644 --- a/test/sqlite.test.ts +++ b/test/sqlite.test.ts @@ -35,7 +35,7 @@ describe('SqliteFormatter', () => { additionally: ['NATURAL LEFT JOIN', 'NATURAL LEFT OUTER JOIN'], }); supportsOperators(format, SqliteFormatter.operators); - supportsParams(format, { positional: true, numbered: ['?'], named: [':', '$', '@', '@""'] }); + supportsParams(format, { positional: true, numbered: ['?'], named: [':', '$', '@'] }); it('formats FETCH FIRST like LIMIT', () => { const result = format('SELECT * FETCH FIRST 2 ROWS ONLY;'); From 4f4a73fde1d93b7ce757ef115107e0aa09454738 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 10:35:23 +0300 Subject: [PATCH 107/334] Split named placeholders to two: named and quoted For start only Transact-SQL supports the latter --- src/core/Tokenizer.ts | 3 ++- src/languages/tsql.formatter.ts | 1 + test/options/param.ts | 7 ++++--- test/tsql.test.ts | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index b36165163d..4cdcd0d291 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -22,6 +22,7 @@ interface TokenizerOptions { positionalPlaceholders?: boolean; numberedPlaceholderTypes?: string[]; namedPlaceholderTypes?: string[]; + quotedPlaceholderTypes?: string[]; lineCommentTypes?: string[]; specialWordChars?: { prefix?: string; any?: string; suffix?: string }; operators?: string[]; @@ -123,7 +124,7 @@ export default class Tokenizer { { // :"name" placeholders regex: regexFactory.createPlaceholderRegex( - cfg.namedPlaceholderTypes ?? [], + cfg.quotedPlaceholderTypes ?? [], regexFactory.createQuotePattern(cfg.identifierTypes) ), parseKey: v => diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index 1abe40767b..06f9ba027f 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1245,6 +1245,7 @@ export default class TSqlFormatter extends Formatter { stringTypes: ["''", { prefix: 'N', quote: "''" }], identifierTypes: [`""`, '[]'], namedPlaceholderTypes: ['@'], + quotedPlaceholderTypes: ['@'], specialWordChars: { any: '#@' }, operators: TSqlFormatter.operators, // TODO: Support for money constants diff --git a/test/options/param.ts b/test/options/param.ts index 6c1f4255ed..0c98b1d869 100644 --- a/test/options/param.ts +++ b/test/options/param.ts @@ -4,7 +4,8 @@ import { FormatFn } from '../../src/sqlFormatter'; interface ParamsTypes { positional?: boolean; numbered?: ('?' | '$' | ':')[]; - named?: (':' | '$' | '@' | '@""' | '@[]')[]; + named?: (':' | '$' | '@')[]; + quoted?: ('@""' | '@[]')[]; } export default function supportsParams(format: FormatFn, params: ParamsTypes) { @@ -199,7 +200,7 @@ export default function supportsParams(format: FormatFn, params: ParamsTypes) { }); } - if (params.named?.includes('@""')) { + if (params.quoted?.includes('@""')) { it(`recognizes @"name" placeholders`, () => { expect(format(`SELECT @"foo", @"foo bar";`)).toBe(dedent` SELECT @@ -221,7 +222,7 @@ export default function supportsParams(format: FormatFn, params: ParamsTypes) { }); } - if (params.named?.includes('@[]')) { + if (params.quoted?.includes('@[]')) { it(`recognizes @[name] placeholders`, () => { expect(format(`SELECT @[foo], @[foo bar];`)).toBe(dedent` SELECT diff --git a/test/tsql.test.ts b/test/tsql.test.ts index fbe8a8ad30..a9de71b53c 100644 --- a/test/tsql.test.ts +++ b/test/tsql.test.ts @@ -32,7 +32,7 @@ describe('TSqlFormatter', () => { supportsSchema(format); supportsOperators(format, TSqlFormatter.operators); supportsJoin(format, { without: ['NATURAL'] }); - supportsParams(format, { named: ['@', '@""', '@[]'] }); + supportsParams(format, { named: ['@'], quoted: ['@""', '@[]'] }); // TODO: The following are duplicated from StandardSQLFormatter test From 8e5ec88e2e87a0b59fa94587941cc6c9bd730999 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 10:37:24 +0300 Subject: [PATCH 108/334] Update docs for Transact-SQL parameter syntax --- sql/parameters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/parameters.md b/sql/parameters.md index 769c228343..ac80d6ed32 100644 --- a/sql/parameters.md +++ b/sql/parameters.md @@ -32,7 +32,7 @@ These come in the form of single question mark (`?`), supported by: - [N1QL][]: `$` followed by unquoted [identifier][] - [PL/SQL][]: colon (`:`) followed by name (`[a-zA-Z][a-zA-Z0-9_]*`) - [SQLite][]: `$`, `@` or `:` followed by unquoted [identifier][] -- [Transact-SQL][]: `@` or `:`3 followed by name (see also [identifier][] syntax) +- [Transact-SQL][]: `@` or `:`3 followed by [identifier][] (either quoted or unquoted) ### Notes: From ff6e1ffee1546679f7798c0ac0a43e0ec577f448 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 10:40:57 +0300 Subject: [PATCH 109/334] Add named and quoted params to BigQuery --- src/languages/bigquery.formatter.ts | 2 ++ test/bigquery.test.ts | 2 +- test/options/param.ts | 24 +++++++++++++++++++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index b0806da3a9..9a293d30ad 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -862,6 +862,8 @@ export default class BigQueryFormatter extends Formatter { ], identifierTypes: ['``'], positionalPlaceholders: true, + namedPlaceholderTypes: ['@'], + quotedPlaceholderTypes: ['@'], lineCommentTypes: ['--', '#'], specialWordChars: { any: '_@$-' }, operators: BigQueryFormatter.operators, diff --git a/test/bigquery.test.ts b/test/bigquery.test.ts index 0843fa75c4..f35164769c 100644 --- a/test/bigquery.test.ts +++ b/test/bigquery.test.ts @@ -28,7 +28,7 @@ describe('BigQueryFormatter', () => { supportsSchema(format); supportsJoin(format, { without: ['NATURAL JOIN'] }); supportsOperators(format, BigQueryFormatter.operators); - supportsParams(format, { positional: true }); + supportsParams(format, { positional: true, named: ['@'], quoted: ['@``'] }); it('supports # line comment', () => { const result = format('SELECT alpha # commment\nFROM beta'); diff --git a/test/options/param.ts b/test/options/param.ts index 0c98b1d869..fb3c2e4743 100644 --- a/test/options/param.ts +++ b/test/options/param.ts @@ -5,7 +5,7 @@ interface ParamsTypes { positional?: boolean; numbered?: ('?' | '$' | ':')[]; named?: (':' | '$' | '@')[]; - quoted?: ('@""' | '@[]')[]; + quoted?: ('@""' | '@[]' | '@``')[]; } export default function supportsParams(format: FormatFn, params: ParamsTypes) { @@ -243,4 +243,26 @@ export default function supportsParams(format: FormatFn, params: ParamsTypes) { `); }); } + + if (params.quoted?.includes('@``')) { + it('recognizes @`name` placeholders', () => { + expect(format('SELECT @`foo`, @`foo bar`;')).toBe(dedent` + SELECT + @\`foo\`, + @\`foo bar\`; + `); + }); + + it('replaces @`name` placeholders with param values', () => { + expect( + format('WHERE name = @`name` AND age > @`current age`;', { + params: { 'name': "'John'", 'current age': '10' }, + }) + ).toBe(dedent` + WHERE + name = 'John' + AND age > 10; + `); + }); + } } From dc43652e592934105bc3aba0a680803785beb79b Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 10:44:08 +0300 Subject: [PATCH 110/334] Remove dot (.) from placeholder names No idea why it was there, but it really shouldn't have been as it's the table.column separator. --- src/core/Tokenizer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 4cdcd0d291..d692387afb 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -117,7 +117,7 @@ export default class Tokenizer { // :name placeholders regex: regexFactory.createPlaceholderRegex( cfg.namedPlaceholderTypes ?? [], - '[a-zA-Z0-9._$]+' + '[a-zA-Z0-9_$]+' ), parseKey: v => v.slice(1), }, From a252bdb05494e662491b162508c0b73550dfc1f6 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 12:06:11 +0300 Subject: [PATCH 111/334] Restrict placeholder types --- src/core/Tokenizer.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index d692387afb..9c8a52ef83 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -20,9 +20,9 @@ interface TokenizerOptions { blockStart?: string[]; blockEnd?: string[]; positionalPlaceholders?: boolean; - numberedPlaceholderTypes?: string[]; - namedPlaceholderTypes?: string[]; - quotedPlaceholderTypes?: string[]; + numberedPlaceholderTypes?: ('?' | ':' | '$')[]; + namedPlaceholderTypes?: (':' | '@' | '$')[]; + quotedPlaceholderTypes?: (':' | '@' | '$')[]; lineCommentTypes?: string[]; specialWordChars?: { prefix?: string; any?: string; suffix?: string }; operators?: string[]; From 472683aa42893733d094fcee006bb9e658255b81 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 16:49:20 +0300 Subject: [PATCH 112/334] Define REGEX_MAP type using Record<> --- src/core/Tokenizer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 9c8a52ef83..602bd9340a 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -33,7 +33,7 @@ type PlaceholderPattern = { regex: RegExp; parseKey: (s: string) => string }; /** Converts SQL language string into a token stream */ export default class Tokenizer { - REGEX_MAP: { [tokenType in TokenType]: RegExp }; + REGEX_MAP: Record; private placeholderPatterns: PlaceholderPattern[]; From 947cc1649c099b517c48996f277da21143b9d8ca Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 16:55:54 +0300 Subject: [PATCH 113/334] Rename WORD token to IDENT (and the current IDENT to QUOTED_IDENT) --- src/core/AliasAs.ts | 8 ++++---- src/core/StatementFormatter.ts | 2 +- src/core/Tokenizer.ts | 8 ++++---- src/core/token.ts | 2 +- src/languages/spark.formatter.ts | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/core/AliasAs.ts b/src/core/AliasAs.ts index 592d21786c..9769fa8b7f 100644 --- a/src/core/AliasAs.ts +++ b/src/core/AliasAs.ts @@ -20,7 +20,7 @@ export default class AliasAs { // if table alias is missing and should be added private isMissingTableAlias(token: Token): boolean { return ( - this.aliasAs === 'always' && token.type === TokenType.WORD && this.lookBehind().value === ')' + this.aliasAs === 'always' && token.type === TokenType.IDENT && this.lookBehind().value === ')' ); } @@ -31,9 +31,9 @@ export default class AliasAs { return ( (this.aliasAs === 'always' || this.aliasAs === 'select') && this.formatter.isWithinSelect() && - token.type === TokenType.WORD && + token.type === TokenType.IDENT && (isToken.END(prevToken) || - ((prevToken.type === TokenType.WORD || prevToken.type === TokenType.NUMBER) && + ((prevToken.type === TokenType.IDENT || prevToken.type === TokenType.NUMBER) && (nextToken.value === ',' || isCommand(nextToken)))) ); } @@ -50,7 +50,7 @@ export default class AliasAs { this.formatter.isWithinSelect() && isToken.CAST(this.formatter.getPreviousReservedToken()) && isToken.AS(this.lookAhead()) && - (this.lookAhead(2).type === TokenType.WORD || + (this.lookAhead(2).type === TokenType.IDENT || this.lookAhead(2).type === TokenType.RESERVED_KEYWORD) && this.lookAhead(3).value === ')' ); diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 5f4fe88ab5..d66a265b56 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -87,8 +87,8 @@ export default class StatementFormatter { return this.formatPlaceholder(token); case TokenType.OPERATOR: return this.formatOperator(token); - case TokenType.WORD: case TokenType.IDENT: + case TokenType.QUOTED_IDENT: case TokenType.STRING: case TokenType.NUMBER: return this.formatWord(token); diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 602bd9340a..a82114ad08 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -66,8 +66,8 @@ export default class Tokenizer { const specialWordCharsAll = Object.values(cfg.specialWordChars ?? {}).join(''); this.REGEX_MAP = { - [TokenType.WORD]: regexFactory.createWordRegex(cfg.specialWordChars), - [TokenType.IDENT]: regexFactory.createQuoteRegex(cfg.identifierTypes), + [TokenType.IDENT]: regexFactory.createWordRegex(cfg.specialWordChars), + [TokenType.QUOTED_IDENT]: regexFactory.createQuoteRegex(cfg.identifierTypes), [TokenType.STRING]: regexFactory.createQuoteRegex(cfg.stringTypes), [TokenType.RESERVED_KEYWORD]: regexFactory.createReservedWordRegex( cfg.reservedKeywords, @@ -204,13 +204,13 @@ export default class Tokenizer { this.matchToken(TokenType.LINE_COMMENT)(input) || this.matchToken(TokenType.BLOCK_COMMENT)(input) || this.matchToken(TokenType.STRING)(input) || - this.matchToken(TokenType.IDENT)(input) || + this.matchToken(TokenType.QUOTED_IDENT)(input) || this.matchToken(TokenType.BLOCK_START)(input) || this.matchToken(TokenType.BLOCK_END)(input) || this.getPlaceholderToken(input) || this.matchToken(TokenType.NUMBER)(input) || this.getReservedWordToken(input, previousToken) || - this.matchToken(TokenType.WORD)(input) || + this.matchToken(TokenType.IDENT)(input) || this.matchToken(TokenType.OPERATOR)(input) ); } diff --git a/src/core/token.ts b/src/core/token.ts index 50fa62bfcb..b247482b04 100644 --- a/src/core/token.ts +++ b/src/core/token.ts @@ -1,7 +1,7 @@ /** Token type enum for all possible Token categories */ export enum TokenType { - WORD = 'WORD', IDENT = 'IDENT', + QUOTED_IDENT = 'QUOTED_IDENT', STRING = 'STRING', RESERVED_KEYWORD = 'RESERVED_KEYWORD', RESERVED_LOGICAL_OPERATOR = 'RESERVED_LOGICAL_OPERATOR', diff --git a/src/languages/spark.formatter.ts b/src/languages/spark.formatter.ts index c7269d5d79..af0c5d4576 100644 --- a/src/languages/spark.formatter.ts +++ b/src/languages/spark.formatter.ts @@ -812,7 +812,7 @@ function preprocess(tokens: Token[]) { if (token.value === 'ITEMS' && token.type === TokenType.RESERVED_KEYWORD) { if (!(prevToken.value === 'COLLECTION' && nextToken.value === 'TERMINATED')) { // this is a word and not COLLECTION ITEMS - return { type: TokenType.WORD, text: token.text, value: token.text }; + return { type: TokenType.IDENT, text: token.text, value: token.text }; } } From 5d689cb84d9fa8d9d76b5222957e2f096971ddac Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 17:01:53 +0300 Subject: [PATCH 114/334] Combine quoted and unquoted tokens to single IDENT token --- src/core/StatementFormatter.ts | 1 - src/core/Tokenizer.ts | 16 +++++++++++++--- src/core/token.ts | 1 - 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index d66a265b56..a45df111ca 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -88,7 +88,6 @@ export default class StatementFormatter { case TokenType.OPERATOR: return this.formatOperator(token); case TokenType.IDENT: - case TokenType.QUOTED_IDENT: case TokenType.STRING: case TokenType.NUMBER: return this.formatWord(token); diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index a82114ad08..bd8ae62697 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -34,7 +34,7 @@ type PlaceholderPattern = { regex: RegExp; parseKey: (s: string) => string }; /** Converts SQL language string into a token stream */ export default class Tokenizer { REGEX_MAP: Record; - + private quotedIdentRegex: RegExp; private placeholderPatterns: PlaceholderPattern[]; private preprocess = (tokens: Token[]) => tokens; @@ -65,9 +65,10 @@ export default class Tokenizer { } const specialWordCharsAll = Object.values(cfg.specialWordChars ?? {}).join(''); + this.quotedIdentRegex = regexFactory.createQuoteRegex(cfg.identifierTypes); + this.REGEX_MAP = { [TokenType.IDENT]: regexFactory.createWordRegex(cfg.specialWordChars), - [TokenType.QUOTED_IDENT]: regexFactory.createQuoteRegex(cfg.identifierTypes), [TokenType.STRING]: regexFactory.createQuoteRegex(cfg.stringTypes), [TokenType.RESERVED_KEYWORD]: regexFactory.createReservedWordRegex( cfg.reservedKeywords, @@ -204,7 +205,7 @@ export default class Tokenizer { this.matchToken(TokenType.LINE_COMMENT)(input) || this.matchToken(TokenType.BLOCK_COMMENT)(input) || this.matchToken(TokenType.STRING)(input) || - this.matchToken(TokenType.QUOTED_IDENT)(input) || + this.getQuotedIdentToken(input) || this.matchToken(TokenType.BLOCK_START)(input) || this.matchToken(TokenType.BLOCK_END)(input) || this.getPlaceholderToken(input) || @@ -238,6 +239,15 @@ export default class Tokenizer { return key.replace(new RegExp(escapeRegExp('\\' + quoteChar), 'gu'), quoteChar); } + getQuotedIdentToken(input: string): Token | undefined { + return this.getTokenOnFirstMatch({ + input, + regex: this.quotedIdentRegex, + type: TokenType.IDENT, + transform: id, + }); + } + /** * Attempts to match a Reserved word token pattern, avoiding edge cases of Reserved words within string tokens * @return {Token | undefined} - The Reserved word token if found, otherwise undefined diff --git a/src/core/token.ts b/src/core/token.ts index b247482b04..99d1d7fe52 100644 --- a/src/core/token.ts +++ b/src/core/token.ts @@ -1,7 +1,6 @@ /** Token type enum for all possible Token categories */ export enum TokenType { IDENT = 'IDENT', - QUOTED_IDENT = 'QUOTED_IDENT', STRING = 'STRING', RESERVED_KEYWORD = 'RESERVED_KEYWORD', RESERVED_LOGICAL_OPERATOR = 'RESERVED_LOGICAL_OPERATOR', From 7e7447e2c1d26272113be6c55dbfbf323af2bb7f Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 17:03:21 +0300 Subject: [PATCH 115/334] Rename specialWordChars to specialIdentChars --- src/core/Tokenizer.ts | 20 ++++++++++---------- src/languages/bigquery.formatter.ts | 2 +- src/languages/db2.formatter.ts | 2 +- src/languages/mariadb.formatter.ts | 2 +- src/languages/mysql.formatter.ts | 2 +- src/languages/plsql.formatter.ts | 2 +- src/languages/tsql.formatter.ts | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index bd8ae62697..63105b837a 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -24,7 +24,7 @@ interface TokenizerOptions { namedPlaceholderTypes?: (':' | '@' | '$')[]; quotedPlaceholderTypes?: (':' | '@' | '$')[]; lineCommentTypes?: string[]; - specialWordChars?: { prefix?: string; any?: string; suffix?: string }; + specialIdentChars?: { prefix?: string; any?: string; suffix?: string }; operators?: string[]; preprocess?: (tokens: Token[]) => Token[]; } @@ -55,7 +55,7 @@ export default class Tokenizer { * @param {string[]} cfg.numberedPlaceholderTypes - Prefixes for numbered placeholders, like ":" for :1, :2, :3 * @param {string[]} cfg.namedPlaceholderTypes - Prefixes for named placeholders, like @ and : * @param {string[]} cfg.lineCommentTypes - Line comments to enable, like # and -- - * @param {string[]} cfg.specialWordChars - Special chars that can be found inside of words, like @ and # + * @param {string[]} cfg.specialIdentChars - Special chars that can be found inside identifiers, like @ and # * @param {string[]} cfg.operators - Additional operators to recognize * @param {Function} cfg.preprocess - Optional function to process tokens before emitting */ @@ -64,35 +64,35 @@ export default class Tokenizer { this.preprocess = cfg.preprocess; } - const specialWordCharsAll = Object.values(cfg.specialWordChars ?? {}).join(''); + const specialIdentCharsAll = Object.values(cfg.specialIdentChars ?? {}).join(''); this.quotedIdentRegex = regexFactory.createQuoteRegex(cfg.identifierTypes); this.REGEX_MAP = { - [TokenType.IDENT]: regexFactory.createWordRegex(cfg.specialWordChars), + [TokenType.IDENT]: regexFactory.createWordRegex(cfg.specialIdentChars), [TokenType.STRING]: regexFactory.createQuoteRegex(cfg.stringTypes), [TokenType.RESERVED_KEYWORD]: regexFactory.createReservedWordRegex( cfg.reservedKeywords, - specialWordCharsAll + specialIdentCharsAll ), [TokenType.RESERVED_DEPENDENT_CLAUSE]: regexFactory.createReservedWordRegex( cfg.reservedDependentClauses ?? [], - specialWordCharsAll + specialIdentCharsAll ), [TokenType.RESERVED_LOGICAL_OPERATOR]: regexFactory.createReservedWordRegex( cfg.reservedLogicalOperators ?? ['AND', 'OR'], - specialWordCharsAll + specialIdentCharsAll ), [TokenType.RESERVED_COMMAND]: regexFactory.createReservedWordRegex( cfg.reservedCommands, - specialWordCharsAll + specialIdentCharsAll ), [TokenType.RESERVED_BINARY_COMMAND]: regexFactory.createReservedWordRegex( cfg.reservedBinaryCommands, - specialWordCharsAll + specialIdentCharsAll ), [TokenType.RESERVED_JOIN_CONDITION]: regexFactory.createReservedWordRegex( cfg.reservedJoinConditions ?? ['ON', 'USING'], - specialWordCharsAll + specialIdentCharsAll ), [TokenType.OPERATOR]: regexFactory.createOperatorRegex('+-/*%&|^><=.,;[]{}`:$@', [ '<>', diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index 9a293d30ad..3330003519 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -865,7 +865,7 @@ export default class BigQueryFormatter extends Formatter { namedPlaceholderTypes: ['@'], quotedPlaceholderTypes: ['@'], lineCommentTypes: ['--', '#'], - specialWordChars: { any: '_@$-' }, + specialIdentChars: { any: '_@$-' }, operators: BigQueryFormatter.operators, preprocess, }); diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index d52b770b16..f6d4029dfc 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -881,7 +881,7 @@ export default class Db2Formatter extends Formatter { identifierTypes: [`""`], positionalPlaceholders: true, namedPlaceholderTypes: [':'], - specialWordChars: { any: '#@' }, + specialIdentChars: { any: '#@' }, operators: Db2Formatter.operators, }); } diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index 3fd56fc3aa..24c1996e54 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1168,7 +1168,7 @@ export default class MariaDbFormatter extends Formatter { identifierTypes: ['``'], positionalPlaceholders: true, lineCommentTypes: ['--', '#'], - specialWordChars: { prefix: '@' }, + specialIdentChars: { prefix: '@' }, operators: MariaDbFormatter.operators, preprocess, }); diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index 8b9763081f..a579ace95f 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1331,7 +1331,7 @@ export default class MySqlFormatter extends Formatter { identifierTypes: ['``'], positionalPlaceholders: true, lineCommentTypes: ['--', '#'], - specialWordChars: { prefix: '@:' }, + specialIdentChars: { prefix: '@:' }, operators: MySqlFormatter.operators, preprocess, }); diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 4bb6ebf7e8..4e4087a2c2 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -466,7 +466,7 @@ export default class PlSqlFormatter extends Formatter { identifierTypes: [`""`], numberedPlaceholderTypes: [':'], namedPlaceholderTypes: [':'], - specialWordChars: { any: '_$#' }, + specialIdentChars: { any: '_$#' }, operators: PlSqlFormatter.operators, preprocess, }); diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index 06f9ba027f..cc0182f507 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1246,7 +1246,7 @@ export default class TSqlFormatter extends Formatter { identifierTypes: [`""`, '[]'], namedPlaceholderTypes: ['@'], quotedPlaceholderTypes: ['@'], - specialWordChars: { any: '#@' }, + specialIdentChars: { any: '#@' }, operators: TSqlFormatter.operators, // TODO: Support for money constants }); From dbde3ab452e17f946f3b29f0e50a69193ef91908 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 17:05:30 +0300 Subject: [PATCH 116/334] Rename createWordRegex to createIdentRegex --- src/core/Tokenizer.ts | 2 +- src/core/regexFactory.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 63105b837a..ac7ad1ff36 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -68,7 +68,7 @@ export default class Tokenizer { this.quotedIdentRegex = regexFactory.createQuoteRegex(cfg.identifierTypes); this.REGEX_MAP = { - [TokenType.IDENT]: regexFactory.createWordRegex(cfg.specialIdentChars), + [TokenType.IDENT]: regexFactory.createIdentRegex(cfg.specialIdentChars), [TokenType.STRING]: regexFactory.createQuoteRegex(cfg.stringTypes), [TokenType.RESERVED_KEYWORD]: regexFactory.createReservedWordRegex( cfg.reservedKeywords, diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index fb18e055d2..71647ad26d 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -50,7 +50,7 @@ export const createReservedWordRegex = ( * @param {string} specialChars.prefix - concatenated string of chars that only appear at the beginning of a valid identifier * @param {string} specialChars.suffix - concatenated string of chars that only appear at the end of a valid identifier */ -export const createWordRegex = ( +export const createIdentRegex = ( specialChars: { any?: string; prefix?: string; suffix?: string } = {} ): RegExp => { const prefixLookBehind = `[${escapeRegExp(specialChars.prefix ?? '')}]*`; From f4917aeb95176872261246713adaa5cdb4dbff1b Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 17:07:47 +0300 Subject: [PATCH 117/334] Mark Tokenizer methods as public/private --- src/core/Tokenizer.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index ac7ad1ff36..fc91b0521a 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -33,7 +33,7 @@ type PlaceholderPattern = { regex: RegExp; parseKey: (s: string) => string }; /** Converts SQL language string into a token stream */ export default class Tokenizer { - REGEX_MAP: Record; + private REGEX_MAP: Record; private quotedIdentRegex: RegExp; private placeholderPatterns: PlaceholderPattern[]; @@ -157,7 +157,7 @@ export default class Tokenizer { * @param {string} input - The SQL string * @returns {Token[]} output token stream */ - tokenize(input: string): Token[] { + public tokenize(input: string): Token[] { const tokens: Token[] = []; let token: Token | undefined; @@ -183,13 +183,13 @@ export default class Tokenizer { } /** Matches preceding whitespace if present */ - getWhitespace(input: string): string { + private getWhitespace(input: string): string { const matches = input.match(WHITESPACE_REGEX); return matches ? matches[1] : ''; } /** Curried function of `getTokenOnFirstMatch` that allows token type to be passed first */ - matchToken = + private matchToken = (tokenType: TokenType) => (input: string): Token | undefined => this.getTokenOnFirstMatch({ @@ -200,7 +200,7 @@ export default class Tokenizer { }); /** Attempts to match next token from input string, tests RegExp patterns in decreasing priority */ - getNextToken(input: string, previousToken?: Token): Token | undefined { + private getNextToken(input: string, previousToken?: Token): Token | undefined { return ( this.matchToken(TokenType.LINE_COMMENT)(input) || this.matchToken(TokenType.BLOCK_COMMENT)(input) || @@ -220,7 +220,7 @@ export default class Tokenizer { * Attempts to match a placeholder token pattern * @return {Token | undefined} - The placeholder token if found, otherwise undefined */ - getPlaceholderToken(input: string): Token | undefined { + private getPlaceholderToken(input: string): Token | undefined { for (const { regex, parseKey } of this.placeholderPatterns) { const token = this.getTokenOnFirstMatch({ input, @@ -235,11 +235,11 @@ export default class Tokenizer { return undefined; } - getEscapedPlaceholderKey({ key, quoteChar }: { key: string; quoteChar: string }): string { + private getEscapedPlaceholderKey({ key, quoteChar }: { key: string; quoteChar: string }): string { return key.replace(new RegExp(escapeRegExp('\\' + quoteChar), 'gu'), quoteChar); } - getQuotedIdentToken(input: string): Token | undefined { + private getQuotedIdentToken(input: string): Token | undefined { return this.getTokenOnFirstMatch({ input, regex: this.quotedIdentRegex, @@ -252,7 +252,7 @@ export default class Tokenizer { * Attempts to match a Reserved word token pattern, avoiding edge cases of Reserved words within string tokens * @return {Token | undefined} - The Reserved word token if found, otherwise undefined */ - getReservedWordToken(input: string, previousToken?: Token): Token | undefined { + private getReservedWordToken(input: string, previousToken?: Token): Token | undefined { // A reserved word cannot be preceded by a '.' // this makes it so in "mytable.from", "from" is not considered a reserved word if (previousToken?.value === '.') { @@ -291,7 +291,7 @@ export default class Tokenizer { * @param {RegExp} _.regex - The regex to match * @return {Token | undefined} - The matched token if found, otherwise undefined */ - getTokenOnFirstMatch({ + private getTokenOnFirstMatch({ input, type, regex, From 18b14eeaa5f67b9386508526f8aa5281f10ed615 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 17:10:41 +0300 Subject: [PATCH 118/334] Rename all get*Token methods to match*Token --- src/core/Tokenizer.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index fc91b0521a..984ba8128a 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -205,12 +205,12 @@ export default class Tokenizer { this.matchToken(TokenType.LINE_COMMENT)(input) || this.matchToken(TokenType.BLOCK_COMMENT)(input) || this.matchToken(TokenType.STRING)(input) || - this.getQuotedIdentToken(input) || + this.matchQuotedIdentToken(input) || this.matchToken(TokenType.BLOCK_START)(input) || this.matchToken(TokenType.BLOCK_END)(input) || - this.getPlaceholderToken(input) || + this.matchPlaceholderToken(input) || this.matchToken(TokenType.NUMBER)(input) || - this.getReservedWordToken(input, previousToken) || + this.matchReservedWordToken(input, previousToken) || this.matchToken(TokenType.IDENT)(input) || this.matchToken(TokenType.OPERATOR)(input) ); @@ -220,7 +220,7 @@ export default class Tokenizer { * Attempts to match a placeholder token pattern * @return {Token | undefined} - The placeholder token if found, otherwise undefined */ - private getPlaceholderToken(input: string): Token | undefined { + private matchPlaceholderToken(input: string): Token | undefined { for (const { regex, parseKey } of this.placeholderPatterns) { const token = this.getTokenOnFirstMatch({ input, @@ -239,7 +239,7 @@ export default class Tokenizer { return key.replace(new RegExp(escapeRegExp('\\' + quoteChar), 'gu'), quoteChar); } - private getQuotedIdentToken(input: string): Token | undefined { + private matchQuotedIdentToken(input: string): Token | undefined { return this.getTokenOnFirstMatch({ input, regex: this.quotedIdentRegex, @@ -252,7 +252,7 @@ export default class Tokenizer { * Attempts to match a Reserved word token pattern, avoiding edge cases of Reserved words within string tokens * @return {Token | undefined} - The Reserved word token if found, otherwise undefined */ - private getReservedWordToken(input: string, previousToken?: Token): Token | undefined { + private matchReservedWordToken(input: string, previousToken?: Token): Token | undefined { // A reserved word cannot be preceded by a '.' // this makes it so in "mytable.from", "from" is not considered a reserved word if (previousToken?.value === '.') { From 002bf5afed917e8cc9277f0dedd0e8d3d76c679e Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 17:13:53 +0300 Subject: [PATCH 119/334] Convert curried matchToken()() to ordinary method --- src/core/Tokenizer.ts | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 984ba8128a..4c3186fb44 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -188,31 +188,20 @@ export default class Tokenizer { return matches ? matches[1] : ''; } - /** Curried function of `getTokenOnFirstMatch` that allows token type to be passed first */ - private matchToken = - (tokenType: TokenType) => - (input: string): Token | undefined => - this.getTokenOnFirstMatch({ - input, - type: tokenType, - regex: this.REGEX_MAP[tokenType], - transform: id, - }); - /** Attempts to match next token from input string, tests RegExp patterns in decreasing priority */ private getNextToken(input: string, previousToken?: Token): Token | undefined { return ( - this.matchToken(TokenType.LINE_COMMENT)(input) || - this.matchToken(TokenType.BLOCK_COMMENT)(input) || - this.matchToken(TokenType.STRING)(input) || + this.matchToken(TokenType.LINE_COMMENT, input) || + this.matchToken(TokenType.BLOCK_COMMENT, input) || + this.matchToken(TokenType.STRING, input) || this.matchQuotedIdentToken(input) || - this.matchToken(TokenType.BLOCK_START)(input) || - this.matchToken(TokenType.BLOCK_END)(input) || + this.matchToken(TokenType.BLOCK_START, input) || + this.matchToken(TokenType.BLOCK_END, input) || this.matchPlaceholderToken(input) || - this.matchToken(TokenType.NUMBER)(input) || + this.matchToken(TokenType.NUMBER, input) || this.matchReservedWordToken(input, previousToken) || - this.matchToken(TokenType.IDENT)(input) || - this.matchToken(TokenType.OPERATOR)(input) + this.matchToken(TokenType.IDENT, input) || + this.matchToken(TokenType.OPERATOR, input) ); } @@ -284,6 +273,16 @@ export default class Tokenizer { ); } + // Shorthand for `getTokenOnFirstMatch` that looks up regex for REGEX_MAP + private matchToken(tokenType: TokenType, input: string): Token | undefined { + return this.getTokenOnFirstMatch({ + input, + type: tokenType, + regex: this.REGEX_MAP[tokenType], + transform: id, + }); + } + /** * Attempts to match RegExp from head of input, returning undefined if not found * @param {string} _.input - The string to match From 464ee965252bbf8c6e93e7a1dcb01b594a893a29 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 17:15:46 +0300 Subject: [PATCH 120/334] Rename getTokenOnFirstMatch() to simply match() --- src/core/Tokenizer.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 4c3186fb44..d3edf38b0f 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -211,7 +211,7 @@ export default class Tokenizer { */ private matchPlaceholderToken(input: string): Token | undefined { for (const { regex, parseKey } of this.placeholderPatterns) { - const token = this.getTokenOnFirstMatch({ + const token = this.match({ input, regex, type: TokenType.PLACEHOLDER, @@ -229,7 +229,7 @@ export default class Tokenizer { } private matchQuotedIdentToken(input: string): Token | undefined { - return this.getTokenOnFirstMatch({ + return this.match({ input, regex: this.quotedIdentRegex, type: TokenType.IDENT, @@ -263,7 +263,7 @@ export default class Tokenizer { return reservedTokenList.reduce( (matchedToken: Token | undefined, tokenType) => matchedToken || - this.getTokenOnFirstMatch({ + this.match({ input, type: tokenType, regex: this.REGEX_MAP[tokenType], @@ -273,9 +273,9 @@ export default class Tokenizer { ); } - // Shorthand for `getTokenOnFirstMatch` that looks up regex for REGEX_MAP + // Shorthand for `match` that looks up regex from REGEX_MAP private matchToken(tokenType: TokenType, input: string): Token | undefined { - return this.getTokenOnFirstMatch({ + return this.match({ input, type: tokenType, regex: this.REGEX_MAP[tokenType], @@ -290,7 +290,7 @@ export default class Tokenizer { * @param {RegExp} _.regex - The regex to match * @return {Token | undefined} - The matched token if found, otherwise undefined */ - private getTokenOnFirstMatch({ + private match({ input, type, regex, From b73e399c770f9001daeb63e4a8794c92bdbb053c Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Fri, 27 May 2022 17:22:01 +0300 Subject: [PATCH 121/334] Eliminate complex reduce() from reserved word matching --- src/core/Tokenizer.ts | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index d3edf38b0f..5114bf20b7 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -249,30 +249,28 @@ export default class Tokenizer { } // prioritised list of Reserved token types - const reservedTokenList = [ - TokenType.RESERVED_CASE_START, - TokenType.RESERVED_CASE_END, - TokenType.RESERVED_COMMAND, - TokenType.RESERVED_BINARY_COMMAND, - TokenType.RESERVED_DEPENDENT_CLAUSE, - TokenType.RESERVED_LOGICAL_OPERATOR, - TokenType.RESERVED_KEYWORD, - TokenType.RESERVED_JOIN_CONDITION, - ]; - - return reservedTokenList.reduce( - (matchedToken: Token | undefined, tokenType) => - matchedToken || - this.match({ - input, - type: tokenType, - regex: this.REGEX_MAP[tokenType], - transform: toCanonicalKeyword, - }), - undefined + return ( + this.matchReservedToken(TokenType.RESERVED_CASE_START, input) || + this.matchReservedToken(TokenType.RESERVED_CASE_END, input) || + this.matchReservedToken(TokenType.RESERVED_COMMAND, input) || + this.matchReservedToken(TokenType.RESERVED_BINARY_COMMAND, input) || + this.matchReservedToken(TokenType.RESERVED_DEPENDENT_CLAUSE, input) || + this.matchReservedToken(TokenType.RESERVED_LOGICAL_OPERATOR, input) || + this.matchReservedToken(TokenType.RESERVED_KEYWORD, input) || + this.matchReservedToken(TokenType.RESERVED_JOIN_CONDITION, input) ); } + // Helper for matching RESERVED_* tokens which need to be transformed to canonical form + private matchReservedToken(tokenType: TokenType, input: string): Token | undefined { + return this.match({ + input, + type: tokenType, + regex: this.REGEX_MAP[tokenType], + transform: toCanonicalKeyword, + }); + } + // Shorthand for `match` that looks up regex from REGEX_MAP private matchToken(tokenType: TokenType, input: string): Token | undefined { return this.match({ From 37a94b9e123be6330e80f4b462b7d93a1cbb260b Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Mon, 30 May 2022 14:47:36 -0700 Subject: [PATCH 122/334] add vsce as dev dep --- vscode/package.json | 10 +- vscode/yarn.lock | 759 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 757 insertions(+), 12 deletions(-) diff --git a/vscode/package.json b/vscode/package.json index 4c20874068..03408e0d30 100644 --- a/vscode/package.json +++ b/vscode/package.json @@ -52,8 +52,8 @@ "main": "./out/extension.js", "scripts": { "clean": "rimraf out .vscode-test", - "compile": "tsc --project ./", - "compile:types": "tsc --emitDeclarationOnly --project ./", + "compile": "tsc --project ./tsconfig.json", + "compile:types": "tsc --emitDeclarationOnly --project ./tsconfig.json", "watch": "tsc --watch --project ./", "build": "esbuild ./src/extension.ts --bundle --outfile=out/extension.js --external:vscode --format=cjs --platform=node", "build:prod": "yarn run build --minify && yarn run compile:types", @@ -61,7 +61,8 @@ "vscode:prepublish": "yarn run build:prod", "lint": "eslint src --ext ts", "pretest": "yarn run compile && yarn run lint", - "test": "node ./out/test/runTest.js" + "test": "node ./out/test/runTest.js", + "vsce": "vsce" }, "dependencies": { "prettier-sql": "^5.1.0" @@ -78,7 +79,8 @@ "eslint": "^8.1.0", "glob": "^7.1.7", "mocha": "^9.1.3", - "typescript": "^4.4.4" + "typescript": "^4.4.4", + "vsce": "^2.7.0" }, "contributes": { "languages": [ diff --git a/vscode/yarn.lock b/vscode/yarn.lock index 37be133d43..f7c79bfca9 100644 --- a/vscode/yarn.lock +++ b/vscode/yarn.lock @@ -212,11 +212,23 @@ ansi-colors@4.1.1, ansi-colors@^4.1.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" @@ -232,6 +244,19 @@ anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.7" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" + integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + argparse@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" @@ -242,11 +267,24 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +azure-devops-node-api@^11.0.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/azure-devops-node-api/-/azure-devops-node-api-11.1.1.tgz#dd1356031fa4e334e016732594e8fee0f68268c4" + integrity sha512-XDG91XzLZ15reP12s3jFkKS8oiagSICjnLwxEYieme4+4h3ZveFOFRA4iYIG40RyHXsiI0mefFYYMFIJbMpWcg== + dependencies: + tunnel "0.0.6" + typed-rest-client "^1.8.4" + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + big-integer@^1.6.17: version "1.6.51" resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" @@ -265,11 +303,25 @@ binary@~0.3.0: buffers "~0.1.1" chainsaw "~0.1.0" +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + bluebird@~3.4.1: version "3.4.7" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" integrity sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM= +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -290,16 +342,37 @@ browser-stdout@1.3.1: resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + buffer-indexof-polyfill@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz#d2732135c5999c64b277fcf9b1abe3498254729c" integrity sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A== +buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + buffers@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" integrity sha1-skV5w77U1tOWru5tmorn9Ugqt7s= +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -317,6 +390,15 @@ chainsaw@~0.1.0: dependencies: traverse ">=0.3.0 <0.4" +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -325,6 +407,30 @@ chalk@^4.0.0, chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +cheerio-select@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-1.6.0.tgz#489f36604112c722afa147dedd0d4609c09e1696" + integrity sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g== + dependencies: + css-select "^4.3.0" + css-what "^6.0.1" + domelementtype "^2.2.0" + domhandler "^4.3.1" + domutils "^2.8.0" + +cheerio@^1.0.0-rc.9: + version "1.0.0-rc.10" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.10.tgz#2ba3dcdfcc26e7956fc1f440e61d51c643379f3e" + integrity sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw== + dependencies: + cheerio-select "^1.5.0" + dom-serializer "^1.3.2" + domhandler "^4.2.0" + htmlparser2 "^6.1.0" + parse5 "^6.0.1" + parse5-htmlparser2-tree-adapter "^6.0.1" + tslib "^2.2.0" + chokidar@3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" @@ -340,6 +446,11 @@ chokidar@3.5.2: optionalDependencies: fsevents "~2.3.2" +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -349,6 +460,18 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -356,16 +479,31 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +commander@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" @@ -380,6 +518,22 @@ cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" +css-select@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" + integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== + dependencies: + boolbase "^1.0.0" + css-what "^6.0.1" + domhandler "^4.3.1" + domutils "^2.8.0" + nth-check "^2.0.1" + +css-what@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + debug@4, debug@^4.1.1, debug@^4.3.2: version "4.3.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" @@ -399,11 +553,33 @@ decamelize@^4.0.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +detect-libc@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" + integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== + diff@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" @@ -423,6 +599,36 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dom-serializer@^1.0.1, dom-serializer@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" + integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" + integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== + dependencies: + domelementtype "^2.2.0" + +domutils@^2.5.2, domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + duplexer2@~0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" @@ -435,6 +641,13 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + enquirer@^2.3.5: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" @@ -442,6 +655,16 @@ enquirer@^2.3.5: dependencies: ansi-colors "^4.1.1" +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +entities@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" + integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== + esbuild-android-arm64@0.14.8: version "0.14.8" resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.8.tgz#69324e08ba68c7d9a541e7b825d7235b83e17bd6" @@ -566,6 +789,11 @@ escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" @@ -681,6 +909,11 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -714,6 +947,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= + dependencies: + pend "~1.2.0" + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -754,6 +994,11 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.4.tgz#28d9969ea90661b5134259f312ab6aa7929ac5e2" integrity sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw== +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -774,16 +1019,49 @@ fstream@^1.0.12: mkdirp ">=0.5 0" rimraf "2" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-intrinsic@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -810,7 +1088,7 @@ glob@7.1.7: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.3, glob@^7.1.7: +glob@^7.0.6, glob@^7.1.3, glob@^7.1.7: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== @@ -851,16 +1129,55 @@ growl@1.10.5: resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-symbols@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + he@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +hosted-git-info@^4.0.2: + version "4.1.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" + integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== + dependencies: + lru-cache "^6.0.0" + +htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" + http-proxy-agent@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" @@ -878,6 +1195,11 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -909,11 +1231,16 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@~2.0.0, inherits@~2.0.3: +inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -926,6 +1253,13 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" @@ -980,6 +1314,19 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= +keytar@^7.7.0: + version "7.9.0" + resolved "https://registry.yarnpkg.com/keytar/-/keytar-7.9.0.tgz#4c6225708f51b50cbf77c5aae81721964c2918cb" + integrity sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ== + dependencies: + node-addon-api "^4.3.0" + prebuild-install "^7.0.1" + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -988,6 +1335,13 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +linkify-it@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.3.tgz#a98baf44ce45a550efb4d49c769d07524cc2fa2e" + integrity sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ== + dependencies: + uc.micro "^1.0.1" + listenercount@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937" @@ -1020,6 +1374,22 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +markdown-it@^12.3.2: + version "12.3.2" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90" + integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg== + dependencies: + argparse "^2.0.1" + entities "~2.1.0" + linkify-it "^3.0.1" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= + merge2@^1.3.0: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" @@ -1033,6 +1403,16 @@ micromatch@^4.0.4: braces "^3.0.1" picomatch "^2.2.3" +mime@^1.3.4: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -1040,11 +1420,28 @@ minimatch@3.0.4, minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +minimatch@^3.0.3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.3: + version "1.2.6" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + "mkdirp@>=0.5 0": version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" @@ -1092,22 +1489,76 @@ ms@2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +mute-stream@~0.0.4: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + nanoid@3.1.25: version "3.1.25" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +node-abi@^3.3.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.8.0.tgz#679957dc8e7aa47b0a02589dbfde4f77b29ccb32" + integrity sha512-tzua9qWWi7iW4I42vUPKM+SfaF0vQSLAm4yO5J83mSwB7GeoWrDKC/K+8YCnYNwqP5duwazbw2X9l4m8SC2cUw== + dependencies: + semver "^7.3.5" + +node-addon-api@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f" + integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== + normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -once@^1.3.0: +npmlog@^4.0.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +nth-check@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" + integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w== + dependencies: + boolbase "^1.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-inspect@^1.9.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" + integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -1147,6 +1598,25 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-semver@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/parse-semver/-/parse-semver-1.1.1.tgz#9a4afd6df063dc4826f93fba4a99cf223f666cb8" + integrity sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg= + dependencies: + semver "^5.1.0" + +parse5-htmlparser2-tree-adapter@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" + integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== + dependencies: + parse5 "^6.0.1" + +parse5@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -1167,11 +1637,35 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: version "2.3.0" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== +prebuild-install@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.0.1.tgz#c10075727c318efe72412f333e0ef625beaf3870" + integrity sha512-QBSab31WqkyxpnMWQxubYAHR5S9B2+r81ucocew34Fkl98FhvKIF50jIJnNOBmAZfyNV7vE5T6gd3hTVWgY6tg== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + npmlog "^4.0.1" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -1194,11 +1688,26 @@ progress@^2.0.0: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +qs@^6.9.1: + version "6.10.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== + dependencies: + side-channel "^1.0.4" + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -1211,7 +1720,24 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -readable-stream@^2.0.2, readable-stream@~2.3.6: +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= + dependencies: + mute-stream "~0.0.4" + +readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -1224,6 +1750,15 @@ readable-stream@^2.0.2, readable-stream@~2.3.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@^3.1.1, readable-stream@^3.4.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -1258,7 +1793,7 @@ rimraf@2: dependencies: glob "^7.1.3" -rimraf@^3.0.2: +rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -1272,7 +1807,7 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -safe-buffer@^5.1.0: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -1282,6 +1817,16 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +sax@>=0.6.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +semver@^5.1.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + semver@^7.2.1, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" @@ -1296,6 +1841,11 @@ serialize-javascript@6.0.0: dependencies: randombytes "^2.1.0" +set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + setimmediate@~1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" @@ -1313,12 +1863,49 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.0: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -string-width@^4.1.0, string-width@^4.2.0: +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -1327,6 +1914,13 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -1334,6 +1928,13 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -1346,6 +1947,11 @@ strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1. resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + supports-color@8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" @@ -1353,6 +1959,13 @@ supports-color@8.1.1: dependencies: has-flag "^4.0.0" +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -1360,11 +1973,39 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +tar-fs@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -1382,6 +2023,11 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" + integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" @@ -1389,6 +2035,18 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tunnel@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" + integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -1401,11 +2059,30 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== +typed-rest-client@^1.8.4: + version "1.8.6" + resolved "https://registry.yarnpkg.com/typed-rest-client/-/typed-rest-client-1.8.6.tgz#d8facd6abd98cbd8ad14cccf056ca5cc306919d7" + integrity sha512-xcQpTEAJw2DP7GqVNECh4dD+riS+C1qndXLfBCJ3xk0kqprtGN491P5KlmrDbKdtuW8NEcP/5ChxiJI3S9WYTA== + dependencies: + qs "^6.9.1" + tunnel "0.0.6" + underscore "^1.12.1" + typescript@^4.4.4: version "4.5.4" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg== +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== + +underscore@^1.12.1: + version "1.13.2" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.2.tgz#276cea1e8b9722a8dbed0100a407dda572125881" + integrity sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g== + unzipper@^0.10.11: version "0.10.11" resolved "https://registry.yarnpkg.com/unzipper/-/unzipper-0.10.11.tgz#0b4991446472cbdb92ee7403909f26c2419c782e" @@ -1429,7 +2106,12 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -util-deprecate@~1.0.1: +url-join@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" + integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= @@ -1439,6 +2121,32 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== +vsce@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/vsce/-/vsce-2.7.0.tgz#7be8deebd1e673b996238d608e7f7324c98744ed" + integrity sha512-CKU34wrQlbKDeJCRBkd1a8iwF9EvNxcYMg9hAUH6AxFGR6Wo2IKWwt3cJIcusHxx6XdjDHWlfAS/fJN30uvVnA== + dependencies: + azure-devops-node-api "^11.0.1" + chalk "^2.4.2" + cheerio "^1.0.0-rc.9" + commander "^6.1.0" + glob "^7.0.6" + hosted-git-info "^4.0.2" + keytar "^7.7.0" + leven "^3.1.0" + markdown-it "^12.3.2" + mime "^1.3.4" + minimatch "^3.0.3" + parse-semver "^1.1.1" + read "^1.0.7" + semver "^5.1.0" + tmp "^0.2.1" + typed-rest-client "^1.8.4" + url-join "^4.0.1" + xml2js "^0.4.23" + yauzl "^2.3.1" + yazl "^2.2.2" + which@2.0.2, which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -1446,6 +2154,13 @@ which@2.0.2, which@^2.0.1: dependencies: isexe "^2.0.0" +wide-align@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + word-wrap@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" @@ -1470,6 +2185,19 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +xml2js@^0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" + integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" @@ -1513,6 +2241,21 @@ yargs@16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yauzl@^2.3.1: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + +yazl@^2.2.2: + version "2.5.1" + resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35" + integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw== + dependencies: + buffer-crc32 "~0.2.3" + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" From a409bac9e82d480c70bba287cd116d63bd73c689 Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Mon, 30 May 2022 16:31:13 -0700 Subject: [PATCH 123/334] add pre-commit --- package.json | 4 +++- yarn.lock | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index b0584cb4b6..7c79d72d2f 100644 --- a/package.json +++ b/package.json @@ -82,10 +82,11 @@ "build": "yarn build:commonjs && yarn build:umd && yarn build:umd:min", "release": "release-it" }, - "pre-push": [ + "pre-commit": [ "ts:check", "lint" ], + "pre-push": "build", "repository": { "type": "git", "url": "https://github.com/zeroturnaround/sql-formatter.git" @@ -119,6 +120,7 @@ "eslint-plugin-import": "^2.22.0", "eslint-plugin-prettier": "^4.0.0", "jest": "^28.0.2", + "pre-commit": "^1.2.2", "pre-push": "^0.1.2", "prettier": "^2.0.5", "release-it": "^14.11.7", diff --git a/yarn.lock b/yarn.lock index 2fc003ff86..a7d80c802a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4775,6 +4775,15 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +pre-commit@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/pre-commit/-/pre-commit-1.2.2.tgz#dbcee0ee9de7235e57f79c56d7ce94641a69eec6" + integrity sha1-287g7p3nI15X95xW186UZBpp7sY= + dependencies: + cross-spawn "^5.0.1" + spawn-sync "^1.0.15" + which "1.2.x" + pre-push@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/pre-push/-/pre-push-0.1.2.tgz#185bbde6e8dfe2ab6dff937b674f0cbfc5a98295" From f3e8c1be9fd5b26e5380f12545a95c55fc41e2a0 Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Mon, 30 May 2022 17:14:33 -0700 Subject: [PATCH 124/334] add npm-cli as dep for pre-push --- package.json | 1 + yarn.lock | 1554 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 1514 insertions(+), 41 deletions(-) diff --git a/package.json b/package.json index 7c79d72d2f..7976910655 100644 --- a/package.json +++ b/package.json @@ -120,6 +120,7 @@ "eslint-plugin-import": "^2.22.0", "eslint-plugin-prettier": "^4.0.0", "jest": "^28.0.2", + "npm-cli": "^0.1.0", "pre-commit": "^1.2.2", "pre-push": "^0.1.2", "prettier": "^2.0.5", diff --git a/yarn.lock b/yarn.lock index a7d80c802a..35558dec8c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1775,6 +1775,16 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +abbrev@~1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + integrity sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q== + acorn-import-assertions@^1.7.6: version "1.8.0" resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" @@ -1795,7 +1805,7 @@ ajv-keywords@^3.5.2: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5: +ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1819,11 +1829,26 @@ ansi-escapes@^4.2.1: dependencies: type-fest "^0.21.3" +ansi-regex@*: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA== + ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -1843,6 +1868,16 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== +ansicolors@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" + integrity sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg== + +ansistyles@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/ansistyles/-/ansistyles-0.1.3.tgz#5de60415bda071bb37127854c864f41b23254539" + integrity sha512-6QWEyvMgIXX0eO972y7YPBLSBsq7UWKFAoNNTLGaOJ9bstcEL9sCbcjf96dVfNDdUsRoGOK82vWFJlKApXds7g== + anymatch@^3.0.3, anymatch@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" @@ -1851,6 +1886,29 @@ anymatch@^3.0.3, anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +aproba@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.0.4.tgz#2713680775e7614c8ba186c065d4e2e52d1072c0" + integrity sha512-g4T1BR2vAjWV6GrBYeM7DmHUBe0WB45xRKKpNKxh4zHkUsjdGfANjdHY//9RzHi1XkWTLc1k58ddAUZ81yC8Cw== + +archy@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== + +are-we-there-yet@~1.1.2: + version "1.1.7" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" + integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -1874,6 +1932,14 @@ array-includes@^3.1.4: get-intrinsic "^1.1.1" is-string "^1.0.7" +array-index@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-index/-/array-index-1.0.0.tgz#ec56a749ee103e4e08c790b9c353df16055b97f9" + integrity sha512-jesyNbBkLQgGZMSwA1FanaFjalb1mZUGxGeUEkSDidzgrbjBGhvizJkaItdhkt8eIHFOJC7nDsrXk+BaehTdRw== + dependencies: + debug "^2.2.0" + es6-symbol "^3.0.2" + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -1900,6 +1966,28 @@ array.prototype.map@^1.0.4: es-array-method-boxes-properly "^1.0.0" is-string "^1.0.7" +asap@^2.0.0, asap@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== + +asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + integrity sha512-u1L0ZLywRziOVjUhRxI0Qg9G+4RnFB9H/Rq40YWn0dieDgO7vAYeJz6jKAO6t/aruzlDFLAPkQTT87e+f8Imaw== + async-retry@1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.3.tgz#0e7f36c04d8478e7a58bdbed80cedf977785f280" @@ -1912,6 +2000,21 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + integrity sha512-JnJpAS0p9RmixkOvW2XwDxxzs1bd4/VAGIl6Q0EC5YOo+p+hqIhtDhn/nmFnB/xUNXbLkpE2mOjgVIBRKD4xYw== + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== + +aws4@^1.2.1, aws4@^1.8.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== + babel-eslint@^10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" @@ -2040,6 +2143,13 @@ base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + before-after-hook@^2.2.0: version "2.2.2" resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e" @@ -2064,6 +2174,27 @@ bl@^4.1.0: inherits "^2.0.4" readable-stream "^3.4.0" +bl@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.1.2.tgz#fdca871a99713aa00d19e3bbba41c44787a65398" + integrity sha512-uVVYHEQk+OuWvCi5U+iquVXvvGCWXKawjwELIR2XMLsqfV/e2sGDClVBs8OlGIgGsStPRY/Es311YKYIlYCWAg== + dependencies: + readable-stream "~2.0.5" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha512-OorbnJVPII4DuUKbjARAe8u8EfqOmkEEaSFIyoQ7OjTHn6kafxWl0wLgoZ2rXaYd7MyLcDaU4TmhfxtwgcccMQ== + dependencies: + inherits "~2.0.0" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + integrity sha512-KbiZEa9/vofNcVJXGwdWWn25reQ3V3dHBWbS07FTF3/TOehLnm9GEhJV4T6ZvGPkShRpmUqYwnaCrkj0mRnP6Q== + dependencies: + hoek "2.x.x" + boxen@^5.0.0: version "5.1.2" resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" @@ -2123,6 +2254,11 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer-shims@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" + integrity sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g== + buffer@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" @@ -2131,6 +2267,21 @@ buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ== + +builtins@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-0.0.7.tgz#355219cd6cf18dbe7c01cc7fd2dce765cfdc549a" + integrity sha512-T8uCGKc0/2aLVt6omt8JxDRBoWEMkku+wFesxnhxnt4NygVZG99zqxo7ciK8eebszceKamGoUiLdkXCgGQyrQw== + +builtins@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" + integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ== + cacheable-request@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" @@ -2172,6 +2323,16 @@ caniuse-lite@^1.0.30001332: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001332.tgz#39476d3aa8d83ea76359c70302eafdd4a1d727dd" integrity sha512-10T30NYOEQtN6C11YGg411yebhvpnC6Z102+B95eAsN0oB6KUs01ivE8u+G6FMIRtIrVlYXhL+LUwQ3/hXwDWw== +caseless@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + integrity sha512-ODLXH644w9C2fMPAm7bMDQ3GRvipZWZfKc+8As6hIadRIelE0n0xZuN38NS6kiK3KPEVrpymmQD8bvncAHWQkQ== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== + chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -2180,6 +2341,17 @@ chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: ansi-styles "^4.1.0" supports-color "^7.1.0" +chalk@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A== + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + chalk@^2.0.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -2214,6 +2386,11 @@ chokidar@^3.4.0: optionalDependencies: fsevents "~2.3.2" +chownr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + integrity sha512-cKnqUJAC8G6cuN1DiRRTifu+s1BlAQNtalzGphFEV0pl0p46dsxJD4l1AOlyKJeLZOFzo3c34R7F3djxaCu8Kw== + chrome-trace-event@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" @@ -2286,11 +2463,24 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= +cmd-shim@~2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb" + integrity sha512-NLt0ntM0kvuSNrToO0RTFiNRHdioWsLW+OgDAEVDvIivsYwR+AjlzvLaMJ2Z+SNRpV3vdsDrHp1WI00eetDYzw== + dependencies: + graceful-fs "^4.1.2" + mkdirp "~0.5.0" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== + collect-v8-coverage@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" @@ -2325,14 +2515,22 @@ colorette@^2.0.14: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== -combined-stream@^1.0.8: +columnify@~1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" + integrity sha512-rFl+iXVT1nhLQPfGDw+3WcS8rmm7XsLKUmhsGE3ihzzpIikeGrTaZPIRKYWeLsLBypsHzjXIvYEltVUZS84XxQ== + dependencies: + strip-ansi "^3.0.0" + wcwidth "^1.0.0" + +combined-stream@^1.0.5, combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.5, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" -commander@^2.20.0: +commander@^2.20.0, commander@^2.9.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -2357,7 +2555,7 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concat-stream@^1.4.7: +concat-stream@^1.4.7, concat-stream@^1.5.2: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== @@ -2367,6 +2565,14 @@ concat-stream@^1.4.7: readable-stream "^2.2.2" typedarray "^0.0.6" +config-chain@~1.1.11: + version "1.1.13" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" + integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + configstore@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" @@ -2384,6 +2590,11 @@ confusing-browser-globals@^1.0.10: resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== + convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.8.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" @@ -2399,6 +2610,11 @@ core-js-compat@^3.20.2, core-js-compat@^3.21.0: browserslist "^4.20.2" semver "7.0.0" +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== + core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" @@ -2433,11 +2649,33 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + integrity sha512-FFN5KwpvvQTTS5hWPxrU8/QE4kQUc6uwZcrnlMBN82t1MgAtq8mnoDwINBly9Tdr02seeIIhtdF+UH1feBYGog== + dependencies: + boom "2.x.x" + crypto-random-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== + dependencies: + assert-plus "^1.0.0" + debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" @@ -2445,7 +2683,7 @@ debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2: dependencies: ms "2.1.2" -debug@^2.6.9: +debug@^2.2.0, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -2459,6 +2697,11 @@ debug@^3.2.7: dependencies: ms "^2.1.1" +debuglog@*, debuglog@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" + integrity sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw== + decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -2521,6 +2764,11 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== + deprecation@^2.0.0, deprecation@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" @@ -2531,6 +2779,14 @@ detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== +dezalgo@^1.0.0, dezalgo@^1.0.1, dezalgo@~1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.4.tgz#751235260469084c132157dfa857f386d4c33d81" + integrity sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig== + dependencies: + asap "^2.0.0" + wrappy "1" + diff-sequences@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" @@ -2574,6 +2830,19 @@ duplexer3@^0.1.4: resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +editor@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/editor/-/editor-1.0.0.tgz#60c7f87bd62bcc6a894fa8ccd6afb7823a24f742" + integrity sha512-SoRmbGStwNYHgKfjOrX2L0mUvp9bUVv0uPppZSOMAntEbcFtoC3MKF5b3T6HQPXKIV+QGY3xPO3JK5it5lVkuw== + electron-to-chromium@^1.4.118: version "1.4.123" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.123.tgz#de88ea7fd29d7c868e63c88f129e91494bcf3266" @@ -2687,6 +2956,32 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es5-ext@^0.10.35, es5-ext@^0.10.50: + version "0.10.61" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.61.tgz#311de37949ef86b6b0dcea894d1ffedb909d3269" + integrity sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + next-tick "^1.1.0" + +es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.0.2, es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -2697,7 +2992,7 @@ escape-goat@^2.0.0: resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== -escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -2949,6 +3244,18 @@ expect@^28.0.2: jest-message-util "^28.0.2" jest-util "^28.0.2" +ext@^1.1.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" + integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== + dependencies: + type "^2.5.0" + +extend@~3.0.0, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -2958,6 +3265,16 @@ external-editor@^3.0.3: iconv-lite "^0.4.24" tmp "^0.0.33" +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== + +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -3071,6 +3388,11 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== + form-data@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -3080,11 +3402,48 @@ form-data@4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.0.0.tgz#6f0aebadcc5da16c13e1ecc11137d85f9b883b25" + integrity sha512-BWUNep0UvjzlIJgDsi0SFD3MvnLlwiRaVpfr82Hj2xgc9MJJcl1tSQj01CJDMG+w/kzm+vkZMmXwRM2XrkBuaA== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.11" + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + fs-readdir-recursive@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== +fs-vacuum@~1.2.9: + version "1.2.10" + resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.10.tgz#b7629bec07a4031a2548fdf99f5ecf1cc8b31e36" + integrity sha512-bwbv1FcWYwxN1F08I1THN8nS4Qe/pGq0gM8dy1J34vpxxp3qgZKJPPaqex36RyZO0sD2J+2ocnbwC2d/OjYICQ== + dependencies: + graceful-fs "^4.1.2" + path-is-inside "^1.0.1" + rimraf "^2.5.2" + +fs-write-stream-atomic@~1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA== + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -3095,6 +3454,33 @@ fsevents@^2.3.2, fsevents@~2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== +fstream-ignore@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + integrity sha512-VVRuOs41VUqptEGiR0N5ZoWEcfGvbGRqLINyZAhHRnF3DH5wrqjNkYr3VbRoZnI41BZgO7zIVdiobc13TVI1ow== + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream-npm@~1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/fstream-npm/-/fstream-npm-1.2.1.tgz#08c4a452f789dcbac4c89a4563c902b2c862fd5b" + integrity sha512-iBHpm/LmD1qw0TlHMAqVd9rwdU6M+EHRUnPkXpRi5G/Hf0FIFH+oZFryodAU2MFNfGRh/CzhUFlMKV3pdeOTDw== + dependencies: + fstream-ignore "^1.0.0" + inherits "2" + +fstream@^1.0.0, fstream@^1.0.12, fstream@~1.0.10: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -3105,6 +3491,49 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +gauge@~2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.6.0.tgz#d35301ad18e96902b4751dcbbe40f4218b942a46" + integrity sha512-YFArj4ApymqXBC2KORLBtKc2CIc1r+ycx786XYEkEF4++1rBGhTD7QHOSWYYGCx50Op+WuboEk9xQa+wNmzuLA== + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-color "^0.1.7" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +gauge@~2.7.1: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg== + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +generate-function@^2.0.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" + integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ== + dependencies: + is-property "^1.0.2" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + integrity sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ== + dependencies: + is-property "^1.0.0" + gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -3156,6 +3585,13 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== + dependencies: + assert-plus "^1.0.0" + git-up@^4.0.0: version "4.0.5" resolved "https://registry.yarnpkg.com/git-up/-/git-up-4.0.5.tgz#e7bb70981a37ea2fb8fe049669800a1f9a01d759" @@ -3202,7 +3638,19 @@ glob@^7.0.0, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.3: +glob@^7.0.3, glob@^7.0.5, glob@^7.1.1: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.3, glob@~7.1.0: version "7.1.7" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== @@ -3274,16 +3722,56 @@ got@9.6.0, got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.9: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.4, graceful-fs@^4.2.9: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +graceful-fs@~4.1.9: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== + +har-validator@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" + integrity sha512-P6tFV+wCcUL3nbyTDAvveDySfbhy0XkDtAIfZP6HITjM2WUsiPna/Eg1Yy93SFXvahqoX+kt0n+6xlXKDXYowA== + dependencies: + chalk "^1.1.1" + commander "^2.9.0" + is-my-json-valid "^2.12.4" + pinkie-promise "^2.0.0" + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg== + dependencies: + ansi-regex "^2.0.0" + has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== +has-color@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + integrity sha512-kaNz5OTAYYmt646Hkqw50/qyxP2vFnTVu5AQ1Zmk22Kk5+4Qx6BpO8+u7IKsML5fOsFk0ZT0AcCJNYwcvaLBvw== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -3313,6 +3801,11 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" +has-unicode@^2.0.0, has-unicode@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== + has-yarn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" @@ -3325,6 +3818,31 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + integrity sha512-X8xbmTc1cbPXcQV4WkLcRMALuyoxhfpFATmyuCxJPOAvrDS4DNnsTAOmKUxMTOWU6TzrTOkxPKwIx5ZOpJVSrg== + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + integrity sha512-V6Yw1rIcYV/4JsnggjBU0l4Kr+EXhpwqXRusENU1Xx6ro00IHPHYNynCuBTOZAPlr3AAmLvchH9I7N/VUdvOwQ== + +hosted-git-info@^2.1.4, hosted-git-info@^2.1.5, hosted-git-info@^2.4.2: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +hosted-git-info@~2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.1.5.tgz#0ba81d90da2e25ab34a332e6ec77936e1598118b" + integrity sha512-5sLwVGWIA8493A2PzG/py8s+uBrYqrwmLp6C6U5+Gpw5Ll49OOigsuD4LKbUTExbgedTNPvPb/0GV5ohHYYNBg== + html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" @@ -3335,6 +3853,24 @@ http-cache-semantics@^4.0.0: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + integrity sha512-iUn0NcRULlDGtqNLN1Jxmzayk8ogm7NToldASyZBpM2qggbphjXzNOiw3piN8tgz+e/DRs6X5gAzFwTI6BCRcg== + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + human-signals@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" @@ -3357,6 +3893,11 @@ ieee754@^1.1.13: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== +iferr@^0.1.5, iferr@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA== + ignore@^5.1.4, ignore@^5.1.8, ignore@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" @@ -3397,12 +3938,12 @@ import-local@^3.0.2: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" -imurmurhash@^0.1.4: +imurmurhash@*, imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -inflight@^1.0.4: +inflight@^1.0.4, inflight@~1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= @@ -3410,7 +3951,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -3420,11 +3961,25 @@ ini@2.0.0: resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== -ini@~1.3.0: +ini@^1.3.4, ini@~1.3.0, ini@~1.3.4: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== +init-package-json@~1.9.4: + version "1.9.6" + resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-1.9.6.tgz#789fc2b74466a4952b9ea77c0575bc78ebd60a61" + integrity sha512-ocaj90F9qTLDpkhhy+ZemKVexbybm2S0fo65/v13KJDI75kyB7eb8ShhRkxZrbGzzS9833A+o5Bus8aFdQEfOg== + dependencies: + glob "^7.1.1" + npm-package-arg "^4.0.0 || ^5.0.0" + promzard "^0.3.0" + read "~1.0.1" + read-package-json "1 || 2" + semver "2.x || 3.x || 4 || 5" + validate-npm-package-license "^3.0.1" + validate-npm-package-name "^3.0.0" + inquirer@8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.0.tgz#f44f008dd344bbfc4b30031f45d984e034a3ac3a" @@ -3499,6 +4054,13 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + integrity sha512-C2wz7Juo5pUZTFQVer9c+9b4qw3I5T/CHQxQyhVu7BJel6C22FmsLIWsdseYyOw6xz9Pqy9eJWSkQ7+3iN1HVw== + dependencies: + builtin-modules "^1.0.0" + is-callable@^1.1.4, is-callable@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" @@ -3542,6 +4104,13 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" @@ -3577,6 +4146,22 @@ is-map@^2.0.2: resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== +is-my-ip-valid@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz#f7220d1146257c98672e6fba097a9f3f2d348442" + integrity sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg== + +is-my-json-valid@^2.12.4: + version "2.20.6" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz#a9d89e56a36493c77bda1440d69ae0dc46a08387" + integrity sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw== + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + is-my-ip-valid "^1.0.0" + jsonpointer "^5.0.0" + xtend "^4.0.0" + is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" @@ -3621,6 +4206,11 @@ is-plain-object@^5.0.0: resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== +is-property@^1.0.0, is-property@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + integrity sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g== + is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -3667,7 +4257,7 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" -is-typedarray@^1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -3716,6 +4306,11 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== + istanbul-lib-coverage@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" @@ -4187,6 +4782,11 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== + jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -4202,7 +4802,7 @@ json-buffer@3.0.0: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= -json-parse-better-errors@^1.0.2: +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== @@ -4217,11 +4817,21 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + json5@2.x, json5@^2.1.2, json5@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" @@ -4234,6 +4844,21 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +jsonpointer@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.0.tgz#f802669a524ec4805fa7389eadbc9921d5dc8072" + integrity sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg== + +jsprim@^1.2.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + keyv@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" @@ -4305,6 +4930,63 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +lockfile@~1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lockfile/-/lockfile-1.0.4.tgz#07f819d25ae48f87e538e6578b6964a4981a5609" + integrity sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA== + dependencies: + signal-exit "^3.0.2" + +lodash._baseindexof@*: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c" + integrity sha512-bSYo8Pc/f0qAkr8fPJydpJjtrHiSynYfYBjtANIgXv5xEf1WlTC63dIDlgu0s9dmTvzRu1+JJTxcIAHe+sH0FQ== + +lodash._baseuniq@~4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" + integrity sha512-Ja1YevpHZctlI5beLA7oc5KNDhGcPixFhcqSiORHNsp/1QTv7amAXzw+gu4YOvErqVlMVyIJGgtzeepCnnur0A== + dependencies: + lodash._createset "~4.0.0" + lodash._root "~3.0.0" + +lodash._bindcallback@*: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" + integrity sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ== + +lodash._cacheindexof@*: + version "3.0.2" + resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92" + integrity sha512-S8dUjWr7SUT/X6TBIQ/OYoCHo1Stu1ZRy6uMUSKqzFnZp5G5RyQizSm6kvxD2Ewyy6AVfMg4AToeZzKfF99T5w== + +lodash._createcache@*: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093" + integrity sha512-ev5SP+iFpZOugyab/DEUQxUeZP5qyciVTlgQ1f4Vlw7VUcCD8fVnyIqVUEIaoFH9zjAqdgi69KiofzvVmda/ZQ== + dependencies: + lodash._getnative "^3.0.0" + +lodash._createset@~4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" + integrity sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA== + +lodash._getnative@*, lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + integrity sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA== + +lodash._root@~3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" + integrity sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ== + +lodash.clonedeep@~4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -4320,11 +5002,31 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.restparam@*: + version "3.6.1" + resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" + integrity sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw== + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= +lodash.union@~4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" + integrity sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw== + +lodash.uniq@~4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== + +lodash.without@~4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac" + integrity sha512-M3MefBwfDhgKgINVuBJCO1YR3+gf6s9HNJsIiZ/Ru77Ws6uTb9eBuvrkpzO+9iLoAaRodGuq7tyrPCx+74QYGQ== + lodash@4.17.21, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -4418,7 +5120,7 @@ mime-db@1.52.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@2.1.35, mime-types@^2.1.12, mime-types@^2.1.27: +mime-types@2.1.35, mime-types@^2.1.11, mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.19, mime-types@~2.1.7: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -4435,7 +5137,7 @@ mimic-response@^1.0.0, mimic-response@^1.0.1: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== -minimatch@^3.0.4, minimatch@^3.1.2: +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -4447,6 +5149,13 @@ minimist@^1.2.0, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@~0.5.0, mkdirp@~0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -4462,7 +5171,7 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -mute-stream@0.0.8: +mute-stream@0.0.8, mute-stream@~0.0.4: version "0.0.8" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== @@ -4484,6 +5193,11 @@ new-github-release-url@1.0.0: dependencies: type-fest "^0.4.1" +next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + node-fetch@^2.6.7: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" @@ -4491,6 +5205,26 @@ node-fetch@^2.6.7: dependencies: whatwg-url "^5.0.0" +node-gyp@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.4.0.tgz#dda558393b3ecbbe24c9e6b8703c71194c63fa36" + integrity sha1-3aVYOTs+y74kyea4cDxxGUxj+jY= + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + minimatch "^3.0.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3" + osenv "0" + path-array "^1.0.0" + request "2" + rimraf "2" + semver "2.x || 3.x || 4 || 5" + tar "^2.0.0" + which "1" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -4501,6 +5235,43 @@ node-releases@^2.0.3: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" integrity sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw== +node-uuid@~1.4.7: + version "1.4.8" + resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" + integrity sha1-sEDrCSOWivq/jTL7HxfxFn/auQc= + +"nopt@2 || 3", nopt@~3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + +normalize-git-url@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/normalize-git-url/-/normalize-git-url-3.0.2.tgz#8e5f14be0bdaedb73e07200310aa416c27350fc4" + integrity sha1-jl8Uvgva7bc+ByADEKpBbCc1D8Q= + +normalize-package-data@^2.0.0, "normalize-package-data@~1.0.1 || ^2.0.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-package-data@~2.3.5: + version "2.3.8" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.8.tgz#d819eda2a9dedbd1ffa563ea4071d936782295bb" + integrity sha1-2Bntoqne29H/pWPqQHHZNngilbs= + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -4516,6 +5287,66 @@ normalize-url@^6.1.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== +npm-cache-filename@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz#ded306c5b0bfc870a9e9faf823bc5f283e05ae11" + integrity sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE= + +npm-cli@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/npm-cli/-/npm-cli-0.1.0.tgz#081e0fe2c1cdfb822b9db360bc5eb2875c041088" + integrity sha1-CB4P4sHN+4IrnbNgvF6yh1wEEIg= + dependencies: + npm "^3" + semver "^4.1.0" + +npm-install-checks@~3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-3.0.2.tgz#ab2e32ad27baa46720706908e5b14c1852de44d9" + integrity sha512-E4kzkyZDIWoin6uT5howP8VDvkM+E8IQDcHAycaAxMbwkqhIg5eEYALnXOl3Hq9MrkdQB/2/g1xwBINXdKSRkg== + dependencies: + semver "^2.3.0 || 3.x || 4 || 5" + +npm-normalize-package-bin@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" + integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== + +"npm-package-arg@^3.0.0 || ^4.0.0", npm-package-arg@^4.1.1, npm-package-arg@~4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-4.2.1.tgz#593303fdea85f7c422775f17f9eb7670f680e3ec" + integrity sha1-WTMD/eqF98Qid18X+et2cPaA4+w= + dependencies: + hosted-git-info "^2.1.5" + semver "^5.1.0" + +"npm-package-arg@^4.0.0 || ^5.0.0": + version "5.1.2" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-5.1.2.tgz#fb18d17bb61e60900d6312619919bd753755ab37" + integrity sha512-wJBsrf0qpypPT7A0LART18hCdyhpCMxeTtcb0X4IZO2jsP6Om7EHN1d9KSKiqD+KVH030RVNpWS9thk+pb7wzA== + dependencies: + hosted-git-info "^2.4.2" + osenv "^0.1.4" + semver "^5.1.0" + validate-npm-package-name "^3.0.0" + +npm-registry-client@~7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/npm-registry-client/-/npm-registry-client-7.2.1.tgz#c792266b088cc313f8525e7e35248626c723db75" + integrity sha1-x5ImawiMwxP4Ul5+NSSGJscj23U= + dependencies: + concat-stream "^1.5.2" + graceful-fs "^4.1.6" + normalize-package-data "~1.0.1 || ^2.0.0" + npm-package-arg "^3.0.0 || ^4.0.0" + once "^1.3.3" + request "^2.74.0" + retry "^0.10.0" + semver "2 >=2.2.1 || 3.x || 4 || 5" + slide "^1.1.3" + optionalDependencies: + npmlog "~2.0.0 || ~3.1.0" + npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" @@ -4523,6 +5354,128 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +npm-user-validate@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-0.1.5.tgz#52465d50c2d20294a57125b996baedbf56c5004b" + integrity sha1-UkZdUMLSApSlcSW5lrrtv1bFAEs= + +npm@^3: + version "3.10.10" + resolved "https://registry.yarnpkg.com/npm/-/npm-3.10.10.tgz#5b1d577e4c8869d6c8603bc89e9cd1637303e46e" + integrity sha1-Wx1XfkyIadbIYDvInpzRY3MD5G4= + dependencies: + abbrev "~1.0.9" + ansicolors "~0.3.2" + ansistyles "~0.1.3" + aproba "~1.0.4" + archy "~1.0.0" + asap "~2.0.5" + chownr "~1.0.1" + cmd-shim "~2.0.2" + columnify "~1.5.4" + config-chain "~1.1.11" + dezalgo "~1.0.3" + editor "~1.0.0" + fs-vacuum "~1.2.9" + fs-write-stream-atomic "~1.0.8" + fstream "~1.0.10" + fstream-npm "~1.2.0" + glob "~7.1.0" + graceful-fs "~4.1.9" + has-unicode "~2.0.1" + hosted-git-info "~2.1.5" + iferr "~0.1.5" + inflight "~1.0.5" + inherits "~2.0.3" + ini "~1.3.4" + init-package-json "~1.9.4" + lockfile "~1.0.2" + lodash._baseuniq "~4.6.0" + lodash.clonedeep "~4.5.0" + lodash.union "~4.6.0" + lodash.uniq "~4.5.0" + lodash.without "~4.4.0" + mkdirp "~0.5.1" + node-gyp "~3.4.0" + nopt "~3.0.6" + normalize-git-url "~3.0.2" + normalize-package-data "~2.3.5" + npm-cache-filename "~1.0.2" + npm-install-checks "~3.0.0" + npm-package-arg "~4.2.0" + npm-registry-client "~7.2.1" + npm-user-validate "~0.1.5" + npmlog "~4.0.0" + once "~1.4.0" + opener "~1.4.2" + osenv "~0.1.3" + path-is-inside "~1.0.2" + read "~1.0.7" + read-cmd-shim "~1.0.1" + read-installed "~4.0.3" + read-package-json "~2.0.4" + read-package-tree "~5.1.5" + readable-stream "~2.1.5" + realize-package-specifier "~3.0.3" + request "~2.75.0" + retry "~0.10.0" + rimraf "~2.5.4" + semver "~5.3.0" + sha "~2.0.1" + slide "~1.1.6" + sorted-object "~2.0.1" + strip-ansi "~3.0.1" + tar "~2.2.1" + text-table "~0.2.0" + uid-number "0.0.6" + umask "~1.1.0" + unique-filename "~1.1.0" + unpipe "~1.0.0" + validate-npm-package-name "~2.2.2" + which "~1.2.11" + wrappy "~1.0.2" + write-file-atomic "~1.2.0" + +"npmlog@0 || 1 || 2 || 3", "npmlog@~2.0.0 || ~3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-3.1.2.tgz#2d46fa874337af9498a2f12bb43d8d0be4a36873" + integrity sha1-LUb6h0M3r5SYovErtD2NC+SjaHM= + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.6.0" + set-blocking "~2.0.0" + +npmlog@~4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.2.tgz#d03950e0e78ce1527ba26d2a7592e9348ac3e75f" + integrity sha1-0DlQ4OeM4VJ7om0qdZLpNIrD518= + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.1" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +oauth-sign@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM= + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + object-inspect@^1.12.0, object-inspect@^1.9.0: version "1.12.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" @@ -4561,7 +5514,7 @@ object.values@^1.1.5: define-properties "^1.1.3" es-abstract "^1.19.1" -once@^1.3.0, once@^1.3.1, once@^1.4.0: +once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0, once@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -4583,6 +5536,11 @@ open@7.4.2: is-docker "^2.0.0" is-wsl "^2.1.1" +opener@~1.4.2: + version "1.4.3" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8" + integrity sha1-XG2ixdflgx6P+jlklQ+NZnSskLg= + optionator@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" @@ -4610,6 +5568,11 @@ ora@5.4.1, ora@^5.4.1: strip-ansi "^6.0.0" wcwidth "^1.0.1" +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + os-name@4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/os-name/-/os-name-4.0.1.tgz#32cee7823de85a8897647ba4d76db46bf845e555" @@ -4623,11 +5586,19 @@ os-shim@^0.1.2: resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917" integrity sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc= -os-tmpdir@~1.0.2: +os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= +osenv@0, osenv@^0.1.4, osenv@~0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + p-cancelable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" @@ -4718,6 +5689,13 @@ parse-url@^6.0.0: parse-path "^4.0.0" protocols "^1.4.0" +path-array@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-array/-/path-array-1.0.1.tgz#7e2f0f35f07a2015122b868b7eac0eb2c4fec271" + integrity sha1-fi8PNfB6IBUSK4aLfqwOssT+wnE= + dependencies: + array-index "^1.0.0" + path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -4733,6 +5711,11 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= +path-is-inside@^1.0.1, path-is-inside@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" @@ -4748,6 +5731,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -4763,6 +5751,18 @@ pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + pirates@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" @@ -4834,6 +5834,11 @@ pretty-format@^28.0.2: ansi-styles "^5.0.0" react-is "^18.0.0" +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -4859,6 +5864,18 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" +promzard@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" + integrity sha1-JqXW7ox97kyxIggwWs+5O6OCqe4= + dependencies: + read "1" + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= + protocols@^1.1.0, protocols@^1.4.0: version "1.4.8" resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.8.tgz#48eea2d8f58d9644a4a32caae5d5db290a075ce8" @@ -4869,6 +5886,11 @@ pseudomap@^1.0.2: resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -4877,7 +5899,12 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^2.1.0: +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -4896,6 +5923,16 @@ qs@^6.9.4: dependencies: side-channel "^1.0.4" +qs@~6.2.0: + version "6.2.4" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.4.tgz#d90821bb8537cecc140e6c34f54ec76e54b39b22" + integrity sha512-E57gmgKXqDda+qWTkUJgIwgJICK7zgMfqZZopTRKZ6mY9gzLlmJN9EpXNnDrTxXFlOM/a+I28kJkF/60rqgnYw== + +qs@~6.5.2: + version "6.5.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== + query-string@^6.13.8: version "6.14.1" resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a" @@ -4938,7 +5975,68 @@ react-is@^18.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67" integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg== -readable-stream@^2.2.2: +read-cmd-shim@~1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz#87e43eba50098ba5a32d0ceb583ab8e43b961c16" + integrity sha512-v5yCqQ/7okKoZZkBQUAfTsQ3sVJtXdNfbPnI5cceppoxEVLYA3k+VtV2omkeo8MS94JCy4fSiUwlRBAwCVRPUA== + dependencies: + graceful-fs "^4.1.2" + +read-installed@~4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067" + integrity sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc= + dependencies: + debuglog "^1.0.1" + read-package-json "^2.0.0" + readdir-scoped-modules "^1.0.0" + semver "2 || 3 || 4 || 5" + slide "~1.1.3" + util-extend "^1.0.1" + optionalDependencies: + graceful-fs "^4.1.2" + +"read-package-json@1 || 2", read-package-json@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.1.2.tgz#6992b2b66c7177259feb8eaac73c3acd28b9222a" + integrity sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA== + dependencies: + glob "^7.1.1" + json-parse-even-better-errors "^2.3.0" + normalize-package-data "^2.0.0" + npm-normalize-package-bin "^1.0.0" + +read-package-json@~2.0.4: + version "2.0.13" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.0.13.tgz#2e82ebd9f613baa6d2ebe3aa72cefe3f68e41f4a" + integrity sha512-/1dZ7TRZvGrYqE0UAfN6qQb5GYBsNcqS1C0tNK601CFOJmtHI7NIGXwetEPU/OtoFHZL3hDxm4rolFFVE9Bnmg== + dependencies: + glob "^7.1.1" + json-parse-better-errors "^1.0.1" + normalize-package-data "^2.0.0" + slash "^1.0.0" + optionalDependencies: + graceful-fs "^4.1.2" + +read-package-tree@~5.1.5: + version "5.1.6" + resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.1.6.tgz#4f03e83d0486856fb60d97c94882841c2a7b1b7a" + integrity sha512-FCX1aT3GWyY658wzDICef4p+n0dB+ENRct8E/Qyvppj6xVpOYerBHfUu7OP5Rt1/393Tdglguf5ju5DEX4wZNg== + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + once "^1.3.0" + read-package-json "^2.0.0" + readdir-scoped-modules "^1.0.0" + +read@1, read@~1.0.1, read@~1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= + dependencies: + mute-stream "~0.0.4" + +"readable-stream@1 || 2", readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.2: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -4960,6 +6058,41 @@ readable-stream@^3.4.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" +readable-stream@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" + integrity sha1-j5A0HmilPMySh4jaz80Rs265t44= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readable-stream@~2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" + integrity sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA= + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readdir-scoped-modules@*, readdir-scoped-modules@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" + integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + graceful-fs "^4.1.2" + once "^1.3.0" + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -4967,6 +6100,14 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +realize-package-specifier@~3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/realize-package-specifier/-/realize-package-specifier-3.0.3.tgz#d0def882952b8de3f67eba5e91199661271f41f4" + integrity sha1-0N74gpUrjeP2frpekRmWYScfQfQ= + dependencies: + dezalgo "^1.0.1" + npm-package-arg "^4.1.1" + rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -5084,6 +6225,59 @@ release-it@^14.11.7: yaml "1.10.2" yargs-parser "20.2.9" +request@2, request@^2.74.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +request@~2.75.0: + version "2.75.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.75.0.tgz#d2b8268a286da13eaa5d01adf5d18cc90f657d93" + integrity sha1-0rgmiihtoT6qXQGt9dGMyQ9lfZM= + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + bl "~1.1.2" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.0.0" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + node-uuid "~1.4.7" + oauth-sign "~0.8.1" + qs "~6.2.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -5111,7 +6305,7 @@ resolve.exports@^1.1.0: resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== -resolve@^1.1.6, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.9.0: +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.9.0: version "1.22.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== @@ -5148,11 +6342,23 @@ retry@0.13.1: resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== +retry@^0.10.0, retry@~0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" + integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q= + reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +rimraf@2, rimraf@^2.5.2: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -5160,6 +6366,13 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" +rimraf@~2.5.4: + version "2.5.4" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04" + integrity sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ= + dependencies: + glob "^7.0.5" + run-async@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" @@ -5179,7 +6392,7 @@ rxjs@^7.2.0: dependencies: tslib "^2.1.0" -safe-buffer@^5.1.0, safe-buffer@~5.2.0: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -5189,7 +6402,7 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -5219,6 +6432,11 @@ semver-diff@^3.1.1: dependencies: semver "^6.3.0" +"semver@2 >=2.2.1 || 3.x || 4 || 5", "semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.1.0, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + semver@7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" @@ -5238,16 +6456,21 @@ semver@7.x, semver@^7.3.4, semver@^7.3.5: dependencies: lru-cache "^6.0.0" -semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== +semver@^4.1.0: + version "4.3.6" + resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" + integrity sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto= semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= + serialize-javascript@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -5255,6 +6478,19 @@ serialize-javascript@^6.0.0: dependencies: randombytes "^2.1.0" +set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +sha@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/sha/-/sha-2.0.1.tgz#6030822fbd2c9823949f8f72ed6411ee5cf25aae" + integrity sha1-YDCCL70smCOUn49y7WQR7lzyWq4= + dependencies: + graceful-fs "^4.1.2" + readable-stream "^2.0.2" + shallow-clone@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" @@ -5304,7 +6540,7 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: +signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== @@ -5314,6 +6550,11 @@ sisteransi@^1.0.5: resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + slash@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" @@ -5324,6 +6565,23 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +slide@^1.1.3, slide@^1.1.5, slide@~1.1.3, slide@~1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + integrity sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg= + dependencies: + hoek "2.x.x" + +sorted-object@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/sorted-object/-/sorted-object-2.0.1.tgz#7d631f4bd3a798a24af1dffcfbfe83337a5df5fc" + integrity sha1-fWMfS9OnmKJK8d/8+/6DM3pd9fw= + source-map-support@0.5.13: version "0.5.13" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" @@ -5365,6 +6623,32 @@ spawn-sync@^1.0.15: concat-stream "^1.4.7" os-shim "^0.1.2" +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.11" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" + integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== + split-on-first@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" @@ -5375,6 +6659,21 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= +sshpk@^1.7.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" + integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + stack-utils@^2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" @@ -5395,7 +6694,16 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -5427,6 +6735,11 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -5434,6 +6747,18 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +stringstream@~0.0.4: + version "0.0.6" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.6.tgz#7880225b0d4ad10e30927d167a1d6f2fd3b33a72" + integrity sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA== + +strip-ansi@^3.0.0, strip-ansi@^3.0.1, strip-ansi@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -5466,6 +6791,11 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -5505,6 +6835,15 @@ tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +tar@^2.0.0, tar@~2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" + integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== + dependencies: + block-stream "*" + fstream "^1.0.12" + inherits "2" + terminal-link@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" @@ -5543,7 +6882,7 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" -text-table@^0.2.0: +text-table@^0.2.0, text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= @@ -5587,6 +6926,21 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +tough-cookie@~2.3.0: + version "2.3.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" + integrity sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA== + dependencies: + punycode "^1.4.1" + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" @@ -5650,6 +7004,23 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tunnel-agent@~0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + integrity sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us= + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -5677,6 +7048,16 @@ type-fest@^0.4.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8" integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw== +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.6.0.tgz#3ca6099af5981d36ca86b78442973694278a219f" + integrity sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ== + typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -5694,6 +7075,16 @@ typescript@^4.3.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== +uid-number@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE= + +umask@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d" + integrity sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0= + unbox-primitive@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" @@ -5727,6 +7118,20 @@ unicode-property-aliases-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== +unique-filename@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + unique-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" @@ -5739,6 +7144,11 @@ universal-user-agent@^6.0.0: resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== +unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + update-notifier@5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" @@ -5783,11 +7193,21 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +util-extend@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f" + integrity sha1-p8IW0mdUUWljeztu3GypEZ4v+T8= + uuid@8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + v8-compile-cache@^2.0.3: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" @@ -5802,6 +7222,37 @@ v8-to-istanbul@^9.0.0: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" +validate-npm-package-license@*, validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +validate-npm-package-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" + integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= + dependencies: + builtins "^1.0.3" + +validate-npm-package-name@~2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-2.2.2.tgz#f65695b22f7324442019a3c7fa39a6e7fd299085" + integrity sha1-9laVsi9zJEQgGaPH+jmm5/0pkIU= + dependencies: + builtins "0.0.7" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + walker@^1.0.7: version "1.0.8" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" @@ -5817,7 +7268,7 @@ watchpack@^2.3.1: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" -wcwidth@^1.0.1: +wcwidth@^1.0.0, wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= @@ -5923,20 +7374,20 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" -which@1.2.x: - version "1.2.14" - resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" - integrity sha1-mofEN48D6CfOyvGs31bHNsAcFOU= - dependencies: - isexe "^2.0.0" - -which@^1.2.9: +which@1, which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" +which@1.2.x, which@~1.2.11: + version "1.2.14" + resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" + integrity sha1-mofEN48D6CfOyvGs31bHNsAcFOU= + dependencies: + isexe "^2.0.0" + which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -5944,6 +7395,13 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +wide-align@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + widest-line@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" @@ -5982,7 +7440,7 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrappy@1: +wrappy@1, wrappy@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= @@ -6005,11 +7463,25 @@ write-file-atomic@^4.0.1: imurmurhash "^0.1.4" signal-exit "^3.0.7" +write-file-atomic@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.2.0.tgz#14c66d4e4cb3ca0565c28cf3b7a6f3e4d5938fab" + integrity sha1-FMZtTkyzygVlwozzt6bz5NWTj6s= + dependencies: + graceful-fs "^4.1.2" + imurmurhash "^0.1.4" + slide "^1.1.5" + xdg-basedir@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== +xtend@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" From 49c4f5820dd94f6ddd0b8a9a246236a7c079a7b3 Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Mon, 30 May 2022 23:42:39 -0700 Subject: [PATCH 125/334] add branch naming guidelines --- CONTRIBUTING.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1fecd104e4..d1d4e71339 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,6 +4,21 @@ Run `yarn` after checkout to install all dependencies. +## Branch Guidelines + +New branches: Please branch off of the `develop` branch. + +### Naming + +Please use one of the following prefixes: (ie. feature/new-feature) + +- feature/ - development towards a new feature +- dev/ - misc development not tied to a key feature / refactoring +- vscode/ - development related to the VSCode Extension +- issue/ - fix specifically for a issue # +- bug/ - misc bug fixes not tied to a public issue +- repo/ - meta dev related changes (ie. typescript, CI/CD, dependencies) + ## Tests Tests can be run with `yarn test`. From e9cf7efd1242386ef80b4a7c9fceff7977c49762 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 13:07:42 +0300 Subject: [PATCH 126/334] Move Tokenizer options docs inside TokenizerOptions type def --- src/core/Tokenizer.ts | 44 ++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 5114bf20b7..64681e3f6c 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -9,23 +9,45 @@ const toCanonicalKeyword = (text: string) => equalizeWhitespace(text.toUpperCase /** Struct that defines how a SQL language can be broken into tokens */ interface TokenizerOptions { - reservedKeywords: string[]; + // Main clauses that start new block, like: SELECT, FROM, WHERE, ORDER BY reservedCommands: string[]; + // Logical operator keywords, defaults to: [AND, OR] reservedLogicalOperators?: string[]; + // Keywords in CASE expressions that begin new line, like: WHEN, ELSE reservedDependentClauses: string[]; + // Keywords that create newline but no indentaion of their body. + // These contain set operations like UNION and various joins like LEFT OUTER JOIN reservedBinaryCommands: string[]; + // keywords used for JOIN conditions, defaults to: [ON, USING] reservedJoinConditions?: string[]; + // all other reserved words (not included to any of the above lists) + reservedKeywords: string[]; + // Types of quotes to use for strings stringTypes: regexFactory.QuoteType[]; + // Types of quotes to use for quoted identifiers identifierTypes: regexFactory.QuoteType[]; + // Open-parenthesis characters, like: (, [, { blockStart?: string[]; + // Close-parenthesis characters, like: ), ], } blockEnd?: string[]; + // True to allow for positional "?" parameter placeholders positionalPlaceholders?: boolean; + // Prefixes for numbered parameter placeholders to support, e.g. :1, :2, :3 numberedPlaceholderTypes?: ('?' | ':' | '$')[]; + // Prefixes for named parameter placeholders to support, e.g. :name namedPlaceholderTypes?: (':' | '@' | '$')[]; + // Prefixes for quoted parameter placeholders to support, e.g. :"name" + // The type of quotes will depend on `identifierTypes` option. quotedPlaceholderTypes?: (':' | '@' | '$')[]; + // Line comment types to support, defaults to -- lineCommentTypes?: string[]; + // Additioanl characters to support in identifiers specialIdentChars?: { prefix?: string; any?: string; suffix?: string }; + // Additional multi-character operators to support, in addition to <=, >=, <>, != operators?: string[]; + // Allows custom modifications on the token array. + // Called after the whole input string has been split into tokens. + // The result of this will be the output of the tokenizer. preprocess?: (tokens: Token[]) => Token[]; } @@ -39,26 +61,6 @@ export default class Tokenizer { private preprocess = (tokens: Token[]) => tokens; - /** - * @param {TokenizerOptions} cfg - * @param {string[]} cfg.reservedKeywords - Reserved words in SQL - * @param {string[]} cfg.reservedDependentClauses - Words that following a specific Statement and must have data attached - * @param {string[]} cfg.reservedLogicalOperators - Words that are set to newline - * @param {string[]} cfg.reservedCommands - Words that are set to new line separately - * @param {string[]} cfg.reservedBinaryCommands - Words that are top level but have no indentation - * @param {string[]} cfg.reservedJoinConditions - ON and USING - * @param {string[]} cfg.stringTypes - string types to enable - '', "", N'', ... - * @param {string[]} cfg.identifierTypes - identifier types to enable - "", ``, [], ... - * @param {string[]} cfg.blockStart - Opening parentheses to enable, like (, [ - * @param {string[]} cfg.blockEnd - Closing parentheses to enable, like ), ] - * @param {boolean} cfg.positionalPlaceholders - True to enable positional placeholders "?" - * @param {string[]} cfg.numberedPlaceholderTypes - Prefixes for numbered placeholders, like ":" for :1, :2, :3 - * @param {string[]} cfg.namedPlaceholderTypes - Prefixes for named placeholders, like @ and : - * @param {string[]} cfg.lineCommentTypes - Line comments to enable, like # and -- - * @param {string[]} cfg.specialIdentChars - Special chars that can be found inside identifiers, like @ and # - * @param {string[]} cfg.operators - Additional operators to recognize - * @param {Function} cfg.preprocess - Optional function to process tokens before emitting - */ constructor(cfg: TokenizerOptions) { if (cfg.preprocess) { this.preprocess = cfg.preprocess; From a59bbd18dc0d1dde3fb4f8fe55c3f8ea4df61994 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 13:22:44 +0300 Subject: [PATCH 127/334] Remove underscore from BigQuery & PL/SQL specialIdentChars This is supported already by default --- src/languages/bigquery.formatter.ts | 2 +- src/languages/plsql.formatter.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index 3330003519..e27ad44b38 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -865,7 +865,7 @@ export default class BigQueryFormatter extends Formatter { namedPlaceholderTypes: ['@'], quotedPlaceholderTypes: ['@'], lineCommentTypes: ['--', '#'], - specialIdentChars: { any: '_@$-' }, + specialIdentChars: { any: '@$-' }, operators: BigQueryFormatter.operators, preprocess, }); diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 4e4087a2c2..4cf3025e76 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -466,7 +466,7 @@ export default class PlSqlFormatter extends Formatter { identifierTypes: [`""`], numberedPlaceholderTypes: [':'], namedPlaceholderTypes: [':'], - specialIdentChars: { any: '_$#' }, + specialIdentChars: { any: '$#' }, operators: PlSqlFormatter.operators, preprocess, }); From bfc17184eb7c7b922245401ed09265084976d6f2 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 13:24:58 +0300 Subject: [PATCH 128/334] Remove inorrect lookBehind/Ahead terminology from createReservedWordRegex --- src/core/regexFactory.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 71647ad26d..174991b0b1 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -53,8 +53,8 @@ export const createReservedWordRegex = ( export const createIdentRegex = ( specialChars: { any?: string; prefix?: string; suffix?: string } = {} ): RegExp => { - const prefixLookBehind = `[${escapeRegExp(specialChars.prefix ?? '')}]*`; - const suffixLookAhead = `[${escapeRegExp(specialChars.suffix ?? '')}]*`; + const prefix = `[${escapeRegExp(specialChars.prefix ?? '')}]*`; + const suffix = `[${escapeRegExp(specialChars.suffix ?? '')}]*`; const unicodeWordChar = '\\p{Alphabetic}\\p{Mark}\\p{Decimal_Number}\\p{Connector_Punctuation}\\p{Join_Control}'; const specialWordChars = `${escapeRegExp(specialChars.any ?? '')}`; @@ -63,7 +63,7 @@ export const createIdentRegex = ( const mapAccessor = `\\[['"][${unicodeWordChar}]+['"]\\]`; return new RegExp( - `^((${prefixLookBehind}([${unicodeWordChar}${specialWordChars}]+)${suffixLookAhead})(${arrayAccessor}|${mapAccessor})?)`, + `^((${prefix}([${unicodeWordChar}${specialWordChars}]+)${suffix})(${arrayAccessor}|${mapAccessor})?)`, 'u' ); }; From 250a03ef45142529c99f678cf8a6bdacd00f62a1 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 13:28:53 +0300 Subject: [PATCH 129/334] Prefer empty string '' over empty '[]*' regex --- src/core/regexFactory.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 174991b0b1..6be0aa1d68 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -53,8 +53,8 @@ export const createReservedWordRegex = ( export const createIdentRegex = ( specialChars: { any?: string; prefix?: string; suffix?: string } = {} ): RegExp => { - const prefix = `[${escapeRegExp(specialChars.prefix ?? '')}]*`; - const suffix = `[${escapeRegExp(specialChars.suffix ?? '')}]*`; + const prefix = specialChars.prefix ? `[${escapeRegExp(specialChars.prefix)}]*` : ''; + const suffix = specialChars.suffix ? `[${escapeRegExp(specialChars.suffix)}]*` : ''; const unicodeWordChar = '\\p{Alphabetic}\\p{Mark}\\p{Decimal_Number}\\p{Connector_Punctuation}\\p{Join_Control}'; const specialWordChars = `${escapeRegExp(specialChars.any ?? '')}`; From 45a5b67cead1962f5f4067de61fba33b5c71cc77 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 13:29:53 +0300 Subject: [PATCH 130/334] Remove unnecessary string-interpolation --- src/core/regexFactory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 6be0aa1d68..2313379f9d 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -57,7 +57,7 @@ export const createIdentRegex = ( const suffix = specialChars.suffix ? `[${escapeRegExp(specialChars.suffix)}]*` : ''; const unicodeWordChar = '\\p{Alphabetic}\\p{Mark}\\p{Decimal_Number}\\p{Connector_Punctuation}\\p{Join_Control}'; - const specialWordChars = `${escapeRegExp(specialChars.any ?? '')}`; + const specialWordChars = escapeRegExp(specialChars.any ?? ''); const arrayAccessor = '\\[\\d\\]'; const mapAccessor = `\\[['"][${unicodeWordChar}]+['"]\\]`; From 5aaddff0a221ea93a41b418520efbae840d457d2 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 13:33:24 +0300 Subject: [PATCH 131/334] Extract IdentChars type --- src/core/Tokenizer.ts | 2 +- src/core/regexFactory.ts | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 64681e3f6c..be7b3d513b 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -42,7 +42,7 @@ interface TokenizerOptions { // Line comment types to support, defaults to -- lineCommentTypes?: string[]; // Additioanl characters to support in identifiers - specialIdentChars?: { prefix?: string; any?: string; suffix?: string }; + specialIdentChars?: regexFactory.IdentChars; // Additional multi-character operators to support, in addition to <=, >=, <>, != operators?: string[]; // Allows custom modifications on the token array. diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 2313379f9d..72a172dea7 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -43,16 +43,20 @@ export const createReservedWordRegex = ( ); }; +export interface IdentChars { + // concatenated string of chars that can appear anywhere in a valid identifier + any?: string; + // concatenated string of chars that only appear at the beginning of a valid identifier + prefix?: string; + // concatenated string of chars that only appear at the end of a valid identifier + suffix?: string; +} + /** * Builds a RegExp for valid identifiers in a SQL dialect - * @param {Object} specialChars - * @param {string} specialChars.any - concatenated string of chars that can appear anywhere in a valid identifier - * @param {string} specialChars.prefix - concatenated string of chars that only appear at the beginning of a valid identifier - * @param {string} specialChars.suffix - concatenated string of chars that only appear at the end of a valid identifier + * @param {IdentChars} specialChars */ -export const createIdentRegex = ( - specialChars: { any?: string; prefix?: string; suffix?: string } = {} -): RegExp => { +export const createIdentRegex = (specialChars: IdentChars = {}): RegExp => { const prefix = specialChars.prefix ? `[${escapeRegExp(specialChars.prefix)}]*` : ''; const suffix = specialChars.suffix ? `[${escapeRegExp(specialChars.suffix)}]*` : ''; const unicodeWordChar = From ae035ec4b38afaefe6789076e994b6c38bcc28fa Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 13:34:05 +0300 Subject: [PATCH 132/334] Drop unused suffix field from IdentChars --- src/core/regexFactory.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 72a172dea7..06e632c6e8 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -48,8 +48,6 @@ export interface IdentChars { any?: string; // concatenated string of chars that only appear at the beginning of a valid identifier prefix?: string; - // concatenated string of chars that only appear at the end of a valid identifier - suffix?: string; } /** @@ -58,7 +56,6 @@ export interface IdentChars { */ export const createIdentRegex = (specialChars: IdentChars = {}): RegExp => { const prefix = specialChars.prefix ? `[${escapeRegExp(specialChars.prefix)}]*` : ''; - const suffix = specialChars.suffix ? `[${escapeRegExp(specialChars.suffix)}]*` : ''; const unicodeWordChar = '\\p{Alphabetic}\\p{Mark}\\p{Decimal_Number}\\p{Connector_Punctuation}\\p{Join_Control}'; const specialWordChars = escapeRegExp(specialChars.any ?? ''); @@ -67,7 +64,7 @@ export const createIdentRegex = (specialChars: IdentChars = {}): RegExp => { const mapAccessor = `\\[['"][${unicodeWordChar}]+['"]\\]`; return new RegExp( - `^((${prefix}([${unicodeWordChar}${specialWordChars}]+)${suffix})(${arrayAccessor}|${mapAccessor})?)`, + `^((${prefix}([${unicodeWordChar}${specialWordChars}]+))(${arrayAccessor}|${mapAccessor})?)`, 'u' ); }; From df52877a517012a1355266fb11a48cda433fa3e0 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 13:49:54 +0300 Subject: [PATCH 133/334] BREAKING! Drop variables support for MariaDB and MySQL Removing this for now, to simplify refactoring. Planning to bring this back later with implementing general support for variables in SQL. --- src/languages/mariadb.formatter.ts | 1 - src/languages/mysql.formatter.ts | 1 - test/behavesLikeMariaDbFormatter.ts | 6 ++++-- test/mysql.test.ts | 3 ++- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index 24c1996e54..2efb215aa7 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1168,7 +1168,6 @@ export default class MariaDbFormatter extends Formatter { identifierTypes: ['``'], positionalPlaceholders: true, lineCommentTypes: ['--', '#'], - specialIdentChars: { prefix: '@' }, operators: MariaDbFormatter.operators, preprocess, }); diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index a579ace95f..d499ca5e58 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1331,7 +1331,6 @@ export default class MySqlFormatter extends Formatter { identifierTypes: ['``'], positionalPlaceholders: true, lineCommentTypes: ['--', '#'], - specialIdentChars: { prefix: '@:' }, operators: MySqlFormatter.operators, preprocess, }); diff --git a/test/behavesLikeMariaDbFormatter.ts b/test/behavesLikeMariaDbFormatter.ts index 41bc683bfc..eba95a7812 100644 --- a/test/behavesLikeMariaDbFormatter.ts +++ b/test/behavesLikeMariaDbFormatter.ts @@ -38,7 +38,9 @@ export default function behavesLikeMariaDbFormatter(format: FormatFn) { }); supportsParams(format, { positional: true }); - it('supports @variables', () => { + // TODO: Disabled for now. + // Bring these back later by implementing a generic support for variables in all dialects. + it.skip('supports @variables', () => { expect(format('SELECT @foo, @bar')).toBe(dedent` SELECT @foo, @@ -46,7 +48,7 @@ export default function behavesLikeMariaDbFormatter(format: FormatFn) { `); }); - it('supports setting variables: @var :=', () => { + it.skip('supports setting variables: @var :=', () => { expect(format('SET @foo := (SELECT * FROM tbl);')).toBe(dedent` SET @foo := ( diff --git a/test/mysql.test.ts b/test/mysql.test.ts index f4e0600224..79ec220e89 100644 --- a/test/mysql.test.ts +++ b/test/mysql.test.ts @@ -13,7 +13,8 @@ describe('MySqlFormatter', () => { supportsOperators(format, MySqlFormatter.operators, ['AND', 'OR', 'XOR']); - it('supports @@ system variables', () => { + // TODO: disabled for now + it.skip('supports @@ system variables', () => { const result = format('SELECT @@GLOBAL.time, @@SYSTEM.date, @@hour FROM foo;'); expect(result).toBe(dedent` SELECT From c9d65dc3df5d5a924cf6e7e0e1d18bd78c95411d Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 13:55:10 +0300 Subject: [PATCH 134/334] BigQuery only supports dashes in identifiers, not $ and @ --- src/languages/bigquery.formatter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index e27ad44b38..c69daeb1ba 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -865,7 +865,7 @@ export default class BigQueryFormatter extends Formatter { namedPlaceholderTypes: ['@'], quotedPlaceholderTypes: ['@'], lineCommentTypes: ['--', '#'], - specialIdentChars: { any: '@$-' }, + specialIdentChars: { any: '-' }, operators: BigQueryFormatter.operators, preprocess, }); From f4b2ccaf6900953cf606bb86ca88b05a0784fa02 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 14:15:00 +0300 Subject: [PATCH 135/334] Support $ in TSQL identifiers --- src/languages/tsql.formatter.ts | 2 +- test/tsql.test.ts | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index cc0182f507..7b7a8caf0b 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1246,7 +1246,7 @@ export default class TSqlFormatter extends Formatter { identifierTypes: [`""`, '[]'], namedPlaceholderTypes: ['@'], quotedPlaceholderTypes: ['@'], - specialIdentChars: { any: '#@' }, + specialIdentChars: { any: '#@$' }, operators: TSqlFormatter.operators, // TODO: Support for money constants }); diff --git a/test/tsql.test.ts b/test/tsql.test.ts index a9de71b53c..4c429adc1f 100644 --- a/test/tsql.test.ts +++ b/test/tsql.test.ts @@ -59,4 +59,16 @@ describe('TSqlFormatter', () => { CROSS JOIN t2 on t.id = t2.id_t `); }); + + it('recognizes @, $, # as part of identifiers', () => { + const result = format('SELECT from@bar, where#to, join$me FROM tbl;'); + expect(result).toBe(dedent` + SELECT + from@bar, + where#to, + join$me + FROM + tbl; + `); + }); }); From 0eae6aa64548d4b3b9fe7ac7f6b1d6cdabf12329 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 14:23:16 +0300 Subject: [PATCH 136/334] Use ident regex also for named placeholders --- src/core/Tokenizer.ts | 2 +- src/core/regexFactory.ts | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index be7b3d513b..873d9a027b 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -120,7 +120,7 @@ export default class Tokenizer { // :name placeholders regex: regexFactory.createPlaceholderRegex( cfg.namedPlaceholderTypes ?? [], - '[a-zA-Z0-9_$]+' + regexFactory.createIdentPattern(cfg.specialIdentChars) ), parseKey: v => v.slice(1), }, diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 06e632c6e8..b105ec3801 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -52,9 +52,14 @@ export interface IdentChars { /** * Builds a RegExp for valid identifiers in a SQL dialect - * @param {IdentChars} specialChars */ -export const createIdentRegex = (specialChars: IdentChars = {}): RegExp => { +export const createIdentRegex = (specialChars: IdentChars = {}): RegExp => + new RegExp(`^(${createIdentPattern(specialChars)})`, 'u'); + +/** + * Builds a RegExp string for valid identifiers in a SQL dialect + */ +export const createIdentPattern = (specialChars: IdentChars = {}): string => { const prefix = specialChars.prefix ? `[${escapeRegExp(specialChars.prefix)}]*` : ''; const unicodeWordChar = '\\p{Alphabetic}\\p{Mark}\\p{Decimal_Number}\\p{Connector_Punctuation}\\p{Join_Control}'; @@ -63,10 +68,7 @@ export const createIdentRegex = (specialChars: IdentChars = {}): RegExp => { const arrayAccessor = '\\[\\d\\]'; const mapAccessor = `\\[['"][${unicodeWordChar}]+['"]\\]`; - return new RegExp( - `^((${prefix}([${unicodeWordChar}${specialWordChars}]+))(${arrayAccessor}|${mapAccessor})?)`, - 'u' - ); + return `(${prefix}([${unicodeWordChar}${specialWordChars}]+))(${arrayAccessor}|${mapAccessor})?`; }; // This enables the following quote styles: From 9ade2ecd684013204266b372710242f3173a971e Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 14:34:41 +0300 Subject: [PATCH 137/334] Don't allow prefix chars inside identifiers Refactored createReservedWordRegex() to only consider IdentChars.any option when constructing the regex. Also documented this tricky logic. --- src/core/Tokenizer.ts | 13 ++++++------- src/core/regexFactory.ts | 19 ++++++++++++------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 873d9a027b..79eb7898cb 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -66,7 +66,6 @@ export default class Tokenizer { this.preprocess = cfg.preprocess; } - const specialIdentCharsAll = Object.values(cfg.specialIdentChars ?? {}).join(''); this.quotedIdentRegex = regexFactory.createQuoteRegex(cfg.identifierTypes); this.REGEX_MAP = { @@ -74,27 +73,27 @@ export default class Tokenizer { [TokenType.STRING]: regexFactory.createQuoteRegex(cfg.stringTypes), [TokenType.RESERVED_KEYWORD]: regexFactory.createReservedWordRegex( cfg.reservedKeywords, - specialIdentCharsAll + cfg.specialIdentChars ), [TokenType.RESERVED_DEPENDENT_CLAUSE]: regexFactory.createReservedWordRegex( cfg.reservedDependentClauses ?? [], - specialIdentCharsAll + cfg.specialIdentChars ), [TokenType.RESERVED_LOGICAL_OPERATOR]: regexFactory.createReservedWordRegex( cfg.reservedLogicalOperators ?? ['AND', 'OR'], - specialIdentCharsAll + cfg.specialIdentChars ), [TokenType.RESERVED_COMMAND]: regexFactory.createReservedWordRegex( cfg.reservedCommands, - specialIdentCharsAll + cfg.specialIdentChars ), [TokenType.RESERVED_BINARY_COMMAND]: regexFactory.createReservedWordRegex( cfg.reservedBinaryCommands, - specialIdentCharsAll + cfg.specialIdentChars ), [TokenType.RESERVED_JOIN_CONDITION]: regexFactory.createReservedWordRegex( cfg.reservedJoinConditions ?? ['ON', 'USING'], - specialIdentCharsAll + cfg.specialIdentChars ), [TokenType.OPERATOR]: regexFactory.createOperatorRegex('+-/*%&|^><=.,;[]{}`:$@', [ '<>', diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index b105ec3801..a8e5d69950 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -24,23 +24,28 @@ export const createLineCommentRegex = (lineCommentTypes: string[]): RegExp => /** * Builds a RegExp for all Reserved Keywords in a SQL dialect - * @param {string[]} reservedKeywords - list of strings of all Reserved Keywords - * @param {string} specialWordChars - concatenated string of all special chars that can appear in valid identifiers (and not in Reserved Keywords) */ export const createReservedWordRegex = ( reservedKeywords: string[], - specialWordChars: string = '' + specialChars: IdentChars = {} ): RegExp => { if (reservedKeywords.length === 0) { return /^\b$/u; } + + // Negative lookahead to avoid matching a keyword that's actually part of identifier, + // which can happen when identifier allows word-boundary characters inside it. + // + // For example "SELECT$ME" should be tokenized as: + // - ["SELECT$ME"] when $ is allowed inside identifiers + // - ["SELECT", "$", "ME"] when $ can't be part of identifiers. + const avoidIdentChars = specialChars.any ? `(?![${escapeRegExp(specialChars.any)}])` : ''; + const reservedKeywordsPattern = sortByLengthDesc(reservedKeywords) .join('|') .replace(/ /gu, '\\s+'); - return new RegExp( - `^(${reservedKeywordsPattern})(?![${escapeRegExp(specialWordChars)}]+)\\b`, - 'iu' - ); + + return new RegExp(`^(${reservedKeywordsPattern})${avoidIdentChars}\\b`, 'iu'); }; export interface IdentChars { From 4161b0326048d2c3e1739f7290efdad4bab3aed0 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 14:49:51 +0300 Subject: [PATCH 138/334] Drop join control chars in identifiers It's not clear to me that these are supported in SQL dialects. These are invisible characters, only two of them: - U+200C ZERO WIDTH NON-JOINER - U+200D ZERO WIDTH JOINER Anybody using these in his SQL is likely asking for trouble. I'd say, less complexity for the win! --- src/core/regexFactory.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index a8e5d69950..f7ab7c4ab9 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -66,8 +66,7 @@ export const createIdentRegex = (specialChars: IdentChars = {}): RegExp => */ export const createIdentPattern = (specialChars: IdentChars = {}): string => { const prefix = specialChars.prefix ? `[${escapeRegExp(specialChars.prefix)}]*` : ''; - const unicodeWordChar = - '\\p{Alphabetic}\\p{Mark}\\p{Decimal_Number}\\p{Connector_Punctuation}\\p{Join_Control}'; + const unicodeWordChar = '\\p{Alphabetic}\\p{Mark}\\p{Decimal_Number}\\p{Connector_Punctuation}'; const specialWordChars = escapeRegExp(specialChars.any ?? ''); const arrayAccessor = '\\[\\d\\]'; From 3b555128059663da5df6f49be9f3a15e6d0e4924 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 14:55:46 +0300 Subject: [PATCH 139/334] Replace Connector_Punctuation with just an underscore This set contains bunch of underscore-like characters. From the docs of various SQL dialects it wasn't clear to me that these all are supported. What was clear though, was the support for underscore character in particular. --- src/core/regexFactory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index f7ab7c4ab9..0d56627930 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -66,7 +66,7 @@ export const createIdentRegex = (specialChars: IdentChars = {}): RegExp => */ export const createIdentPattern = (specialChars: IdentChars = {}): string => { const prefix = specialChars.prefix ? `[${escapeRegExp(specialChars.prefix)}]*` : ''; - const unicodeWordChar = '\\p{Alphabetic}\\p{Mark}\\p{Decimal_Number}\\p{Connector_Punctuation}'; + const unicodeWordChar = '\\p{Alphabetic}\\p{Mark}\\p{Decimal_Number}_'; const specialWordChars = escapeRegExp(specialChars.any ?? ''); const arrayAccessor = '\\[\\d\\]'; From 7a0c803ba93c4c897d1bb6fceac3f6d0b28c319d Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 15:02:02 +0300 Subject: [PATCH 140/334] Clarify use of unicode letters/numbers in regex creation --- src/core/regexFactory.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 0d56627930..d63857a5b2 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -66,13 +66,16 @@ export const createIdentRegex = (specialChars: IdentChars = {}): RegExp => */ export const createIdentPattern = (specialChars: IdentChars = {}): string => { const prefix = specialChars.prefix ? `[${escapeRegExp(specialChars.prefix)}]*` : ''; - const unicodeWordChar = '\\p{Alphabetic}\\p{Mark}\\p{Decimal_Number}_'; + // Unicode letters, diacritical marks and underscore + const letter = '\\p{Alphabetic}\\p{Mark}_'; + // Numbers 0..9, plus various unicode numbers + const number = '\\p{Decimal_Number}'; const specialWordChars = escapeRegExp(specialChars.any ?? ''); const arrayAccessor = '\\[\\d\\]'; - const mapAccessor = `\\[['"][${unicodeWordChar}]+['"]\\]`; + const mapAccessor = `\\[['"][${letter}${number}]+['"]\\]`; - return `(${prefix}([${unicodeWordChar}${specialWordChars}]+))(${arrayAccessor}|${mapAccessor})?`; + return `(${prefix}([${letter}${number}${specialWordChars}]+))(${arrayAccessor}|${mapAccessor})?`; }; // This enables the following quote styles: From 9895c3d79a6c71e5a42a7d44df06b0ba21f8e08a Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 15:06:30 +0300 Subject: [PATCH 141/334] Add test for unicode numbers --- test/behavesLikeSqlFormatter.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/test/behavesLikeSqlFormatter.ts b/test/behavesLikeSqlFormatter.ts index 1d096c9239..0ef672d655 100644 --- a/test/behavesLikeSqlFormatter.ts +++ b/test/behavesLikeSqlFormatter.ts @@ -330,7 +330,7 @@ export default function behavesLikeSqlFormatter(format: FormatFn) { expect(result).toBe("((foo = 'bar'))"); }); - it('formats unicode correctly', () => { + it('supports unicode letters in identifiers', () => { const result = format('SELECT 结合使用, тест FROM töörõõm;'); expect(result).toBe(dedent` SELECT @@ -341,6 +341,17 @@ export default function behavesLikeSqlFormatter(format: FormatFn) { `); }); + // Using Myanmar and Tibetan digits 1, 2, 3 + it('supports unicode numbers in identifiers', () => { + const result = format('SELECT my၁၂၃ FROM tbl༡༢༣;'); + expect(result).toBe(dedent` + SELECT + my၁၂၃ + FROM + tbl༡༢༣; + `); + }); + it('does not split UNION ALL in half', () => { const result = format(` SELECT * FROM tbl1 From 2e6da0f7c97660e38dbda15fb6a043ad7f1e001b Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 15:14:43 +0300 Subject: [PATCH 142/334] Add test for unicode diacritical marks --- test/behavesLikeSqlFormatter.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/behavesLikeSqlFormatter.ts b/test/behavesLikeSqlFormatter.ts index 0ef672d655..dc4eea9163 100644 --- a/test/behavesLikeSqlFormatter.ts +++ b/test/behavesLikeSqlFormatter.ts @@ -352,6 +352,17 @@ export default function behavesLikeSqlFormatter(format: FormatFn) { `); }); + it('supports unicode diacritical marks in identifiers', () => { + const COMBINING_TILDE = String.fromCodePoint(0x0303); + const result = format('SELECT o' + COMBINING_TILDE + ' FROM tbl;'); + expect(result).toBe(dedent` + SELECT + õ + FROM + tbl; + `); + }); + it('does not split UNION ALL in half', () => { const result = format(` SELECT * FROM tbl1 From f843c2fda7392d24e696e040b0dc8918d818c0b8 Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Tue, 31 May 2022 07:00:29 -0700 Subject: [PATCH 143/334] update dependency --- vscode/package.json | 2 +- vscode/yarn.lock | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/vscode/package.json b/vscode/package.json index a91e81c73d..313ef0bfee 100644 --- a/vscode/package.json +++ b/vscode/package.json @@ -65,7 +65,7 @@ "vsce": "vsce" }, "dependencies": { - "prettier-sql": "^5.1.0" + "sql-formatter": "^6.1.2" }, "devDependencies": { "@types/glob": "^7.1.4", diff --git a/vscode/yarn.lock b/vscode/yarn.lock index f7c79bfca9..8572cb888f 100644 --- a/vscode/yarn.lock +++ b/vscode/yarn.lock @@ -1896,6 +1896,13 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +sql-formatter@^6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/sql-formatter/-/sql-formatter-6.1.2.tgz#78b05021c641020312a5f144ec313b38e7663258" + integrity sha512-09AiPmA6zDq82IBXOj5kN33VeAqaV92enkoonlhJge0fmfTESiYs3pwsntGKxa1C89xj/9MoHlNeqMmCr23BJw== + dependencies: + argparse "^2.0.1" + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" From d182948c2afe39cb34b61aea824ffb9e0f488530 Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Tue, 31 May 2022 07:02:15 -0700 Subject: [PATCH 144/334] update extension with v6 setting changes --- vscode/package.json | 64 +++++++++++++++++------------------------ vscode/src/extension.ts | 44 +++++++++++++--------------- 2 files changed, 46 insertions(+), 62 deletions(-) diff --git a/vscode/package.json b/vscode/package.json index 313ef0bfee..612164fef8 100644 --- a/vscode/package.json +++ b/vscode/package.json @@ -120,6 +120,7 @@ "postgresql", "redshift", "spark", + "sqlite", "tsql" ], "default": "sql", @@ -141,17 +142,22 @@ "default": true, "markdownDescription": "Override for `insertSpaces` if `#Prettier-SQL.ignoreTabSettings#` is active" }, - "Prettier-SQL.uppercaseKeywords": { - "type": "boolean", - "default": true, - "markdownDescription": "Whether to print keywords in ALL CAPS or lowercase" + "Prettier-SQL.keywordCase": { + "type": "string", + "enum": [ + "preserve", + "upper", + "lower" + ], + "default": "preserve", + "markdownDescription": "Whether to print keywords in ALL CAPS, lowercase, or preserve existing" }, - "Prettier-SQL.keywordPosition": { + "Prettier-SQL.indentStyle": { "type": "string", "enum": [ "standard", - "tenSpaceLeft", - "tenSpaceRight" + "tabularLeft", + "tabularRight" ], "enumDescriptions": [ "Standard SQL format, with cascading indents", @@ -161,19 +167,25 @@ "default": "standard", "markdownDescription": "Where to place keywords" }, - "Prettier-SQL.breakBeforeBooleanOperator": { - "type": "boolean", - "default": false, + "Prettier-SQL.logicalOperatorNewline": { + "type": "string", + "enum": [ + "before", + "after" + ], + "default": "before", "markdownDescription": "Whether to break before or after AND and OR" }, "Prettier-SQL.aliasAS": { "type": "string", "enum": [ + "preserve", "always", "select", "never" ], "enumDescriptions": [ + "Preserve existing AS usage", "Use AS in SELECT clauses and for tables", "Use AS only in SELECT clauses", "Do not use AS for aliases" @@ -201,41 +213,17 @@ "default": "after", "markdownDescription": "Where to place commas for SELECT and GROUP BY clauses" }, - "Prettier-SQL.keywordNewline.newlineMode": { - "type": "string", - "enum": [ - "always", - "lineWidth", - "itemCount", - "never" - ], - "markdownEnumDescriptions": [ - "Always break keywords items onto a newline", - "Break onto newline when line width > `#Prettier-SQL.lineWidth#` ", - "Break onto newline when item count > `#Prettier-SQL.itemCount#` ", - "Place all selected columns on the same line as keyword" - ], - "minimum": 1, - "default": "always", - "markdownDescription": "Rule for when to break keyword clauses onto a newline" - }, - "Prettier-SQL.keywordNewline.itemCount": { - "type": "number", - "minimum": 1, - "default": 3, - "markdownDescription": "Breaks keywords clauses onto newline after n items when `#Prettier-SQL.keywordNewline#` is set to itemCount" - }, - "Prettier-SQL.parenOptions.openParenNewline": { + "Prettier-SQL.parenOptions.newlineBeforeOpenParen": { "type": "boolean", "default": false, "markdownDescription": "Place (, Open Paren, CASE on newline when creating a new block" }, - "Prettier-SQL.parenOptions.closeParenNewline": { + "Prettier-SQL.parenOptions.newlineBeforeCloseParen": { "type": "boolean", "default": true, "markdownDescription": "Place ), Close Paren, END on newline when closing a block" }, - "Prettier-SQL.lineWidth": { + "Prettier-SQL.expressionWidth": { "type": "integer", "default": 50, "minimum": 0, @@ -252,7 +240,7 @@ "default": false, "markdownDescription": "Strip whitespace around operators such as + or >=" }, - "Prettier-SQL.semicolonNewline": { + "Prettier-SQL.newlineBeforeSemicolon": { "type": "boolean", "default": false, "markdownDescription": "Whether to place semicolon on its own line or on previous line" diff --git a/vscode/src/extension.ts b/vscode/src/extension.ts index 3f48d13a73..1fcd675fd7 100644 --- a/vscode/src/extension.ts +++ b/vscode/src/extension.ts @@ -1,17 +1,18 @@ import * as vscode from 'vscode'; -import { format } from 'prettier-sql'; +import { format } from 'sql-formatter'; import type { + SqlLanguage, + KeywordCase, + IndentStyle, AliasMode, CommaPosition, - FormatterLanguage, - KeywordMode, - NewlineMode, -} from 'prettier-sql'; + LogicalOperatorNewline, +} from 'sql-formatter'; const getConfigs = ( settings: vscode.WorkspaceConfiguration, formattingOptions: vscode.FormattingOptions | { tabSize: number; insertSpaces: boolean }, - language: FormatterLanguage + language: SqlLanguage ) => { const ignoreTabSettings = settings.get('ignoreTabSettings'); const { tabSize, insertSpaces } = ignoreTabSettings // override tab settings if ignoreTabSettings is true @@ -26,34 +27,28 @@ const getConfigs = ( const formatConfigs = { language: language === 'sql' // override default SQL language mode if SQLFlavourOverride is set - ? settings.get('SQLFlavourOverride') ?? 'sql' + ? settings.get('SQLFlavourOverride') ?? 'sql' : language, indent, - uppercase: settings.get('uppercaseKeywords'), - keywordPosition: settings.get('keywordPosition'), - breakBeforeBooleanOperator: settings.get('breakBeforeBooleanOperator'), + keywordCase: settings.get('keywordCase'), + indentStyle: settings.get('indentStyle'), + logicalOperatorNewline: settings.get('logicalOperatorNewline'), aliasAs: settings.get('aliasAS'), tabulateAlias: settings.get('tabulateAlias'), commaPosition: settings.get('commaPosition'), - newline: (newlineSetting => - newlineSetting === 'itemCount' - ? settings.get('itemCount') // pass itemCount number if keywordNewline is itemCount mode - : (newlineSetting as NewlineMode))(settings.get('keywordNewline')), - parenOptions: { - openParenNewline: settings.get('parenOptions.openParenNewline'), - closeParenNewline: settings.get('parenOptions.closeParenNewline'), - }, - lineWidth: settings.get('lineWidth'), + newlineBeforeOpenParen: settings.get('newlineBeforeOpenParen'), + newlineBeforeCloseParen: settings.get('newlineBeforeCloseParen'), + expressionWidth: settings.get('expressionWidth'), linesBetweenQueries: settings.get('linesBetweenQueries'), denseOperators: settings.get('denseOperators'), - semicolonNewline: settings.get('semicolonNewline'), + newlineBeforeSemicolon: settings.get('newlineBeforeSemicolon'), }; return formatConfigs; }; export function activate(context: vscode.ExtensionContext) { - const formatProvider = (language: FormatterLanguage) => ({ + const formatProvider = (language: SqlLanguage) => ({ provideDocumentFormattingEdits( document: vscode.TextDocument, options: vscode.FormattingOptions @@ -84,14 +79,15 @@ export function activate(context: vscode.ExtensionContext) { }, }); - const languages: { [lang: string]: FormatterLanguage } = { + const languages: { [lang: string]: SqlLanguage } = { 'sql': 'sql', 'plsql': 'plsql', 'mysql': 'mysql', 'postgres': 'postgresql', - 'hql': 'sql', - 'hive-sql': 'sql', + 'hql': 'hive', + 'hive-sql': 'hive', 'sql-bigquery': 'bigquery', + 'sqlite': 'sqlite', }; // add Prettier-SQL as a format provider for each language Object.entries(languages).forEach(([vscodeLang, prettierLang]) => From 7ab674c1e7bfa1bacc5d9a38824a868a0821eaa1 Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Tue, 31 May 2022 07:58:47 -0700 Subject: [PATCH 145/334] remove npm-cli --- package.json | 1 - yarn.lock | 1554 ++------------------------------------------------ 2 files changed, 41 insertions(+), 1514 deletions(-) diff --git a/package.json b/package.json index 7976910655..7c79d72d2f 100644 --- a/package.json +++ b/package.json @@ -120,7 +120,6 @@ "eslint-plugin-import": "^2.22.0", "eslint-plugin-prettier": "^4.0.0", "jest": "^28.0.2", - "npm-cli": "^0.1.0", "pre-commit": "^1.2.2", "pre-push": "^0.1.2", "prettier": "^2.0.5", diff --git a/yarn.lock b/yarn.lock index 35558dec8c..a7d80c802a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1775,16 +1775,6 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -abbrev@~1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" - integrity sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q== - acorn-import-assertions@^1.7.6: version "1.8.0" resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" @@ -1805,7 +1795,7 @@ ajv-keywords@^3.5.2: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: +ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1829,26 +1819,11 @@ ansi-escapes@^4.2.1: dependencies: type-fest "^0.21.3" -ansi-regex@*: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== - ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA== - ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -1868,16 +1843,6 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== -ansicolors@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" - integrity sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg== - -ansistyles@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/ansistyles/-/ansistyles-0.1.3.tgz#5de60415bda071bb37127854c864f41b23254539" - integrity sha512-6QWEyvMgIXX0eO972y7YPBLSBsq7UWKFAoNNTLGaOJ9bstcEL9sCbcjf96dVfNDdUsRoGOK82vWFJlKApXds7g== - anymatch@^3.0.3, anymatch@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" @@ -1886,29 +1851,6 @@ anymatch@^3.0.3, anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -aproba@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.0.4.tgz#2713680775e7614c8ba186c065d4e2e52d1072c0" - integrity sha512-g4T1BR2vAjWV6GrBYeM7DmHUBe0WB45xRKKpNKxh4zHkUsjdGfANjdHY//9RzHi1XkWTLc1k58ddAUZ81yC8Cw== - -archy@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== - -are-we-there-yet@~1.1.2: - version "1.1.7" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" - integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -1932,14 +1874,6 @@ array-includes@^3.1.4: get-intrinsic "^1.1.1" is-string "^1.0.7" -array-index@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-index/-/array-index-1.0.0.tgz#ec56a749ee103e4e08c790b9c353df16055b97f9" - integrity sha512-jesyNbBkLQgGZMSwA1FanaFjalb1mZUGxGeUEkSDidzgrbjBGhvizJkaItdhkt8eIHFOJC7nDsrXk+BaehTdRw== - dependencies: - debug "^2.2.0" - es6-symbol "^3.0.2" - array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -1966,28 +1900,6 @@ array.prototype.map@^1.0.4: es-array-method-boxes-properly "^1.0.0" is-string "^1.0.7" -asap@^2.0.0, asap@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== - -asn1@~0.2.3: - version "0.2.6" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" - integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== - -assert-plus@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" - integrity sha512-u1L0ZLywRziOVjUhRxI0Qg9G+4RnFB9H/Rq40YWn0dieDgO7vAYeJz6jKAO6t/aruzlDFLAPkQTT87e+f8Imaw== - async-retry@1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.3.tgz#0e7f36c04d8478e7a58bdbed80cedf977785f280" @@ -2000,21 +1912,6 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= -aws-sign2@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" - integrity sha512-JnJpAS0p9RmixkOvW2XwDxxzs1bd4/VAGIl6Q0EC5YOo+p+hqIhtDhn/nmFnB/xUNXbLkpE2mOjgVIBRKD4xYw== - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== - -aws4@^1.2.1, aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - babel-eslint@^10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" @@ -2143,13 +2040,6 @@ base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== - dependencies: - tweetnacl "^0.14.3" - before-after-hook@^2.2.0: version "2.2.2" resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e" @@ -2174,27 +2064,6 @@ bl@^4.1.0: inherits "^2.0.4" readable-stream "^3.4.0" -bl@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/bl/-/bl-1.1.2.tgz#fdca871a99713aa00d19e3bbba41c44787a65398" - integrity sha512-uVVYHEQk+OuWvCi5U+iquVXvvGCWXKawjwELIR2XMLsqfV/e2sGDClVBs8OlGIgGsStPRY/Es311YKYIlYCWAg== - dependencies: - readable-stream "~2.0.5" - -block-stream@*: - version "0.0.9" - resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" - integrity sha512-OorbnJVPII4DuUKbjARAe8u8EfqOmkEEaSFIyoQ7OjTHn6kafxWl0wLgoZ2rXaYd7MyLcDaU4TmhfxtwgcccMQ== - dependencies: - inherits "~2.0.0" - -boom@2.x.x: - version "2.10.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" - integrity sha512-KbiZEa9/vofNcVJXGwdWWn25reQ3V3dHBWbS07FTF3/TOehLnm9GEhJV4T6ZvGPkShRpmUqYwnaCrkj0mRnP6Q== - dependencies: - hoek "2.x.x" - boxen@^5.0.0: version "5.1.2" resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" @@ -2254,11 +2123,6 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer-shims@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" - integrity sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g== - buffer@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" @@ -2267,21 +2131,6 @@ buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" -builtin-modules@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - integrity sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ== - -builtins@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-0.0.7.tgz#355219cd6cf18dbe7c01cc7fd2dce765cfdc549a" - integrity sha512-T8uCGKc0/2aLVt6omt8JxDRBoWEMkku+wFesxnhxnt4NygVZG99zqxo7ciK8eebszceKamGoUiLdkXCgGQyrQw== - -builtins@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" - integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ== - cacheable-request@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" @@ -2323,16 +2172,6 @@ caniuse-lite@^1.0.30001332: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001332.tgz#39476d3aa8d83ea76359c70302eafdd4a1d727dd" integrity sha512-10T30NYOEQtN6C11YGg411yebhvpnC6Z102+B95eAsN0oB6KUs01ivE8u+G6FMIRtIrVlYXhL+LUwQ3/hXwDWw== -caseless@~0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" - integrity sha512-ODLXH644w9C2fMPAm7bMDQ3GRvipZWZfKc+8As6hIadRIelE0n0xZuN38NS6kiK3KPEVrpymmQD8bvncAHWQkQ== - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== - chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -2341,17 +2180,6 @@ chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A== - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - chalk@^2.0.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -2386,11 +2214,6 @@ chokidar@^3.4.0: optionalDependencies: fsevents "~2.3.2" -chownr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" - integrity sha512-cKnqUJAC8G6cuN1DiRRTifu+s1BlAQNtalzGphFEV0pl0p46dsxJD4l1AOlyKJeLZOFzo3c34R7F3djxaCu8Kw== - chrome-trace-event@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" @@ -2463,24 +2286,11 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= -cmd-shim@~2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb" - integrity sha512-NLt0ntM0kvuSNrToO0RTFiNRHdioWsLW+OgDAEVDvIivsYwR+AjlzvLaMJ2Z+SNRpV3vdsDrHp1WI00eetDYzw== - dependencies: - graceful-fs "^4.1.2" - mkdirp "~0.5.0" - co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== - collect-v8-coverage@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" @@ -2515,22 +2325,14 @@ colorette@^2.0.14: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== -columnify@~1.5.4: - version "1.5.4" - resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" - integrity sha512-rFl+iXVT1nhLQPfGDw+3WcS8rmm7XsLKUmhsGE3ihzzpIikeGrTaZPIRKYWeLsLBypsHzjXIvYEltVUZS84XxQ== - dependencies: - strip-ansi "^3.0.0" - wcwidth "^1.0.0" - -combined-stream@^1.0.5, combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.5, combined-stream@~1.0.6: +combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" -commander@^2.20.0, commander@^2.9.0: +commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -2555,7 +2357,7 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concat-stream@^1.4.7, concat-stream@^1.5.2: +concat-stream@^1.4.7: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== @@ -2565,14 +2367,6 @@ concat-stream@^1.4.7, concat-stream@^1.5.2: readable-stream "^2.2.2" typedarray "^0.0.6" -config-chain@~1.1.11: - version "1.1.13" - resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" - integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== - dependencies: - ini "^1.3.4" - proto-list "~1.2.1" - configstore@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" @@ -2590,11 +2384,6 @@ confusing-browser-globals@^1.0.10: resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== - convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.8.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" @@ -2610,11 +2399,6 @@ core-js-compat@^3.20.2, core-js-compat@^3.21.0: browserslist "^4.20.2" semver "7.0.0" -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== - core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" @@ -2649,33 +2433,11 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -cryptiles@2.x.x: - version "2.0.5" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" - integrity sha512-FFN5KwpvvQTTS5hWPxrU8/QE4kQUc6uwZcrnlMBN82t1MgAtq8mnoDwINBly9Tdr02seeIIhtdF+UH1feBYGog== - dependencies: - boom "2.x.x" - crypto-random-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== -d@1, d@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" - integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== - dependencies: - es5-ext "^0.10.50" - type "^1.0.1" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== - dependencies: - assert-plus "^1.0.0" - debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" @@ -2683,7 +2445,7 @@ debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2: dependencies: ms "2.1.2" -debug@^2.2.0, debug@^2.6.9: +debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -2697,11 +2459,6 @@ debug@^3.2.7: dependencies: ms "^2.1.1" -debuglog@*, debuglog@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" - integrity sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw== - decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -2764,11 +2521,6 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== - deprecation@^2.0.0, deprecation@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" @@ -2779,14 +2531,6 @@ detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -dezalgo@^1.0.0, dezalgo@^1.0.1, dezalgo@~1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.4.tgz#751235260469084c132157dfa857f386d4c33d81" - integrity sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig== - dependencies: - asap "^2.0.0" - wrappy "1" - diff-sequences@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" @@ -2830,19 +2574,6 @@ duplexer3@^0.1.4: resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -editor@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/editor/-/editor-1.0.0.tgz#60c7f87bd62bcc6a894fa8ccd6afb7823a24f742" - integrity sha512-SoRmbGStwNYHgKfjOrX2L0mUvp9bUVv0uPppZSOMAntEbcFtoC3MKF5b3T6HQPXKIV+QGY3xPO3JK5it5lVkuw== - electron-to-chromium@^1.4.118: version "1.4.123" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.123.tgz#de88ea7fd29d7c868e63c88f129e91494bcf3266" @@ -2956,32 +2687,6 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -es5-ext@^0.10.35, es5-ext@^0.10.50: - version "0.10.61" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.61.tgz#311de37949ef86b6b0dcea894d1ffedb909d3269" - integrity sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA== - dependencies: - es6-iterator "^2.0.3" - es6-symbol "^3.1.3" - next-tick "^1.1.0" - -es6-iterator@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== - dependencies: - d "1" - es5-ext "^0.10.35" - es6-symbol "^3.1.1" - -es6-symbol@^3.0.2, es6-symbol@^3.1.1, es6-symbol@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" - integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== - dependencies: - d "^1.0.1" - ext "^1.1.2" - escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -2992,7 +2697,7 @@ escape-goat@^2.0.0: resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -3244,18 +2949,6 @@ expect@^28.0.2: jest-message-util "^28.0.2" jest-util "^28.0.2" -ext@^1.1.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" - integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== - dependencies: - type "^2.5.0" - -extend@~3.0.0, extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -3265,16 +2958,6 @@ external-editor@^3.0.3: iconv-lite "^0.4.24" tmp "^0.0.33" -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== - -extsprintf@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" - integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== - fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -3388,11 +3071,6 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== - form-data@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -3402,48 +3080,11 @@ form-data@4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" -form-data@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.0.0.tgz#6f0aebadcc5da16c13e1ecc11137d85f9b883b25" - integrity sha512-BWUNep0UvjzlIJgDsi0SFD3MvnLlwiRaVpfr82Hj2xgc9MJJcl1tSQj01CJDMG+w/kzm+vkZMmXwRM2XrkBuaA== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.11" - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - fs-readdir-recursive@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== -fs-vacuum@~1.2.9: - version "1.2.10" - resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.10.tgz#b7629bec07a4031a2548fdf99f5ecf1cc8b31e36" - integrity sha512-bwbv1FcWYwxN1F08I1THN8nS4Qe/pGq0gM8dy1J34vpxxp3qgZKJPPaqex36RyZO0sD2J+2ocnbwC2d/OjYICQ== - dependencies: - graceful-fs "^4.1.2" - path-is-inside "^1.0.1" - rimraf "^2.5.2" - -fs-write-stream-atomic@~1.0.8: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" - integrity sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA== - dependencies: - graceful-fs "^4.1.2" - iferr "^0.1.5" - imurmurhash "^0.1.4" - readable-stream "1 || 2" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -3454,33 +3095,6 @@ fsevents@^2.3.2, fsevents@~2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== -fstream-ignore@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" - integrity sha512-VVRuOs41VUqptEGiR0N5ZoWEcfGvbGRqLINyZAhHRnF3DH5wrqjNkYr3VbRoZnI41BZgO7zIVdiobc13TVI1ow== - dependencies: - fstream "^1.0.0" - inherits "2" - minimatch "^3.0.0" - -fstream-npm@~1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/fstream-npm/-/fstream-npm-1.2.1.tgz#08c4a452f789dcbac4c89a4563c902b2c862fd5b" - integrity sha512-iBHpm/LmD1qw0TlHMAqVd9rwdU6M+EHRUnPkXpRi5G/Hf0FIFH+oZFryodAU2MFNfGRh/CzhUFlMKV3pdeOTDw== - dependencies: - fstream-ignore "^1.0.0" - inherits "2" - -fstream@^1.0.0, fstream@^1.0.12, fstream@~1.0.10: - version "1.0.12" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" - integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== - dependencies: - graceful-fs "^4.1.2" - inherits "~2.0.0" - mkdirp ">=0.5 0" - rimraf "2" - function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -3491,49 +3105,6 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= -gauge@~2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.6.0.tgz#d35301ad18e96902b4751dcbbe40f4218b942a46" - integrity sha512-YFArj4ApymqXBC2KORLBtKc2CIc1r+ycx786XYEkEF4++1rBGhTD7QHOSWYYGCx50Op+WuboEk9xQa+wNmzuLA== - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-color "^0.1.7" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -gauge@~2.7.1: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg== - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -generate-function@^2.0.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" - integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ== - dependencies: - is-property "^1.0.2" - -generate-object-property@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" - integrity sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ== - dependencies: - is-property "^1.0.0" - gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -3585,13 +3156,6 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== - dependencies: - assert-plus "^1.0.0" - git-up@^4.0.0: version "4.0.5" resolved "https://registry.yarnpkg.com/git-up/-/git-up-4.0.5.tgz#e7bb70981a37ea2fb8fe049669800a1f9a01d759" @@ -3638,19 +3202,7 @@ glob@^7.0.0, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.3, glob@^7.0.5, glob@^7.1.1: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.3, glob@~7.1.0: +glob@^7.1.3: version "7.1.7" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== @@ -3722,56 +3274,16 @@ got@9.6.0, got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.4, graceful-fs@^4.2.9: +graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.9: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== -graceful-fs@~4.1.9: - version "4.1.15" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" - integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== - -har-validator@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" - integrity sha512-P6tFV+wCcUL3nbyTDAvveDySfbhy0XkDtAIfZP6HITjM2WUsiPna/Eg1Yy93SFXvahqoX+kt0n+6xlXKDXYowA== - dependencies: - chalk "^1.1.1" - commander "^2.9.0" - is-my-json-valid "^2.12.4" - pinkie-promise "^2.0.0" - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg== - dependencies: - ansi-regex "^2.0.0" - has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== -has-color@^0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" - integrity sha512-kaNz5OTAYYmt646Hkqw50/qyxP2vFnTVu5AQ1Zmk22Kk5+4Qx6BpO8+u7IKsML5fOsFk0ZT0AcCJNYwcvaLBvw== - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -3801,11 +3313,6 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" -has-unicode@^2.0.0, has-unicode@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== - has-yarn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" @@ -3818,31 +3325,6 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -hawk@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" - integrity sha512-X8xbmTc1cbPXcQV4WkLcRMALuyoxhfpFATmyuCxJPOAvrDS4DNnsTAOmKUxMTOWU6TzrTOkxPKwIx5ZOpJVSrg== - dependencies: - boom "2.x.x" - cryptiles "2.x.x" - hoek "2.x.x" - sntp "1.x.x" - -hoek@2.x.x: - version "2.16.3" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" - integrity sha512-V6Yw1rIcYV/4JsnggjBU0l4Kr+EXhpwqXRusENU1Xx6ro00IHPHYNynCuBTOZAPlr3AAmLvchH9I7N/VUdvOwQ== - -hosted-git-info@^2.1.4, hosted-git-info@^2.1.5, hosted-git-info@^2.4.2: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -hosted-git-info@~2.1.5: - version "2.1.5" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.1.5.tgz#0ba81d90da2e25ab34a332e6ec77936e1598118b" - integrity sha512-5sLwVGWIA8493A2PzG/py8s+uBrYqrwmLp6C6U5+Gpw5Ll49OOigsuD4LKbUTExbgedTNPvPb/0GV5ohHYYNBg== - html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" @@ -3853,24 +3335,6 @@ http-cache-semantics@^4.0.0: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== -http-signature@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" - integrity sha512-iUn0NcRULlDGtqNLN1Jxmzayk8ogm7NToldASyZBpM2qggbphjXzNOiw3piN8tgz+e/DRs6X5gAzFwTI6BCRcg== - dependencies: - assert-plus "^0.2.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - human-signals@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" @@ -3893,11 +3357,6 @@ ieee754@^1.1.13: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -iferr@^0.1.5, iferr@~0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" - integrity sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA== - ignore@^5.1.4, ignore@^5.1.8, ignore@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" @@ -3938,12 +3397,12 @@ import-local@^3.0.2: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" -imurmurhash@*, imurmurhash@^0.1.4: +imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -inflight@^1.0.4, inflight@~1.0.5: +inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= @@ -3951,7 +3410,7 @@ inflight@^1.0.4, inflight@~1.0.5: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -3961,25 +3420,11 @@ ini@2.0.0: resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== -ini@^1.3.4, ini@~1.3.0, ini@~1.3.4: +ini@~1.3.0: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -init-package-json@~1.9.4: - version "1.9.6" - resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-1.9.6.tgz#789fc2b74466a4952b9ea77c0575bc78ebd60a61" - integrity sha512-ocaj90F9qTLDpkhhy+ZemKVexbybm2S0fo65/v13KJDI75kyB7eb8ShhRkxZrbGzzS9833A+o5Bus8aFdQEfOg== - dependencies: - glob "^7.1.1" - npm-package-arg "^4.0.0 || ^5.0.0" - promzard "^0.3.0" - read "~1.0.1" - read-package-json "1 || 2" - semver "2.x || 3.x || 4 || 5" - validate-npm-package-license "^3.0.1" - validate-npm-package-name "^3.0.0" - inquirer@8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.0.tgz#f44f008dd344bbfc4b30031f45d984e034a3ac3a" @@ -4054,13 +3499,6 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-builtin-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" - integrity sha512-C2wz7Juo5pUZTFQVer9c+9b4qw3I5T/CHQxQyhVu7BJel6C22FmsLIWsdseYyOw6xz9Pqy9eJWSkQ7+3iN1HVw== - dependencies: - builtin-modules "^1.0.0" - is-callable@^1.1.4, is-callable@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" @@ -4104,13 +3542,6 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== - dependencies: - number-is-nan "^1.0.0" - is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" @@ -4146,22 +3577,6 @@ is-map@^2.0.2: resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== -is-my-ip-valid@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz#f7220d1146257c98672e6fba097a9f3f2d348442" - integrity sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg== - -is-my-json-valid@^2.12.4: - version "2.20.6" - resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz#a9d89e56a36493c77bda1440d69ae0dc46a08387" - integrity sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw== - dependencies: - generate-function "^2.0.0" - generate-object-property "^1.1.0" - is-my-ip-valid "^1.0.0" - jsonpointer "^5.0.0" - xtend "^4.0.0" - is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" @@ -4206,11 +3621,6 @@ is-plain-object@^5.0.0: resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== -is-property@^1.0.0, is-property@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" - integrity sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g== - is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -4257,7 +3667,7 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" -is-typedarray@^1.0.0, is-typedarray@~1.0.0: +is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -4306,11 +3716,6 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== - istanbul-lib-coverage@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" @@ -4782,11 +4187,6 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== - jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -4802,7 +4202,7 @@ json-buffer@3.0.0: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= -json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: +json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== @@ -4817,21 +4217,11 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" - integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== - json5@2.x, json5@^2.1.2, json5@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" @@ -4844,21 +4234,6 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -jsonpointer@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.0.tgz#f802669a524ec4805fa7389eadbc9921d5dc8072" - integrity sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg== - -jsprim@^1.2.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" - integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.4.0" - verror "1.10.0" - keyv@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" @@ -4930,63 +4305,6 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lockfile@~1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lockfile/-/lockfile-1.0.4.tgz#07f819d25ae48f87e538e6578b6964a4981a5609" - integrity sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA== - dependencies: - signal-exit "^3.0.2" - -lodash._baseindexof@*: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c" - integrity sha512-bSYo8Pc/f0qAkr8fPJydpJjtrHiSynYfYBjtANIgXv5xEf1WlTC63dIDlgu0s9dmTvzRu1+JJTxcIAHe+sH0FQ== - -lodash._baseuniq@~4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" - integrity sha512-Ja1YevpHZctlI5beLA7oc5KNDhGcPixFhcqSiORHNsp/1QTv7amAXzw+gu4YOvErqVlMVyIJGgtzeepCnnur0A== - dependencies: - lodash._createset "~4.0.0" - lodash._root "~3.0.0" - -lodash._bindcallback@*: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" - integrity sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ== - -lodash._cacheindexof@*: - version "3.0.2" - resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92" - integrity sha512-S8dUjWr7SUT/X6TBIQ/OYoCHo1Stu1ZRy6uMUSKqzFnZp5G5RyQizSm6kvxD2Ewyy6AVfMg4AToeZzKfF99T5w== - -lodash._createcache@*: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093" - integrity sha512-ev5SP+iFpZOugyab/DEUQxUeZP5qyciVTlgQ1f4Vlw7VUcCD8fVnyIqVUEIaoFH9zjAqdgi69KiofzvVmda/ZQ== - dependencies: - lodash._getnative "^3.0.0" - -lodash._createset@~4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" - integrity sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA== - -lodash._getnative@*, lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - integrity sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA== - -lodash._root@~3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" - integrity sha512-O0pWuFSK6x4EXhM1dhZ8gchNtG7JMqBtrHdoUFUWXD7dJnNSUze1GuyQr5sOs0aCvgGeI3o/OJW8f4ca7FDxmQ== - -lodash.clonedeep@~4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== - lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -5002,31 +4320,11 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.restparam@*: - version "3.6.1" - resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" - integrity sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw== - lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= -lodash.union@~4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" - integrity sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw== - -lodash.uniq@~4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== - -lodash.without@~4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac" - integrity sha512-M3MefBwfDhgKgINVuBJCO1YR3+gf6s9HNJsIiZ/Ru77Ws6uTb9eBuvrkpzO+9iLoAaRodGuq7tyrPCx+74QYGQ== - lodash@4.17.21, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -5120,7 +4418,7 @@ mime-db@1.52.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@2.1.35, mime-types@^2.1.11, mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.19, mime-types@~2.1.7: +mime-types@2.1.35, mime-types@^2.1.12, mime-types@^2.1.27: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -5137,7 +4435,7 @@ mimic-response@^1.0.0, mimic-response@^1.0.1: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -5149,13 +4447,6 @@ minimist@^1.2.0, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== -"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@~0.5.0, mkdirp@~0.5.1: - version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" - integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== - dependencies: - minimist "^1.2.6" - ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -5171,7 +4462,7 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -mute-stream@0.0.8, mute-stream@~0.0.4: +mute-stream@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== @@ -5193,11 +4484,6 @@ new-github-release-url@1.0.0: dependencies: type-fest "^0.4.1" -next-tick@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" - integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== - node-fetch@^2.6.7: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" @@ -5205,26 +4491,6 @@ node-fetch@^2.6.7: dependencies: whatwg-url "^5.0.0" -node-gyp@~3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.4.0.tgz#dda558393b3ecbbe24c9e6b8703c71194c63fa36" - integrity sha1-3aVYOTs+y74kyea4cDxxGUxj+jY= - dependencies: - fstream "^1.0.0" - glob "^7.0.3" - graceful-fs "^4.1.2" - minimatch "^3.0.2" - mkdirp "^0.5.0" - nopt "2 || 3" - npmlog "0 || 1 || 2 || 3" - osenv "0" - path-array "^1.0.0" - request "2" - rimraf "2" - semver "2.x || 3.x || 4 || 5" - tar "^2.0.0" - which "1" - node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -5235,43 +4501,6 @@ node-releases@^2.0.3: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" integrity sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw== -node-uuid@~1.4.7: - version "1.4.8" - resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" - integrity sha1-sEDrCSOWivq/jTL7HxfxFn/auQc= - -"nopt@2 || 3", nopt@~3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= - dependencies: - abbrev "1" - -normalize-git-url@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/normalize-git-url/-/normalize-git-url-3.0.2.tgz#8e5f14be0bdaedb73e07200310aa416c27350fc4" - integrity sha1-jl8Uvgva7bc+ByADEKpBbCc1D8Q= - -normalize-package-data@^2.0.0, "normalize-package-data@~1.0.1 || ^2.0.0": - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-package-data@~2.3.5: - version "2.3.8" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.8.tgz#d819eda2a9dedbd1ffa563ea4071d936782295bb" - integrity sha1-2Bntoqne29H/pWPqQHHZNngilbs= - dependencies: - hosted-git-info "^2.1.4" - is-builtin-module "^1.0.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -5287,66 +4516,6 @@ normalize-url@^6.1.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== -npm-cache-filename@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz#ded306c5b0bfc870a9e9faf823bc5f283e05ae11" - integrity sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE= - -npm-cli@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/npm-cli/-/npm-cli-0.1.0.tgz#081e0fe2c1cdfb822b9db360bc5eb2875c041088" - integrity sha1-CB4P4sHN+4IrnbNgvF6yh1wEEIg= - dependencies: - npm "^3" - semver "^4.1.0" - -npm-install-checks@~3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-3.0.2.tgz#ab2e32ad27baa46720706908e5b14c1852de44d9" - integrity sha512-E4kzkyZDIWoin6uT5howP8VDvkM+E8IQDcHAycaAxMbwkqhIg5eEYALnXOl3Hq9MrkdQB/2/g1xwBINXdKSRkg== - dependencies: - semver "^2.3.0 || 3.x || 4 || 5" - -npm-normalize-package-bin@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" - integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== - -"npm-package-arg@^3.0.0 || ^4.0.0", npm-package-arg@^4.1.1, npm-package-arg@~4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-4.2.1.tgz#593303fdea85f7c422775f17f9eb7670f680e3ec" - integrity sha1-WTMD/eqF98Qid18X+et2cPaA4+w= - dependencies: - hosted-git-info "^2.1.5" - semver "^5.1.0" - -"npm-package-arg@^4.0.0 || ^5.0.0": - version "5.1.2" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-5.1.2.tgz#fb18d17bb61e60900d6312619919bd753755ab37" - integrity sha512-wJBsrf0qpypPT7A0LART18hCdyhpCMxeTtcb0X4IZO2jsP6Om7EHN1d9KSKiqD+KVH030RVNpWS9thk+pb7wzA== - dependencies: - hosted-git-info "^2.4.2" - osenv "^0.1.4" - semver "^5.1.0" - validate-npm-package-name "^3.0.0" - -npm-registry-client@~7.2.1: - version "7.2.1" - resolved "https://registry.yarnpkg.com/npm-registry-client/-/npm-registry-client-7.2.1.tgz#c792266b088cc313f8525e7e35248626c723db75" - integrity sha1-x5ImawiMwxP4Ul5+NSSGJscj23U= - dependencies: - concat-stream "^1.5.2" - graceful-fs "^4.1.6" - normalize-package-data "~1.0.1 || ^2.0.0" - npm-package-arg "^3.0.0 || ^4.0.0" - once "^1.3.3" - request "^2.74.0" - retry "^0.10.0" - semver "2 >=2.2.1 || 3.x || 4 || 5" - slide "^1.1.3" - optionalDependencies: - npmlog "~2.0.0 || ~3.1.0" - npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" @@ -5354,128 +4523,6 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" -npm-user-validate@~0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-0.1.5.tgz#52465d50c2d20294a57125b996baedbf56c5004b" - integrity sha1-UkZdUMLSApSlcSW5lrrtv1bFAEs= - -npm@^3: - version "3.10.10" - resolved "https://registry.yarnpkg.com/npm/-/npm-3.10.10.tgz#5b1d577e4c8869d6c8603bc89e9cd1637303e46e" - integrity sha1-Wx1XfkyIadbIYDvInpzRY3MD5G4= - dependencies: - abbrev "~1.0.9" - ansicolors "~0.3.2" - ansistyles "~0.1.3" - aproba "~1.0.4" - archy "~1.0.0" - asap "~2.0.5" - chownr "~1.0.1" - cmd-shim "~2.0.2" - columnify "~1.5.4" - config-chain "~1.1.11" - dezalgo "~1.0.3" - editor "~1.0.0" - fs-vacuum "~1.2.9" - fs-write-stream-atomic "~1.0.8" - fstream "~1.0.10" - fstream-npm "~1.2.0" - glob "~7.1.0" - graceful-fs "~4.1.9" - has-unicode "~2.0.1" - hosted-git-info "~2.1.5" - iferr "~0.1.5" - inflight "~1.0.5" - inherits "~2.0.3" - ini "~1.3.4" - init-package-json "~1.9.4" - lockfile "~1.0.2" - lodash._baseuniq "~4.6.0" - lodash.clonedeep "~4.5.0" - lodash.union "~4.6.0" - lodash.uniq "~4.5.0" - lodash.without "~4.4.0" - mkdirp "~0.5.1" - node-gyp "~3.4.0" - nopt "~3.0.6" - normalize-git-url "~3.0.2" - normalize-package-data "~2.3.5" - npm-cache-filename "~1.0.2" - npm-install-checks "~3.0.0" - npm-package-arg "~4.2.0" - npm-registry-client "~7.2.1" - npm-user-validate "~0.1.5" - npmlog "~4.0.0" - once "~1.4.0" - opener "~1.4.2" - osenv "~0.1.3" - path-is-inside "~1.0.2" - read "~1.0.7" - read-cmd-shim "~1.0.1" - read-installed "~4.0.3" - read-package-json "~2.0.4" - read-package-tree "~5.1.5" - readable-stream "~2.1.5" - realize-package-specifier "~3.0.3" - request "~2.75.0" - retry "~0.10.0" - rimraf "~2.5.4" - semver "~5.3.0" - sha "~2.0.1" - slide "~1.1.6" - sorted-object "~2.0.1" - strip-ansi "~3.0.1" - tar "~2.2.1" - text-table "~0.2.0" - uid-number "0.0.6" - umask "~1.1.0" - unique-filename "~1.1.0" - unpipe "~1.0.0" - validate-npm-package-name "~2.2.2" - which "~1.2.11" - wrappy "~1.0.2" - write-file-atomic "~1.2.0" - -"npmlog@0 || 1 || 2 || 3", "npmlog@~2.0.0 || ~3.1.0": - version "3.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-3.1.2.tgz#2d46fa874337af9498a2f12bb43d8d0be4a36873" - integrity sha1-LUb6h0M3r5SYovErtD2NC+SjaHM= - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.6.0" - set-blocking "~2.0.0" - -npmlog@~4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.2.tgz#d03950e0e78ce1527ba26d2a7592e9348ac3e75f" - integrity sha1-0DlQ4OeM4VJ7om0qdZLpNIrD518= - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.1" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -oauth-sign@~0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM= - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - object-inspect@^1.12.0, object-inspect@^1.9.0: version "1.12.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" @@ -5514,7 +4561,7 @@ object.values@^1.1.5: define-properties "^1.1.3" es-abstract "^1.19.1" -once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0, once@~1.4.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -5536,11 +4583,6 @@ open@7.4.2: is-docker "^2.0.0" is-wsl "^2.1.1" -opener@~1.4.2: - version "1.4.3" - resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8" - integrity sha1-XG2ixdflgx6P+jlklQ+NZnSskLg= - optionator@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" @@ -5568,11 +4610,6 @@ ora@5.4.1, ora@^5.4.1: strip-ansi "^6.0.0" wcwidth "^1.0.1" -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - os-name@4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/os-name/-/os-name-4.0.1.tgz#32cee7823de85a8897647ba4d76db46bf845e555" @@ -5586,19 +4623,11 @@ os-shim@^0.1.2: resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917" integrity sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc= -os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: +os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -osenv@0, osenv@^0.1.4, osenv@~0.1.3: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - p-cancelable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" @@ -5689,13 +4718,6 @@ parse-url@^6.0.0: parse-path "^4.0.0" protocols "^1.4.0" -path-array@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-array/-/path-array-1.0.1.tgz#7e2f0f35f07a2015122b868b7eac0eb2c4fec271" - integrity sha1-fi8PNfB6IBUSK4aLfqwOssT+wnE= - dependencies: - array-index "^1.0.0" - path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -5711,11 +4733,6 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-is-inside@^1.0.1, path-is-inside@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= - path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" @@ -5731,11 +4748,6 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -5751,18 +4763,6 @@ pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - pirates@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" @@ -5834,11 +4834,6 @@ pretty-format@^28.0.2: ansi-styles "^5.0.0" react-is "^18.0.0" -process-nextick-args@~1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" - integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= - process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -5864,18 +4859,6 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" -promzard@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" - integrity sha1-JqXW7ox97kyxIggwWs+5O6OCqe4= - dependencies: - read "1" - -proto-list@~1.2.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" - integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= - protocols@^1.1.0, protocols@^1.4.0: version "1.4.8" resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.8.tgz#48eea2d8f58d9644a4a32caae5d5db290a075ce8" @@ -5886,11 +4869,6 @@ pseudomap@^1.0.2: resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -5899,12 +4877,7 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -punycode@^2.1.0, punycode@^2.1.1: +punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -5923,16 +4896,6 @@ qs@^6.9.4: dependencies: side-channel "^1.0.4" -qs@~6.2.0: - version "6.2.4" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.4.tgz#d90821bb8537cecc140e6c34f54ec76e54b39b22" - integrity sha512-E57gmgKXqDda+qWTkUJgIwgJICK7zgMfqZZopTRKZ6mY9gzLlmJN9EpXNnDrTxXFlOM/a+I28kJkF/60rqgnYw== - -qs@~6.5.2: - version "6.5.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" - integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== - query-string@^6.13.8: version "6.14.1" resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a" @@ -5975,68 +4938,7 @@ react-is@^18.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67" integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg== -read-cmd-shim@~1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz#87e43eba50098ba5a32d0ceb583ab8e43b961c16" - integrity sha512-v5yCqQ/7okKoZZkBQUAfTsQ3sVJtXdNfbPnI5cceppoxEVLYA3k+VtV2omkeo8MS94JCy4fSiUwlRBAwCVRPUA== - dependencies: - graceful-fs "^4.1.2" - -read-installed@~4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067" - integrity sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc= - dependencies: - debuglog "^1.0.1" - read-package-json "^2.0.0" - readdir-scoped-modules "^1.0.0" - semver "2 || 3 || 4 || 5" - slide "~1.1.3" - util-extend "^1.0.1" - optionalDependencies: - graceful-fs "^4.1.2" - -"read-package-json@1 || 2", read-package-json@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.1.2.tgz#6992b2b66c7177259feb8eaac73c3acd28b9222a" - integrity sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA== - dependencies: - glob "^7.1.1" - json-parse-even-better-errors "^2.3.0" - normalize-package-data "^2.0.0" - npm-normalize-package-bin "^1.0.0" - -read-package-json@~2.0.4: - version "2.0.13" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.0.13.tgz#2e82ebd9f613baa6d2ebe3aa72cefe3f68e41f4a" - integrity sha512-/1dZ7TRZvGrYqE0UAfN6qQb5GYBsNcqS1C0tNK601CFOJmtHI7NIGXwetEPU/OtoFHZL3hDxm4rolFFVE9Bnmg== - dependencies: - glob "^7.1.1" - json-parse-better-errors "^1.0.1" - normalize-package-data "^2.0.0" - slash "^1.0.0" - optionalDependencies: - graceful-fs "^4.1.2" - -read-package-tree@~5.1.5: - version "5.1.6" - resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.1.6.tgz#4f03e83d0486856fb60d97c94882841c2a7b1b7a" - integrity sha512-FCX1aT3GWyY658wzDICef4p+n0dB+ENRct8E/Qyvppj6xVpOYerBHfUu7OP5Rt1/393Tdglguf5ju5DEX4wZNg== - dependencies: - debuglog "^1.0.1" - dezalgo "^1.0.0" - once "^1.3.0" - read-package-json "^2.0.0" - readdir-scoped-modules "^1.0.0" - -read@1, read@~1.0.1, read@~1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" - integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= - dependencies: - mute-stream "~0.0.4" - -"readable-stream@1 || 2", readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.2: +readable-stream@^2.2.2: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -6058,41 +4960,6 @@ readable-stream@^3.4.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" - integrity sha1-j5A0HmilPMySh4jaz80Rs265t44= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - string_decoder "~0.10.x" - util-deprecate "~1.0.1" - -readable-stream@~2.1.5: - version "2.1.5" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" - integrity sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA= - dependencies: - buffer-shims "^1.0.0" - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - string_decoder "~0.10.x" - util-deprecate "~1.0.1" - -readdir-scoped-modules@*, readdir-scoped-modules@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" - integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== - dependencies: - debuglog "^1.0.1" - dezalgo "^1.0.0" - graceful-fs "^4.1.2" - once "^1.3.0" - readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -6100,14 +4967,6 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -realize-package-specifier@~3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/realize-package-specifier/-/realize-package-specifier-3.0.3.tgz#d0def882952b8de3f67eba5e91199661271f41f4" - integrity sha1-0N74gpUrjeP2frpekRmWYScfQfQ= - dependencies: - dezalgo "^1.0.1" - npm-package-arg "^4.1.1" - rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -6225,59 +5084,6 @@ release-it@^14.11.7: yaml "1.10.2" yargs-parser "20.2.9" -request@2, request@^2.74.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -request@~2.75.0: - version "2.75.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.75.0.tgz#d2b8268a286da13eaa5d01adf5d18cc90f657d93" - integrity sha1-0rgmiihtoT6qXQGt9dGMyQ9lfZM= - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" - bl "~1.1.2" - caseless "~0.11.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~2.0.0" - har-validator "~2.0.6" - hawk "~3.1.3" - http-signature "~1.1.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - node-uuid "~1.4.7" - oauth-sign "~0.8.1" - qs "~6.2.0" - stringstream "~0.0.4" - tough-cookie "~2.3.0" - tunnel-agent "~0.4.1" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -6305,7 +5111,7 @@ resolve.exports@^1.1.0: resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.9.0: +resolve@^1.1.6, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.9.0: version "1.22.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== @@ -6342,23 +5148,11 @@ retry@0.13.1: resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== -retry@^0.10.0, retry@~0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" - integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q= - reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@2, rimraf@^2.5.2: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -6366,13 +5160,6 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" -rimraf@~2.5.4: - version "2.5.4" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04" - integrity sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ= - dependencies: - glob "^7.0.5" - run-async@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" @@ -6392,7 +5179,7 @@ rxjs@^7.2.0: dependencies: tslib "^2.1.0" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: +safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -6402,7 +5189,7 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -6432,11 +5219,6 @@ semver-diff@^3.1.1: dependencies: semver "^6.3.0" -"semver@2 >=2.2.1 || 3.x || 4 || 5", "semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.1.0, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - semver@7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" @@ -6456,21 +5238,16 @@ semver@7.x, semver@^7.3.4, semver@^7.3.5: dependencies: lru-cache "^6.0.0" -semver@^4.1.0: - version "4.3.6" - resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" - integrity sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto= +semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@~5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" - integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= - serialize-javascript@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -6478,19 +5255,6 @@ serialize-javascript@^6.0.0: dependencies: randombytes "^2.1.0" -set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -sha@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/sha/-/sha-2.0.1.tgz#6030822fbd2c9823949f8f72ed6411ee5cf25aae" - integrity sha1-YDCCL70smCOUn49y7WQR7lzyWq4= - dependencies: - graceful-fs "^4.1.2" - readable-stream "^2.0.2" - shallow-clone@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" @@ -6540,7 +5304,7 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: +signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== @@ -6550,11 +5314,6 @@ sisteransi@^1.0.5: resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= - slash@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" @@ -6565,23 +5324,6 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slide@^1.1.3, slide@^1.1.5, slide@~1.1.3, slide@~1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" - integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= - -sntp@1.x.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" - integrity sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg= - dependencies: - hoek "2.x.x" - -sorted-object@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/sorted-object/-/sorted-object-2.0.1.tgz#7d631f4bd3a798a24af1dffcfbfe83337a5df5fc" - integrity sha1-fWMfS9OnmKJK8d/8+/6DM3pd9fw= - source-map-support@0.5.13: version "0.5.13" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" @@ -6623,32 +5365,6 @@ spawn-sync@^1.0.15: concat-stream "^1.4.7" os-shim "^0.1.2" -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.11" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" - integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== - split-on-first@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" @@ -6659,21 +5375,6 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -sshpk@^1.7.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" - integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - stack-utils@^2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" @@ -6694,16 +5395,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -6735,11 +5427,6 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= - string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -6747,18 +5434,6 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -stringstream@~0.0.4: - version "0.0.6" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.6.tgz#7880225b0d4ad10e30927d167a1d6f2fd3b33a72" - integrity sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA== - -strip-ansi@^3.0.0, strip-ansi@^3.0.1, strip-ansi@~3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -6791,11 +5466,6 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -6835,15 +5505,6 @@ tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -tar@^2.0.0, tar@~2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" - integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== - dependencies: - block-stream "*" - fstream "^1.0.12" - inherits "2" - terminal-link@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" @@ -6882,7 +5543,7 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" -text-table@^0.2.0, text-table@~0.2.0: +text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= @@ -6926,21 +5587,6 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -tough-cookie@~2.3.0: - version "2.3.4" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" - integrity sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA== - dependencies: - punycode "^1.4.1" - -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" @@ -7004,23 +5650,6 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tunnel-agent@~0.4.1: - version "0.4.3" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" - integrity sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us= - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -7048,16 +5677,6 @@ type-fest@^0.4.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8" integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw== -type@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" - integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== - -type@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.6.0.tgz#3ca6099af5981d36ca86b78442973694278a219f" - integrity sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ== - typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -7075,16 +5694,6 @@ typescript@^4.3.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== -uid-number@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" - integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE= - -umask@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d" - integrity sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0= - unbox-primitive@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" @@ -7118,20 +5727,6 @@ unicode-property-aliases-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== -unique-filename@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== - dependencies: - unique-slug "^2.0.0" - -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" - integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== - dependencies: - imurmurhash "^0.1.4" - unique-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" @@ -7144,11 +5739,6 @@ universal-user-agent@^6.0.0: resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== -unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - update-notifier@5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" @@ -7193,21 +5783,11 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util-extend@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f" - integrity sha1-p8IW0mdUUWljeztu3GypEZ4v+T8= - uuid@8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - v8-compile-cache@^2.0.3: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" @@ -7222,37 +5802,6 @@ v8-to-istanbul@^9.0.0: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" -validate-npm-package-license@*, validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -validate-npm-package-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" - integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= - dependencies: - builtins "^1.0.3" - -validate-npm-package-name@~2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-2.2.2.tgz#f65695b22f7324442019a3c7fa39a6e7fd299085" - integrity sha1-9laVsi9zJEQgGaPH+jmm5/0pkIU= - dependencies: - builtins "0.0.7" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - walker@^1.0.7: version "1.0.8" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" @@ -7268,7 +5817,7 @@ watchpack@^2.3.1: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" -wcwidth@^1.0.0, wcwidth@^1.0.1: +wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= @@ -7374,20 +5923,20 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" -which@1, which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -which@1.2.x, which@~1.2.11: +which@1.2.x: version "1.2.14" resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" integrity sha1-mofEN48D6CfOyvGs31bHNsAcFOU= dependencies: isexe "^2.0.0" +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -7395,13 +5944,6 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -wide-align@^1.1.0: - version "1.1.5" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" - integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== - dependencies: - string-width "^1.0.2 || 2 || 3 || 4" - widest-line@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" @@ -7440,7 +5982,7 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrappy@1, wrappy@~1.0.2: +wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= @@ -7463,25 +6005,11 @@ write-file-atomic@^4.0.1: imurmurhash "^0.1.4" signal-exit "^3.0.7" -write-file-atomic@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.2.0.tgz#14c66d4e4cb3ca0565c28cf3b7a6f3e4d5938fab" - integrity sha1-FMZtTkyzygVlwozzt6bz5NWTj6s= - dependencies: - graceful-fs "^4.1.2" - imurmurhash "^0.1.4" - slide "^1.1.5" - xdg-basedir@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== -xtend@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" From 481fc5abc32306ab7b44e8ef62cf827c22510a23 Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Tue, 31 May 2022 08:00:33 -0700 Subject: [PATCH 146/334] update eslint and tsc to only run on changed files --- .gitignore | 1 + package.json | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index e3646df702..9a4c697102 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ lib node_modules .DS_Store coverage +.eslintcache diff --git a/package.json b/package.json index 7c79d72d2f..ae07375351 100644 --- a/package.json +++ b/package.json @@ -67,11 +67,14 @@ ], "scripts": { "clean": "rimraf lib dist coverage", + "git:changes": "git diff --name-only --diff-filter d | xargs", "ts:check": "tsc --noEmit", - "lint": "eslint .", + "ts:changes": "tsc --noEmit --incremental", + "lint": "eslint --cache .", + "lint:changes": "sh -c eslint --cache $(git:changes)", "pretty": "prettier --write .", - "fix": "yarn pretty && eslint --fix .", "pretty:check": "prettier --check .", + "fix": "yarn pretty && eslint --fix .", "test": "jest", "test:watch": "yarn test -- --watch", "check": "yarn ts:check && yarn pretty:check && yarn lint && yarn test", @@ -83,8 +86,8 @@ "release": "release-it" }, "pre-commit": [ - "ts:check", - "lint" + "ts:changes", + "lint:changes" ], "pre-push": "build", "repository": { From f2040e851259b064abbcb0a06a190725f0571acf Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Tue, 31 May 2022 08:01:37 -0700 Subject: [PATCH 147/334] add npm-run-all --- package.json | 1 + yarn.lock | 164 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 157 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index ae07375351..500f7bd67c 100644 --- a/package.json +++ b/package.json @@ -123,6 +123,7 @@ "eslint-plugin-import": "^2.22.0", "eslint-plugin-prettier": "^4.0.0", "jest": "^28.0.2", + "npm-run-all": "^4.1.5", "pre-commit": "^1.2.2", "pre-push": "^0.1.2", "prettier": "^2.0.5", diff --git a/yarn.lock b/yarn.lock index a7d80c802a..8a5e8c346c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2180,7 +2180,7 @@ chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^2.0.0: +chalk@^2.0.0, chalk@^2.4.1: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -2424,6 +2424,17 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -3325,6 +3336,11 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" @@ -4202,7 +4218,7 @@ json-buffer@3.0.0: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= -json-parse-better-errors@^1.0.2: +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== @@ -4276,6 +4292,16 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw== + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + loader-runner@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" @@ -4395,6 +4421,11 @@ makeerror@1.0.12: dependencies: tmpl "1.0.5" +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -4484,6 +4515,11 @@ new-github-release-url@1.0.0: dependencies: type-fest "^0.4.1" +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + node-fetch@^2.6.7: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" @@ -4501,6 +4537,16 @@ node-releases@^2.0.3: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" integrity sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw== +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -4516,6 +4562,21 @@ normalize-url@^6.1.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== +npm-run-all@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" + integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== + dependencies: + ansi-styles "^3.2.1" + chalk "^2.4.1" + cross-spawn "^6.0.5" + memorystream "^0.3.1" + minimatch "^3.0.4" + pidtree "^0.3.0" + read-pkg "^3.0.0" + shell-quote "^1.6.1" + string.prototype.padend "^3.0.0" + npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" @@ -4698,6 +4759,14 @@ parse-json@5.2.0, parse-json@^5.0.0, parse-json@^5.2.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + parse-path@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-4.0.3.tgz#82d81ec3e071dcc4ab49aa9f2c9c0b8966bb22bf" @@ -4733,6 +4802,11 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= +path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" @@ -4743,6 +4817,13 @@ path-parse@^1.0.6, path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -4758,6 +4839,16 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +pidtree@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" + integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA== + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + pify@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" @@ -4938,6 +5029,15 @@ react-is@^18.0.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67" integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg== +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + readable-stream@^2.2.2: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" @@ -5111,7 +5211,7 @@ resolve.exports@^1.1.0: resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== -resolve@^1.1.6, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.9.0: +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.9.0: version "1.22.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== @@ -5219,6 +5319,11 @@ semver-diff@^3.1.1: dependencies: semver "^6.3.0" +"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + semver@7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" @@ -5238,11 +5343,6 @@ semver@7.x, semver@^7.3.4, semver@^7.3.5: dependencies: lru-cache "^6.0.0" -semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -5286,6 +5386,11 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +shell-quote@^1.6.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" + integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== + shelljs@0.8.5: version "0.8.5" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" @@ -5365,6 +5470,32 @@ spawn-sync@^1.0.15: concat-stream "^1.4.7" os-shim "^0.1.2" +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.11" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" + integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== + split-on-first@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" @@ -5404,6 +5535,15 @@ string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2 is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string.prototype.padend@^3.0.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz#997a6de12c92c7cb34dc8a201a6c53d9bd88a5f1" + integrity sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + string.prototype.trimend@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" @@ -5802,6 +5942,14 @@ v8-to-istanbul@^9.0.0: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + walker@^1.0.7: version "1.0.8" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" From 2a7326b97a1c9ddea72a44acca07832165dea500 Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Tue, 31 May 2022 08:02:36 -0700 Subject: [PATCH 148/334] use npm-run-all for parallel pre-commit hook --- package.json | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 500f7bd67c..c95cadaf9c 100644 --- a/package.json +++ b/package.json @@ -79,16 +79,14 @@ "test:watch": "yarn test -- --watch", "check": "yarn ts:check && yarn pretty:check && yarn lint && yarn test", "prepare": "yarn clean && yarn fix && yarn check && yarn build", + "pre-commit": "npm-run-all --parallel ts:changes lint:changes", "build:commonjs": "babel src --out-dir lib --extensions .ts --source-maps && tsc --module commonjs --emitDeclarationOnly --isolatedModules", "build:umd": "webpack --config webpack.dev.js", "build:umd:min": "webpack --config webpack.prod.js", "build": "yarn build:commonjs && yarn build:umd && yarn build:umd:min", "release": "release-it" }, - "pre-commit": [ - "ts:changes", - "lint:changes" - ], + "pre-commit": "pre-commit", "pre-push": "build", "repository": { "type": "git", From b43c57ed343ac19d4f6d08ca26cdfa3c5329f24a Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Tue, 31 May 2022 08:10:51 -0700 Subject: [PATCH 149/334] use npm-run-all to optimise build --- package.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c95cadaf9c..c26183523f 100644 --- a/package.json +++ b/package.json @@ -80,10 +80,12 @@ "check": "yarn ts:check && yarn pretty:check && yarn lint && yarn test", "prepare": "yarn clean && yarn fix && yarn check && yarn build", "pre-commit": "npm-run-all --parallel ts:changes lint:changes", - "build:commonjs": "babel src --out-dir lib --extensions .ts --source-maps && tsc --module commonjs --emitDeclarationOnly --isolatedModules", + "build:commonjs:babel": "babel src --out-dir lib --extensions .ts --source-maps", + "build:commonjs:tsc": "tsc --module commonjs --emitDeclarationOnly --isolatedModules", + "build:commonjs": "npm-run-all --parallel build:commonjs:babel build:commonjs:tsc", "build:umd": "webpack --config webpack.dev.js", "build:umd:min": "webpack --config webpack.prod.js", - "build": "yarn build:commonjs && yarn build:umd && yarn build:umd:min", + "build": "npm-run-all --parallel build:commonjs build:umd build:umd:min", "release": "release-it" }, "pre-commit": "pre-commit", From 51c394aee4047821e2e3e245217124ddab223a6c Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Tue, 31 May 2022 19:27:02 +0300 Subject: [PATCH 150/334] Fix lint:changes command --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c26183523f..986997db70 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "ts:check": "tsc --noEmit", "ts:changes": "tsc --noEmit --incremental", "lint": "eslint --cache .", - "lint:changes": "sh -c eslint --cache $(git:changes)", + "lint:changes": "sh -c eslint --cache $(yarn git:changes)", "pretty": "prettier --write .", "pretty:check": "prettier --check .", "fix": "yarn pretty && eslint --fix .", From a6ce81f8fda7e53cb17e74e84855bfe489d6b7b0 Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Mon, 30 May 2022 16:14:47 -0700 Subject: [PATCH 151/334] update tsconfig to allow absolute imports --- tsconfig.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tsconfig.json b/tsconfig.json index ab54a99bac..d19e158b7f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,10 @@ "lib": ["es6", "dom"], "rootDirs": ["src"], "outDir": "lib", + "baseUrl": "./", + "paths": { + "src/*": ["./src/*"] + }, "sourceMap": true, "declaration": true, "esModuleInterop": true, From e46f3a9a3a689ff01b8e7d0adf7b3e63e13b1129 Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Mon, 30 May 2022 16:15:19 -0700 Subject: [PATCH 152/334] update import paths for src --- src/core/AliasAs.ts | 3 ++- src/core/AsTokenFactory.ts | 3 ++- src/core/Indentation.ts | 2 +- src/core/StatementFormatter.ts | 5 +++-- src/core/Tokenizer.ts | 3 ++- src/core/WhitespaceBuilder.ts | 3 ++- src/core/config.ts | 2 +- src/core/formatAliasPositions.ts | 2 +- src/core/formatCommaPositions.ts | 5 +++-- src/core/regexFactory.ts | 2 +- src/core/tabularStyle.ts | 2 +- src/languages/bigquery.formatter.ts | 10 +++++----- src/languages/db2.formatter.ts | 8 ++++---- src/languages/hive.formatter.ts | 8 ++++---- src/languages/mariadb.formatter.ts | 10 +++++----- src/languages/mysql.formatter.ts | 10 +++++----- src/languages/n1ql.formatter.ts | 8 ++++---- src/languages/plsql.formatter.ts | 10 +++++----- src/languages/postgresql.formatter.ts | 8 ++++---- src/languages/redshift.formatter.ts | 8 ++++---- src/languages/spark.formatter.ts | 10 +++++----- src/languages/sql.formatter.ts | 8 ++++---- src/languages/sqlite.formatter.ts | 6 +++--- src/languages/tsql.formatter.ts | 8 ++++---- src/sqlFormatter.ts | 26 +++++++++++++------------- 25 files changed, 88 insertions(+), 82 deletions(-) diff --git a/src/core/AliasAs.ts b/src/core/AliasAs.ts index 592d21786c..982c6149f8 100644 --- a/src/core/AliasAs.ts +++ b/src/core/AliasAs.ts @@ -1,4 +1,5 @@ -import { AliasMode } from '../types'; +import { AliasMode } from 'src/types'; + import { isCommand, isToken, Token, TokenType } from './token'; export interface TokenStream { diff --git a/src/core/AsTokenFactory.ts b/src/core/AsTokenFactory.ts index e8810e4386..2babae17d9 100644 --- a/src/core/AsTokenFactory.ts +++ b/src/core/AsTokenFactory.ts @@ -1,4 +1,5 @@ -import { KeywordCase } from '../types'; +import { KeywordCase } from 'src/types'; + import { isToken, Token, TokenType } from './token'; export default class AsTokenFactory { diff --git a/src/core/Indentation.ts b/src/core/Indentation.ts index cf27972ec2..f64e1ef972 100644 --- a/src/core/Indentation.ts +++ b/src/core/Indentation.ts @@ -1,4 +1,4 @@ -import { last } from '../utils'; +import { last } from 'src/utils'; const INDENT_TYPE_TOP_LEVEL = 'top-level'; const INDENT_TYPE_BLOCK_LEVEL = 'block-level'; diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 91f3f8ef6b..610c69c632 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -1,9 +1,10 @@ +import { FormatOptions } from 'src/types'; +import { equalizeWhitespace } from 'src/utils'; + import Indentation from './Indentation'; import InlineBlock from './InlineBlock'; import Params from './Params'; -import { equalizeWhitespace } from '../utils'; import { isReserved, isCommand, isToken, Token, TokenType, EOF_TOKEN } from './token'; -import { FormatOptions } from '../types'; import toTabularFormat from './tabularStyle'; import AliasAs from './AliasAs'; import AsTokenFactory from './AsTokenFactory'; diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 66caad1fc9..9f2c92b42d 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -1,5 +1,6 @@ +import { equalizeWhitespace, escapeRegExp, id } from 'src/utils'; + import * as regexFactory from './regexFactory'; -import { equalizeWhitespace, escapeRegExp, id } from '../utils'; import { Token, TokenType } from './token'; // convert to partial type import in TS 4.5 export const WHITESPACE_REGEX = /^(\s+)/u; diff --git a/src/core/WhitespaceBuilder.ts b/src/core/WhitespaceBuilder.ts index 2f4cae4800..c19bf1207b 100644 --- a/src/core/WhitespaceBuilder.ts +++ b/src/core/WhitespaceBuilder.ts @@ -1,4 +1,5 @@ -import { last } from '../utils'; +import { last } from 'src/utils'; + import Indentation from './Indentation'; /** Whitespace modifiers to be used with add() method */ diff --git a/src/core/config.ts b/src/core/config.ts index f39cab4136..2ad1d11f99 100644 --- a/src/core/config.ts +++ b/src/core/config.ts @@ -1,4 +1,4 @@ -import { FormatOptions } from '../types'; +import { FormatOptions } from 'src/types'; // Utility functions for config options diff --git a/src/core/formatAliasPositions.ts b/src/core/formatAliasPositions.ts index fcd3035f97..205c3681fa 100644 --- a/src/core/formatAliasPositions.ts +++ b/src/core/formatAliasPositions.ts @@ -1,4 +1,4 @@ -import { maxLength } from '../utils'; +import { maxLength } from 'src/utils'; /** * Handles select alias placement - tabulates if enabled diff --git a/src/core/formatCommaPositions.ts b/src/core/formatCommaPositions.ts index 7d80a877ed..bc17e18960 100644 --- a/src/core/formatCommaPositions.ts +++ b/src/core/formatCommaPositions.ts @@ -1,5 +1,6 @@ -import { CommaPosition } from '../types'; -import { maxLength } from '../utils'; +import { CommaPosition } from 'src/types'; +import { maxLength } from 'src/utils'; + import { WHITESPACE_REGEX } from './Tokenizer'; /** diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index b5f790d3aa..a9fda754bc 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -1,4 +1,4 @@ -import { escapeRegExp, isEmpty, sortByLengthDesc } from '../utils'; +import { escapeRegExp, isEmpty, sortByLengthDesc } from 'src/utils'; /** * Builds a RegExp containing all operators for a SQL dialect diff --git a/src/core/tabularStyle.ts b/src/core/tabularStyle.ts index 0ddfa71f83..ec90614770 100644 --- a/src/core/tabularStyle.ts +++ b/src/core/tabularStyle.ts @@ -1,4 +1,4 @@ -import { IndentStyle } from '../types'; +import { IndentStyle } from 'src/types'; /** * When tabular style enabled, diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index 673bd88969..3fae04f6c2 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -1,8 +1,8 @@ -import Formatter from '../core/Formatter'; -import Tokenizer from '../core/Tokenizer'; -import type { StringPatternType } from '../core/regexFactory'; -import { EOF_TOKEN, Token } from '../core/token'; -import { dedupe } from '../utils'; +import Formatter from 'src/core/Formatter'; +import Tokenizer from 'src/core/Tokenizer'; +import type { StringPatternType } from 'src/core/regexFactory'; +import { EOF_TOKEN, Token } from 'src/core/token'; +import { dedupe } from 'src/utils'; /** * Priority 5 (last) diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index f8ec66d284..aaf58fb672 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -1,7 +1,7 @@ -import Formatter from '../core/Formatter'; -import Tokenizer from '../core/Tokenizer'; -import type { StringPatternType } from '../core/regexFactory'; -import { dedupe } from '../utils'; +import Formatter from 'src/core/Formatter'; +import Tokenizer from 'src/core/Tokenizer'; +import type { StringPatternType } from 'src/core/regexFactory'; +import { dedupe } from 'src/utils'; /** * Priority 5 (last) diff --git a/src/languages/hive.formatter.ts b/src/languages/hive.formatter.ts index ed25cb431d..25a6952525 100644 --- a/src/languages/hive.formatter.ts +++ b/src/languages/hive.formatter.ts @@ -1,7 +1,7 @@ -import Formatter from '../core/Formatter'; -import Tokenizer from '../core/Tokenizer'; -import type { StringPatternType } from '../core/regexFactory'; -import { dedupe } from '../utils'; +import Formatter from 'src/core/Formatter'; +import Tokenizer from 'src/core/Tokenizer'; +import type { StringPatternType } from 'src/core/regexFactory'; +import { dedupe } from 'src/utils'; /** * Priority 5 (last) diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index f945eaf6fd..0cba8c09da 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1,8 +1,8 @@ -import Formatter from '../core/Formatter'; -import Tokenizer from '../core/Tokenizer'; -import { EOF_TOKEN, isToken, Token, TokenType } from '../core/token'; -import type { StringPatternType } from '../core/regexFactory'; -import { dedupe } from '../utils'; +import Formatter from 'src/core/Formatter'; +import Tokenizer from 'src/core/Tokenizer'; +import { EOF_TOKEN, isToken, Token, TokenType } from 'src/core/token'; +import type { StringPatternType } from 'src/core/regexFactory'; +import { dedupe } from 'src/utils'; /** * Priority 5 (last) diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index 3613f156d7..d4f04092b8 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1,8 +1,8 @@ -import Formatter from '../core/Formatter'; -import Tokenizer from '../core/Tokenizer'; -import { EOF_TOKEN, isToken, Token, TokenType } from '../core/token'; -import type { StringPatternType } from '../core/regexFactory'; -import { dedupe } from '../utils'; +import Formatter from 'src/core/Formatter'; +import Tokenizer from 'src/core/Tokenizer'; +import { EOF_TOKEN, isToken, Token, TokenType } from 'src/core/token'; +import type { StringPatternType } from 'src/core/regexFactory'; +import { dedupe } from 'src/utils'; // TODO: split this into object with function categories /** diff --git a/src/languages/n1ql.formatter.ts b/src/languages/n1ql.formatter.ts index 32e54b56a0..a34bd0a408 100644 --- a/src/languages/n1ql.formatter.ts +++ b/src/languages/n1ql.formatter.ts @@ -1,7 +1,7 @@ -import Formatter from '../core/Formatter'; -import Tokenizer from '../core/Tokenizer'; -import type { StringPatternType } from '../core/regexFactory'; -import { dedupe } from '../utils'; +import Formatter from 'src/core/Formatter'; +import Tokenizer from 'src/core/Tokenizer'; +import type { StringPatternType } from 'src/core/regexFactory'; +import { dedupe } from 'src/utils'; // TODO: split this into object with function categories /** diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 4558255803..00755c40cb 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -1,8 +1,8 @@ -import Formatter from '../core/Formatter'; -import Tokenizer from '../core/Tokenizer'; -import { EOF_TOKEN, isReserved, isToken, Token, TokenType } from '../core/token'; // convert to partial type import in TS 4.5 -import type { StringPatternType } from '../core/regexFactory'; -import { dedupe } from '../utils'; +import Formatter from 'src/core/Formatter'; +import Tokenizer from 'src/core/Tokenizer'; +import { EOF_TOKEN, isReserved, isToken, Token, TokenType } from 'src/core/token'; // convert to partial type import in TS 4.5 +import type { StringPatternType } from 'src/core/regexFactory'; +import { dedupe } from 'src/utils'; /** * Priority 5 (last) diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index 05df3a908f..1cf177f12a 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1,7 +1,7 @@ -import Formatter from '../core/Formatter'; -import Tokenizer from '../core/Tokenizer'; -import type { StringPatternType } from '../core/regexFactory'; -import { dedupe } from '../utils'; +import Formatter from 'src/core/Formatter'; +import Tokenizer from 'src/core/Tokenizer'; +import type { StringPatternType } from 'src/core/regexFactory'; +import { dedupe } from 'src/utils'; /** * Priority 5 (last) diff --git a/src/languages/redshift.formatter.ts b/src/languages/redshift.formatter.ts index 7391f0db6d..b4bc3f8bc3 100644 --- a/src/languages/redshift.formatter.ts +++ b/src/languages/redshift.formatter.ts @@ -1,7 +1,7 @@ -import Formatter from '../core/Formatter'; -import Tokenizer from '../core/Tokenizer'; -import type { StringPatternType } from '../core/regexFactory'; -import { dedupe } from '../utils'; +import Formatter from 'src/core/Formatter'; +import Tokenizer from 'src/core/Tokenizer'; +import type { StringPatternType } from 'src/core/regexFactory'; +import { dedupe } from 'src/utils'; /** * Priority 5 (last) diff --git a/src/languages/spark.formatter.ts b/src/languages/spark.formatter.ts index 129e7a8f89..3df212ee6c 100644 --- a/src/languages/spark.formatter.ts +++ b/src/languages/spark.formatter.ts @@ -1,8 +1,8 @@ -import Formatter from '../core/Formatter'; -import Tokenizer from '../core/Tokenizer'; -import { EOF_TOKEN, isToken, Token, TokenType } from '../core/token'; // convert to partial type import in TS 4.5 -import type { StringPatternType } from '../core/regexFactory'; -import { dedupe } from '../utils'; +import Formatter from 'src/core/Formatter'; +import Tokenizer from 'src/core/Tokenizer'; +import { EOF_TOKEN, isToken, Token, TokenType } from 'src/core/token'; // convert to partial type import in TS 4.5 +import type { StringPatternType } from 'src/core/regexFactory'; +import { dedupe } from 'src/utils'; /** * Priority 5 (last) diff --git a/src/languages/sql.formatter.ts b/src/languages/sql.formatter.ts index 9301b64d42..43b4c2ce03 100644 --- a/src/languages/sql.formatter.ts +++ b/src/languages/sql.formatter.ts @@ -1,7 +1,7 @@ -import Formatter from '../core/Formatter'; -import Tokenizer from '../core/Tokenizer'; -import type { StringPatternType } from '../core/regexFactory'; -import { dedupe } from '../utils'; +import Formatter from 'src/core/Formatter'; +import Tokenizer from 'src/core/Tokenizer'; +import type { StringPatternType } from 'src/core/regexFactory'; +import { dedupe } from 'src/utils'; /** * Priority 5 (last) diff --git a/src/languages/sqlite.formatter.ts b/src/languages/sqlite.formatter.ts index ee2bd95b07..8a4100800c 100644 --- a/src/languages/sqlite.formatter.ts +++ b/src/languages/sqlite.formatter.ts @@ -1,6 +1,6 @@ -import Formatter from '../core/Formatter'; -import { StringPatternType } from '../core/regexFactory'; -import Tokenizer from '../core/Tokenizer'; +import Formatter from 'src/core/Formatter'; +import { StringPatternType } from 'src/core/regexFactory'; +import Tokenizer from 'src/core/Tokenizer'; // https://jakewheat.github.io/sql-overview/sql-2008-foundation-grammar.html#reserved-word const standardReservedWords = [ diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index 0db9b68c28..8932def52c 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1,7 +1,7 @@ -import Formatter from '../core/Formatter'; -import Tokenizer from '../core/Tokenizer'; -import type { StringPatternType } from '../core/regexFactory'; -import { dedupe } from '../utils'; +import Formatter from 'src/core/Formatter'; +import Tokenizer from 'src/core/Tokenizer'; +import type { StringPatternType } from 'src/core/regexFactory'; +import { dedupe } from 'src/utils'; /** * Priority 5 (last) diff --git a/src/sqlFormatter.ts b/src/sqlFormatter.ts index e6febe62f9..7bfa5b0bee 100644 --- a/src/sqlFormatter.ts +++ b/src/sqlFormatter.ts @@ -1,16 +1,16 @@ -import BigQueryFormatter from './languages/bigquery.formatter'; -import Db2Formatter from './languages/db2.formatter'; -import HiveFormatter from './languages/hive.formatter'; -import MariaDbFormatter from './languages/mariadb.formatter'; -import MySqlFormatter from './languages/mysql.formatter'; -import N1qlFormatter from './languages/n1ql.formatter'; -import PlSqlFormatter from './languages/plsql.formatter'; -import PostgreSqlFormatter from './languages/postgresql.formatter'; -import RedshiftFormatter from './languages/redshift.formatter'; -import SparkFormatter from './languages/spark.formatter'; -import SqliteFormatter from './languages/sqlite.formatter'; -import SqlFormatter from './languages/sql.formatter'; -import TSqlFormatter from './languages/tsql.formatter'; +import BigQueryFormatter from 'src/languages/bigquery.formatter'; +import Db2Formatter from 'src/languages/db2.formatter'; +import HiveFormatter from 'src/languages/hive.formatter'; +import MariaDbFormatter from 'src/languages/mariadb.formatter'; +import MySqlFormatter from 'src/languages/mysql.formatter'; +import N1qlFormatter from 'src/languages/n1ql.formatter'; +import PlSqlFormatter from 'src/languages/plsql.formatter'; +import PostgreSqlFormatter from 'src/languages/postgresql.formatter'; +import RedshiftFormatter from 'src/languages/redshift.formatter'; +import SparkFormatter from 'src/languages/spark.formatter'; +import SqliteFormatter from 'src/languages/sqlite.formatter'; +import SqlFormatter from 'src/languages/sql.formatter'; +import TSqlFormatter from 'src/languages/tsql.formatter'; import { FormatOptions } from './types'; import { isNumber } from './utils'; From 7544874b5bd3f77f160f3789102fb7f498b93bda Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Mon, 30 May 2022 16:21:16 -0700 Subject: [PATCH 153/334] update import paths for test --- test/behavesLikeMariaDbFormatter.ts | 5 +++-- test/behavesLikeSqlFormatter.ts | 5 +++-- test/bigquery.test.ts | 7 ++++--- test/db2.test.ts | 7 ++++--- test/features/alterTable.ts | 3 ++- test/features/alterTableModify.ts | 3 ++- test/features/array.ts | 3 ++- test/features/between.ts | 2 +- test/features/case.ts | 3 ++- test/features/comments.ts | 3 ++- test/features/constraints.ts | 3 ++- test/features/createTable.ts | 3 ++- test/features/deleteFrom.ts | 3 ++- test/features/join.ts | 3 ++- test/features/numbers.ts | 3 ++- test/features/operators.ts | 3 ++- test/features/returning.ts | 3 ++- test/features/schema.ts | 3 ++- test/features/strings.ts | 3 ++- test/hive.test.ts | 7 ++++--- test/mariadb.test.ts | 4 ++-- test/mysql.test.ts | 5 +++-- test/n1ql.test.ts | 7 ++++--- test/options/aliasAs.ts | 3 ++- test/options/commaPosition.ts | 3 ++- test/options/expressionWidth.ts | 3 ++- test/options/indentStyle.ts | 3 ++- test/options/keywordCase.ts | 3 ++- test/options/linesBetweenQueries.ts | 3 ++- test/options/logicalOperatorNewline.ts | 3 ++- test/options/multilineLists.ts | 3 ++- test/options/newlineBeforeParen.ts | 3 ++- test/options/newlineBeforeSemicolon.ts | 3 ++- test/options/param.ts | 3 ++- test/options/tabWidth.ts | 3 ++- test/options/tabulateAlias.ts | 3 ++- test/options/useTabs.ts | 2 +- test/plsql.test.ts | 7 ++++--- test/postgresql.test.ts | 6 +++--- test/redshift.test.ts | 7 ++++--- test/spark.test.ts | 7 ++++--- test/sql.test.ts | 7 ++++--- test/sqlFormatter.test.ts | 2 +- test/sqlite.test.ts | 7 ++++--- test/tsql.test.ts | 7 ++++--- test/unit/tabularStyle.test.ts | 2 +- 46 files changed, 112 insertions(+), 72 deletions(-) diff --git a/test/behavesLikeMariaDbFormatter.ts b/test/behavesLikeMariaDbFormatter.ts index 77b98374ad..6c0ae532bf 100644 --- a/test/behavesLikeMariaDbFormatter.ts +++ b/test/behavesLikeMariaDbFormatter.ts @@ -1,6 +1,7 @@ import dedent from 'dedent-js'; + +import { FormatFn } from 'src/sqlFormatter'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; -import { FormatFn } from '../src/sqlFormatter'; import supportsCreateTable from './features/createTable'; import supportsAlterTable from './features/alterTable'; @@ -8,8 +9,8 @@ import supportsBetween from './features/between'; import supportsJoin from './features/join'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; -import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsParams from './options/param'; /** * Shared tests for MySQL and MariaDB diff --git a/test/behavesLikeSqlFormatter.ts b/test/behavesLikeSqlFormatter.ts index 1d096c9239..c823a601fa 100644 --- a/test/behavesLikeSqlFormatter.ts +++ b/test/behavesLikeSqlFormatter.ts @@ -1,7 +1,9 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../src/sqlFormatter'; +import { FormatFn } from 'src/sqlFormatter'; + import supportsCase from './features/case'; +import supportsNumbers from './features/numbers'; import supportsTabWidth from './options/tabWidth'; import supportsUseTabs from './options/useTabs'; import supportsAliasAs from './options/aliasAs'; @@ -15,7 +17,6 @@ import supportsLinesBetweenQueries from './options/linesBetweenQueries'; import supportsNewlineBeforeSemicolon from './options/newlineBeforeSemicolon'; import supportsLogicalOperatorNewline from './options/logicalOperatorNewline'; import supportsTabulateAlias from './options/tabulateAlias'; -import supportsNumbers from './features/numbers'; /** * Core tests for all SQL formatters diff --git a/test/bigquery.test.ts b/test/bigquery.test.ts index dfb0e65ca1..203cf195ae 100644 --- a/test/bigquery.test.ts +++ b/test/bigquery.test.ts @@ -1,6 +1,7 @@ import dedent from 'dedent-js'; -import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; -import BigQueryFormatter from '../src/languages/bigquery.formatter'; + +import { format as originalFormat, FormatFn } from 'src/sqlFormatter'; +import BigQueryFormatter from 'src/languages/bigquery.formatter'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; import supportsCreateTable from './features/createTable'; @@ -10,8 +11,8 @@ import supportsBetween from './features/between'; import supportsJoin from './features/join'; import supportsOperators from './features/operators'; import supportsDeleteFrom from './features/deleteFrom'; -import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsParams from './options/param'; describe('BigQueryFormatter', () => { const language = 'bigquery'; diff --git a/test/db2.test.ts b/test/db2.test.ts index d562d59e0a..bf5992f411 100644 --- a/test/db2.test.ts +++ b/test/db2.test.ts @@ -1,6 +1,7 @@ import dedent from 'dedent-js'; -import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; -import Db2Formatter from '../src/languages/db2.formatter'; + +import { format as originalFormat, FormatFn } from 'src/sqlFormatter'; +import Db2Formatter from 'src/languages/db2.formatter'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; import supportsAlterTable from './features/alterTable'; @@ -12,8 +13,8 @@ import supportsSchema from './features/schema'; import supportsStrings from './features/strings'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; -import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsParams from './options/param'; describe('Db2Formatter', () => { const language = 'db2'; diff --git a/test/features/alterTable.ts b/test/features/alterTable.ts index 6f894139eb..b5abbae7a5 100644 --- a/test/features/alterTable.ts +++ b/test/features/alterTable.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsAlterTable(format: FormatFn) { it('formats ALTER TABLE ... ALTER COLUMN query', () => { diff --git a/test/features/alterTableModify.ts b/test/features/alterTableModify.ts index c6f215a772..e648dd5065 100644 --- a/test/features/alterTableModify.ts +++ b/test/features/alterTableModify.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsAlterTableModify(format: FormatFn) { it('formats ALTER TABLE ... MODIFY statement', () => { diff --git a/test/features/array.ts b/test/features/array.ts index 3ab15d2f87..38fda580cc 100644 --- a/test/features/array.ts +++ b/test/features/array.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsArray(format: FormatFn) { it('supports square brackets for array indexing', () => { diff --git a/test/features/between.ts b/test/features/between.ts index 76ab10c2e5..1f4eafd4e4 100644 --- a/test/features/between.ts +++ b/test/features/between.ts @@ -1,4 +1,4 @@ -import { FormatFn } from '../../src/sqlFormatter'; +import { FormatFn } from 'src/sqlFormatter'; export default function supportsBetween(format: FormatFn) { it('formats BETWEEN _ AND _ on single line', () => { diff --git a/test/features/case.ts b/test/features/case.ts index 41e77719d4..4522b9969e 100644 --- a/test/features/case.ts +++ b/test/features/case.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsCase(format: FormatFn) { it('formats CASE ... WHEN with a blank expression', () => { diff --git a/test/features/comments.ts b/test/features/comments.ts index 2d0aeb92c8..d67ca9e957 100644 --- a/test/features/comments.ts +++ b/test/features/comments.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; import { itIf } from '../utils'; interface CommentsConfig { diff --git a/test/features/constraints.ts b/test/features/constraints.ts index deb38c2748..4eba80f0dc 100644 --- a/test/features/constraints.ts +++ b/test/features/constraints.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsConstraints(format: FormatFn) { it('treats ON UPDATE & ON DELETE as distinct keywords from ON', () => { diff --git a/test/features/createTable.ts b/test/features/createTable.ts index bc23d0dfc5..98a247db57 100644 --- a/test/features/createTable.ts +++ b/test/features/createTable.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsCreateTable(format: FormatFn) { it('formats short CREATE TABLE', () => { diff --git a/test/features/deleteFrom.ts b/test/features/deleteFrom.ts index 78ab4224f8..e81a2e3643 100644 --- a/test/features/deleteFrom.ts +++ b/test/features/deleteFrom.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsDeleteFrom(format: FormatFn) { it('formats simple DELETE FROM statement', () => { diff --git a/test/features/join.ts b/test/features/join.ts index 115e5b6a69..8f43f3020d 100644 --- a/test/features/join.ts +++ b/test/features/join.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; type Options = { without?: string[]; additionally?: string[] }; diff --git a/test/features/numbers.ts b/test/features/numbers.ts index 8c03bc17d8..f342b671f4 100644 --- a/test/features/numbers.ts +++ b/test/features/numbers.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsNumbers(format: FormatFn) { it('supports decimal numbers', () => { diff --git a/test/features/operators.ts b/test/features/operators.ts index 8b802f727d..ac255bd9f7 100644 --- a/test/features/operators.ts +++ b/test/features/operators.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsOperators( format: FormatFn, diff --git a/test/features/returning.ts b/test/features/returning.ts index 3f3a2183aa..f1991da5fa 100644 --- a/test/features/returning.ts +++ b/test/features/returning.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsReturning(format: FormatFn) { it('places RETURNING to new line', () => { diff --git a/test/features/schema.ts b/test/features/schema.ts index 2e53db8fee..2b10a2155d 100644 --- a/test/features/schema.ts +++ b/test/features/schema.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsSchema(format: FormatFn) { it('formats simple SET SCHEMA statements', () => { diff --git a/test/features/strings.ts b/test/features/strings.ts index 00d8113cc1..47faa1110f 100644 --- a/test/features/strings.ts +++ b/test/features/strings.ts @@ -1,6 +1,7 @@ import { expect } from '@jest/globals'; import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsStrings(format: FormatFn, stringTypes: string[]) { if (stringTypes.includes('""')) { diff --git a/test/hive.test.ts b/test/hive.test.ts index 8f0a2cd414..013df350b8 100644 --- a/test/hive.test.ts +++ b/test/hive.test.ts @@ -1,5 +1,6 @@ -import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; -import HiveFormatter from '../src/languages/hive.formatter'; +import { format as originalFormat, FormatFn } from 'src/sqlFormatter'; + +import HiveFormatter from 'src/languages/hive.formatter'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; import supportsCreateTable from './features/createTable'; @@ -10,8 +11,8 @@ import supportsBetween from './features/between'; import supportsJoin from './features/join'; import supportsOperators from './features/operators'; import supportsArray from './features/array'; -import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsParams from './options/param'; describe('HiveFormatter', () => { const language = 'hive'; diff --git a/test/mariadb.test.ts b/test/mariadb.test.ts index 455db797c7..0adb2f1a82 100644 --- a/test/mariadb.test.ts +++ b/test/mariadb.test.ts @@ -1,5 +1,5 @@ -import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; -import MariaDbFormatter from '../src/languages/mariadb.formatter'; +import { format as originalFormat, FormatFn } from 'src/sqlFormatter'; +import MariaDbFormatter from 'src/languages/mariadb.formatter'; import behavesLikeMariaDbFormatter from './behavesLikeMariaDbFormatter'; import supportsStrings from './features/strings'; diff --git a/test/mysql.test.ts b/test/mysql.test.ts index 5ee17ec8e3..1fe93ecfce 100644 --- a/test/mysql.test.ts +++ b/test/mysql.test.ts @@ -1,6 +1,7 @@ import dedent from 'dedent-js'; -import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; -import MySqlFormatter from '../src/languages/mysql.formatter'; + +import { format as originalFormat, FormatFn } from 'src/sqlFormatter'; +import MySqlFormatter from 'src/languages/mysql.formatter'; import behavesLikeMariaDbFormatter from './behavesLikeMariaDbFormatter'; import supportsStrings from './features/strings'; diff --git a/test/n1ql.test.ts b/test/n1ql.test.ts index ff078c181f..1cee0fb391 100644 --- a/test/n1ql.test.ts +++ b/test/n1ql.test.ts @@ -1,6 +1,7 @@ import dedent from 'dedent-js'; -import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; -import N1qlFormatter from '../src/languages/n1ql.formatter'; + +import { format as originalFormat, FormatFn } from 'src/sqlFormatter'; +import N1qlFormatter from 'src/languages/n1ql.formatter'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; import supportsBetween from './features/between'; @@ -11,8 +12,8 @@ import supportsStrings from './features/strings'; import supportsReturning from './features/returning'; import supportsDeleteFrom from './features/deleteFrom'; import supportsArray from './features/array'; -import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsParams from './options/param'; describe('N1qlFormatter', () => { const language = 'n1ql'; diff --git a/test/options/aliasAs.ts b/test/options/aliasAs.ts index f1d06939ce..4943b58ed2 100644 --- a/test/options/aliasAs.ts +++ b/test/options/aliasAs.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsAliasAs(format: FormatFn) { describe('by default', () => { diff --git a/test/options/commaPosition.ts b/test/options/commaPosition.ts index d7ce002438..11c50f5b69 100644 --- a/test/options/commaPosition.ts +++ b/test/options/commaPosition.ts @@ -1,6 +1,7 @@ import { expect } from '@jest/globals'; import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsCommaPosition(format: FormatFn) { it('defaults to comma after column', () => { diff --git a/test/options/expressionWidth.ts b/test/options/expressionWidth.ts index aceb7beb3f..f58a081243 100644 --- a/test/options/expressionWidth.ts +++ b/test/options/expressionWidth.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsExpressionWidth(format: FormatFn) { it('throws error when expressionWidth negative number', () => { diff --git a/test/options/indentStyle.ts b/test/options/indentStyle.ts index beb375072d..4eaba09f67 100644 --- a/test/options/indentStyle.ts +++ b/test/options/indentStyle.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsIndentStyle(format: FormatFn) { const baseQuery = ` diff --git a/test/options/keywordCase.ts b/test/options/keywordCase.ts index 84b398208a..03d03a0240 100644 --- a/test/options/keywordCase.ts +++ b/test/options/keywordCase.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsKeywordCase(format: FormatFn) { it('preserves keyword case by default', () => { diff --git a/test/options/linesBetweenQueries.ts b/test/options/linesBetweenQueries.ts index adc18683e2..976988ef66 100644 --- a/test/options/linesBetweenQueries.ts +++ b/test/options/linesBetweenQueries.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsLinesBetweenQueries(format: FormatFn) { it('defaults to single empty line between queries', () => { diff --git a/test/options/logicalOperatorNewline.ts b/test/options/logicalOperatorNewline.ts index da820259c3..8348becada 100644 --- a/test/options/logicalOperatorNewline.ts +++ b/test/options/logicalOperatorNewline.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsLogicalOperatorNewline(format: FormatFn) { it('by default adds newline before logical operator', () => { diff --git a/test/options/multilineLists.ts b/test/options/multilineLists.ts index ece8c99f3e..1c8abd7463 100644 --- a/test/options/multilineLists.ts +++ b/test/options/multilineLists.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsMultilineLists(format: FormatFn) { it('throws error when multilineLists is negative number', () => { diff --git a/test/options/newlineBeforeParen.ts b/test/options/newlineBeforeParen.ts index 6d68d1b8ef..a96addd519 100644 --- a/test/options/newlineBeforeParen.ts +++ b/test/options/newlineBeforeParen.ts @@ -1,6 +1,7 @@ import { expect } from '@jest/globals'; import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsNewlineBeforeParen(format: FormatFn) { it('defaults to newline before opening and closing parenthesis', () => { diff --git a/test/options/newlineBeforeSemicolon.ts b/test/options/newlineBeforeSemicolon.ts index ed9f3d6235..3705861452 100644 --- a/test/options/newlineBeforeSemicolon.ts +++ b/test/options/newlineBeforeSemicolon.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsNewlineBeforeSemicolon(format: FormatFn) { it('formats lonely semicolon', () => { diff --git a/test/options/param.ts b/test/options/param.ts index 881dfaa240..ae89cd84a3 100644 --- a/test/options/param.ts +++ b/test/options/param.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; interface ParamsTypes { indexed?: ('?' | '$')[]; diff --git a/test/options/tabWidth.ts b/test/options/tabWidth.ts index e5d33d79d7..66ee57dd0c 100644 --- a/test/options/tabWidth.ts +++ b/test/options/tabWidth.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsTabWidth(format: FormatFn) { it('indents with 2 spaces by default', () => { diff --git a/test/options/tabulateAlias.ts b/test/options/tabulateAlias.ts index f4d20ddaa3..c3dd07ea35 100644 --- a/test/options/tabulateAlias.ts +++ b/test/options/tabulateAlias.ts @@ -1,5 +1,6 @@ import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; + +import { FormatFn } from 'src/sqlFormatter'; export default function supportsTabulateAlias(format: FormatFn) { it('tabulates aliases which use AS keyword', () => { diff --git a/test/options/useTabs.ts b/test/options/useTabs.ts index 61c8c45c5a..beaf63bd84 100644 --- a/test/options/useTabs.ts +++ b/test/options/useTabs.ts @@ -1,4 +1,4 @@ -import { FormatFn } from '../../src/sqlFormatter'; +import { FormatFn } from 'src/sqlFormatter'; export default function supportsUseTabs(format: FormatFn) { it('supports indenting with tabs', () => { diff --git a/test/plsql.test.ts b/test/plsql.test.ts index d2f80db172..96ee26c70c 100644 --- a/test/plsql.test.ts +++ b/test/plsql.test.ts @@ -1,6 +1,7 @@ import dedent from 'dedent-js'; -import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; -import PlSqlFormatter from '../src/languages/plsql.formatter'; + +import { format as originalFormat, FormatFn } from 'src/sqlFormatter'; +import PlSqlFormatter from 'src/languages/plsql.formatter'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; import supportsAlterTable from './features/alterTable'; @@ -14,8 +15,8 @@ import supportsStrings from './features/strings'; import supportsReturning from './features/returning'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; -import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsParams from './options/param'; describe('PlSqlFormatter', () => { const language = 'plsql'; diff --git a/test/postgresql.test.ts b/test/postgresql.test.ts index 4b9be128a0..4c4d7a2196 100644 --- a/test/postgresql.test.ts +++ b/test/postgresql.test.ts @@ -1,5 +1,5 @@ -import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; -import PostgreSqlFormatter from '../src/languages/postgresql.formatter'; +import { format as originalFormat, FormatFn } from 'src/sqlFormatter'; +import PostgreSqlFormatter from 'src/languages/postgresql.formatter'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; import supportsAlterTable from './features/alterTable'; @@ -12,8 +12,8 @@ import supportsStrings from './features/strings'; import supportsReturning from './features/returning'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; -import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsParams from './options/param'; describe('PostgreSqlFormatter', () => { const language = 'postgresql'; diff --git a/test/redshift.test.ts b/test/redshift.test.ts index 340e436038..f2d2dda5ca 100644 --- a/test/redshift.test.ts +++ b/test/redshift.test.ts @@ -1,6 +1,7 @@ import dedent from 'dedent-js'; -import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; -import RedshiftFormatter from '../src/languages/redshift.formatter'; + +import { format as originalFormat, FormatFn } from 'src/sqlFormatter'; +import RedshiftFormatter from 'src/languages/redshift.formatter'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; import supportsAlterTable from './features/alterTable'; @@ -11,8 +12,8 @@ import supportsOperators from './features/operators'; import supportsSchema from './features/schema'; import supportsStrings from './features/strings'; import supportsDeleteFrom from './features/deleteFrom'; -import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsParams from './options/param'; describe('RedshiftFormatter', () => { const language = 'redshift'; diff --git a/test/spark.test.ts b/test/spark.test.ts index fb20ee1228..6e3e248815 100644 --- a/test/spark.test.ts +++ b/test/spark.test.ts @@ -1,6 +1,7 @@ import dedent from 'dedent-js'; -import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; -import SparkFormatter from '../src/languages/spark.formatter'; + +import { format as originalFormat, FormatFn } from 'src/sqlFormatter'; +import SparkFormatter from 'src/languages/spark.formatter'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; import supportsAlterTable from './features/alterTable'; @@ -11,8 +12,8 @@ import supportsOperators from './features/operators'; import supportsSchema from './features/schema'; import supportsStrings from './features/strings'; import supportsArray from './features/array'; -import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsParams from './options/param'; describe('SparkFormatter', () => { const language = 'spark'; diff --git a/test/sql.test.ts b/test/sql.test.ts index efb4557567..05171f6090 100644 --- a/test/sql.test.ts +++ b/test/sql.test.ts @@ -1,6 +1,7 @@ import dedent from 'dedent-js'; -import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; -import SqlFormatter from '../src/languages/sql.formatter'; + +import { format as originalFormat, FormatFn } from 'src/sqlFormatter'; +import SqlFormatter from 'src/languages/sql.formatter'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; import supportsCreateTable from './features/createTable'; @@ -12,8 +13,8 @@ import supportsJoin from './features/join'; import supportsOperators from './features/operators'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; -import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsParams from './options/param'; describe('SqlFormatter', () => { const language = 'sql'; diff --git a/test/sqlFormatter.test.ts b/test/sqlFormatter.test.ts index ec17e0fb91..3e16d00686 100644 --- a/test/sqlFormatter.test.ts +++ b/test/sqlFormatter.test.ts @@ -1,4 +1,4 @@ -import { format, SqlLanguage } from '../src/sqlFormatter'; +import { format, SqlLanguage } from 'src/sqlFormatter'; describe('sqlFormatter', () => { it('throws error when unsupported language parameter specified', () => { diff --git a/test/sqlite.test.ts b/test/sqlite.test.ts index 1938d15c61..e54dfdf526 100644 --- a/test/sqlite.test.ts +++ b/test/sqlite.test.ts @@ -1,6 +1,7 @@ import dedent from 'dedent-js'; -import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; -import SqliteFormatter from '../src/languages/sqlite.formatter'; + +import { format as originalFormat, FormatFn } from 'src/sqlFormatter'; +import SqliteFormatter from 'src/languages/sqlite.formatter'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; import supportsCreateTable from './features/createTable'; @@ -12,8 +13,8 @@ import supportsJoin from './features/join'; import supportsOperators from './features/operators'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; -import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsParams from './options/param'; describe('SqliteFormatter', () => { const language = 'sqlite'; diff --git a/test/tsql.test.ts b/test/tsql.test.ts index 953f08bce3..6f04440ce4 100644 --- a/test/tsql.test.ts +++ b/test/tsql.test.ts @@ -1,6 +1,7 @@ import dedent from 'dedent-js'; -import { format as originalFormat, FormatFn } from '../src/sqlFormatter'; -import TSqlFormatter from '../src/languages/tsql.formatter'; + +import { format as originalFormat, FormatFn } from 'src/sqlFormatter'; +import TSqlFormatter from 'src/languages/tsql.formatter'; import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; import supportsCreateTable from './features/createTable'; @@ -12,8 +13,8 @@ import supportsOperators from './features/operators'; import supportsJoin from './features/join'; import supportsConstraints from './features/constraints'; import supportsDeleteFrom from './features/deleteFrom'; -import supportsParams from './options/param'; import supportsComments from './features/comments'; +import supportsParams from './options/param'; describe('TSqlFormatter', () => { const language = 'tsql'; diff --git a/test/unit/tabularStyle.test.ts b/test/unit/tabularStyle.test.ts index 429e6b974e..7aca39ea1f 100644 --- a/test/unit/tabularStyle.test.ts +++ b/test/unit/tabularStyle.test.ts @@ -1,4 +1,4 @@ -import toTabularFormat from '../../src/core/tabularStyle'; +import toTabularFormat from 'src/core/tabularStyle'; describe('toTabularFormat()', () => { it('does nothing in standard style', () => { From 83103b5d8f02b58009e8d13fc7a28a19d3407008 Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Mon, 30 May 2022 16:28:33 -0700 Subject: [PATCH 154/334] update partial type imports --- src/core/AliasAs.ts | 4 ++-- src/core/AsTokenFactory.ts | 4 ++-- src/core/Formatter.ts | 6 +++--- src/core/InlineBlock.ts | 2 +- src/core/Params.ts | 2 +- src/core/Parser.ts | 2 +- src/core/StatementFormatter.ts | 6 +++--- src/core/Tokenizer.ts | 2 +- src/core/config.ts | 2 +- src/core/formatCommaPositions.ts | 2 +- src/core/tabularStyle.ts | 2 +- src/languages/bigquery.formatter.ts | 4 ++-- src/languages/db2.formatter.ts | 2 +- src/languages/hive.formatter.ts | 2 +- src/languages/mariadb.formatter.ts | 4 ++-- src/languages/mysql.formatter.ts | 4 ++-- src/languages/n1ql.formatter.ts | 2 +- src/languages/plsql.formatter.ts | 4 ++-- src/languages/postgresql.formatter.ts | 2 +- src/languages/redshift.formatter.ts | 2 +- src/languages/spark.formatter.ts | 4 ++-- src/languages/sql.formatter.ts | 2 +- src/languages/sqlite.formatter.ts | 2 +- src/languages/tsql.formatter.ts | 2 +- src/sqlFormatter.ts | 2 +- src/types.ts | 2 +- 26 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/core/AliasAs.ts b/src/core/AliasAs.ts index 982c6149f8..0f77ae19c6 100644 --- a/src/core/AliasAs.ts +++ b/src/core/AliasAs.ts @@ -1,6 +1,6 @@ -import { AliasMode } from 'src/types'; +import type { AliasMode } from 'src/types'; -import { isCommand, isToken, Token, TokenType } from './token'; +import { isCommand, isToken, type Token, TokenType } from './token'; export interface TokenStream { isWithinSelect(): boolean; diff --git a/src/core/AsTokenFactory.ts b/src/core/AsTokenFactory.ts index 2babae17d9..b4162b093b 100644 --- a/src/core/AsTokenFactory.ts +++ b/src/core/AsTokenFactory.ts @@ -1,6 +1,6 @@ -import { KeywordCase } from 'src/types'; +import type { KeywordCase } from 'src/types'; -import { isToken, Token, TokenType } from './token'; +import { isToken, type Token, TokenType } from './token'; export default class AsTokenFactory { private detectedCase: KeywordCase; diff --git a/src/core/Formatter.ts b/src/core/Formatter.ts index bcfdcdffd0..add598f945 100644 --- a/src/core/Formatter.ts +++ b/src/core/Formatter.ts @@ -1,12 +1,12 @@ import Params from './Params'; import Tokenizer from './Tokenizer'; -import { FormatOptions } from '../types'; +import type { FormatOptions } from '../types'; import formatCommaPositions from './formatCommaPositions'; import formatAliasPositions from './formatAliasPositions'; import AsTokenFactory from './AsTokenFactory'; -import Parser, { Statement } from './Parser'; +import Parser, { type Statement } from './Parser'; import StatementFormatter from './StatementFormatter'; -import { Token } from './token'; +import { type Token } from './token'; import { indentString } from './config'; /** Main formatter class that produces a final output string from list of tokens */ diff --git a/src/core/InlineBlock.ts b/src/core/InlineBlock.ts index b48e17b4ac..9b00c43745 100644 --- a/src/core/InlineBlock.ts +++ b/src/core/InlineBlock.ts @@ -1,4 +1,4 @@ -import { isToken, Token, TokenType } from './token'; +import { isToken, type Token, TokenType } from './token'; /** * Bookkeeper for inline blocks. diff --git a/src/core/Params.ts b/src/core/Params.ts index a0fdce0b7a..33d78d3267 100644 --- a/src/core/Params.ts +++ b/src/core/Params.ts @@ -1,4 +1,4 @@ -import type { Token } from './token'; +import { type Token } from './token'; export type ParamItems = { [k: string]: string }; diff --git a/src/core/Parser.ts b/src/core/Parser.ts index cdf2bd72d4..e50dc4383e 100644 --- a/src/core/Parser.ts +++ b/src/core/Parser.ts @@ -1,4 +1,4 @@ -import { EOF_TOKEN, Token, TokenType } from './token'; +import { EOF_TOKEN, type Token, TokenType } from './token'; /* eslint-disable no-cond-assign */ export type Statement = { diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 610c69c632..d8cb2ff112 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -1,14 +1,14 @@ -import { FormatOptions } from 'src/types'; +import type { FormatOptions } from 'src/types'; import { equalizeWhitespace } from 'src/utils'; import Indentation from './Indentation'; import InlineBlock from './InlineBlock'; import Params from './Params'; -import { isReserved, isCommand, isToken, Token, TokenType, EOF_TOKEN } from './token'; +import { isReserved, isCommand, isToken, type Token, TokenType, EOF_TOKEN } from './token'; import toTabularFormat from './tabularStyle'; import AliasAs from './AliasAs'; import AsTokenFactory from './AsTokenFactory'; -import { Statement } from './Parser'; +import { type Statement } from './Parser'; import { indentString, isTabularStyle } from './config'; import WhitespaceBuilder, { WS } from './WhitespaceBuilder'; diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 9f2c92b42d..d3150dc18b 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -1,7 +1,7 @@ import { equalizeWhitespace, escapeRegExp, id } from 'src/utils'; import * as regexFactory from './regexFactory'; -import { Token, TokenType } from './token'; // convert to partial type import in TS 4.5 +import { type Token, TokenType } from './token'; export const WHITESPACE_REGEX = /^(\s+)/u; const NULL_REGEX = /(?!)/; // zero-width negative lookahead, matches nothing diff --git a/src/core/config.ts b/src/core/config.ts index 2ad1d11f99..186c4c47aa 100644 --- a/src/core/config.ts +++ b/src/core/config.ts @@ -1,4 +1,4 @@ -import { FormatOptions } from 'src/types'; +import type { FormatOptions } from 'src/types'; // Utility functions for config options diff --git a/src/core/formatCommaPositions.ts b/src/core/formatCommaPositions.ts index bc17e18960..cfda17899f 100644 --- a/src/core/formatCommaPositions.ts +++ b/src/core/formatCommaPositions.ts @@ -1,4 +1,4 @@ -import { CommaPosition } from 'src/types'; +import type { CommaPosition } from 'src/types'; import { maxLength } from 'src/utils'; import { WHITESPACE_REGEX } from './Tokenizer'; diff --git a/src/core/tabularStyle.ts b/src/core/tabularStyle.ts index ec90614770..b0057382b9 100644 --- a/src/core/tabularStyle.ts +++ b/src/core/tabularStyle.ts @@ -1,4 +1,4 @@ -import { IndentStyle } from 'src/types'; +import type { IndentStyle } from 'src/types'; /** * When tabular style enabled, diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index 3fae04f6c2..329b95be29 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -1,7 +1,7 @@ import Formatter from 'src/core/Formatter'; import Tokenizer from 'src/core/Tokenizer'; -import type { StringPatternType } from 'src/core/regexFactory'; -import { EOF_TOKEN, Token } from 'src/core/token'; +import { type StringPatternType } from 'src/core/regexFactory'; +import { EOF_TOKEN, type Token } from 'src/core/token'; import { dedupe } from 'src/utils'; /** diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index aaf58fb672..c3b54ad006 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -1,6 +1,6 @@ import Formatter from 'src/core/Formatter'; import Tokenizer from 'src/core/Tokenizer'; -import type { StringPatternType } from 'src/core/regexFactory'; +import { type StringPatternType } from 'src/core/regexFactory'; import { dedupe } from 'src/utils'; /** diff --git a/src/languages/hive.formatter.ts b/src/languages/hive.formatter.ts index 25a6952525..eb0ff7d741 100644 --- a/src/languages/hive.formatter.ts +++ b/src/languages/hive.formatter.ts @@ -1,6 +1,6 @@ import Formatter from 'src/core/Formatter'; import Tokenizer from 'src/core/Tokenizer'; -import type { StringPatternType } from 'src/core/regexFactory'; +import { type StringPatternType } from 'src/core/regexFactory'; import { dedupe } from 'src/utils'; /** diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index 0cba8c09da..4751fac06c 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1,7 +1,7 @@ import Formatter from 'src/core/Formatter'; import Tokenizer from 'src/core/Tokenizer'; -import { EOF_TOKEN, isToken, Token, TokenType } from 'src/core/token'; -import type { StringPatternType } from 'src/core/regexFactory'; +import { EOF_TOKEN, isToken, type Token, TokenType } from 'src/core/token'; +import { type StringPatternType } from 'src/core/regexFactory'; import { dedupe } from 'src/utils'; /** diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index d4f04092b8..4a5ec7b530 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1,7 +1,7 @@ import Formatter from 'src/core/Formatter'; import Tokenizer from 'src/core/Tokenizer'; -import { EOF_TOKEN, isToken, Token, TokenType } from 'src/core/token'; -import type { StringPatternType } from 'src/core/regexFactory'; +import { EOF_TOKEN, isToken, type Token, TokenType } from 'src/core/token'; +import { type StringPatternType } from 'src/core/regexFactory'; import { dedupe } from 'src/utils'; // TODO: split this into object with function categories diff --git a/src/languages/n1ql.formatter.ts b/src/languages/n1ql.formatter.ts index a34bd0a408..5693050482 100644 --- a/src/languages/n1ql.formatter.ts +++ b/src/languages/n1ql.formatter.ts @@ -1,6 +1,6 @@ import Formatter from 'src/core/Formatter'; import Tokenizer from 'src/core/Tokenizer'; -import type { StringPatternType } from 'src/core/regexFactory'; +import { type StringPatternType } from 'src/core/regexFactory'; import { dedupe } from 'src/utils'; // TODO: split this into object with function categories diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 00755c40cb..f13618bac7 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -1,7 +1,7 @@ import Formatter from 'src/core/Formatter'; import Tokenizer from 'src/core/Tokenizer'; -import { EOF_TOKEN, isReserved, isToken, Token, TokenType } from 'src/core/token'; // convert to partial type import in TS 4.5 -import type { StringPatternType } from 'src/core/regexFactory'; +import { EOF_TOKEN, isReserved, isToken, type Token, TokenType } from 'src/core/token'; +import { type StringPatternType } from 'src/core/regexFactory'; import { dedupe } from 'src/utils'; /** diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index 1cf177f12a..e459bb792a 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1,6 +1,6 @@ import Formatter from 'src/core/Formatter'; import Tokenizer from 'src/core/Tokenizer'; -import type { StringPatternType } from 'src/core/regexFactory'; +import { type StringPatternType } from 'src/core/regexFactory'; import { dedupe } from 'src/utils'; /** diff --git a/src/languages/redshift.formatter.ts b/src/languages/redshift.formatter.ts index b4bc3f8bc3..d80a82ac10 100644 --- a/src/languages/redshift.formatter.ts +++ b/src/languages/redshift.formatter.ts @@ -1,6 +1,6 @@ import Formatter from 'src/core/Formatter'; import Tokenizer from 'src/core/Tokenizer'; -import type { StringPatternType } from 'src/core/regexFactory'; +import { type StringPatternType } from 'src/core/regexFactory'; import { dedupe } from 'src/utils'; /** diff --git a/src/languages/spark.formatter.ts b/src/languages/spark.formatter.ts index 3df212ee6c..98590b4f3c 100644 --- a/src/languages/spark.formatter.ts +++ b/src/languages/spark.formatter.ts @@ -1,7 +1,7 @@ import Formatter from 'src/core/Formatter'; import Tokenizer from 'src/core/Tokenizer'; -import { EOF_TOKEN, isToken, Token, TokenType } from 'src/core/token'; // convert to partial type import in TS 4.5 -import type { StringPatternType } from 'src/core/regexFactory'; +import { EOF_TOKEN, isToken, type Token, TokenType } from 'src/core/token'; +import { type StringPatternType } from 'src/core/regexFactory'; import { dedupe } from 'src/utils'; /** diff --git a/src/languages/sql.formatter.ts b/src/languages/sql.formatter.ts index 43b4c2ce03..a22a4077a2 100644 --- a/src/languages/sql.formatter.ts +++ b/src/languages/sql.formatter.ts @@ -1,6 +1,6 @@ import Formatter from 'src/core/Formatter'; import Tokenizer from 'src/core/Tokenizer'; -import type { StringPatternType } from 'src/core/regexFactory'; +import { type StringPatternType } from 'src/core/regexFactory'; import { dedupe } from 'src/utils'; /** diff --git a/src/languages/sqlite.formatter.ts b/src/languages/sqlite.formatter.ts index 8a4100800c..f90c9eb366 100644 --- a/src/languages/sqlite.formatter.ts +++ b/src/languages/sqlite.formatter.ts @@ -1,5 +1,5 @@ import Formatter from 'src/core/Formatter'; -import { StringPatternType } from 'src/core/regexFactory'; +import { type StringPatternType } from 'src/core/regexFactory'; import Tokenizer from 'src/core/Tokenizer'; // https://jakewheat.github.io/sql-overview/sql-2008-foundation-grammar.html#reserved-word diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index 8932def52c..09e0358361 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1,6 +1,6 @@ import Formatter from 'src/core/Formatter'; import Tokenizer from 'src/core/Tokenizer'; -import type { StringPatternType } from 'src/core/regexFactory'; +import { type StringPatternType } from 'src/core/regexFactory'; import { dedupe } from 'src/utils'; /** diff --git a/src/sqlFormatter.ts b/src/sqlFormatter.ts index 7bfa5b0bee..b210538b08 100644 --- a/src/sqlFormatter.ts +++ b/src/sqlFormatter.ts @@ -12,7 +12,7 @@ import SqliteFormatter from 'src/languages/sqlite.formatter'; import SqlFormatter from 'src/languages/sql.formatter'; import TSqlFormatter from 'src/languages/tsql.formatter'; -import { FormatOptions } from './types'; +import type { FormatOptions } from './types'; import { isNumber } from './utils'; export const formatters = { diff --git a/src/types.ts b/src/types.ts index f1e0aad8f0..e321c58656 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -import { ParamItems } from './core/Params'; +import { type ParamItems } from './core/Params'; export type IndentStyle = 'standard' | 'tabularLeft' | 'tabularRight'; From 5d04270e88d51b46bebcccabf1ee13aaa084b1cf Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Mon, 30 May 2022 16:36:59 -0700 Subject: [PATCH 155/334] add webpack alias for absolute imports --- webpack.common.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/webpack.common.js b/webpack.common.js index dfe84c15f7..aba4152caa 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -10,6 +10,9 @@ module.exports = { }, resolve: { extensions: ['.js', '.ts'], + alias: { + src: path.resolve(__dirname, 'src/'), + }, }, module: { rules: [ From ae4755117c1ac0786e4043ebef4c961f11d5431f Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Mon, 30 May 2022 17:30:02 -0700 Subject: [PATCH 156/334] update jest config to alias absolute path --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 986997db70..9634501011 100644 --- a/package.json +++ b/package.json @@ -144,6 +144,9 @@ "collectCoverage": true, "collectCoverageFrom": [ "src/**/*.ts" - ] + ], + "moduleNameMapper": { + "src/(.*)": "/src/$1" + } } } From fc6335f1a0332d6574fe7852e3b65da11ce34542 Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Mon, 30 May 2022 17:40:00 -0700 Subject: [PATCH 157/334] :recycle: --- src/core/Formatter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Formatter.ts b/src/core/Formatter.ts index add598f945..1803c3fd6a 100644 --- a/src/core/Formatter.ts +++ b/src/core/Formatter.ts @@ -1,6 +1,6 @@ +import type { FormatOptions } from 'src/types'; import Params from './Params'; import Tokenizer from './Tokenizer'; -import type { FormatOptions } from '../types'; import formatCommaPositions from './formatCommaPositions'; import formatAliasPositions from './formatAliasPositions'; import AsTokenFactory from './AsTokenFactory'; From 4f2fae72cccbe9406622316a1322c8739e35e0e2 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 1 Jun 2022 10:52:30 +0300 Subject: [PATCH 158/334] Remove automatic pre-commit and pre-push hooks Instead allowing each dev to set up his own hooks, however he prefers. --- package.json | 4 -- yarn.lock | 121 ++------------------------------------------------- 2 files changed, 3 insertions(+), 122 deletions(-) diff --git a/package.json b/package.json index 9634501011..2cbcc5aae1 100644 --- a/package.json +++ b/package.json @@ -88,8 +88,6 @@ "build": "npm-run-all --parallel build:commonjs build:umd build:umd:min", "release": "release-it" }, - "pre-commit": "pre-commit", - "pre-push": "build", "repository": { "type": "git", "url": "https://github.com/zeroturnaround/sql-formatter.git" @@ -124,8 +122,6 @@ "eslint-plugin-prettier": "^4.0.0", "jest": "^28.0.2", "npm-run-all": "^4.1.5", - "pre-commit": "^1.2.2", - "pre-push": "^0.1.2", "prettier": "^2.0.5", "release-it": "^14.11.7", "rimraf": "^3.0.2", diff --git a/yarn.lock b/yarn.lock index 8a5e8c346c..638459a01e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2357,16 +2357,6 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concat-stream@^1.4.7: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - configstore@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" @@ -2399,11 +2389,6 @@ core-js-compat@^3.20.2, core-js-compat@^3.21.0: browserslist "^4.20.2" semver "7.0.0" -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - cosmiconfig@7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" @@ -2415,15 +2400,6 @@ cosmiconfig@7.0.1: path-type "^4.0.0" yaml "^1.10.0" -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -3426,7 +3402,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2, inherits@^2.0.3, inherits@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -3717,11 +3693,6 @@ isarray@^2.0.5: resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -4374,14 +4345,6 @@ lowercase-keys@^2.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== -lru-cache@^4.0.1: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -4679,11 +4642,6 @@ os-name@4.0.1: macos-release "^2.5.0" windows-release "^4.0.0" -os-shim@^0.1.2: - version "0.1.3" - resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917" - integrity sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc= - os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -4866,24 +4824,6 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -pre-commit@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/pre-commit/-/pre-commit-1.2.2.tgz#dbcee0ee9de7235e57f79c56d7ce94641a69eec6" - integrity sha1-287g7p3nI15X95xW186UZBpp7sY= - dependencies: - cross-spawn "^5.0.1" - spawn-sync "^1.0.15" - which "1.2.x" - -pre-push@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/pre-push/-/pre-push-0.1.2.tgz#185bbde6e8dfe2ab6dff937b674f0cbfc5a98295" - integrity sha512-WymiU20I3W1yGV4VEqa+xOqaqGHYUz49R4ARvEdmYPgL07E/Gn7NLewI9k5g6KUc2EOaWE42rBb7nfVKYtkpCA== - dependencies: - cross-spawn "^5.0.1" - spawn-sync "^1.0.15" - which "1.2.x" - prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -4925,11 +4865,6 @@ pretty-format@^28.0.2: ansi-styles "^5.0.0" react-is "^18.0.0" -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - promise.allsettled@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.5.tgz#2443f3d4b2aa8dfa560f6ac2aa6c4ea999d75f53" @@ -4955,11 +4890,6 @@ protocols@^1.1.0, protocols@^1.4.0: resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.8.tgz#48eea2d8f58d9644a4a32caae5d5db290a075ce8" integrity sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg== -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -5038,19 +4968,6 @@ read-pkg@^3.0.0: normalize-package-data "^2.3.2" path-type "^3.0.0" -readable-stream@^2.2.2: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - readable-stream@^3.4.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" @@ -5284,7 +5201,7 @@ safe-buffer@^5.1.0, safe-buffer@~5.2.0: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== @@ -5462,14 +5379,6 @@ source-map@~0.8.0-beta.0: dependencies: whatwg-url "^7.0.0" -spawn-sync@^1.0.15: - version "1.0.15" - resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476" - integrity sha1-sAeZVX63+wyDdsKdROih6mfldHY= - dependencies: - concat-stream "^1.4.7" - os-shim "^0.1.2" - spdx-correct@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" @@ -5567,13 +5476,6 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -5824,11 +5726,6 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - typescript@^4.3.5: version "4.6.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" @@ -5918,7 +5815,7 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" -util-deprecate@^1.0.1, util-deprecate@~1.0.1: +util-deprecate@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= @@ -6071,13 +5968,6 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" -which@1.2.x: - version "1.2.14" - resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" - integrity sha1-mofEN48D6CfOyvGs31bHNsAcFOU= - dependencies: - isexe "^2.0.0" - which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -6163,11 +6053,6 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" From f7d5f82fa20af1b805ce687196bb8dd36a019646 Mon Sep 17 00:00:00 2001 From: inferrinizzard Date: Wed, 1 Jun 2022 13:08:48 -0700 Subject: [PATCH 159/334] bump version --- vscode/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vscode/package.json b/vscode/package.json index 612164fef8..fe037d7f27 100644 --- a/vscode/package.json +++ b/vscode/package.json @@ -2,7 +2,7 @@ "name": "prettier-sql-vscode", "displayName": "Prettier SQL VSCode", "description": "VSCode Extension to format SQL files", - "version": "0.3.0", + "version": "1.0.0", "publisher": "inferrinizzard", "author": { "name": "inferrinizzard" From ea15b525156ab6c1356d1a56ded3a2f17a0d0d39 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Sun, 5 Jun 2022 20:52:53 +0300 Subject: [PATCH 160/334] Fix typo in comment --- src/core/Tokenizer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index deb18e3279..a84d0461d7 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -42,7 +42,7 @@ interface TokenizerOptions { quotedPlaceholderTypes?: (':' | '@' | '$')[]; // Line comment types to support, defaults to -- lineCommentTypes?: string[]; - // Additioanl characters to support in identifiers + // Additional characters to support in identifiers specialIdentChars?: regexFactory.IdentChars; // Additional multi-character operators to support, in addition to <=, >=, <>, != operators?: string[]; From ac4b39d0ec8d1ec043dedd609dcc940343f4fad6 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Sun, 5 Jun 2022 21:19:32 +0300 Subject: [PATCH 161/334] Document SQL variables syntax --- sql/syntax.md | 1 + sql/variables.md | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 sql/variables.md diff --git a/sql/syntax.md b/sql/syntax.md index 683afec472..b367e82bb5 100644 --- a/sql/syntax.md +++ b/sql/syntax.md @@ -4,5 +4,6 @@ Reference of SQL syntax variations. - [Identifiers](./identifiers.md) - [Parameters](./parameters.md) +- [Variables](./variables.md) - [Strings](./strings.md) - [SELECT](./select.md) diff --git a/sql/variables.md b/sql/variables.md new file mode 100644 index 0000000000..cfa0b64146 --- /dev/null +++ b/sql/variables.md @@ -0,0 +1,24 @@ +# Variables + +- [BigQuery][]: identifier syntax +- [DB2][]: identifier syntax +- [Hive][]: `${hivevar:name}` or `${hiveconf:name}`. Although referred to as variables, they are more akin to prepared statement parameters. +- [MariaDB][]: `@name` (where the name consists of alphanumeric characters, `.`, `_`, and `$`), `@'var name'`, `@"var name"`, `` @`var name` `` (can be quoted as string or identifier) +- [MySQL][]: Same as MariaDB +- N1QL: _N/A_ +- [PL/SQL][]: `&name` substitution variables and `:name` bind variables. +- [PostgreSQL][]: identifier syntax (only in PL/pgSQL). +- Redshift: _N/A_ +- [Spark][]: `${name}` Like with Hive, these seem to be more similar to prepared statement properties. +- SQLite: _N/A_ +- [Transact-SQL][]: `@name` (using identifier syntax for name) + +[bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language +[db2]: https://www.ibm.com/docs/en/db2-for-zos/11?topic=pl-references-sql-parameters-variables +[hive]: https://stackoverflow.com/questions/12464636/how-to-set-variables-in-hive-scripts +[mariadb]: https://mariadb.com/kb/en/user-defined-variables/ +[mysql]: https://dev.mysql.com/doc/refman/8.0/en/user-variables.html +[pl/sql]: https://stackoverflow.com/a/22171706/15982 +[postgresql]: https://www.postgresql.org/docs/current/sql-declare.html +[spark]: https://stackoverflow.com/questions/65019868/how-to-use-variables-in-sql-queries +[transact-sql]: https://docs.microsoft.com/en-us/sql/relational-databases/databases/database-identifiers?view=sql-server-ver15 From b77abb040e1274c2066a541b9b6773467a264996 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Sun, 5 Jun 2022 21:27:47 +0300 Subject: [PATCH 162/334] Fix spelling of consecutive --- test/features/identifiers.ts | 2 +- test/features/strings.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/features/identifiers.ts b/test/features/identifiers.ts index 8c0267defa..4f6cbae0c8 100644 --- a/test/features/identifiers.ts +++ b/test/features/identifiers.ts @@ -71,7 +71,7 @@ export default function supportsIdentifiers(format: FormatFn, identifierTypes: I `); }); - it('detects consequitive U&"" identifiers as separate ones', () => { + it('detects consecuitive U&"" identifiers as separate ones', () => { expect(format('U&"foo"U&"bar"')).toBe('U&"foo" U&"bar"'); }); } diff --git a/test/features/strings.ts b/test/features/strings.ts index 29e2a55d17..d517b725ff 100644 --- a/test/features/strings.ts +++ b/test/features/strings.ts @@ -52,7 +52,7 @@ export default function supportsStrings(format: FormatFn, stringTypes: StringTyp `); }); - it("detects consequitive U&'' strings as separate ones", () => { + it("detects consecutive U&'' strings as separate ones", () => { expect(format("U&'foo'U&'bar'")).toBe("U&'foo' U&'bar'"); }); } @@ -82,7 +82,7 @@ export default function supportsStrings(format: FormatFn, stringTypes: StringTyp `); }); - it("detects consequitive N'' strings as separate ones", () => { + it("detects consecutive N'' strings as separate ones", () => { expect(format("N'foo'N'bar'")).toBe("N'foo' N'bar'"); }); } @@ -99,7 +99,7 @@ export default function supportsStrings(format: FormatFn, stringTypes: StringTyp `); }); - it("detects consequitive X'' strings as separate ones", () => { + it("detects consecutive X'' strings as separate ones", () => { expect(format("X'AE01'X'01F6'")).toBe("X'AE01' X'01F6'"); }); } From 316df6f24835bb637fcac675443bc786063518d3 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Sun, 5 Jun 2022 21:29:14 +0300 Subject: [PATCH 163/334] Use interface instead of type for consistency --- src/core/Tokenizer.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index a84d0461d7..cfe006b333 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -52,7 +52,10 @@ interface TokenizerOptions { preprocess?: (tokens: Token[]) => Token[]; } -type PlaceholderPattern = { regex: RegExp; parseKey: (s: string) => string }; +interface PlaceholderPattern { + regex: RegExp; + parseKey: (s: string) => string; +} /** Converts SQL language string into a token stream */ export default class Tokenizer { From dd2ec3b124f7306144a57dfdcedc199f24b32440 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Sun, 5 Jun 2022 21:59:57 +0300 Subject: [PATCH 164/334] Use absolute path import --- test/features/identifiers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/features/identifiers.ts b/test/features/identifiers.ts index 4f6cbae0c8..f0f666e9ec 100644 --- a/test/features/identifiers.ts +++ b/test/features/identifiers.ts @@ -1,6 +1,6 @@ import { expect } from '@jest/globals'; import dedent from 'dedent-js'; -import { FormatFn } from '../../src/sqlFormatter'; +import { FormatFn } from 'src/sqlFormatter'; type IdentType = '""' | '``' | '[]' | 'U&""'; From 0941b4c6c50fcd8d9799e36090dfc30a26a81c4a Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Mon, 6 Jun 2022 10:30:38 +0300 Subject: [PATCH 165/334] Shorter syntax for defining strings with prefixes --- src/core/regexFactory.ts | 8 ++++++-- src/languages/bigquery.formatter.ts | 24 ++++-------------------- src/languages/db2.formatter.ts | 10 +--------- src/languages/mariadb.formatter.ts | 2 +- src/languages/mysql.formatter.ts | 2 +- src/languages/plsql.formatter.ts | 2 +- src/languages/postgresql.formatter.ts | 11 ++--------- src/languages/spark.formatter.ts | 2 +- src/languages/sql.formatter.ts | 2 +- src/languages/sqlite.formatter.ts | 2 +- src/languages/tsql.formatter.ts | 2 +- 11 files changed, 20 insertions(+), 47 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 36ef8f74a9..1b77c31d57 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -99,7 +99,7 @@ export type PlainQuoteType = keyof typeof quotePatterns; export type PrefixedQuoteType = { quote: PlainQuoteType; - prefix: string; + prefixes: string[]; }; export type QuoteType = PlainQuoteType | PrefixedQuoteType; @@ -111,11 +111,15 @@ const toCaseInsensitivePattern = (prefix: string): string => .map(char => '[' + char.toUpperCase() + char.toLowerCase() + ']') .join(''); +// Converts ["a", "b"] to "(?:[Aa]|[Bb|)" +const prefixesPattern = (prefixes: string[]): string => + '(?:' + prefixes.map(toCaseInsensitivePattern).join('|') + '|)'; + const createSingleQuotePattern = (type: QuoteType): string => { if (typeof type === 'string') { return '(' + quotePatterns[type] + ')'; } else { - return '(' + toCaseInsensitivePattern(type.prefix) + quotePatterns[type.quote] + ')'; + return '(' + prefixesPattern(type.prefixes) + quotePatterns[type.quote] + ')'; } }; diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index 21e41cd0f5..80a2a673e6 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -839,26 +839,10 @@ export default class BigQueryFormatter extends Formatter { stringTypes: [ // The triple-quoted strings are listed first, so they get matched first. // Otherwise the first two quotes of """ will get matched as an empty "" string. - '""".."""', - { prefix: 'R', quote: '""".."""' }, - { prefix: 'B', quote: '""".."""' }, - { prefix: 'RB', quote: '""".."""' }, - { prefix: 'BR', quote: '""".."""' }, - "'''..'''", - { prefix: 'R', quote: "'''..'''" }, - { prefix: 'B', quote: "'''..'''" }, - { prefix: 'RB', quote: "'''..'''" }, - { prefix: 'BR', quote: "'''..'''" }, - '""', - { prefix: 'R', quote: '""' }, - { prefix: 'B', quote: '""' }, - { prefix: 'RB', quote: '""' }, - { prefix: 'BR', quote: '""' }, - "''", - { prefix: 'R', quote: "''" }, - { prefix: 'B', quote: "''" }, - { prefix: 'RB', quote: "''" }, - { prefix: 'BR', quote: "''" }, + { quote: '""".."""', prefixes: ['R', 'B', 'RB', 'BR'] }, + { quote: "'''..'''", prefixes: ['R', 'B', 'RB', 'BR'] }, + { quote: '""', prefixes: ['R', 'B', 'RB', 'BR'] }, + { quote: "''", prefixes: ['R', 'B', 'RB', 'BR'] }, ], identifierTypes: ['``'], positionalPlaceholders: true, diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index 18c743e9a0..a709443a21 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -869,15 +869,7 @@ export default class Db2Formatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), - stringTypes: [ - "''", - { prefix: 'X', quote: "''" }, - { prefix: 'G', quote: "''" }, - { prefix: 'N', quote: "''" }, - { prefix: 'GX', quote: "''" }, - { prefix: 'UX', quote: "''" }, - { prefix: 'U&', quote: "''" }, - ], + stringTypes: [{ quote: "''", prefixes: ['X', 'G', 'N', 'GX', 'UX', 'U&'] }], identifierTypes: [`""`], positionalPlaceholders: true, namedPlaceholderTypes: [':'], diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index 329abaeae9..d8a441ab96 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1164,7 +1164,7 @@ export default class MariaDbFormatter extends Formatter { reservedDependentClauses, reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), - stringTypes: ["''", '""', { prefix: 'X', quote: "''" }], + stringTypes: ['""', { quote: "''", prefixes: ['X'] }], identifierTypes: ['``'], positionalPlaceholders: true, lineCommentTypes: ['--', '#'], diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index 2e3e697f79..00f1b90631 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1327,7 +1327,7 @@ export default class MySqlFormatter extends Formatter { reservedDependentClauses, reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), - stringTypes: ["''", '""', { prefix: 'X', quote: "''" }], + stringTypes: ['""', { quote: "''", prefixes: ['X'] }], identifierTypes: ['``'], positionalPlaceholders: true, lineCommentTypes: ['--', '#'], diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 8a042e03a3..7af8b26864 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -462,7 +462,7 @@ export default class PlSqlFormatter extends Formatter { reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe(reservedKeywords), // TODO: support custom-delimited strings: Q'{..}' q'<..>' etc - stringTypes: ["''", { prefix: 'N', quote: "''" }], + stringTypes: [{ quote: "''", prefixes: ['N'] }], identifierTypes: [`""`], numberedPlaceholderTypes: [':'], namedPlaceholderTypes: [':'], diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index e2c3f70c76..752fab4fee 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1681,15 +1681,8 @@ export default class PostgreSqlFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...reservedKeywords, ]), - stringTypes: [ - "''", - '$$', - { prefix: 'U&', quote: "''" }, - { prefix: 'E', quote: "''" }, - { prefix: 'X', quote: "''" }, - { prefix: 'B', quote: "''" }, - ], - identifierTypes: [`""`, { prefix: 'U&', quote: '""' }], + stringTypes: [{ quote: "''", prefixes: ['U&', 'E', 'X', 'B'] }, '$$'], + identifierTypes: [{ quote: '""', prefixes: ['U&'] }], numberedPlaceholderTypes: ['$'], operators: PostgreSqlFormatter.operators, }); diff --git a/src/languages/spark.formatter.ts b/src/languages/spark.formatter.ts index bbcb3f9801..1e4628fcf3 100644 --- a/src/languages/spark.formatter.ts +++ b/src/languages/spark.formatter.ts @@ -789,7 +789,7 @@ export default class SparkFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...reservedKeywords, ]), - stringTypes: ["''", { prefix: 'X', quote: "''" }], + stringTypes: [{ quote: "''", prefixes: ['X'] }], identifierTypes: ['``'], operators: SparkFormatter.operators, preprocess, diff --git a/src/languages/sql.formatter.ts b/src/languages/sql.formatter.ts index 5443222b74..079b519af2 100644 --- a/src/languages/sql.formatter.ts +++ b/src/languages/sql.formatter.ts @@ -377,7 +377,7 @@ export default class SqlFormatter extends Formatter { reservedBinaryCommands, reservedDependentClauses, reservedKeywords: dedupe(reservedKeywords), - stringTypes: ["''", { prefix: 'X', quote: "''" }], + stringTypes: [{ quote: "''", prefixes: ['X'] }], identifierTypes: [`""`, '``'], positionalPlaceholders: true, }); diff --git a/src/languages/sqlite.formatter.ts b/src/languages/sqlite.formatter.ts index 313229dac0..9e26c14300 100644 --- a/src/languages/sqlite.formatter.ts +++ b/src/languages/sqlite.formatter.ts @@ -430,7 +430,7 @@ export default class SqliteFormatter extends Formatter { reservedDependentClauses, // https://www.sqlite.org/lang_keywords.html reservedKeywords: [...standardReservedWords, ...nonStandardSqliteReservedWords], - stringTypes: ["''", { prefix: 'X', quote: "''" }], + stringTypes: [{ quote: "''", prefixes: ['X'] }], identifierTypes: [`""`, '``', '[]'], // https://www.sqlite.org/lang_expr.html#parameters positionalPlaceholders: true, diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index f5bc65a05e..7c2d908ae8 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1242,7 +1242,7 @@ export default class TSqlFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), - stringTypes: ["''", { prefix: 'N', quote: "''" }], + stringTypes: [{ quote: "''", prefixes: ['N'] }], identifierTypes: [`""`, '[]'], namedPlaceholderTypes: ['@'], quotedPlaceholderTypes: ['@'], From 5e12c3a17a51060c4b2f5538e1cfe211244a072d Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 8 Jun 2022 11:54:56 +0300 Subject: [PATCH 166/334] Fix demo link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c02aec755f..7304670e02 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ It does not support: - Stored procedures. - Changing of the delimiter type to something else than `;`. -→ [Try the demo.](https://zeroturnaround.github.io/sql-formatter) +→ [Try the demo.](https://sql-formatter-org.github.io/sql-formatter) ## Install From 7f86d5de1929d80bfeffbf4e6172fcb72ba436ff Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 8 Jun 2022 13:01:47 +0300 Subject: [PATCH 167/334] Clarify substitution variables in Hive, Spark, PL/SQL --- sql/variables.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sql/variables.md b/sql/variables.md index cfa0b64146..41953333bc 100644 --- a/sql/variables.md +++ b/sql/variables.md @@ -2,17 +2,21 @@ - [BigQuery][]: identifier syntax - [DB2][]: identifier syntax -- [Hive][]: `${hivevar:name}` or `${hiveconf:name}`. Although referred to as variables, they are more akin to prepared statement parameters. +- [Hive][]: `${hivevar:name}`, `${hiveconf:name}` or `${name}`. These are substitution variables (as in Oracle SQL terminology). + They behave more like string-interpolation, that is, the values aren't automatically escaped by the system. + A common example is to place the variable inside a string: `SELECT * FROM users WHERE name = '${hivevar:USER_NAME}'`. + Also one can use the variable to parameterize table or column name (`SELECT * FROM ${hivevar:my_table}`). - [MariaDB][]: `@name` (where the name consists of alphanumeric characters, `.`, `_`, and `$`), `@'var name'`, `@"var name"`, `` @`var name` `` (can be quoted as string or identifier) - [MySQL][]: Same as MariaDB - N1QL: _N/A_ -- [PL/SQL][]: `&name` substitution variables and `:name` bind variables. +- [PL/SQL][]: `&name` substitution variables (and `:name` bind variables - see [parameters][]). - [PostgreSQL][]: identifier syntax (only in PL/pgSQL). - Redshift: _N/A_ -- [Spark][]: `${name}` Like with Hive, these seem to be more similar to prepared statement properties. +- [Spark][]: `${name}` Like with Hive, these are substitution variables. - SQLite: _N/A_ - [Transact-SQL][]: `@name` (using identifier syntax for name) +[parameters]: ./parameters.md [bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language [db2]: https://www.ibm.com/docs/en/db2-for-zos/11?topic=pl-references-sql-parameters-variables [hive]: https://stackoverflow.com/questions/12464636/how-to-set-variables-in-hive-scripts From 9838251a977d4e539f2e3c7dd07c983b23ea7ea6 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 8 Jun 2022 13:28:55 +0300 Subject: [PATCH 168/334] Add ${name} variable support for Hive and Spark --- src/core/StatementFormatter.ts | 1 + src/core/Tokenizer.ts | 6 ++++++ src/core/regexFactory.ts | 2 ++ src/core/token.ts | 1 + src/languages/hive.formatter.ts | 1 + src/languages/spark.formatter.ts | 1 + test/hive.test.ts | 19 +++++++++++++++++++ test/spark.test.ts | 17 +++++++++++++++++ 8 files changed, 48 insertions(+) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index c234616dfa..394f952fb3 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -91,6 +91,7 @@ export default class StatementFormatter { case TokenType.IDENT: case TokenType.STRING: case TokenType.NUMBER: + case TokenType.VARIABLE: return this.formatWord(token); default: throw new Error(`Unexpected token type: ${token.type}`); diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index cfe006b333..d583688b87 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -27,6 +27,8 @@ interface TokenizerOptions { stringTypes: regexFactory.QuoteType[]; // Types of quotes to use for quoted identifiers identifierTypes: regexFactory.QuoteType[]; + // Types of quotes to use for variables + variableTypes?: regexFactory.QuoteType[]; // Open-parenthesis characters, like: (, [, { blockStart?: string[]; // Close-parenthesis characters, like: ), ], } @@ -75,6 +77,9 @@ export default class Tokenizer { this.REGEX_MAP = { [TokenType.IDENT]: regexFactory.createIdentRegex(cfg.specialIdentChars), [TokenType.STRING]: regexFactory.createQuoteRegex(cfg.stringTypes), + [TokenType.VARIABLE]: cfg.variableTypes + ? regexFactory.createQuoteRegex(cfg.variableTypes) + : NULL_REGEX, [TokenType.RESERVED_KEYWORD]: regexFactory.createReservedWordRegex( cfg.reservedKeywords, cfg.specialIdentChars @@ -200,6 +205,7 @@ export default class Tokenizer { this.matchToken(TokenType.BLOCK_COMMENT, input) || this.matchToken(TokenType.STRING, input) || this.matchQuotedIdentToken(input) || + this.matchToken(TokenType.VARIABLE, input) || this.matchToken(TokenType.BLOCK_START, input) || this.matchToken(TokenType.BLOCK_END, input) || this.matchPlaceholderToken(input) || diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 1b77c31d57..f790ced195 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -86,6 +86,7 @@ export const createIdentPattern = (specialChars: IdentChars = {}): string => { // 5. PostgreSQL dollar-quoted // 6. BigQuery '''triple-quoted''' // 7. BigQuery """triple-quoted""" +// 8. Hive and Spark variables: ${name} const quotePatterns = { '``': '(`[^`]*($|`))+', '[]': '(\\[[^\\]]*($|\\]))(\\][^\\]]*($|\\]))*', @@ -94,6 +95,7 @@ const quotePatterns = { '$$': '(?\\$\\w*\\$)[\\s\\S]*?(?:\\k|$)', "'''..'''": "'''[^\\\\]*?(?:\\\\.[^\\\\]*?)*?('''|$)", '""".."""': '"""[^\\\\]*?(?:\\\\.[^\\\\]*?)*?("""|$)', + '${}': '(\\$\\{[^\\}]*($|\\}))', }; export type PlainQuoteType = keyof typeof quotePatterns; diff --git a/src/core/token.ts b/src/core/token.ts index 99d1d7fe52..8b3f4849c9 100644 --- a/src/core/token.ts +++ b/src/core/token.ts @@ -2,6 +2,7 @@ export enum TokenType { IDENT = 'IDENT', STRING = 'STRING', + VARIABLE = 'VARIABLE', RESERVED_KEYWORD = 'RESERVED_KEYWORD', RESERVED_LOGICAL_OPERATOR = 'RESERVED_LOGICAL_OPERATOR', RESERVED_DEPENDENT_CLAUSE = 'RESERVED_DEPENDENT_CLAUSE', diff --git a/src/languages/hive.formatter.ts b/src/languages/hive.formatter.ts index 29ed7d62fe..e8a02db10e 100644 --- a/src/languages/hive.formatter.ts +++ b/src/languages/hive.formatter.ts @@ -626,6 +626,7 @@ export default class HiveFormatter extends Formatter { ]), stringTypes: ['""', "''"], identifierTypes: ['``'], + variableTypes: ['${}'], operators: HiveFormatter.operators, }); } diff --git a/src/languages/spark.formatter.ts b/src/languages/spark.formatter.ts index 1e4628fcf3..187dd3d6b2 100644 --- a/src/languages/spark.formatter.ts +++ b/src/languages/spark.formatter.ts @@ -791,6 +791,7 @@ export default class SparkFormatter extends Formatter { ]), stringTypes: [{ quote: "''", prefixes: ['X'] }], identifierTypes: ['``'], + variableTypes: ['${}'], operators: SparkFormatter.operators, preprocess, }); diff --git a/test/hive.test.ts b/test/hive.test.ts index 2a02d52e5c..4e786d2818 100644 --- a/test/hive.test.ts +++ b/test/hive.test.ts @@ -1,3 +1,5 @@ +import dedent from 'dedent-js'; + import { format as originalFormat, FormatFn } from 'src/sqlFormatter'; import HiveFormatter from 'src/languages/hive.formatter'; @@ -35,4 +37,21 @@ describe('HiveFormatter', () => { 'Unexpected "params" option. Prepared statement placeholders not supported for Hive.' ); }); + + // eslint-disable-next-line no-template-curly-in-string + it('recognizes ${hivevar:name} substitution variables', () => { + const result = format( + // eslint-disable-next-line no-template-curly-in-string + "SELECT ${var1}, ${ var 2 } FROM ${hivevar:table_name} WHERE name = '${hivevar:name}';" + ); + expect(result).toBe(dedent` + SELECT + \${var1}, + \${ var 2 } + FROM + \${hivevar:table_name} + WHERE + name = '\${hivevar:name}'; + `); + }); }); diff --git a/test/spark.test.ts b/test/spark.test.ts index 5e1a5d9e17..2d468b5d98 100644 --- a/test/spark.test.ts +++ b/test/spark.test.ts @@ -88,4 +88,21 @@ describe('SparkFormatter', () => { 'Unexpected "params" option. Prepared statement placeholders not supported for Spark.' ); }); + + // eslint-disable-next-line no-template-curly-in-string + it('recognizes ${name} substitution variables', () => { + const result = format( + // eslint-disable-next-line no-template-curly-in-string + "SELECT ${var1}, ${ var 2 } FROM ${table_name} WHERE name = '${name}';" + ); + expect(result).toBe(dedent` + SELECT + \${var1}, + \${ var 2 } + FROM + \${table_name} + WHERE + name = '\${name}'; + `); + }); }); From a73ae55accc45df6f01fdee63f8449dd718897fe Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 8 Jun 2022 14:54:23 +0300 Subject: [PATCH 169/334] Implement ${name} variables using required quote prefixes --- src/core/regexFactory.ts | 11 ++++++----- src/languages/hive.formatter.ts | 2 +- src/languages/spark.formatter.ts | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index f790ced195..6811d8bcd6 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -95,13 +95,14 @@ const quotePatterns = { '$$': '(?\\$\\w*\\$)[\\s\\S]*?(?:\\k|$)', "'''..'''": "'''[^\\\\]*?(?:\\\\.[^\\\\]*?)*?('''|$)", '""".."""': '"""[^\\\\]*?(?:\\\\.[^\\\\]*?)*?("""|$)', - '${}': '(\\$\\{[^\\}]*($|\\}))', + '{}': '(\\{[^\\}]*($|\\}))', }; export type PlainQuoteType = keyof typeof quotePatterns; export type PrefixedQuoteType = { quote: PlainQuoteType; prefixes: string[]; + required?: boolean; // True when prefix is required }; export type QuoteType = PlainQuoteType | PrefixedQuoteType; @@ -113,15 +114,15 @@ const toCaseInsensitivePattern = (prefix: string): string => .map(char => '[' + char.toUpperCase() + char.toLowerCase() + ']') .join(''); -// Converts ["a", "b"] to "(?:[Aa]|[Bb|)" -const prefixesPattern = (prefixes: string[]): string => - '(?:' + prefixes.map(toCaseInsensitivePattern).join('|') + '|)'; +// Converts ["a", "b"] to "(?:[Aa]|[Bb]|)" or "(?:[Aa]|[Bb])" when required = true +const prefixesPattern = ({ prefixes, required }: PrefixedQuoteType): string => + '(?:' + prefixes.map(toCaseInsensitivePattern).join('|') + (required ? '' : '|') + ')'; const createSingleQuotePattern = (type: QuoteType): string => { if (typeof type === 'string') { return '(' + quotePatterns[type] + ')'; } else { - return '(' + prefixesPattern(type.prefixes) + quotePatterns[type.quote] + ')'; + return '(' + prefixesPattern(type) + quotePatterns[type.quote] + ')'; } }; diff --git a/src/languages/hive.formatter.ts b/src/languages/hive.formatter.ts index e8a02db10e..e45de9b352 100644 --- a/src/languages/hive.formatter.ts +++ b/src/languages/hive.formatter.ts @@ -626,7 +626,7 @@ export default class HiveFormatter extends Formatter { ]), stringTypes: ['""', "''"], identifierTypes: ['``'], - variableTypes: ['${}'], + variableTypes: [{ quote: '{}', prefixes: ['$'], required: true }], operators: HiveFormatter.operators, }); } diff --git a/src/languages/spark.formatter.ts b/src/languages/spark.formatter.ts index 187dd3d6b2..b30afbe707 100644 --- a/src/languages/spark.formatter.ts +++ b/src/languages/spark.formatter.ts @@ -791,7 +791,7 @@ export default class SparkFormatter extends Formatter { ]), stringTypes: [{ quote: "''", prefixes: ['X'] }], identifierTypes: ['``'], - variableTypes: ['${}'], + variableTypes: [{ quote: '{}', prefixes: ['$'], required: true }], operators: SparkFormatter.operators, preprocess, }); From 6c1ec4e6f3d347e3126cdb60a4f85bfb7008ac13 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 8 Jun 2022 15:04:22 +0300 Subject: [PATCH 170/334] Support @"name" variables for MySQL & MariaDB --- src/languages/mariadb.formatter.ts | 5 +++++ src/languages/mysql.formatter.ts | 5 +++++ test/behavesLikeMariaDbFormatter.ts | 23 +++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index d8a441ab96..a7a8a68019 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1166,6 +1166,11 @@ export default class MariaDbFormatter extends Formatter { reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: ['""', { quote: "''", prefixes: ['X'] }], identifierTypes: ['``'], + variableTypes: [ + { quote: '""', prefixes: ['@'], required: true }, + { quote: "''", prefixes: ['@'], required: true }, + { quote: '``', prefixes: ['@'], required: true }, + ], positionalPlaceholders: true, lineCommentTypes: ['--', '#'], operators: MariaDbFormatter.operators, diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index 00f1b90631..2acdc872aa 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1329,6 +1329,11 @@ export default class MySqlFormatter extends Formatter { reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: ['""', { quote: "''", prefixes: ['X'] }], identifierTypes: ['``'], + variableTypes: [ + { quote: '""', prefixes: ['@'], required: true }, + { quote: "''", prefixes: ['@'], required: true }, + { quote: '``', prefixes: ['@'], required: true }, + ], positionalPlaceholders: true, lineCommentTypes: ['--', '#'], operators: MySqlFormatter.operators, diff --git a/test/behavesLikeMariaDbFormatter.ts b/test/behavesLikeMariaDbFormatter.ts index 8a156bfcea..c410ac090d 100644 --- a/test/behavesLikeMariaDbFormatter.ts +++ b/test/behavesLikeMariaDbFormatter.ts @@ -61,6 +61,29 @@ export default function behavesLikeMariaDbFormatter(format: FormatFn) { `); }); + it('supports @"name", @\'name\', @`name` variables', () => { + expect(format(`SELECT @"foo fo", @'bar ar', @\`baz zaz\` FROM tbl;`)).toBe(dedent` + SELECT + @"foo fo", + @'bar ar', + @\`baz zaz\` + FROM + tbl; + `); + }); + + it('supports setting variables: @"var" :=', () => { + expect(format('SET @"foo" := (SELECT * FROM tbl);')).toBe(dedent` + SET + @"foo" := ( + SELECT + * + FROM + tbl + ); + `); + }); + // Issue #181 it('does not wrap CHARACTER SET to multiple lines', () => { expect(format('ALTER TABLE t MODIFY col1 VARCHAR(50) CHARACTER SET greek')).toBe(dedent` From 1b3650345291daa856d98e31dbbe2422d7ad21db Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 8 Jun 2022 15:22:18 +0300 Subject: [PATCH 171/334] Support @name variables for MySQL and MariaDB --- src/core/Tokenizer.ts | 4 ++-- src/core/regexFactory.ts | 22 +++++++++++++++++++++- src/languages/mariadb.formatter.ts | 1 + src/languages/mysql.formatter.ts | 1 + test/behavesLikeMariaDbFormatter.ts | 19 ++++++------------- 5 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index d583688b87..db712265e9 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -28,7 +28,7 @@ interface TokenizerOptions { // Types of quotes to use for quoted identifiers identifierTypes: regexFactory.QuoteType[]; // Types of quotes to use for variables - variableTypes?: regexFactory.QuoteType[]; + variableTypes?: regexFactory.VariableType[]; // Open-parenthesis characters, like: (, [, { blockStart?: string[]; // Close-parenthesis characters, like: ), ], } @@ -78,7 +78,7 @@ export default class Tokenizer { [TokenType.IDENT]: regexFactory.createIdentRegex(cfg.specialIdentChars), [TokenType.STRING]: regexFactory.createQuoteRegex(cfg.stringTypes), [TokenType.VARIABLE]: cfg.variableTypes - ? regexFactory.createQuoteRegex(cfg.variableTypes) + ? regexFactory.createVariableRegex(cfg.variableTypes) : NULL_REGEX, [TokenType.RESERVED_KEYWORD]: regexFactory.createReservedWordRegex( cfg.reservedKeywords, diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 6811d8bcd6..b33db0ec52 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -107,6 +107,12 @@ export type PrefixedQuoteType = { export type QuoteType = PlainQuoteType | PrefixedQuoteType; +export type VariableRegex = { + regex: string; +}; + +export type VariableType = VariableRegex | PrefixedQuoteType; + // Converts "ab" to "[Aa][Bb]" const toCaseInsensitivePattern = (prefix: string): string => prefix @@ -130,9 +136,23 @@ const createSingleQuotePattern = (type: QuoteType): string => { export const createQuotePattern = (quoteTypes: QuoteType[]): string => quoteTypes.map(createSingleQuotePattern).join('|'); +const createSingleVariablePattern = (type: VariableType): string => { + if ('regex' in type) { + return '(' + type.regex + ')'; + } else { + return createSingleQuotePattern(type); + } +}; + +const patternToRegex = (pattern: string): RegExp => new RegExp('^(' + pattern + ')', 'u'); + +/** Builds a RegExp for matching variables */ +export const createVariableRegex = (varTypes: VariableType[]): RegExp => + patternToRegex(varTypes.map(createSingleVariablePattern).join('|')); + /** Builds a RegExp for matching quote-delimited patterns */ export const createQuoteRegex = (quoteTypes: QuoteType[]): RegExp => - new RegExp('^(' + createQuotePattern(quoteTypes) + ')', 'u'); + patternToRegex(createQuotePattern(quoteTypes)); /** Escapes paren characters for RegExp patterns */ const escapeParen = (paren: string): string => { diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index a7a8a68019..5661e05ca7 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1167,6 +1167,7 @@ export default class MariaDbFormatter extends Formatter { stringTypes: ['""', { quote: "''", prefixes: ['X'] }], identifierTypes: ['``'], variableTypes: [ + { regex: '@[A-Za-z0-9_.$]+' }, { quote: '""', prefixes: ['@'], required: true }, { quote: "''", prefixes: ['@'], required: true }, { quote: '``', prefixes: ['@'], required: true }, diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index 2acdc872aa..d5bdb23797 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1330,6 +1330,7 @@ export default class MySqlFormatter extends Formatter { stringTypes: ['""', { quote: "''", prefixes: ['X'] }], identifierTypes: ['``'], variableTypes: [ + { regex: '@[A-Za-z0-9_.$]+' }, { quote: '""', prefixes: ['@'], required: true }, { quote: "''", prefixes: ['@'], required: true }, { quote: '``', prefixes: ['@'], required: true }, diff --git a/test/behavesLikeMariaDbFormatter.ts b/test/behavesLikeMariaDbFormatter.ts index c410ac090d..13ff61c7b0 100644 --- a/test/behavesLikeMariaDbFormatter.ts +++ b/test/behavesLikeMariaDbFormatter.ts @@ -39,25 +39,18 @@ export default function behavesLikeMariaDbFormatter(format: FormatFn) { }); supportsParams(format, { positional: true }); - // TODO: Disabled for now. - // Bring these back later by implementing a generic support for variables in all dialects. - it.skip('supports @variables', () => { - expect(format('SELECT @foo, @bar')).toBe(dedent` + it('supports @variables', () => { + expect(format('SELECT @foo, @some_long.var$with$special.chars')).toBe(dedent` SELECT @foo, - @bar + @some_long.var$with$special.chars `); }); - it.skip('supports setting variables: @var :=', () => { - expect(format('SET @foo := (SELECT * FROM tbl);')).toBe(dedent` + it('supports setting variables: @var :=', () => { + expect(format('SET @foo := 10;')).toBe(dedent` SET - @foo := ( - SELECT - * - FROM - tbl - ); + @foo := 10; `); }); From 43a84ef83b7e97ca5d07911ac87b0adc7a2e7cda Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 8 Jun 2022 15:43:48 +0300 Subject: [PATCH 172/334] Document &&name substitution variables --- sql/variables.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/variables.md b/sql/variables.md index 41953333bc..80a975bc32 100644 --- a/sql/variables.md +++ b/sql/variables.md @@ -9,7 +9,7 @@ - [MariaDB][]: `@name` (where the name consists of alphanumeric characters, `.`, `_`, and `$`), `@'var name'`, `@"var name"`, `` @`var name` `` (can be quoted as string or identifier) - [MySQL][]: Same as MariaDB - N1QL: _N/A_ -- [PL/SQL][]: `&name` substitution variables (and `:name` bind variables - see [parameters][]). +- [PL/SQL][]: `&name` or `&&name` substitution variables (and `:name` bind variables - see [parameters][]). - [PostgreSQL][]: identifier syntax (only in PL/pgSQL). - Redshift: _N/A_ - [Spark][]: `${name}` Like with Hive, these are substitution variables. @@ -22,7 +22,7 @@ [hive]: https://stackoverflow.com/questions/12464636/how-to-set-variables-in-hive-scripts [mariadb]: https://mariadb.com/kb/en/user-defined-variables/ [mysql]: https://dev.mysql.com/doc/refman/8.0/en/user-variables.html -[pl/sql]: https://stackoverflow.com/a/22171706/15982 +[pl/sql]: https://docs.oracle.com/en/database/oracle/oracle-database/21/sqpug/using-substitution-variables-sqlplus.html#GUID-0BEEC1D7-876B-495C-9327-17037652D3D2 [postgresql]: https://www.postgresql.org/docs/current/sql-declare.html [spark]: https://stackoverflow.com/questions/65019868/how-to-use-variables-in-sql-queries [transact-sql]: https://docs.microsoft.com/en-us/sql/relational-databases/databases/database-identifiers?view=sql-server-ver15 From 957542e22ba71444bc291e5bc334b19ab677240b Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 8 Jun 2022 15:53:46 +0300 Subject: [PATCH 173/334] Support for Oracle &name substitution variables --- src/languages/plsql.formatter.ts | 1 + test/plsql.test.ts | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 7af8b26864..4f68792e64 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -464,6 +464,7 @@ export default class PlSqlFormatter extends Formatter { // TODO: support custom-delimited strings: Q'{..}' q'<..>' etc stringTypes: [{ quote: "''", prefixes: ['N'] }], identifierTypes: [`""`], + variableTypes: [{ regex: '&{1,2}[A-Za-z][A-Za-z0-9_$#]*' }], numberedPlaceholderTypes: [':'], namedPlaceholderTypes: [':'], specialIdentChars: { any: '$#' }, diff --git a/test/plsql.test.ts b/test/plsql.test.ts index 687d1f1af9..53f4a279b3 100644 --- a/test/plsql.test.ts +++ b/test/plsql.test.ts @@ -66,6 +66,18 @@ describe('PlSqlFormatter', () => { `); }); + it('supports &name substitution variables', () => { + const result = format('SELECT &name, &some$Special#Chars_, &hah123 FROM &&tbl'); + expect(result).toBe(dedent` + SELECT + &name, + &some$Special#Chars_, + &hah123 + FROM + &&tbl + `); + }); + it('formats INSERT without INTO', () => { const result = format( "INSERT Customers (ID, MoneyBalance, Address, City) VALUES (12,-123.4, 'Skagen 2111','Stv');" From d3119953876d70ecbb54877e7e49df697510c790 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 8 Jun 2022 16:38:51 +0300 Subject: [PATCH 174/334] Replace type with interface for consistency --- src/core/regexFactory.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index b33db0ec52..b9c347d250 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -107,9 +107,9 @@ export type PrefixedQuoteType = { export type QuoteType = PlainQuoteType | PrefixedQuoteType; -export type VariableRegex = { +export interface VariableRegex { regex: string; -}; +} export type VariableType = VariableRegex | PrefixedQuoteType; From 0e480af8cba98b32c86fcd433600341e59aafb34 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 8 Jun 2022 16:40:43 +0300 Subject: [PATCH 175/334] Move all type defs to the top of regexFactory.ts --- src/core/regexFactory.ts | 84 ++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index b9c347d250..bd083b3eec 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -1,5 +1,47 @@ import { escapeRegExp, isEmpty, sortByLengthDesc } from 'src/utils'; +// This enables the following quote styles: +// 1. backtick quoted using `` to escape +// 2. square bracket quoted (SQL Server) using ]] to escape +// 3. double quoted using "" or \" to escape +// 4. single quoted using '' or \' to escape +// 5. PostgreSQL dollar-quoted +// 6. BigQuery '''triple-quoted''' +// 7. BigQuery """triple-quoted""" +// 8. Hive and Spark variables: ${name} +const quotePatterns = { + '``': '(`[^`]*($|`))+', + '[]': '(\\[[^\\]]*($|\\]))(\\][^\\]]*($|\\]))*', + '""': '("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+', + "''": "('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", + '$$': '(?\\$\\w*\\$)[\\s\\S]*?(?:\\k|$)', + "'''..'''": "'''[^\\\\]*?(?:\\\\.[^\\\\]*?)*?('''|$)", + '""".."""': '"""[^\\\\]*?(?:\\\\.[^\\\\]*?)*?("""|$)', + '{}': '(\\{[^\\}]*($|\\}))', +}; +export type PlainQuoteType = keyof typeof quotePatterns; + +export type PrefixedQuoteType = { + quote: PlainQuoteType; + prefixes: string[]; + required?: boolean; // True when prefix is required +}; + +export type QuoteType = PlainQuoteType | PrefixedQuoteType; + +export interface VariableRegex { + regex: string; +} + +export type VariableType = VariableRegex | PrefixedQuoteType; + +export interface IdentChars { + // concatenated string of chars that can appear anywhere in a valid identifier + any?: string; + // concatenated string of chars that only appear at the beginning of a valid identifier + prefix?: string; +} + /** * Builds a RegExp containing all operators for a SQL dialect * @param {string} monadOperators - concatenated string of all 1-length operators @@ -48,13 +90,6 @@ export const createReservedWordRegex = ( return new RegExp(`^(${reservedKeywordsPattern})${avoidIdentChars}\\b`, 'iu'); }; -export interface IdentChars { - // concatenated string of chars that can appear anywhere in a valid identifier - any?: string; - // concatenated string of chars that only appear at the beginning of a valid identifier - prefix?: string; -} - /** * Builds a RegExp for valid identifiers in a SQL dialect */ @@ -78,41 +113,6 @@ export const createIdentPattern = (specialChars: IdentChars = {}): string => { return `(${prefix}([${letter}${number}${specialWordChars}]+))(${arrayAccessor}|${mapAccessor})?`; }; -// This enables the following quote styles: -// 1. backtick quoted using `` to escape -// 2. square bracket quoted (SQL Server) using ]] to escape -// 3. double quoted using "" or \" to escape -// 4. single quoted using '' or \' to escape -// 5. PostgreSQL dollar-quoted -// 6. BigQuery '''triple-quoted''' -// 7. BigQuery """triple-quoted""" -// 8. Hive and Spark variables: ${name} -const quotePatterns = { - '``': '(`[^`]*($|`))+', - '[]': '(\\[[^\\]]*($|\\]))(\\][^\\]]*($|\\]))*', - '""': '("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+', - "''": "('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+", - '$$': '(?\\$\\w*\\$)[\\s\\S]*?(?:\\k|$)', - "'''..'''": "'''[^\\\\]*?(?:\\\\.[^\\\\]*?)*?('''|$)", - '""".."""': '"""[^\\\\]*?(?:\\\\.[^\\\\]*?)*?("""|$)', - '{}': '(\\{[^\\}]*($|\\}))', -}; -export type PlainQuoteType = keyof typeof quotePatterns; - -export type PrefixedQuoteType = { - quote: PlainQuoteType; - prefixes: string[]; - required?: boolean; // True when prefix is required -}; - -export type QuoteType = PlainQuoteType | PrefixedQuoteType; - -export interface VariableRegex { - regex: string; -} - -export type VariableType = VariableRegex | PrefixedQuoteType; - // Converts "ab" to "[Aa][Bb]" const toCaseInsensitivePattern = (prefix: string): string => prefix From e398aa37d9e9ded51f5f1a6a55acd6e577c11b6a Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 8 Jun 2022 16:46:45 +0300 Subject: [PATCH 176/334] Re-use patternToRegex() where possible --- src/core/regexFactory.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index bd083b3eec..2695c4a132 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -48,10 +48,9 @@ export interface IdentChars { * @param {string[]} polyadOperators - list of strings of all >1-length operators */ export const createOperatorRegex = (monadOperators: string, polyadOperators: string[]): RegExp => - new RegExp( - `^(${sortByLengthDesc(polyadOperators).map(escapeRegExp).join('|')}|` + - `[${monadOperators.split('').map(escapeRegExp).join('')}])`, - 'u' + patternToRegex( + `${sortByLengthDesc(polyadOperators).map(escapeRegExp).join('|')}|` + + `[${monadOperators.split('').map(escapeRegExp).join('')}]` ); /** @@ -94,7 +93,7 @@ export const createReservedWordRegex = ( * Builds a RegExp for valid identifiers in a SQL dialect */ export const createIdentRegex = (specialChars: IdentChars = {}): RegExp => - new RegExp(`^(${createIdentPattern(specialChars)})`, 'u'); + patternToRegex(createIdentPattern(specialChars)); /** * Builds a RegExp string for valid identifiers in a SQL dialect @@ -144,8 +143,6 @@ const createSingleVariablePattern = (type: VariableType): string => { } }; -const patternToRegex = (pattern: string): RegExp => new RegExp('^(' + pattern + ')', 'u'); - /** Builds a RegExp for matching variables */ export const createVariableRegex = (varTypes: VariableType[]): RegExp => patternToRegex(varTypes.map(createSingleVariablePattern).join('|')); @@ -170,7 +167,7 @@ const escapeParen = (paren: string): string => { * @param {string[]} parens - list of strings that denote parenthesis patterns */ export const createParenRegex = (parens: string[]): RegExp => - new RegExp('^(' + parens.map(escapeParen).join('|') + ')', 'iu'); + patternToRegex(parens.map(escapeParen).join('|')); /** * Builds a RegExp for placeholder patterns @@ -183,5 +180,7 @@ export const createPlaceholderRegex = (types: string[], pattern: string): RegExp } const typesRegex = types.map(escapeRegExp).join('|'); - return new RegExp(`^((?:${typesRegex})(?:${pattern}))`, 'u'); + return patternToRegex(`(?:${typesRegex})(?:${pattern})`); }; + +const patternToRegex = (pattern: string): RegExp => new RegExp('^(' + pattern + ')', 'u'); From 12c67d848e45017f83e12e6741e5d3f1b09a6203 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 8 Jun 2022 17:10:18 +0300 Subject: [PATCH 177/334] Drop support for array and map accessors This reverts b236f69899723db40cbc937330a3929731a9e6c1 --- src/core/regexFactory.ts | 5 +---- test/behavesLikeSqlFormatter.ts | 12 ------------ test/features/array.ts | 18 +++++++++++++++++- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 2695c4a132..999e4d791d 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -106,10 +106,7 @@ export const createIdentPattern = (specialChars: IdentChars = {}): string => { const number = '\\p{Decimal_Number}'; const specialWordChars = escapeRegExp(specialChars.any ?? ''); - const arrayAccessor = '\\[\\d\\]'; - const mapAccessor = `\\[['"][${letter}${number}]+['"]\\]`; - - return `(${prefix}([${letter}${number}${specialWordChars}]+))(${arrayAccessor}|${mapAccessor})?`; + return `(${prefix}([${letter}${number}${specialWordChars}]+))`; }; // Converts "ab" to "[Aa][Bb]" diff --git a/test/behavesLikeSqlFormatter.ts b/test/behavesLikeSqlFormatter.ts index ce5273943b..8c2c3f4934 100644 --- a/test/behavesLikeSqlFormatter.ts +++ b/test/behavesLikeSqlFormatter.ts @@ -382,16 +382,4 @@ export default function behavesLikeSqlFormatter(format: FormatFn) { tbl2; `); }); - - it('handles array and map accessor', () => { - const result = format(`SELECT alpha[1], beta['gamma'], epsilon["zeta"] FROM eta;`); - expect(result).toBe(dedent` - SELECT - alpha[1], - beta['gamma'], - epsilon["zeta"] - FROM - eta; - `); - }); } diff --git a/test/features/array.ts b/test/features/array.ts index 38fda580cc..aa84785115 100644 --- a/test/features/array.ts +++ b/test/features/array.ts @@ -3,7 +3,23 @@ import dedent from 'dedent-js'; import { FormatFn } from 'src/sqlFormatter'; export default function supportsArray(format: FormatFn) { - it('supports square brackets for array indexing', () => { + // TODO: These accessors were implemented as part of identifiers, + // resulting in "alpha[1]" being tokenized to single identifier token. + // That's semantically not correct and quite a surprising behavior. + + it.skip('handles array and map accessors', () => { + const result = format(`SELECT alpha[1], beta['gamma'], epsilon["zeta"] FROM eta;`); + expect(result).toBe(dedent` + SELECT + alpha[1], + beta['gamma'], + epsilon["zeta"] + FROM + eta; + `); + }); + + it.skip('supports square brackets for array indexing', () => { const result = format(`SELECT order_lines[5].productId;`); expect(result).toBe(dedent` SELECT From 84dc258458df8d53e19f8749ac05ebef76caa892 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 8 Jun 2022 23:00:18 +0300 Subject: [PATCH 178/334] Remove some extra parentheses from regexes --- src/core/regexFactory.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 999e4d791d..4741e7301d 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -106,7 +106,7 @@ export const createIdentPattern = (specialChars: IdentChars = {}): string => { const number = '\\p{Decimal_Number}'; const specialWordChars = escapeRegExp(specialChars.any ?? ''); - return `(${prefix}([${letter}${number}${specialWordChars}]+))`; + return `${prefix}[${letter}${number}${specialWordChars}]+`; }; // Converts "ab" to "[Aa][Bb]" @@ -122,9 +122,9 @@ const prefixesPattern = ({ prefixes, required }: PrefixedQuoteType): string => const createSingleQuotePattern = (type: QuoteType): string => { if (typeof type === 'string') { - return '(' + quotePatterns[type] + ')'; + return quotePatterns[type]; } else { - return '(' + prefixesPattern(type) + quotePatterns[type.quote] + ')'; + return prefixesPattern(type) + quotePatterns[type.quote]; } }; @@ -134,7 +134,7 @@ export const createQuotePattern = (quoteTypes: QuoteType[]): string => const createSingleVariablePattern = (type: VariableType): string => { if ('regex' in type) { - return '(' + type.regex + ')'; + return type.regex; } else { return createSingleQuotePattern(type); } From b4852a69aa75c1587be14ec146fc4516a5722fba Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 8 Jun 2022 23:29:35 +0300 Subject: [PATCH 179/334] Don't allow # and @ in DB2 identifiers This got added in the original PR for DB2 support: #25 Don't know how Uku interpreted the DB2 manual, but I for one don't see these characters being allowed in identifiers. Unfortunately I didn't check the manual myself when I originally accepted this PR. --- src/languages/db2.formatter.ts | 1 - test/db2.test.ts | 11 ----------- 2 files changed, 12 deletions(-) diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index a709443a21..2aa6680e63 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -873,7 +873,6 @@ export default class Db2Formatter extends Formatter { identifierTypes: [`""`], positionalPlaceholders: true, namedPlaceholderTypes: [':'], - specialIdentChars: { any: '#@' }, operators: Db2Formatter.operators, }); } diff --git a/test/db2.test.ts b/test/db2.test.ts index 8287eea8ce..b805732f01 100644 --- a/test/db2.test.ts +++ b/test/db2.test.ts @@ -63,17 +63,6 @@ describe('Db2Formatter', () => { `); }); - it('recognizes @ and # as part of identifiers', () => { - const result = format('SELECT col#1, @col2 FROM tbl'); - expect(result).toBe(dedent` - SELECT - col#1, - @col2 - FROM - tbl - `); - }); - // DB2-specific string types it('supports strings with G, GX, UX prefixes', () => { expect(format(`SELECT G'blah blah', GX'01AC', UX'CCF239' FROM foo`)).toBe(dedent` From c70b71c431bf13a5bbe5eba518fb3fc3cb6ca110 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Wed, 8 Jun 2022 23:47:03 +0300 Subject: [PATCH 180/334] Proper dashes support for BigQuery identifiers --- src/core/regexFactory.ts | 19 +++++++++++++------ src/languages/bigquery.formatter.ts | 2 +- test/bigquery.test.ts | 14 ++++++++++++-- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index 4741e7301d..aa034fe8a4 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -40,6 +40,8 @@ export interface IdentChars { any?: string; // concatenated string of chars that only appear at the beginning of a valid identifier prefix?: string; + // True to allow single dashes (-) inside identifiers, but not at the beginning or end + dashes?: boolean; } /** @@ -68,7 +70,7 @@ export const createLineCommentRegex = (lineCommentTypes: string[]): RegExp => */ export const createReservedWordRegex = ( reservedKeywords: string[], - specialChars: IdentChars = {} + { any, dashes }: IdentChars = {} ): RegExp => { if (reservedKeywords.length === 0) { return /^\b$/u; @@ -80,7 +82,8 @@ export const createReservedWordRegex = ( // For example "SELECT$ME" should be tokenized as: // - ["SELECT$ME"] when $ is allowed inside identifiers // - ["SELECT", "$", "ME"] when $ can't be part of identifiers. - const avoidIdentChars = specialChars.any ? `(?![${escapeRegExp(specialChars.any)}])` : ''; + const avoidIdentChars = + any || dashes ? `(?![${escapeRegExp(any || '')}${dashes ? '-' : ''}])` : ''; const reservedKeywordsPattern = sortByLengthDesc(reservedKeywords) .join('|') @@ -98,17 +101,21 @@ export const createIdentRegex = (specialChars: IdentChars = {}): RegExp => /** * Builds a RegExp string for valid identifiers in a SQL dialect */ -export const createIdentPattern = (specialChars: IdentChars = {}): string => { - const prefix = specialChars.prefix ? `[${escapeRegExp(specialChars.prefix)}]*` : ''; +export const createIdentPattern = ({ prefix, any, dashes }: IdentChars = {}): string => { + const prefixChars = prefix ? `[${escapeRegExp(prefix)}]*` : ''; // Unicode letters, diacritical marks and underscore const letter = '\\p{Alphabetic}\\p{Mark}_'; // Numbers 0..9, plus various unicode numbers const number = '\\p{Decimal_Number}'; - const specialWordChars = escapeRegExp(specialChars.any ?? ''); + const specialWordChars = escapeRegExp(any ?? ''); - return `${prefix}[${letter}${number}${specialWordChars}]+`; + const pattern = `${prefixChars}[${letter}${number}${specialWordChars}]+`; + + return dashes ? withDashes(pattern) : pattern; }; +const withDashes = (pattern: string): string => pattern + '(?:-' + pattern + ')*'; + // Converts "ab" to "[Aa][Bb]" const toCaseInsensitivePattern = (prefix: string): string => prefix diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index 80a2a673e6..0e2c7ea175 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -849,7 +849,7 @@ export default class BigQueryFormatter extends Formatter { namedPlaceholderTypes: ['@'], quotedPlaceholderTypes: ['@'], lineCommentTypes: ['--', '#'], - specialIdentChars: { any: '-' }, + specialIdentChars: { dashes: true }, operators: BigQueryFormatter.operators, preprocess, }); diff --git a/test/bigquery.test.ts b/test/bigquery.test.ts index 5e701a7513..68f79f5a62 100644 --- a/test/bigquery.test.ts +++ b/test/bigquery.test.ts @@ -46,11 +46,21 @@ describe('BigQueryFormatter', () => { // "my" "ident" // https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical it('supports dashes inside identifiers', () => { - const result = format('SELECT alpha-foo, some-long-identifier\nFROM beta'); + const result = format('SELECT alpha-foo, where-long-identifier\nFROM beta'); expect(result).toBe(dedent` SELECT alpha-foo, - some-long-identifier + where-long-identifier + FROM + beta + `); + }); + + it('treats repeated dashes as comments', () => { + const result = format('SELECT alpha--foo, where-long-identifier\nFROM beta'); + expect(result).toBe(dedent` + SELECT + alpha --foo, where-long-identifier FROM beta `); From e5ef9655d242b3c47ff066245b029b01d0a03fe5 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 9 Jun 2022 09:41:21 +0300 Subject: [PATCH 181/334] Drop unused prefix field from IdentChars --- src/core/regexFactory.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index aa034fe8a4..f8494c98d5 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -38,8 +38,6 @@ export type VariableType = VariableRegex | PrefixedQuoteType; export interface IdentChars { // concatenated string of chars that can appear anywhere in a valid identifier any?: string; - // concatenated string of chars that only appear at the beginning of a valid identifier - prefix?: string; // True to allow single dashes (-) inside identifiers, but not at the beginning or end dashes?: boolean; } @@ -101,15 +99,14 @@ export const createIdentRegex = (specialChars: IdentChars = {}): RegExp => /** * Builds a RegExp string for valid identifiers in a SQL dialect */ -export const createIdentPattern = ({ prefix, any, dashes }: IdentChars = {}): string => { - const prefixChars = prefix ? `[${escapeRegExp(prefix)}]*` : ''; +export const createIdentPattern = ({ any, dashes }: IdentChars = {}): string => { // Unicode letters, diacritical marks and underscore const letter = '\\p{Alphabetic}\\p{Mark}_'; // Numbers 0..9, plus various unicode numbers const number = '\\p{Decimal_Number}'; const specialWordChars = escapeRegExp(any ?? ''); - const pattern = `${prefixChars}[${letter}${number}${specialWordChars}]+`; + const pattern = `[${letter}${number}${specialWordChars}]+`; return dashes ? withDashes(pattern) : pattern; }; From e40fab0f076e4c14ec5d142c01bf5910e32dab12 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 9 Jun 2022 10:04:36 +0300 Subject: [PATCH 182/334] Delete incorrect $n test from $name test section --- test/options/param.ts | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/test/options/param.ts b/test/options/param.ts index af502bb539..80b82518f0 100644 --- a/test/options/param.ts +++ b/test/options/param.ts @@ -159,22 +159,6 @@ export default function supportsParams(format: FormatFn, params: ParamsTypes) { AND age > 10; `); }); - - it('replaces $n numbered placeholders with param values', () => { - const result = format('SELECT $1, $2, $0;', { - params: { - 0: 'first', - 1: 'second', - 2: 'third', - }, - }); - expect(result).toBe(dedent` - SELECT - second, - third, - first; - `); - }); } }); From 6f2269f12cf158d5a0f3cbdbe2c566e064919ce2 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 9 Jun 2022 10:09:20 +0300 Subject: [PATCH 183/334] Replace "any" with "first" and "rest" in IdentChars --- src/core/regexFactory.ts | 36 +++++++++++++++++++------------- src/languages/plsql.formatter.ts | 2 +- src/languages/tsql.formatter.ts | 2 +- test/tsql.test.ts | 13 ++++++++++++ 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index f8494c98d5..cfa7d6d807 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -36,8 +36,12 @@ export interface VariableRegex { export type VariableType = VariableRegex | PrefixedQuoteType; export interface IdentChars { - // concatenated string of chars that can appear anywhere in a valid identifier - any?: string; + // Additional characters that can be used as first character of an identifier. + // That is: in addition to letters and underscore. + first?: string; + // Additional characters that can appear after the first character of identifier. + // That is: in addition to letters, numbers and underscore. + rest?: string; // True to allow single dashes (-) inside identifiers, but not at the beginning or end dashes?: boolean; } @@ -68,20 +72,13 @@ export const createLineCommentRegex = (lineCommentTypes: string[]): RegExp => */ export const createReservedWordRegex = ( reservedKeywords: string[], - { any, dashes }: IdentChars = {} + identChars: IdentChars = {} ): RegExp => { if (reservedKeywords.length === 0) { return /^\b$/u; } - // Negative lookahead to avoid matching a keyword that's actually part of identifier, - // which can happen when identifier allows word-boundary characters inside it. - // - // For example "SELECT$ME" should be tokenized as: - // - ["SELECT$ME"] when $ is allowed inside identifiers - // - ["SELECT", "$", "ME"] when $ can't be part of identifiers. - const avoidIdentChars = - any || dashes ? `(?![${escapeRegExp(any || '')}${dashes ? '-' : ''}])` : ''; + const avoidIdentChars = rejectIdentCharsPattern(identChars); const reservedKeywordsPattern = sortByLengthDesc(reservedKeywords) .join('|') @@ -90,6 +87,15 @@ export const createReservedWordRegex = ( return new RegExp(`^(${reservedKeywordsPattern})${avoidIdentChars}\\b`, 'iu'); }; +// Negative lookahead to avoid matching a keyword that's actually part of identifier, +// which can happen when identifier allows word-boundary characters inside it. +// +// For example "SELECT$ME" should be tokenized as: +// - ["SELECT$ME"] when $ is allowed inside identifiers +// - ["SELECT", "$", "ME"] when $ can't be part of identifiers. +const rejectIdentCharsPattern = ({ rest, dashes }: IdentChars): string => + rest || dashes ? `(?![${rest || ''}${dashes ? '-' : ''}])` : ''; + /** * Builds a RegExp for valid identifiers in a SQL dialect */ @@ -99,14 +105,16 @@ export const createIdentRegex = (specialChars: IdentChars = {}): RegExp => /** * Builds a RegExp string for valid identifiers in a SQL dialect */ -export const createIdentPattern = ({ any, dashes }: IdentChars = {}): string => { +export const createIdentPattern = ({ first, rest, dashes }: IdentChars = {}): string => { // Unicode letters, diacritical marks and underscore const letter = '\\p{Alphabetic}\\p{Mark}_'; // Numbers 0..9, plus various unicode numbers const number = '\\p{Decimal_Number}'; - const specialWordChars = escapeRegExp(any ?? ''); - const pattern = `[${letter}${number}${specialWordChars}]+`; + const firstChars = escapeRegExp(first ?? ''); + const restChars = escapeRegExp(rest ?? ''); + + const pattern = `[${letter}${firstChars}][${letter}${number}${restChars}]*`; return dashes ? withDashes(pattern) : pattern; }; diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 4f68792e64..76eb1cf21e 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -467,7 +467,7 @@ export default class PlSqlFormatter extends Formatter { variableTypes: [{ regex: '&{1,2}[A-Za-z][A-Za-z0-9_$#]*' }], numberedPlaceholderTypes: [':'], namedPlaceholderTypes: [':'], - specialIdentChars: { any: '$#' }, + specialIdentChars: { rest: '$#' }, operators: PlSqlFormatter.operators, preprocess, }); diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index 7c2d908ae8..82c91f5e74 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1246,7 +1246,7 @@ export default class TSqlFormatter extends Formatter { identifierTypes: [`""`, '[]'], namedPlaceholderTypes: ['@'], quotedPlaceholderTypes: ['@'], - specialIdentChars: { any: '#@$' }, + specialIdentChars: { first: '#@', rest: '#@$' }, operators: TSqlFormatter.operators, // TODO: Support for money constants }); diff --git a/test/tsql.test.ts b/test/tsql.test.ts index 814d04b740..12baf0f7ca 100644 --- a/test/tsql.test.ts +++ b/test/tsql.test.ts @@ -72,4 +72,17 @@ describe('TSqlFormatter', () => { tbl; `); }); + + it('allows @ and # at the start of identifiers', () => { + const result = format('SELECT @bar, #baz, @@some, ##flam FROM tbl;'); + expect(result).toBe(dedent` + SELECT + @bar, + #baz, + @@some, + ##flam + FROM + tbl; + `); + }); }); From 753e2c56cbe22cae724304be0ddeb2dc90cd38c8 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 9 Jun 2022 10:14:12 +0300 Subject: [PATCH 184/334] Allow $ char in MariaDB/MySQL identifiers --- src/languages/mariadb.formatter.ts | 1 + src/languages/mysql.formatter.ts | 1 + test/behavesLikeMariaDbFormatter.ts | 8 ++++++++ 3 files changed, 10 insertions(+) diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index 5661e05ca7..0223d93135 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1172,6 +1172,7 @@ export default class MariaDbFormatter extends Formatter { { quote: "''", prefixes: ['@'], required: true }, { quote: '``', prefixes: ['@'], required: true }, ], + specialIdentChars: { first: '$', rest: '$' }, positionalPlaceholders: true, lineCommentTypes: ['--', '#'], operators: MariaDbFormatter.operators, diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index d5bdb23797..db54c2a2f1 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1335,6 +1335,7 @@ export default class MySqlFormatter extends Formatter { { quote: "''", prefixes: ['@'], required: true }, { quote: '``', prefixes: ['@'], required: true }, ], + specialIdentChars: { first: '$', rest: '$' }, positionalPlaceholders: true, lineCommentTypes: ['--', '#'], operators: MySqlFormatter.operators, diff --git a/test/behavesLikeMariaDbFormatter.ts b/test/behavesLikeMariaDbFormatter.ts index 13ff61c7b0..eb4e7fc8de 100644 --- a/test/behavesLikeMariaDbFormatter.ts +++ b/test/behavesLikeMariaDbFormatter.ts @@ -39,6 +39,14 @@ export default function behavesLikeMariaDbFormatter(format: FormatFn) { }); supportsParams(format, { positional: true }); + it('allows $ character as part of identifiers', () => { + expect(format('SELECT $foo, some$$ident')).toBe(dedent` + SELECT + $foo, + some$$ident + `); + }); + it('supports @variables', () => { expect(format('SELECT @foo, @some_long.var$with$special.chars')).toBe(dedent` SELECT From fec67334f7d69931abcba849169e272563086b5c Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 9 Jun 2022 10:16:13 +0300 Subject: [PATCH 185/334] Allow $ char in Postgres identifiers --- src/languages/postgresql.formatter.ts | 1 + test/postgresql.test.ts | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index 752fab4fee..1ba563e8da 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1683,6 +1683,7 @@ export default class PostgreSqlFormatter extends Formatter { ]), stringTypes: [{ quote: "''", prefixes: ['U&', 'E', 'X', 'B'] }, '$$'], identifierTypes: [{ quote: '""', prefixes: ['U&'] }], + specialIdentChars: { rest: '$' }, numberedPlaceholderTypes: ['$'], operators: PostgreSqlFormatter.operators, }); diff --git a/test/postgresql.test.ts b/test/postgresql.test.ts index ba5d089926..3f87ea09d6 100644 --- a/test/postgresql.test.ts +++ b/test/postgresql.test.ts @@ -37,6 +37,14 @@ describe('PostgreSqlFormatter', () => { supportsReturning(format); supportsParams(format, { numbered: ['$'] }); + it('allows $ character as part of identifiers', () => { + expect(format('SELECT foo$, some$$ident')).toBe(dedent` + SELECT + foo$, + some$$ident + `); + }); + // Postgres-specific string types it('supports bit strings', () => { expect(format(`SELECT B'0110010', B'1101000';`)).toBe(dedent` From 3239952c52ed996a237c45310c34972484175644 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 9 Jun 2022 10:21:01 +0300 Subject: [PATCH 186/334] Rename specialIdentChars to just identChars --- src/core/Tokenizer.ts | 18 +++++++++--------- src/languages/bigquery.formatter.ts | 2 +- src/languages/mariadb.formatter.ts | 2 +- src/languages/mysql.formatter.ts | 2 +- src/languages/plsql.formatter.ts | 2 +- src/languages/postgresql.formatter.ts | 2 +- src/languages/tsql.formatter.ts | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index db712265e9..913ec350e8 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -45,7 +45,7 @@ interface TokenizerOptions { // Line comment types to support, defaults to -- lineCommentTypes?: string[]; // Additional characters to support in identifiers - specialIdentChars?: regexFactory.IdentChars; + identChars?: regexFactory.IdentChars; // Additional multi-character operators to support, in addition to <=, >=, <>, != operators?: string[]; // Allows custom modifications on the token array. @@ -75,34 +75,34 @@ export default class Tokenizer { this.quotedIdentRegex = regexFactory.createQuoteRegex(cfg.identifierTypes); this.REGEX_MAP = { - [TokenType.IDENT]: regexFactory.createIdentRegex(cfg.specialIdentChars), + [TokenType.IDENT]: regexFactory.createIdentRegex(cfg.identChars), [TokenType.STRING]: regexFactory.createQuoteRegex(cfg.stringTypes), [TokenType.VARIABLE]: cfg.variableTypes ? regexFactory.createVariableRegex(cfg.variableTypes) : NULL_REGEX, [TokenType.RESERVED_KEYWORD]: regexFactory.createReservedWordRegex( cfg.reservedKeywords, - cfg.specialIdentChars + cfg.identChars ), [TokenType.RESERVED_DEPENDENT_CLAUSE]: regexFactory.createReservedWordRegex( cfg.reservedDependentClauses ?? [], - cfg.specialIdentChars + cfg.identChars ), [TokenType.RESERVED_LOGICAL_OPERATOR]: regexFactory.createReservedWordRegex( cfg.reservedLogicalOperators ?? ['AND', 'OR'], - cfg.specialIdentChars + cfg.identChars ), [TokenType.RESERVED_COMMAND]: regexFactory.createReservedWordRegex( cfg.reservedCommands, - cfg.specialIdentChars + cfg.identChars ), [TokenType.RESERVED_BINARY_COMMAND]: regexFactory.createReservedWordRegex( cfg.reservedBinaryCommands, - cfg.specialIdentChars + cfg.identChars ), [TokenType.RESERVED_JOIN_CONDITION]: regexFactory.createReservedWordRegex( cfg.reservedJoinConditions ?? ['ON', 'USING'], - cfg.specialIdentChars + cfg.identChars ), [TokenType.OPERATOR]: regexFactory.createOperatorRegex('+-/*%&|^><=.,;[]{}`:$@', [ '<>', @@ -128,7 +128,7 @@ export default class Tokenizer { // :name placeholders regex: regexFactory.createPlaceholderRegex( cfg.namedPlaceholderTypes ?? [], - regexFactory.createIdentPattern(cfg.specialIdentChars) + regexFactory.createIdentPattern(cfg.identChars) ), parseKey: v => v.slice(1), }, diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index 0e2c7ea175..d1bf7dd8aa 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -849,7 +849,7 @@ export default class BigQueryFormatter extends Formatter { namedPlaceholderTypes: ['@'], quotedPlaceholderTypes: ['@'], lineCommentTypes: ['--', '#'], - specialIdentChars: { dashes: true }, + identChars: { dashes: true }, operators: BigQueryFormatter.operators, preprocess, }); diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index 0223d93135..f42581616e 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1172,7 +1172,7 @@ export default class MariaDbFormatter extends Formatter { { quote: "''", prefixes: ['@'], required: true }, { quote: '``', prefixes: ['@'], required: true }, ], - specialIdentChars: { first: '$', rest: '$' }, + identChars: { first: '$', rest: '$' }, positionalPlaceholders: true, lineCommentTypes: ['--', '#'], operators: MariaDbFormatter.operators, diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index db54c2a2f1..f1d9f3ae3b 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1335,7 +1335,7 @@ export default class MySqlFormatter extends Formatter { { quote: "''", prefixes: ['@'], required: true }, { quote: '``', prefixes: ['@'], required: true }, ], - specialIdentChars: { first: '$', rest: '$' }, + identChars: { first: '$', rest: '$' }, positionalPlaceholders: true, lineCommentTypes: ['--', '#'], operators: MySqlFormatter.operators, diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 76eb1cf21e..6f82b60090 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -467,7 +467,7 @@ export default class PlSqlFormatter extends Formatter { variableTypes: [{ regex: '&{1,2}[A-Za-z][A-Za-z0-9_$#]*' }], numberedPlaceholderTypes: [':'], namedPlaceholderTypes: [':'], - specialIdentChars: { rest: '$#' }, + identChars: { rest: '$#' }, operators: PlSqlFormatter.operators, preprocess, }); diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index 1ba563e8da..848ebd5e4a 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1683,7 +1683,7 @@ export default class PostgreSqlFormatter extends Formatter { ]), stringTypes: [{ quote: "''", prefixes: ['U&', 'E', 'X', 'B'] }, '$$'], identifierTypes: [{ quote: '""', prefixes: ['U&'] }], - specialIdentChars: { rest: '$' }, + identChars: { rest: '$' }, numberedPlaceholderTypes: ['$'], operators: PostgreSqlFormatter.operators, }); diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index 82c91f5e74..c61e3e79c3 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1246,7 +1246,7 @@ export default class TSqlFormatter extends Formatter { identifierTypes: [`""`, '[]'], namedPlaceholderTypes: ['@'], quotedPlaceholderTypes: ['@'], - specialIdentChars: { first: '#@', rest: '#@$' }, + identChars: { first: '#@', rest: '#@$' }, operators: TSqlFormatter.operators, // TODO: Support for money constants }); From d634c7283315cded5c9d8016a117099abcb080e1 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 9 Jun 2022 10:23:12 +0300 Subject: [PATCH 187/334] Move identChars close to identifierTypes --- src/languages/bigquery.formatter.ts | 2 +- src/languages/mariadb.formatter.ts | 2 +- src/languages/mysql.formatter.ts | 2 +- src/languages/plsql.formatter.ts | 2 +- src/languages/tsql.formatter.ts | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index d1bf7dd8aa..10a289facc 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -845,11 +845,11 @@ export default class BigQueryFormatter extends Formatter { { quote: "''", prefixes: ['R', 'B', 'RB', 'BR'] }, ], identifierTypes: ['``'], + identChars: { dashes: true }, positionalPlaceholders: true, namedPlaceholderTypes: ['@'], quotedPlaceholderTypes: ['@'], lineCommentTypes: ['--', '#'], - identChars: { dashes: true }, operators: BigQueryFormatter.operators, preprocess, }); diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index f42581616e..5d993a50bd 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1166,13 +1166,13 @@ export default class MariaDbFormatter extends Formatter { reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: ['""', { quote: "''", prefixes: ['X'] }], identifierTypes: ['``'], + identChars: { first: '$', rest: '$' }, variableTypes: [ { regex: '@[A-Za-z0-9_.$]+' }, { quote: '""', prefixes: ['@'], required: true }, { quote: "''", prefixes: ['@'], required: true }, { quote: '``', prefixes: ['@'], required: true }, ], - identChars: { first: '$', rest: '$' }, positionalPlaceholders: true, lineCommentTypes: ['--', '#'], operators: MariaDbFormatter.operators, diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index f1d9f3ae3b..36d684f7df 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1329,13 +1329,13 @@ export default class MySqlFormatter extends Formatter { reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: ['""', { quote: "''", prefixes: ['X'] }], identifierTypes: ['``'], + identChars: { first: '$', rest: '$' }, variableTypes: [ { regex: '@[A-Za-z0-9_.$]+' }, { quote: '""', prefixes: ['@'], required: true }, { quote: "''", prefixes: ['@'], required: true }, { quote: '``', prefixes: ['@'], required: true }, ], - identChars: { first: '$', rest: '$' }, positionalPlaceholders: true, lineCommentTypes: ['--', '#'], operators: MySqlFormatter.operators, diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 6f82b60090..6821a9817d 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -464,10 +464,10 @@ export default class PlSqlFormatter extends Formatter { // TODO: support custom-delimited strings: Q'{..}' q'<..>' etc stringTypes: [{ quote: "''", prefixes: ['N'] }], identifierTypes: [`""`], + identChars: { rest: '$#' }, variableTypes: [{ regex: '&{1,2}[A-Za-z][A-Za-z0-9_$#]*' }], numberedPlaceholderTypes: [':'], namedPlaceholderTypes: [':'], - identChars: { rest: '$#' }, operators: PlSqlFormatter.operators, preprocess, }); diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index c61e3e79c3..c747345e8c 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1244,9 +1244,9 @@ export default class TSqlFormatter extends Formatter { ]), stringTypes: [{ quote: "''", prefixes: ['N'] }], identifierTypes: [`""`, '[]'], + identChars: { first: '#@', rest: '#@$' }, namedPlaceholderTypes: ['@'], quotedPlaceholderTypes: ['@'], - identChars: { first: '#@', rest: '#@$' }, operators: TSqlFormatter.operators, // TODO: Support for money constants }); From 8c0ab3fe939164454a250e4656917627ad839ac8 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 9 Jun 2022 10:24:21 +0300 Subject: [PATCH 188/334] Rename identifierTypes to identTypes for consistency --- src/core/Tokenizer.ts | 6 +++--- src/languages/bigquery.formatter.ts | 2 +- src/languages/db2.formatter.ts | 2 +- src/languages/hive.formatter.ts | 2 +- src/languages/mariadb.formatter.ts | 2 +- src/languages/mysql.formatter.ts | 2 +- src/languages/n1ql.formatter.ts | 2 +- src/languages/plsql.formatter.ts | 2 +- src/languages/postgresql.formatter.ts | 2 +- src/languages/redshift.formatter.ts | 2 +- src/languages/spark.formatter.ts | 2 +- src/languages/sql.formatter.ts | 2 +- src/languages/sqlite.formatter.ts | 2 +- src/languages/tsql.formatter.ts | 2 +- 14 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 913ec350e8..2b7008a78e 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -26,7 +26,7 @@ interface TokenizerOptions { // Types of quotes to use for strings stringTypes: regexFactory.QuoteType[]; // Types of quotes to use for quoted identifiers - identifierTypes: regexFactory.QuoteType[]; + identTypes: regexFactory.QuoteType[]; // Types of quotes to use for variables variableTypes?: regexFactory.VariableType[]; // Open-parenthesis characters, like: (, [, { @@ -72,7 +72,7 @@ export default class Tokenizer { this.preprocess = cfg.preprocess; } - this.quotedIdentRegex = regexFactory.createQuoteRegex(cfg.identifierTypes); + this.quotedIdentRegex = regexFactory.createQuoteRegex(cfg.identTypes); this.REGEX_MAP = { [TokenType.IDENT]: regexFactory.createIdentRegex(cfg.identChars), @@ -136,7 +136,7 @@ export default class Tokenizer { // :"name" placeholders regex: regexFactory.createPlaceholderRegex( cfg.quotedPlaceholderTypes ?? [], - regexFactory.createQuotePattern(cfg.identifierTypes) + regexFactory.createQuotePattern(cfg.identTypes) ), parseKey: v => this.getEscapedPlaceholderKey({ key: v.slice(2, -1), quoteChar: v.slice(-1) }), diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index 10a289facc..7d0be7e346 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -844,7 +844,7 @@ export default class BigQueryFormatter extends Formatter { { quote: '""', prefixes: ['R', 'B', 'RB', 'BR'] }, { quote: "''", prefixes: ['R', 'B', 'RB', 'BR'] }, ], - identifierTypes: ['``'], + identTypes: ['``'], identChars: { dashes: true }, positionalPlaceholders: true, namedPlaceholderTypes: ['@'], diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index 2aa6680e63..87c572bef8 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -870,7 +870,7 @@ export default class Db2Formatter extends Formatter { ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), stringTypes: [{ quote: "''", prefixes: ['X', 'G', 'N', 'GX', 'UX', 'U&'] }], - identifierTypes: [`""`], + identTypes: [`""`], positionalPlaceholders: true, namedPlaceholderTypes: [':'], operators: Db2Formatter.operators, diff --git a/src/languages/hive.formatter.ts b/src/languages/hive.formatter.ts index e45de9b352..d3838cf2ef 100644 --- a/src/languages/hive.formatter.ts +++ b/src/languages/hive.formatter.ts @@ -625,7 +625,7 @@ export default class HiveFormatter extends Formatter { ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), stringTypes: ['""', "''"], - identifierTypes: ['``'], + identTypes: ['``'], variableTypes: [{ quote: '{}', prefixes: ['$'], required: true }], operators: HiveFormatter.operators, }); diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index 5d993a50bd..2d25f70f4f 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1165,7 +1165,7 @@ export default class MariaDbFormatter extends Formatter { reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: ['""', { quote: "''", prefixes: ['X'] }], - identifierTypes: ['``'], + identTypes: ['``'], identChars: { first: '$', rest: '$' }, variableTypes: [ { regex: '@[A-Za-z0-9_.$]+' }, diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index 36d684f7df..4a68bd1351 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1328,7 +1328,7 @@ export default class MySqlFormatter extends Formatter { reservedLogicalOperators: ['AND', 'OR', 'XOR'], reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]), stringTypes: ['""', { quote: "''", prefixes: ['X'] }], - identifierTypes: ['``'], + identTypes: ['``'], identChars: { first: '$', rest: '$' }, variableTypes: [ { regex: '@[A-Za-z0-9_.$]+' }, diff --git a/src/languages/n1ql.formatter.ts b/src/languages/n1ql.formatter.ts index 079cdd0c62..4d9aa4bd61 100644 --- a/src/languages/n1ql.formatter.ts +++ b/src/languages/n1ql.formatter.ts @@ -524,7 +524,7 @@ export default class N1qlFormatter extends Formatter { // but we support them anyway as all other SQL dialects do, // which simplifies writing tests that are shared between all dialects. stringTypes: [`""`, "''"], - identifierTypes: ['``'], + identTypes: ['``'], blockStart: ['(', '[', '{'], blockEnd: [')', ']', '}'], positionalPlaceholders: true, diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 6821a9817d..1631a1fe18 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -463,7 +463,7 @@ export default class PlSqlFormatter extends Formatter { reservedKeywords: dedupe(reservedKeywords), // TODO: support custom-delimited strings: Q'{..}' q'<..>' etc stringTypes: [{ quote: "''", prefixes: ['N'] }], - identifierTypes: [`""`], + identTypes: [`""`], identChars: { rest: '$#' }, variableTypes: [{ regex: '&{1,2}[A-Za-z][A-Za-z0-9_$#]*' }], numberedPlaceholderTypes: [':'], diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index 848ebd5e4a..860d063d1e 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1682,7 +1682,7 @@ export default class PostgreSqlFormatter extends Formatter { ...reservedKeywords, ]), stringTypes: [{ quote: "''", prefixes: ['U&', 'E', 'X', 'B'] }, '$$'], - identifierTypes: [{ quote: '""', prefixes: ['U&'] }], + identTypes: [{ quote: '""', prefixes: ['U&'] }], identChars: { rest: '$' }, numberedPlaceholderTypes: ['$'], operators: PostgreSqlFormatter.operators, diff --git a/src/languages/redshift.formatter.ts b/src/languages/redshift.formatter.ts index 6b06a58f63..520cc1381d 100644 --- a/src/languages/redshift.formatter.ts +++ b/src/languages/redshift.formatter.ts @@ -727,7 +727,7 @@ export default class RedshiftFormatter extends Formatter { ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), stringTypes: ["''"], - identifierTypes: [`""`], + identTypes: [`""`], numberedPlaceholderTypes: ['$'], operators: RedshiftFormatter.operators, }); diff --git a/src/languages/spark.formatter.ts b/src/languages/spark.formatter.ts index b30afbe707..aa1a19d290 100644 --- a/src/languages/spark.formatter.ts +++ b/src/languages/spark.formatter.ts @@ -790,7 +790,7 @@ export default class SparkFormatter extends Formatter { ...reservedKeywords, ]), stringTypes: [{ quote: "''", prefixes: ['X'] }], - identifierTypes: ['``'], + identTypes: ['``'], variableTypes: [{ quote: '{}', prefixes: ['$'], required: true }], operators: SparkFormatter.operators, preprocess, diff --git a/src/languages/sql.formatter.ts b/src/languages/sql.formatter.ts index 079b519af2..73c1bce43b 100644 --- a/src/languages/sql.formatter.ts +++ b/src/languages/sql.formatter.ts @@ -378,7 +378,7 @@ export default class SqlFormatter extends Formatter { reservedDependentClauses, reservedKeywords: dedupe(reservedKeywords), stringTypes: [{ quote: "''", prefixes: ['X'] }], - identifierTypes: [`""`, '``'], + identTypes: [`""`, '``'], positionalPlaceholders: true, }); } diff --git a/src/languages/sqlite.formatter.ts b/src/languages/sqlite.formatter.ts index 9e26c14300..09d98dcc16 100644 --- a/src/languages/sqlite.formatter.ts +++ b/src/languages/sqlite.formatter.ts @@ -431,7 +431,7 @@ export default class SqliteFormatter extends Formatter { // https://www.sqlite.org/lang_keywords.html reservedKeywords: [...standardReservedWords, ...nonStandardSqliteReservedWords], stringTypes: [{ quote: "''", prefixes: ['X'] }], - identifierTypes: [`""`, '``', '[]'], + identTypes: [`""`, '``', '[]'], // https://www.sqlite.org/lang_expr.html#parameters positionalPlaceholders: true, numberedPlaceholderTypes: ['?'], diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index c747345e8c..136d8f5759 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1243,7 +1243,7 @@ export default class TSqlFormatter extends Formatter { ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), stringTypes: [{ quote: "''", prefixes: ['N'] }], - identifierTypes: [`""`, '[]'], + identTypes: [`""`, '[]'], identChars: { first: '#@', rest: '#@$' }, namedPlaceholderTypes: ['@'], quotedPlaceholderTypes: ['@'], From 2c4aacb8fb44ac11566aec45e8da361e4e368d67 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 9 Jun 2022 10:32:10 +0300 Subject: [PATCH 189/334] Rename PLACEHOLDER to PARAMETER This way it's now more consistent with the params config option and overall terminology. --- src/core/StatementFormatter.ts | 8 +++---- src/core/Tokenizer.ts | 34 +++++++++++++-------------- src/core/regexFactory.ts | 4 ++-- src/core/token.ts | 2 +- src/languages/bigquery.formatter.ts | 6 ++--- src/languages/db2.formatter.ts | 4 ++-- src/languages/mariadb.formatter.ts | 2 +- src/languages/mysql.formatter.ts | 2 +- src/languages/n1ql.formatter.ts | 6 ++--- src/languages/plsql.formatter.ts | 4 ++-- src/languages/postgresql.formatter.ts | 2 +- src/languages/redshift.formatter.ts | 2 +- src/languages/sql.formatter.ts | 2 +- src/languages/sqlite.formatter.ts | 6 ++--- src/languages/tsql.formatter.ts | 4 ++-- 15 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/core/StatementFormatter.ts b/src/core/StatementFormatter.ts index 394f952fb3..aee8a23681 100644 --- a/src/core/StatementFormatter.ts +++ b/src/core/StatementFormatter.ts @@ -84,8 +84,8 @@ export default class StatementFormatter { return this.formatCaseStart(token); case TokenType.RESERVED_CASE_END: return this.formatCaseEnd(token); - case TokenType.PLACEHOLDER: - return this.formatPlaceholder(token); + case TokenType.PARAMETER: + return this.formatParameter(token); case TokenType.OPERATOR: return this.formatOperator(token); case TokenType.IDENT: @@ -375,9 +375,9 @@ export default class StatementFormatter { } /** - * Formats a Placeholder item onto query, to be replaced with the value of the placeholder + * Formats a parameter placeholder item onto query, to be replaced with the value of the placeholder */ - formatPlaceholder(token: Token) { + private formatParameter(token: Token) { this.query.add(this.params.get(token), WS.SPACE); } diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 2b7008a78e..42d6e0a158 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -34,14 +34,14 @@ interface TokenizerOptions { // Close-parenthesis characters, like: ), ], } blockEnd?: string[]; // True to allow for positional "?" parameter placeholders - positionalPlaceholders?: boolean; + positionalParams?: boolean; // Prefixes for numbered parameter placeholders to support, e.g. :1, :2, :3 - numberedPlaceholderTypes?: ('?' | ':' | '$')[]; + numberedParamTypes?: ('?' | ':' | '$')[]; // Prefixes for named parameter placeholders to support, e.g. :name - namedPlaceholderTypes?: (':' | '@' | '$')[]; + namedParamTypes?: (':' | '@' | '$')[]; // Prefixes for quoted parameter placeholders to support, e.g. :"name" // The type of quotes will depend on `identifierTypes` option. - quotedPlaceholderTypes?: (':' | '@' | '$')[]; + quotedParamTypes?: (':' | '@' | '$')[]; // Line comment types to support, defaults to -- lineCommentTypes?: string[]; // Additional characters to support in identifiers @@ -54,7 +54,7 @@ interface TokenizerOptions { preprocess?: (tokens: Token[]) => Token[]; } -interface PlaceholderPattern { +interface ParamPattern { regex: RegExp; parseKey: (s: string) => string; } @@ -63,7 +63,7 @@ interface PlaceholderPattern { export default class Tokenizer { private REGEX_MAP: Record; private quotedIdentRegex: RegExp; - private placeholderPatterns: PlaceholderPattern[]; + private paramPatterns: ParamPattern[]; private preprocess = (tokens: Token[]) => tokens; @@ -119,23 +119,23 @@ export default class Tokenizer { [TokenType.BLOCK_COMMENT]: /^(\/\*[^]*?(?:\*\/|$))/u, [TokenType.NUMBER]: /^(0x[0-9a-fA-F]+|0b[01]+|(-\s*)?[0-9]+(\.[0-9]*)?([eE][-+]?[0-9]+(\.[0-9]+)?)?)/u, - [TokenType.PLACEHOLDER]: NULL_REGEX, // matches nothing + [TokenType.PARAMETER]: NULL_REGEX, // matches nothing [TokenType.EOF]: NULL_REGEX, // matches nothing }; - this.placeholderPatterns = this.excludePatternsWithoutRegexes([ + this.paramPatterns = this.excludePatternsWithoutRegexes([ { // :name placeholders - regex: regexFactory.createPlaceholderRegex( - cfg.namedPlaceholderTypes ?? [], + regex: regexFactory.createParameterRegex( + cfg.namedParamTypes ?? [], regexFactory.createIdentPattern(cfg.identChars) ), parseKey: v => v.slice(1), }, { // :"name" placeholders - regex: regexFactory.createPlaceholderRegex( - cfg.quotedPlaceholderTypes ?? [], + regex: regexFactory.createParameterRegex( + cfg.quotedParamTypes ?? [], regexFactory.createQuotePattern(cfg.identTypes) ), parseKey: v => @@ -143,12 +143,12 @@ export default class Tokenizer { }, { // :1, :2, :3 placeholders - regex: regexFactory.createPlaceholderRegex(cfg.numberedPlaceholderTypes ?? [], '[0-9]+'), + regex: regexFactory.createParameterRegex(cfg.numberedParamTypes ?? [], '[0-9]+'), parseKey: v => v.slice(1), }, { // ? placeholders - regex: cfg.positionalPlaceholders ? /^(\?)/ : undefined, + regex: cfg.positionalParams ? /^(\?)/ : undefined, parseKey: v => v.slice(1), }, ]); @@ -157,7 +157,7 @@ export default class Tokenizer { private excludePatternsWithoutRegexes( patterns: { regex?: RegExp; parseKey: (s: string) => string }[] ) { - return patterns.filter((p): p is PlaceholderPattern => p.regex !== undefined); + return patterns.filter((p): p is ParamPattern => p.regex !== undefined); } /** @@ -221,11 +221,11 @@ export default class Tokenizer { * @return {Token | undefined} - The placeholder token if found, otherwise undefined */ private matchPlaceholderToken(input: string): Token | undefined { - for (const { regex, parseKey } of this.placeholderPatterns) { + for (const { regex, parseKey } of this.paramPatterns) { const token = this.match({ input, regex, - type: TokenType.PLACEHOLDER, + type: TokenType.PARAMETER, transform: id, }); if (token) { diff --git a/src/core/regexFactory.ts b/src/core/regexFactory.ts index cfa7d6d807..d2c167f4d0 100644 --- a/src/core/regexFactory.ts +++ b/src/core/regexFactory.ts @@ -179,11 +179,11 @@ export const createParenRegex = (parens: string[]): RegExp => patternToRegex(parens.map(escapeParen).join('|')); /** - * Builds a RegExp for placeholder patterns + * Builds a RegExp for parameter placeholder patterns * @param {string[]} types - list of strings that denote placeholder types * @param {string} pattern - string that denotes placeholder pattern */ -export const createPlaceholderRegex = (types: string[], pattern: string): RegExp | undefined => { +export const createParameterRegex = (types: string[], pattern: string): RegExp | undefined => { if (isEmpty(types)) { return undefined; } diff --git a/src/core/token.ts b/src/core/token.ts index 8b3f4849c9..47c962fbba 100644 --- a/src/core/token.ts +++ b/src/core/token.ts @@ -17,7 +17,7 @@ export enum TokenType { LINE_COMMENT = 'LINE_COMMENT', BLOCK_COMMENT = 'BLOCK_COMMENT', NUMBER = 'NUMBER', - PLACEHOLDER = 'PLACEHOLDER', + PARAMETER = 'PARAMETER', EOF = 'EOF', } diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index 7d0be7e346..8132954df4 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -846,9 +846,9 @@ export default class BigQueryFormatter extends Formatter { ], identTypes: ['``'], identChars: { dashes: true }, - positionalPlaceholders: true, - namedPlaceholderTypes: ['@'], - quotedPlaceholderTypes: ['@'], + positionalParams: true, + namedParamTypes: ['@'], + quotedParamTypes: ['@'], lineCommentTypes: ['--', '#'], operators: BigQueryFormatter.operators, preprocess, diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index 87c572bef8..cb14030576 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -871,8 +871,8 @@ export default class Db2Formatter extends Formatter { ]), stringTypes: [{ quote: "''", prefixes: ['X', 'G', 'N', 'GX', 'UX', 'U&'] }], identTypes: [`""`], - positionalPlaceholders: true, - namedPlaceholderTypes: [':'], + positionalParams: true, + namedParamTypes: [':'], operators: Db2Formatter.operators, }); } diff --git a/src/languages/mariadb.formatter.ts b/src/languages/mariadb.formatter.ts index 2d25f70f4f..e0749171b5 100644 --- a/src/languages/mariadb.formatter.ts +++ b/src/languages/mariadb.formatter.ts @@ -1173,7 +1173,7 @@ export default class MariaDbFormatter extends Formatter { { quote: "''", prefixes: ['@'], required: true }, { quote: '``', prefixes: ['@'], required: true }, ], - positionalPlaceholders: true, + positionalParams: true, lineCommentTypes: ['--', '#'], operators: MariaDbFormatter.operators, preprocess, diff --git a/src/languages/mysql.formatter.ts b/src/languages/mysql.formatter.ts index 4a68bd1351..1cb20ea2b2 100644 --- a/src/languages/mysql.formatter.ts +++ b/src/languages/mysql.formatter.ts @@ -1336,7 +1336,7 @@ export default class MySqlFormatter extends Formatter { { quote: "''", prefixes: ['@'], required: true }, { quote: '``', prefixes: ['@'], required: true }, ], - positionalPlaceholders: true, + positionalParams: true, lineCommentTypes: ['--', '#'], operators: MySqlFormatter.operators, preprocess, diff --git a/src/languages/n1ql.formatter.ts b/src/languages/n1ql.formatter.ts index 4d9aa4bd61..0f44d2c3fe 100644 --- a/src/languages/n1ql.formatter.ts +++ b/src/languages/n1ql.formatter.ts @@ -527,9 +527,9 @@ export default class N1qlFormatter extends Formatter { identTypes: ['``'], blockStart: ['(', '[', '{'], blockEnd: [')', ']', '}'], - positionalPlaceholders: true, - numberedPlaceholderTypes: ['$'], - namedPlaceholderTypes: ['$'], + positionalParams: true, + numberedParamTypes: ['$'], + namedParamTypes: ['$'], lineCommentTypes: ['#', '--'], operators: N1qlFormatter.operators, }); diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 1631a1fe18..51b834c89e 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -466,8 +466,8 @@ export default class PlSqlFormatter extends Formatter { identTypes: [`""`], identChars: { rest: '$#' }, variableTypes: [{ regex: '&{1,2}[A-Za-z][A-Za-z0-9_$#]*' }], - numberedPlaceholderTypes: [':'], - namedPlaceholderTypes: [':'], + numberedParamTypes: [':'], + namedParamTypes: [':'], operators: PlSqlFormatter.operators, preprocess, }); diff --git a/src/languages/postgresql.formatter.ts b/src/languages/postgresql.formatter.ts index 860d063d1e..6afbff4d35 100644 --- a/src/languages/postgresql.formatter.ts +++ b/src/languages/postgresql.formatter.ts @@ -1684,7 +1684,7 @@ export default class PostgreSqlFormatter extends Formatter { stringTypes: [{ quote: "''", prefixes: ['U&', 'E', 'X', 'B'] }, '$$'], identTypes: [{ quote: '""', prefixes: ['U&'] }], identChars: { rest: '$' }, - numberedPlaceholderTypes: ['$'], + numberedParamTypes: ['$'], operators: PostgreSqlFormatter.operators, }); } diff --git a/src/languages/redshift.formatter.ts b/src/languages/redshift.formatter.ts index 520cc1381d..23b087a52c 100644 --- a/src/languages/redshift.formatter.ts +++ b/src/languages/redshift.formatter.ts @@ -728,7 +728,7 @@ export default class RedshiftFormatter extends Formatter { ]), stringTypes: ["''"], identTypes: [`""`], - numberedPlaceholderTypes: ['$'], + numberedParamTypes: ['$'], operators: RedshiftFormatter.operators, }); } diff --git a/src/languages/sql.formatter.ts b/src/languages/sql.formatter.ts index 73c1bce43b..d02d4829e3 100644 --- a/src/languages/sql.formatter.ts +++ b/src/languages/sql.formatter.ts @@ -379,7 +379,7 @@ export default class SqlFormatter extends Formatter { reservedKeywords: dedupe(reservedKeywords), stringTypes: [{ quote: "''", prefixes: ['X'] }], identTypes: [`""`, '``'], - positionalPlaceholders: true, + positionalParams: true, }); } } diff --git a/src/languages/sqlite.formatter.ts b/src/languages/sqlite.formatter.ts index 09d98dcc16..8edb2f0b31 100644 --- a/src/languages/sqlite.formatter.ts +++ b/src/languages/sqlite.formatter.ts @@ -433,9 +433,9 @@ export default class SqliteFormatter extends Formatter { stringTypes: [{ quote: "''", prefixes: ['X'] }], identTypes: [`""`, '``', '[]'], // https://www.sqlite.org/lang_expr.html#parameters - positionalPlaceholders: true, - numberedPlaceholderTypes: ['?'], - namedPlaceholderTypes: [':', '@', '$'], + positionalParams: true, + numberedParamTypes: ['?'], + namedParamTypes: [':', '@', '$'], operators: SqliteFormatter.operators, }); } diff --git a/src/languages/tsql.formatter.ts b/src/languages/tsql.formatter.ts index 136d8f5759..fe178d7dc0 100644 --- a/src/languages/tsql.formatter.ts +++ b/src/languages/tsql.formatter.ts @@ -1245,8 +1245,8 @@ export default class TSqlFormatter extends Formatter { stringTypes: [{ quote: "''", prefixes: ['N'] }], identTypes: [`""`, '[]'], identChars: { first: '#@', rest: '#@$' }, - namedPlaceholderTypes: ['@'], - quotedPlaceholderTypes: ['@'], + namedParamTypes: ['@'], + quotedParamTypes: ['@'], operators: TSqlFormatter.operators, // TODO: Support for money constants }); From 7d17351313680284c1667cfe7e3ef7685b31623c Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 9 Jun 2022 10:42:59 +0300 Subject: [PATCH 190/334] Support @, #, $ characters in DB2 parameters --- src/core/Tokenizer.ts | 6 +++++- src/languages/db2.formatter.ts | 1 + test/db2.test.ts | 12 ++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/core/Tokenizer.ts b/src/core/Tokenizer.ts index 42d6e0a158..aa2aae928a 100644 --- a/src/core/Tokenizer.ts +++ b/src/core/Tokenizer.ts @@ -46,6 +46,10 @@ interface TokenizerOptions { lineCommentTypes?: string[]; // Additional characters to support in identifiers identChars?: regexFactory.IdentChars; + // Additional characters to support in named parameters + // Use this when parameters allow different characters from identifiers + // Defaults to `identChars`. + paramChars?: regexFactory.IdentChars; // Additional multi-character operators to support, in addition to <=, >=, <>, != operators?: string[]; // Allows custom modifications on the token array. @@ -128,7 +132,7 @@ export default class Tokenizer { // :name placeholders regex: regexFactory.createParameterRegex( cfg.namedParamTypes ?? [], - regexFactory.createIdentPattern(cfg.identChars) + regexFactory.createIdentPattern(cfg.paramChars || cfg.identChars) ), parseKey: v => v.slice(1), }, diff --git a/src/languages/db2.formatter.ts b/src/languages/db2.formatter.ts index cb14030576..8c41bbaad3 100644 --- a/src/languages/db2.formatter.ts +++ b/src/languages/db2.formatter.ts @@ -873,6 +873,7 @@ export default class Db2Formatter extends Formatter { identTypes: [`""`], positionalParams: true, namedParamTypes: [':'], + paramChars: { first: '@#$', rest: '@#$' }, operators: Db2Formatter.operators, }); } diff --git a/test/db2.test.ts b/test/db2.test.ts index b805732f01..b1aaaddfff 100644 --- a/test/db2.test.ts +++ b/test/db2.test.ts @@ -74,4 +74,16 @@ describe('Db2Formatter', () => { foo `); }); + + it('supports @, #, $ characters in named parameters', () => { + expect(format(`SELECT :foo@bar, :foo#bar, :foo$bar, :@zip, :#zap, :$zop`)).toBe(dedent` + SELECT + :foo@bar, + :foo#bar, + :foo$bar, + :@zip, + :#zap, + :$zop + `); + }); }); From fe4947597680ef54ebbff8dcc9eaa5191045a704 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 9 Jun 2022 10:51:31 +0300 Subject: [PATCH 191/334] Don't allow # and $ chars in PL/SQL parameters --- src/languages/plsql.formatter.ts | 1 + test/plsql.test.ts | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/src/languages/plsql.formatter.ts b/src/languages/plsql.formatter.ts index 51b834c89e..cc6b198513 100644 --- a/src/languages/plsql.formatter.ts +++ b/src/languages/plsql.formatter.ts @@ -468,6 +468,7 @@ export default class PlSqlFormatter extends Formatter { variableTypes: [{ regex: '&{1,2}[A-Za-z][A-Za-z0-9_$#]*' }], numberedParamTypes: [':'], namedParamTypes: [':'], + paramChars: {}, // Empty object used on purpose to not allow $ and # chars as specified in identChars operators: PlSqlFormatter.operators, preprocess, }); diff --git a/test/plsql.test.ts b/test/plsql.test.ts index 53f4a279b3..d335f0e97c 100644 --- a/test/plsql.test.ts +++ b/test/plsql.test.ts @@ -66,6 +66,16 @@ describe('PlSqlFormatter', () => { `); }); + // Parameters don't allow the same characters as identifiers + it('does not support #, $ in named parameters', () => { + expect(format('SELECT :col$foo')).toBe(dedent` + SELECT + :col $foo + `); + + expect(() => format('SELECT :col#foo')).toThrowError('Parse error: Unexpected "#foo"'); + }); + it('supports &name substitution variables', () => { const result = format('SELECT &name, &some$Special#Chars_, &hah123 FROM &&tbl'); expect(result).toBe(dedent` From a6711c52c86e143c1b3749ad62a7b41d2d2e02ad Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 9 Jun 2022 11:04:08 +0300 Subject: [PATCH 192/334] Additional link to Hive variables docs --- sql/variables.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sql/variables.md b/sql/variables.md index 80a975bc32..32582acf9e 100644 --- a/sql/variables.md +++ b/sql/variables.md @@ -2,10 +2,11 @@ - [BigQuery][]: identifier syntax - [DB2][]: identifier syntax -- [Hive][]: `${hivevar:name}`, `${hiveconf:name}` or `${name}`. These are substitution variables (as in Oracle SQL terminology). +- [Hive][]: `${hivevar:name}`, `${hiveconf:name}`, `${system:name}` or `${name}`. These are substitution variables (as in Oracle SQL terminology). They behave more like string-interpolation, that is, the values aren't automatically escaped by the system. A common example is to place the variable inside a string: `SELECT * FROM users WHERE name = '${hivevar:USER_NAME}'`. Also one can use the variable to parameterize table or column name (`SELECT * FROM ${hivevar:my_table}`). + See also [post in StackOverflow][hive-stackoverflow]. - [MariaDB][]: `@name` (where the name consists of alphanumeric characters, `.`, `_`, and `$`), `@'var name'`, `@"var name"`, `` @`var name` `` (can be quoted as string or identifier) - [MySQL][]: Same as MariaDB - N1QL: _N/A_ @@ -19,7 +20,8 @@ [parameters]: ./parameters.md [bigquery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language [db2]: https://www.ibm.com/docs/en/db2-for-zos/11?topic=pl-references-sql-parameters-variables -[hive]: https://stackoverflow.com/questions/12464636/how-to-set-variables-in-hive-scripts +[hive]: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+VariableSubstitution +[hive-stackoverflow]: https://stackoverflow.com/questions/12464636/how-to-set-variables-in-hive-scripts [mariadb]: https://mariadb.com/kb/en/user-defined-variables/ [mysql]: https://dev.mysql.com/doc/refman/8.0/en/user-variables.html [pl/sql]: https://docs.oracle.com/en/database/oracle/oracle-database/21/sqpug/using-substitution-variables-sqlplus.html#GUID-0BEEC1D7-876B-495C-9327-17037652D3D2 From 8d60a31a730e0d0d603c69742107db4990dede0d Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 9 Jun 2022 11:46:27 +0300 Subject: [PATCH 193/334] Document support for arrays and maps --- sql/arrays-and-maps.md | 30 ++++++++++++++++++++++++++++++ sql/syntax.md | 1 + 2 files changed, 31 insertions(+) create mode 100644 sql/arrays-and-maps.md diff --git a/sql/arrays-and-maps.md b/sql/arrays-and-maps.md new file mode 100644 index 0000000000..4fe98e2d5b --- /dev/null +++ b/sql/arrays-and-maps.md @@ -0,0 +1,30 @@ +# Arrays and Maps + +Some SQL dialects have special syntax for creating and manipulating Array and Map types. + +## Literals + +Array literals `[1, "two", 3]`. Supported by: + +- [BigQuery][bigquery-literals]. +- [N1QL][n1ql-literals]. + +Map literals in JSON style `{"foo": 1, "bar": "John"}`. Supported by: + +- [N1QL][n1ql-literals]. + +## Accessors + +Array and Map access using square brackets like `arr[1]` and `map['key']`. + +Supported by: + +- [Hive][] +- [Spark][] +- [N1QL][] + +[hive]: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF#LanguageManualUDF-OperatorsonComplexTypes +[spark]: https://stackoverflow.com/questions/34916038/sparksql-sql-syntax-for-nth-item-in-array +[n1ql-literals]: https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/datatypes.html#arrays +[n1ql]: https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/nestedops.html#field-selection +[bigquery-literals]: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#array_literals diff --git a/sql/syntax.md b/sql/syntax.md index b367e82bb5..453d98f717 100644 --- a/sql/syntax.md +++ b/sql/syntax.md @@ -6,4 +6,5 @@ Reference of SQL syntax variations. - [Parameters](./parameters.md) - [Variables](./variables.md) - [Strings](./strings.md) +- [Arrays and Maps](./arrays-and-maps.md) - [SELECT](./select.md) From 96ca9e4935915a31b4f0183a994c5f628f75fdbd Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 9 Jun 2022 11:52:47 +0300 Subject: [PATCH 194/334] Restore support for array and map accessors in Spark & Hive --- src/languages/hive.formatter.ts | 2 ++ src/languages/spark.formatter.ts | 2 ++ test/features/array.ts | 29 --------------------------- test/features/arrayAndMapAccessors.ts | 23 +++++++++++++++++++++ test/hive.test.ts | 4 ++-- test/n1ql.test.ts | 4 ++-- test/spark.test.ts | 4 ++-- 7 files changed, 33 insertions(+), 35 deletions(-) delete mode 100644 test/features/array.ts create mode 100644 test/features/arrayAndMapAccessors.ts diff --git a/src/languages/hive.formatter.ts b/src/languages/hive.formatter.ts index d3838cf2ef..c6ccc39987 100644 --- a/src/languages/hive.formatter.ts +++ b/src/languages/hive.formatter.ts @@ -624,6 +624,8 @@ export default class HiveFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), + blockStart: ['(', '['], + blockEnd: [')', ']'], stringTypes: ['""', "''"], identTypes: ['``'], variableTypes: [{ quote: '{}', prefixes: ['$'], required: true }], diff --git a/src/languages/spark.formatter.ts b/src/languages/spark.formatter.ts index aa1a19d290..8d0b37d006 100644 --- a/src/languages/spark.formatter.ts +++ b/src/languages/spark.formatter.ts @@ -789,6 +789,8 @@ export default class SparkFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...reservedKeywords, ]), + blockStart: ['(', '['], + blockEnd: [')', ']'], stringTypes: [{ quote: "''", prefixes: ['X'] }], identTypes: ['``'], variableTypes: [{ quote: '{}', prefixes: ['$'], required: true }], diff --git a/test/features/array.ts b/test/features/array.ts deleted file mode 100644 index aa84785115..0000000000 --- a/test/features/array.ts +++ /dev/null @@ -1,29 +0,0 @@ -import dedent from 'dedent-js'; - -import { FormatFn } from 'src/sqlFormatter'; - -export default function supportsArray(format: FormatFn) { - // TODO: These accessors were implemented as part of identifiers, - // resulting in "alpha[1]" being tokenized to single identifier token. - // That's semantically not correct and quite a surprising behavior. - - it.skip('handles array and map accessors', () => { - const result = format(`SELECT alpha[1], beta['gamma'], epsilon["zeta"] FROM eta;`); - expect(result).toBe(dedent` - SELECT - alpha[1], - beta['gamma'], - epsilon["zeta"] - FROM - eta; - `); - }); - - it.skip('supports square brackets for array indexing', () => { - const result = format(`SELECT order_lines[5].productId;`); - expect(result).toBe(dedent` - SELECT - order_lines[5].productId; - `); - }); -} diff --git a/test/features/arrayAndMapAccessors.ts b/test/features/arrayAndMapAccessors.ts new file mode 100644 index 0000000000..1d384f2da7 --- /dev/null +++ b/test/features/arrayAndMapAccessors.ts @@ -0,0 +1,23 @@ +import dedent from 'dedent-js'; + +import { FormatFn } from 'src/sqlFormatter'; + +export default function supportsArrayAndMapAccessors(format: FormatFn) { + it('supports square brackets for array indexing', () => { + const result = format(`SELECT arr[1], order_lines[5].productId;`); + expect(result).toBe(dedent` + SELECT + arr[1], + order_lines[5].productId; + `); + }); + + it('supports square brackets for map lookup', () => { + const result = format(`SELECT alpha['a'], beta['gamma'].zeta;`); + expect(result).toBe(dedent` + SELECT + alpha['a'], + beta['gamma'].zeta; + `); + }); +} diff --git a/test/hive.test.ts b/test/hive.test.ts index 4e786d2818..3df989c2c1 100644 --- a/test/hive.test.ts +++ b/test/hive.test.ts @@ -12,7 +12,7 @@ import supportsStrings from './features/strings'; import supportsBetween from './features/between'; import supportsJoin from './features/join'; import supportsOperators from './features/operators'; -import supportsArray from './features/array'; +import supportsArrayAndMapAccessors from './features/arrayAndMapAccessors'; import supportsComments from './features/comments'; import supportsIdentifiers from './features/identifiers'; @@ -30,7 +30,7 @@ describe('HiveFormatter', () => { supportsSchema(format); supportsJoin(format, { without: ['NATURAL JOIN'] }); supportsOperators(format, HiveFormatter.operators); - supportsArray(format); + supportsArrayAndMapAccessors(format); it('throws error when params option used', () => { expect(() => format('SELECT *', { params: ['1', '2', '3'] })).toThrow( diff --git a/test/n1ql.test.ts b/test/n1ql.test.ts index d7a203299c..ac7e8b16a2 100644 --- a/test/n1ql.test.ts +++ b/test/n1ql.test.ts @@ -11,7 +11,7 @@ import supportsSchema from './features/schema'; import supportsStrings from './features/strings'; import supportsReturning from './features/returning'; import supportsDeleteFrom from './features/deleteFrom'; -import supportsArray from './features/array'; +import supportsArrayAndMapAccessors from './features/arrayAndMapAccessors'; import supportsComments from './features/comments'; import supportsIdentifiers from './features/identifiers'; import supportsParams from './options/param'; @@ -28,7 +28,7 @@ describe('N1qlFormatter', () => { supportsBetween(format); supportsSchema(format); supportsOperators(format, N1qlFormatter.operators, ['AND', 'OR', 'XOR']); - supportsArray(format); + supportsArrayAndMapAccessors(format); supportsJoin(format, { without: ['FULL', 'CROSS', 'NATURAL'] }); supportsReturning(format); supportsParams(format, { positional: true, numbered: ['$'], named: ['$'] }); diff --git a/test/spark.test.ts b/test/spark.test.ts index 2d468b5d98..c5734c1763 100644 --- a/test/spark.test.ts +++ b/test/spark.test.ts @@ -11,7 +11,7 @@ import supportsJoin from './features/join'; import supportsOperators from './features/operators'; import supportsSchema from './features/schema'; import supportsStrings from './features/strings'; -import supportsArray from './features/array'; +import supportsArrayAndMapAccessors from './features/arrayAndMapAccessors'; import supportsComments from './features/comments'; import supportsIdentifiers from './features/identifiers'; @@ -28,7 +28,7 @@ describe('SparkFormatter', () => { supportsBetween(format); supportsSchema(format); supportsOperators(format, SparkFormatter.operators, ['AND', 'OR', 'XOR']); - supportsArray(format); + supportsArrayAndMapAccessors(format); supportsJoin(format, { additionally: [ 'ANTI JOIN', From 774d2a9f81259325271d1ab6e1b3c40cede014c1 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 9 Jun 2022 12:01:50 +0300 Subject: [PATCH 195/334] Support Array literals in BigQuery Also fixing a bug in formatting of ARRAY[1] --- src/languages/bigquery.formatter.ts | 2 ++ test/bigquery.test.ts | 5 +++-- test/features/arrayLiterals.ts | 15 +++++++++++++++ test/n1ql.test.ts | 15 ++------------- 4 files changed, 22 insertions(+), 15 deletions(-) create mode 100644 test/features/arrayLiterals.ts diff --git a/src/languages/bigquery.formatter.ts b/src/languages/bigquery.formatter.ts index 8132954df4..2afe4e5b0d 100644 --- a/src/languages/bigquery.formatter.ts +++ b/src/languages/bigquery.formatter.ts @@ -836,6 +836,8 @@ export default class BigQueryFormatter extends Formatter { ...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []), ...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []), ]), + blockStart: ['(', '['], + blockEnd: [')', ']'], stringTypes: [ // The triple-quoted strings are listed first, so they get matched first. // Otherwise the first two quotes of """ will get matched as an empty "" string. diff --git a/test/bigquery.test.ts b/test/bigquery.test.ts index 68f79f5a62..c23c55048f 100644 --- a/test/bigquery.test.ts +++ b/test/bigquery.test.ts @@ -7,6 +7,7 @@ import behavesLikeSqlFormatter from './behavesLikeSqlFormatter'; import supportsCreateTable from './features/createTable'; import supportsSchema from './features/schema'; import supportsStrings from './features/strings'; +import supportsArrayLiterals from './features/arrayLiterals'; import supportsBetween from './features/between'; import supportsJoin from './features/join'; import supportsOperators from './features/operators'; @@ -25,6 +26,7 @@ describe('BigQueryFormatter', () => { supportsDeleteFrom(format); supportsStrings(format, ['""', "''"]); supportsIdentifiers(format, ['``']); + supportsArrayLiterals(format); supportsBetween(format); supportsSchema(format); supportsJoin(format, { without: ['NATURAL JOIN'] }); @@ -127,11 +129,10 @@ describe('BigQueryFormatter', () => { it('supports parametric ARRAY and STRUCT', () => { const result = format('SELECT STRUCT>([]), ARRAY[1] FROM tbl'); - // TODO, v6: ARRAY [] should be ARRAY[] expect(result).toBe(dedent` SELECT STRUCT>([]), - ARRAY [1] + ARRAY[1] FROM tbl `); diff --git a/test/features/arrayLiterals.ts b/test/features/arrayLiterals.ts new file mode 100644 index 0000000000..b5316edcb6 --- /dev/null +++ b/test/features/arrayLiterals.ts @@ -0,0 +1,15 @@ +import dedent from 'dedent-js'; + +import { FormatFn } from 'src/sqlFormatter'; + +export default function supportsArrayLiterals(format: FormatFn) { + it('supports array literals', () => { + const result = format(`SELECT [1, 2, 3] FROM ['John', 'Doe'];`); + expect(result).toBe(dedent` + SELECT + [1, 2, 3] + FROM + ['John', 'Doe']; + `); + }); +} diff --git a/test/n1ql.test.ts b/test/n1ql.test.ts index ac7e8b16a2..b2adb6c4ed 100644 --- a/test/n1ql.test.ts +++ b/test/n1ql.test.ts @@ -12,6 +12,7 @@ import supportsStrings from './features/strings'; import supportsReturning from './features/returning'; import supportsDeleteFrom from './features/deleteFrom'; import supportsArrayAndMapAccessors from './features/arrayAndMapAccessors'; +import supportsArrayLiterals from './features/arrayLiterals'; import supportsComments from './features/comments'; import supportsIdentifiers from './features/identifiers'; import supportsParams from './options/param'; @@ -29,23 +30,11 @@ describe('N1qlFormatter', () => { supportsSchema(format); supportsOperators(format, N1qlFormatter.operators, ['AND', 'OR', 'XOR']); supportsArrayAndMapAccessors(format); + supportsArrayLiterals(format); supportsJoin(format, { without: ['FULL', 'CROSS', 'NATURAL'] }); supportsReturning(format); supportsParams(format, { positional: true, numbered: ['$'], named: ['$'] }); - it('formats SELECT query with primary key querying', () => { - const result = format("SELECT fname, email FROM tutorial USE KEYS ['dave', 'ian'];"); - expect(result).toBe(dedent` - SELECT - fname, - email - FROM - tutorial - USE KEYS - ['dave', 'ian']; - `); - }); - it('formats INSERT with {} object literal', () => { const result = format( "INSERT INTO heroes (KEY, VALUE) VALUES ('123', {'id':1,'type':'Tarzan'});" From fa8d4a9c3bbf29e0d624c94a69e232f4d1405132 Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 9 Jun 2022 12:07:31 +0300 Subject: [PATCH 196/334] Additional regression test for map keys Fixes #230 --- test/features/arrayAndMapAccessors.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/features/arrayAndMapAccessors.ts b/test/features/arrayAndMapAccessors.ts index 1d384f2da7..95cba4635a 100644 --- a/test/features/arrayAndMapAccessors.ts +++ b/test/features/arrayAndMapAccessors.ts @@ -12,12 +12,14 @@ export default function supportsArrayAndMapAccessors(format: FormatFn) { `); }); + // The check for yota['foo.bar-baz'] is for Issue #230 it('supports square brackets for map lookup', () => { - const result = format(`SELECT alpha['a'], beta['gamma'].zeta;`); + const result = format(`SELECT alpha['a'], beta['gamma'].zeta, yota['foo.bar-baz'];`); expect(result).toBe(dedent` SELECT alpha['a'], - beta['gamma'].zeta; + beta['gamma'].zeta, + yota['foo.bar-baz']; `); }); } From 6578e1877f36cb8c1863f1d98192c12bbd83acba Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Thu, 9 Jun 2022 15:07:55 +0300 Subject: [PATCH 197/334] Change demo links to point at sql-formatter-org --- static/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/index.html b/static/index.html index 6ae8ac1dc0..4d9406de2f 100644 --- a/static/index.html +++ b/static/index.html @@ -12,7 +12,7 @@ property="og:description" content="A whitespace formatter for different query languages" /> - + @@ -31,7 +31,7 @@

SQL Formatter