From 3892a87948446149d7c420924c8f801b61640e3e Mon Sep 17 00:00:00 2001 From: Remco Haszing Date: Wed, 6 Sep 2023 13:59:02 +0200 Subject: [PATCH 01/18] Fix some small type issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some parameters are optional, but were marked as required. Language service methods were marked as bound methods, but they don’t have to be called as such. The `Thenable` type from `json-rpc` was used. These were replaced with the builtin TypeScript type `PromiseLike`. --- .../handlers/languageHandlers.ts | 4 +- src/languageservice/services/yamlCodeLens.ts | 2 +- src/languageservice/services/yamlFormatter.ts | 2 +- src/languageservice/yamlLanguageService.ts | 44 +++++++++---------- src/yamlSettings.ts | 2 +- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/languageserver/handlers/languageHandlers.ts b/src/languageserver/handlers/languageHandlers.ts index 7820f06e7..df7005b94 100644 --- a/src/languageserver/handlers/languageHandlers.ts +++ b/src/languageserver/handlers/languageHandlers.ts @@ -229,7 +229,7 @@ export class LanguageHandlers { return this.languageService.getCodeAction(textDocument, params); } - codeLensHandler(params: CodeLensParams): Thenable | CodeLens[] | undefined { + codeLensHandler(params: CodeLensParams): PromiseLike | CodeLens[] | undefined { const textDocument = this.yamlSettings.documents.get(params.textDocument.uri); if (!textDocument) { return; @@ -237,7 +237,7 @@ export class LanguageHandlers { return this.languageService.getCodeLens(textDocument); } - codeLensResolveHandler(param: CodeLens): Thenable | CodeLens { + codeLensResolveHandler(param: CodeLens): PromiseLike | CodeLens { return this.languageService.resolveCodeLens(param); } diff --git a/src/languageservice/services/yamlCodeLens.ts b/src/languageservice/services/yamlCodeLens.ts index 7157ccf8a..b1ae69d37 100644 --- a/src/languageservice/services/yamlCodeLens.ts +++ b/src/languageservice/services/yamlCodeLens.ts @@ -44,7 +44,7 @@ export class YamlCodeLens { return result; } - resolveCodeLens(param: CodeLens): Thenable | CodeLens { + resolveCodeLens(param: CodeLens): PromiseLike | CodeLens { return param; } } diff --git a/src/languageservice/services/yamlFormatter.ts b/src/languageservice/services/yamlFormatter.ts index 203cf7491..5727877bc 100644 --- a/src/languageservice/services/yamlFormatter.ts +++ b/src/languageservice/services/yamlFormatter.ts @@ -21,7 +21,7 @@ export class YAMLFormatter { } } - public format(document: TextDocument, options: FormattingOptions & CustomFormatterOptions): TextEdit[] { + public format(document: TextDocument, options: Partial & CustomFormatterOptions = {}): TextEdit[] { if (!this.formatterEnabled) { return []; } diff --git a/src/languageservice/yamlLanguageService.ts b/src/languageservice/yamlLanguageService.ts index 6fd1153da..539371d8b 100644 --- a/src/languageservice/yamlLanguageService.ts +++ b/src/languageservice/yamlLanguageService.ts @@ -157,28 +157,28 @@ export interface CustomFormatterOptions { } export interface LanguageService { - configure(settings: LanguageSettings): void; - registerCustomSchemaProvider(schemaProvider: CustomSchemaProvider): void; - doComplete(document: TextDocument, position: Position, isKubernetes: boolean): Promise; - doValidation(document: TextDocument, isKubernetes: boolean): Promise; - doHover(document: TextDocument, position: Position): Promise; - findDocumentSymbols(document: TextDocument, context: DocumentSymbolsContext): SymbolInformation[]; - findDocumentSymbols2(document: TextDocument, context: DocumentSymbolsContext): DocumentSymbol[]; - findLinks(document: TextDocument): Promise; - resetSchema(uri: string): boolean; - doFormat(document: TextDocument, options: CustomFormatterOptions): TextEdit[]; - doDefinition(document: TextDocument, params: DefinitionParams): DefinitionLink[] | undefined; - doDocumentOnTypeFormatting(document: TextDocument, params: DocumentOnTypeFormattingParams): TextEdit[] | undefined; - addSchema(schemaID: string, schema: JSONSchema): void; - deleteSchema(schemaID: string): void; - modifySchemaContent(schemaAdditions: SchemaAdditions): void; - deleteSchemaContent(schemaDeletions: SchemaDeletions): void; - deleteSchemasWhole(schemaDeletions: SchemaDeletionsAll): void; - getFoldingRanges(document: TextDocument, context: FoldingRangesContext): FoldingRange[] | null; - getSelectionRanges(document: TextDocument, positions: Position[]): SelectionRange[] | undefined; - getCodeAction(document: TextDocument, params: CodeActionParams): CodeAction[] | undefined; - getCodeLens(document: TextDocument): Thenable | CodeLens[] | undefined; - resolveCodeLens(param: CodeLens): Thenable | CodeLens; + configure: (settings: LanguageSettings) => void; + registerCustomSchemaProvider: (schemaProvider: CustomSchemaProvider) => void; + doComplete: (document: TextDocument, position: Position, isKubernetes: boolean) => Promise; + doValidation: (document: TextDocument, isKubernetes: boolean) => Promise; + doHover: (document: TextDocument, position: Position) => Promise; + findDocumentSymbols: (document: TextDocument, context?: DocumentSymbolsContext) => SymbolInformation[]; + findDocumentSymbols2: (document: TextDocument, context?: DocumentSymbolsContext) => DocumentSymbol[]; + findLinks: (document: TextDocument) => Promise; + resetSchema: (uri: string) => boolean; + doFormat: (document: TextDocument, options?: CustomFormatterOptions) => TextEdit[]; + doDefinition: (document: TextDocument, params: DefinitionParams) => DefinitionLink[] | undefined; + doDocumentOnTypeFormatting: (document: TextDocument, params: DocumentOnTypeFormattingParams) => TextEdit[] | undefined; + addSchema: (schemaID: string, schema: JSONSchema) => void; + deleteSchema: (schemaID: string) => void; + modifySchemaContent: (schemaAdditions: SchemaAdditions) => void; + deleteSchemaContent: (schemaDeletions: SchemaDeletions) => void; + deleteSchemasWhole: (schemaDeletions: SchemaDeletionsAll) => void; + getFoldingRanges: (document: TextDocument, context: FoldingRangesContext) => FoldingRange[] | null; + getSelectionRanges: (document: TextDocument, positions: Position[]) => SelectionRange[] | undefined; + getCodeAction: (document: TextDocument, params: CodeActionParams) => CodeAction[] | undefined; + getCodeLens: (document: TextDocument) => PromiseLike | CodeLens[] | undefined; + resolveCodeLens: (param: CodeLens) => PromiseLike | CodeLens; } export function getLanguageService(params: { diff --git a/src/yamlSettings.ts b/src/yamlSettings.ts index 011b0b8bd..fc0260342 100644 --- a/src/yamlSettings.ts +++ b/src/yamlSettings.ts @@ -60,7 +60,7 @@ export interface JSONSchemaSettings { export class SettingsState { yamlConfigurationSettings: JSONSchemaSettings[] = undefined; schemaAssociations: ISchemaAssociations | SchemaConfiguration[] | undefined = undefined; - formatterRegistration: Thenable = null; + formatterRegistration: PromiseLike = null; specificValidatorPaths = []; schemaConfigurationSettings = []; yamlShouldValidate = true; From ad6af4acb0fc6df95f57241aa4029f87cd1f0c4e Mon Sep 17 00:00:00 2001 From: Remco Haszing Date: Fri, 8 Sep 2023 19:51:41 +0200 Subject: [PATCH 02/18] Add volar-service-yaml to clients Volar service YAML makes it possible to integrate `yaml-language-server` for YAML embedded in other text documents, such as frontmatter. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d31a0c0bb..46ad1c328 100755 --- a/README.md +++ b/README.md @@ -388,6 +388,7 @@ This repository only contains the server implementation. Here are some known cli - [monaco-yaml](https://monaco-yaml.js.org) for Monaco editor - [Vim-EasyComplete](https://github.com/jayli/vim-easycomplete) for Vim/NeoVim - [nova-yaml](https://github.com/robb-j/nova-yaml/) for Nova +- [volar-service-yaml](https://github.com/volarjs/services/tree/master/packages/yaml) for Volar ## Developer Support From 8f508fa47813c449370ff05bb07788ec4c099554 Mon Sep 17 00:00:00 2001 From: Remco Haszing Date: Fri, 8 Sep 2023 19:55:44 +0200 Subject: [PATCH 03/18] Remove ide-yaml from known clients Atom has been sunset. The link is no longer available. Clicking the link would take the user to a GitHub blog post about this instead. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 46ad1c328..fd966cfb0 100755 --- a/README.md +++ b/README.md @@ -379,7 +379,6 @@ This repository only contains the server implementation. Here are some known cli - [Eclipse Che](https://www.eclipse.org/che/) - [vscode-yaml](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml) for VSCode -- [ide-yaml](https://atom.io/packages/ide-yaml) for Atom editor - [coc-yaml](https://github.com/neoclide/coc-yaml) for [coc.nvim](https://github.com/neoclide/coc.nvim) - [Eclipse Wild Web Developer](https://marketplace.eclipse.org/content/eclipse-wild-web-developer-web-development-eclipse-ide) for Eclipse IDE - [lsp-mode](https://github.com/emacs-lsp/lsp-mode) for Emacs From 02d69fe2908e68184ed130b936b4e0107122620e Mon Sep 17 00:00:00 2001 From: Petr Spacek Date: Thu, 14 Sep 2023 16:40:52 +0200 Subject: [PATCH 04/18] fix: schema loading performance --- src/languageservice/services/yamlSchemaService.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/languageservice/services/yamlSchemaService.ts b/src/languageservice/services/yamlSchemaService.ts index 08c03229f..61953f166 100644 --- a/src/languageservice/services/yamlSchemaService.ts +++ b/src/languageservice/services/yamlSchemaService.ts @@ -242,7 +242,7 @@ export class YAMLSchemaService extends JSONSchemaService { } const toWalk: JSONSchema[] = [node]; - const seen: JSONSchema[] = []; + const seen: Set = new Set(); // eslint-disable-next-line @typescript-eslint/no-explicit-any const openPromises: Promise[] = []; @@ -278,7 +278,7 @@ export class YAMLSchemaService extends JSONSchemaService { } }; const handleRef = (next: JSONSchema): void => { - const seenRefs = []; + const seenRefs = new Set(); while (next.$ref) { const ref = next.$ref; const segments = ref.split('#', 2); @@ -289,9 +289,9 @@ export class YAMLSchemaService extends JSONSchemaService { openPromises.push(resolveExternalLink(next, segments[0], segments[1], parentSchemaURL, parentSchemaDependencies)); return; } else { - if (seenRefs.indexOf(ref) === -1) { + if (!seenRefs.has(ref)) { merge(next, parentSchema, parentSchemaURL, segments[1]); // can set next.$ref again, use seenRefs to avoid circle - seenRefs.push(ref); + seenRefs.add(ref); } } } @@ -330,10 +330,10 @@ export class YAMLSchemaService extends JSONSchemaService { while (toWalk.length) { const next = toWalk.pop(); - if (seen.indexOf(next) >= 0) { + if (seen.has(next)) { continue; } - seen.push(next); + seen.add(next); handleRef(next); } return Promise.all(openPromises); From 2f2683b105229dc79734dd84149450a5d43bb4e4 Mon Sep 17 00:00:00 2001 From: Petr Spacek Date: Mon, 18 Sep 2023 09:31:34 +0200 Subject: [PATCH 05/18] fix:undefined error in mergingResult.problemArgs --- src/languageservice/parser/jsonParser07.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languageservice/parser/jsonParser07.ts b/src/languageservice/parser/jsonParser07.ts index a9bb2d48d..b4fdfe4b7 100644 --- a/src/languageservice/parser/jsonParser07.ts +++ b/src/languageservice/parser/jsonParser07.ts @@ -400,7 +400,7 @@ export class ValidationResult { (problemType !== ProblemType.missingRequiredPropWarning || isArrayEqual(p.problemArgs, bestResult.problemArgs)) // missingProp is merged only with same problemArg ); if (mergingResult) { - if (mergingResult.problemArgs.length) { + if (mergingResult.problemArgs?.length) { mergingResult.problemArgs .filter((p) => !bestResult.problemArgs.includes(p)) .forEach((p) => bestResult.problemArgs.push(p)); From ed03cbf71ade29ea62b4bcac0d8952195fd6969d Mon Sep 17 00:00:00 2001 From: Remco Haszing Date: Sat, 7 Oct 2023 18:38:07 +0200 Subject: [PATCH 06/18] Remove 'use strict' TypeScript adds this for us. --- src/languageservice/parser/yamlParser07.ts | 1 - src/languageservice/services/documentSymbols.ts | 1 - src/languageservice/services/modelineUtil.ts | 2 +- src/languageservice/services/yamlFormatter.ts | 1 - src/languageservice/services/yamlHover.ts | 1 - src/languageservice/services/yamlSchemaService.ts | 1 - src/languageservice/services/yamlValidation.ts | 1 - src/languageservice/utils/documentPositionCalculator.ts | 1 - src/languageservice/utils/objects.ts | 1 - src/languageservice/utils/strings.ts | 1 - src/server.ts | 1 - test/schema.test.ts | 2 -- 12 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/languageservice/parser/yamlParser07.ts b/src/languageservice/parser/yamlParser07.ts index bd44891de..1f39a8220 100644 --- a/src/languageservice/parser/yamlParser07.ts +++ b/src/languageservice/parser/yamlParser07.ts @@ -3,7 +3,6 @@ * Copyright (c) Adam Voss. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; import { Parser, Composer, Document, LineCounter, ParseOptions, DocumentOptions, SchemaOptions } from 'yaml'; import { YAMLDocument, SingleYAMLDocument } from './yaml-documents'; diff --git a/src/languageservice/services/documentSymbols.ts b/src/languageservice/services/documentSymbols.ts index 6aa631d63..42520736b 100644 --- a/src/languageservice/services/documentSymbols.ts +++ b/src/languageservice/services/documentSymbols.ts @@ -3,7 +3,6 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; import { SymbolInformation, DocumentSymbol } from 'vscode-languageserver-types'; import { YAMLSchemaService } from './yamlSchemaService'; diff --git a/src/languageservice/services/modelineUtil.ts b/src/languageservice/services/modelineUtil.ts index 76aa1bdda..46badd632 100644 --- a/src/languageservice/services/modelineUtil.ts +++ b/src/languageservice/services/modelineUtil.ts @@ -2,7 +2,7 @@ * Copyright (c) Red Hat, Inc. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; + import { SingleYAMLDocument } from '../parser/yamlParser07'; import { JSONDocument } from '../parser/jsonParser07'; diff --git a/src/languageservice/services/yamlFormatter.ts b/src/languageservice/services/yamlFormatter.ts index 5727877bc..fff674444 100644 --- a/src/languageservice/services/yamlFormatter.ts +++ b/src/languageservice/services/yamlFormatter.ts @@ -3,7 +3,6 @@ * Copyright (c) Adam Voss. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; import { Range, Position, TextEdit, FormattingOptions } from 'vscode-languageserver-types'; import { CustomFormatterOptions, LanguageSettings } from '../yamlLanguageService'; diff --git a/src/languageservice/services/yamlHover.ts b/src/languageservice/services/yamlHover.ts index 3e7cc8a50..d19ce53bf 100644 --- a/src/languageservice/services/yamlHover.ts +++ b/src/languageservice/services/yamlHover.ts @@ -3,7 +3,6 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; import { Hover, MarkupContent, MarkupKind, Position, Range } from 'vscode-languageserver-types'; import { matchOffsetToDocument } from '../utils/arrUtils'; diff --git a/src/languageservice/services/yamlSchemaService.ts b/src/languageservice/services/yamlSchemaService.ts index 61953f166..453b74eb9 100644 --- a/src/languageservice/services/yamlSchemaService.ts +++ b/src/languageservice/services/yamlSchemaService.ts @@ -3,7 +3,6 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; import { JSONSchema, JSONSchemaMap, JSONSchemaRef } from '../jsonSchema'; import { SchemaPriority, SchemaRequestService, WorkspaceContextService } from '../yamlLanguageService'; diff --git a/src/languageservice/services/yamlValidation.ts b/src/languageservice/services/yamlValidation.ts index 8ba3f023b..fd26af2e8 100644 --- a/src/languageservice/services/yamlValidation.ts +++ b/src/languageservice/services/yamlValidation.ts @@ -3,7 +3,6 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; import { Diagnostic, Position } from 'vscode-languageserver-types'; import { LanguageSettings } from '../yamlLanguageService'; diff --git a/src/languageservice/utils/documentPositionCalculator.ts b/src/languageservice/utils/documentPositionCalculator.ts index 0abbf098d..a1b2d0f7c 100644 --- a/src/languageservice/utils/documentPositionCalculator.ts +++ b/src/languageservice/utils/documentPositionCalculator.ts @@ -3,7 +3,6 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; import { Position } from 'vscode-languageserver-types'; diff --git a/src/languageservice/utils/objects.ts b/src/languageservice/utils/objects.ts index 7337cf948..8b45199b4 100644 --- a/src/languageservice/utils/objects.ts +++ b/src/languageservice/utils/objects.ts @@ -2,7 +2,6 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types export function equals(one: any, other: any): boolean { diff --git a/src/languageservice/utils/strings.ts b/src/languageservice/utils/strings.ts index 726b260da..6171411df 100644 --- a/src/languageservice/utils/strings.ts +++ b/src/languageservice/utils/strings.ts @@ -2,7 +2,6 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; import { CharCode } from './charCode'; diff --git a/src/server.ts b/src/server.ts index ad8128dc4..0e91671e4 100644 --- a/src/server.ts +++ b/src/server.ts @@ -4,7 +4,6 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; import { createConnection, Connection, ProposedFeatures } from 'vscode-languageserver/node'; import * as nls from 'vscode-nls'; diff --git a/test/schema.test.ts b/test/schema.test.ts index b4ddd1fd4..1747b1c40 100644 --- a/test/schema.test.ts +++ b/test/schema.test.ts @@ -1,5 +1,3 @@ -'use strict'; - import * as assert from 'assert'; import * as parser from '../src/languageservice/parser/yamlParser07'; import * as SchemaService from '../src/languageservice/services/yamlSchemaService'; From d354c58a480dd9d3ef6b754377352b481163f60a Mon Sep 17 00:00:00 2001 From: Skip Baney Date: Tue, 19 Dec 2023 08:48:09 -0600 Subject: [PATCH 07/18] fix: show all enums on hover (#942) --- src/languageservice/services/yamlHover.ts | 67 +++++++++++++++-------- test/hover.test.ts | 41 +++++++++++++- 2 files changed, 82 insertions(+), 26 deletions(-) diff --git a/src/languageservice/services/yamlHover.ts b/src/languageservice/services/yamlHover.ts index d19ce53bf..eb163f6a7 100644 --- a/src/languageservice/services/yamlHover.ts +++ b/src/languageservice/services/yamlHover.ts @@ -12,7 +12,7 @@ import { setKubernetesParserOption } from '../parser/isKubernetes'; import { TextDocument } from 'vscode-languageserver-textdocument'; import { yamlDocumentsCache } from '../parser/yaml-documents'; import { SingleYAMLDocument } from '../parser/yamlParser07'; -import { getNodeValue, IApplicableSchema } from '../parser/jsonParser07'; +import { IApplicableSchema } from '../parser/jsonParser07'; import { JSONSchema } from '../jsonSchema'; import { URI } from 'vscode-uri'; import * as path from 'path'; @@ -113,27 +113,31 @@ export class YAMLHover { let title: string | undefined = undefined; let markdownDescription: string | undefined = undefined; - let markdownEnumValueDescription: string | undefined = undefined; - let enumValue: string | undefined = undefined; + let markdownEnumDescriptions: string[] = []; const markdownExamples: string[] = []; + const markdownEnums: markdownEnum[] = []; matchingSchemas.every((s) => { if ((s.node === node || (node.type === 'property' && node.valueNode === s.node)) && !s.inverted && s.schema) { title = title || s.schema.title || s.schema.closestTitle; markdownDescription = markdownDescription || s.schema.markdownDescription || toMarkdown(s.schema.description); if (s.schema.enum) { - const idx = s.schema.enum.indexOf(getNodeValue(node)); if (s.schema.markdownEnumDescriptions) { - markdownEnumValueDescription = s.schema.markdownEnumDescriptions[idx]; + markdownEnumDescriptions = s.schema.markdownEnumDescriptions; } else if (s.schema.enumDescriptions) { - markdownEnumValueDescription = toMarkdown(s.schema.enumDescriptions[idx]); + markdownEnumDescriptions = s.schema.enumDescriptions.map(toMarkdown); + } else { + markdownEnumDescriptions = []; } - if (markdownEnumValueDescription) { - enumValue = s.schema.enum[idx]; + s.schema.enum.forEach((enumValue, idx) => { if (typeof enumValue !== 'string') { enumValue = JSON.stringify(enumValue); } - } + markdownEnums.push({ + value: enumValue, + description: markdownEnumDescriptions[idx], + }); + }); } if (s.schema.anyOf && isAllSchemasMatched(node, matchingSchemas, s.schema)) { //if append title and description of all matched schemas on hover @@ -163,28 +167,30 @@ export class YAMLHover { result = '#### ' + toMarkdown(title); } if (markdownDescription) { - if (result.length > 0) { - result += '\n\n'; - } + result = ensureLineBreak(result); result += markdownDescription; } - if (markdownEnumValueDescription) { - if (result.length > 0) { - result += '\n\n'; - } - result += `\`${toMarkdownCodeBlock(enumValue)}\`: ${markdownEnumValueDescription}`; + if (markdownEnums.length !== 0) { + result = ensureLineBreak(result); + result += 'Allowed Values:\n\n'; + markdownEnums.forEach((me) => { + if (me.description) { + result += `* \`${toMarkdownCodeBlock(me.value)}\`: ${me.description}\n`; + } else { + result += `* \`${toMarkdownCodeBlock(me.value)}\`\n`; + } + }); } if (markdownExamples.length !== 0) { - if (result.length > 0) { - result += '\n\n'; - } - result += 'Examples:'; + result = ensureLineBreak(result); + result += 'Examples:\n\n'; markdownExamples.forEach((example) => { - result += `\n\n\`\`\`${example}\`\`\``; + result += `* \`\`\`${example}\`\`\`\n`; }); } if (result.length > 0 && schema.schema.url) { - result += `\n\nSource: [${getSchemaName(schema.schema)}](${schema.schema.url})`; + result = ensureLineBreak(result); + result += `Source: [${getSchemaName(schema.schema)}](${schema.schema.url})`; } return createHover(result); } @@ -193,6 +199,21 @@ export class YAMLHover { } } +interface markdownEnum { + value: string; + description: string; +} + +function ensureLineBreak(content: string): string { + if (content.length === 0) { + return content; + } + if (!content.endsWith('\n')) { + content += '\n'; + } + return content + '\n'; +} + function getSchemaName(schema: JSONSchema): string { let result = 'JSON Schema'; const urlString = schema.url; diff --git a/test/hover.test.ts b/test/hover.test.ts index afd286904..83cf9932d 100644 --- a/test/hover.test.ts +++ b/test/hover.test.ts @@ -556,6 +556,37 @@ users: ); }); + it('Hover displays enum descriptions if present', async () => { + schemaProvider.addSchema(SCHEMA_ID, { + type: 'object', + properties: { + animal: { + type: 'string', + description: 'should return this description', + enum: ['cat', 'dog', 'non'], + enumDescriptions: ['', 'Canis familiaris'], + }, + }, + }); + const content = 'animal:\n ca|t|'; // len: 13, pos: 12 + const result = await parseSetup(content); + + assert.strictEqual(MarkupContent.is(result.contents), true); + assert.strictEqual((result.contents as MarkupContent).kind, 'markdown'); + assert.strictEqual( + (result.contents as MarkupContent).value, + `should return this description + +Allowed Values: + +* \`cat\` +* \`dog\`: Canis familiaris +* \`non\` + +Source: [${SCHEMA_ID}](file:///${SCHEMA_ID})` + ); + }); + it('Hover works on examples', async () => { schemaProvider.addSchema(SCHEMA_ID, { type: 'object', @@ -577,11 +608,15 @@ users: (result.contents as MarkupContent).value, `should return this description -Examples: +Allowed Values: + +* \`cat\` +* \`dog\` -\`\`\`"cat"\`\`\` +Examples: -\`\`\`"dog"\`\`\` +* \`\`\`"cat"\`\`\` +* \`\`\`"dog"\`\`\` Source: [${SCHEMA_ID}](file:///${SCHEMA_ID})` ); From 5458ed334db24c36b341d296b5a39e1cc9cead95 Mon Sep 17 00:00:00 2001 From: Pierre Prinetti Date: Fri, 5 Jan 2024 07:29:31 +0100 Subject: [PATCH 08/18] README: Fix syntax highlighting (#945) All JSON is YAML, but no the other way around. Co-authored-by: Muthurajan Sivasubramanian <93245779+msivasubramaniaan@users.noreply.github.com> --- README.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index fd966cfb0..6d6c052a8 100755 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ The following settings are supported: In order to use the custom tags in your YAML file you need to first specify the custom tags in the setting of your code editor. For example, we can have the following custom tags: -```YAML +```yaml "yaml.customTags": [ "!Scalar-example scalar", "!Seq-example sequence", @@ -70,7 +70,7 @@ The !Scalar-example would map to a scalar custom tag, the !Seq-example would map We can then use the newly defined custom tags inside our YAML file: -```YAML +```yaml some_key: !Scalar-example some_value some_sequence: !Seq-example - some_seq_key_1: some_seq_value_1 @@ -93,7 +93,7 @@ myProject you can do -``` +```yaml yaml.schemas: { "https://json.schemastore.org/composer": "/myYamlFile.yaml" } @@ -109,7 +109,7 @@ and that will associate the composer schema with myYamlFile.yaml. When associating a schema it should follow the format below -```json +```yaml yaml.schemas: { "url": "globPattern", "Kubernetes": "globPattern" @@ -118,7 +118,7 @@ yaml.schemas: { e.g. -```json +```yaml yaml.schemas: { "https://json.schemastore.org/composer": "/*" } @@ -126,7 +126,7 @@ yaml.schemas: { e.g. -```json +```yaml yaml.schemas: { "kubernetes": "/myYamlFile.yaml" } @@ -134,7 +134,7 @@ yaml.schemas: { e.g. -```json +```yaml yaml.schemas: { "https://json.schemastore.org/composer": "/*", "kubernetes": "/myYamlFile.yaml" @@ -143,7 +143,7 @@ yaml.schemas: { On Windows with full path: -```json +```yaml yaml.schemas: { "C:\\Users\\user\\Documents\\custom_schema.json": "someFilePattern.yaml", } @@ -151,7 +151,7 @@ yaml.schemas: { On Mac/Linux with full path: -```json +```yaml yaml.schemas: { "/home/user/custom_schema.json": "someFilePattern.yaml", } @@ -159,13 +159,13 @@ yaml.schemas: { Since `0.11.0` YAML Schemas can be used for validation: -```json +```yaml "/home/user/custom_schema.yaml": "someFilePattern.yaml" ``` A schema can be associated with multiple globs using a json array, e.g. -```json +```yaml yaml.schemas: { "kubernetes": ["filePattern1.yaml", "filePattern2.yaml"] } @@ -173,7 +173,7 @@ yaml.schemas: { e.g. -```json +```yaml "yaml.schemas": { "http://json.schemastore.org/composer": ["/*"], "file:///home/johnd/some-schema.json": ["some.yaml"], @@ -184,7 +184,7 @@ e.g. e.g. -```json +```yaml "yaml.schemas": { "kubernetes": ["/myYamlFile.yaml"] } @@ -192,7 +192,7 @@ e.g. e.g. -```json +```yaml "yaml.schemas": { "http://json.schemastore.org/composer": ["/*"], "kubernetes": ["/myYamlFile.yaml"] @@ -205,7 +205,7 @@ You can also use relative paths when working with multi root workspaces. Suppose you have a multi root workspace that is laid out like: -``` +```yaml My_first_project: test.yaml my_schema.json @@ -216,7 +216,7 @@ My_second_project: You must then associate schemas relative to the root of the multi root workspace project. -``` +```yaml yaml.schemas: { "My_first_project/my_schema.json": "test.yaml", "My_second_project/my_schema2.json": "test2.yaml" @@ -229,7 +229,7 @@ yaml.schemas: { Suppose a file is meant to be a component of an existing schema (like a `job.yaml` file in a circleci orb), but there isn't a standalone schema that you can reference. If there is a nested schema definition for this subcomponent, you can reference it using a url fragment, e.g.: -``` +```yaml yaml.schemas: { "https://json.schemastore.org/circleciconfig#/definitions/jobs/additionalProperties": "/src/jobs/*.yaml", } @@ -275,7 +275,7 @@ The image is located at `quay.io/redhat-developer/yaml-language-server` To run the image you can use: -``` +```sh docker run -it quay.io/redhat-developer/yaml-language-server:latest ``` From dfccc6fc095faeb5d07051b51f308478cdac70fd Mon Sep 17 00:00:00 2001 From: Skip Baney Date: Fri, 5 Jan 2024 00:35:22 -0600 Subject: [PATCH 09/18] fix: render examples as yaml on hover (#947) Co-authored-by: Muthurajan Sivasubramanian <93245779+msivasubramaniaan@users.noreply.github.com> --- src/languageservice/services/yamlHover.ts | 48 +++++++++++------------ test/hover.test.ts | 23 +++++++++-- 2 files changed, 43 insertions(+), 28 deletions(-) diff --git a/src/languageservice/services/yamlHover.ts b/src/languageservice/services/yamlHover.ts index eb163f6a7..a0e72ce3a 100644 --- a/src/languageservice/services/yamlHover.ts +++ b/src/languageservice/services/yamlHover.ts @@ -19,6 +19,7 @@ import * as path from 'path'; import { Telemetry } from '../telemetry'; import { convertErrorToTelemetryMsg } from '../utils/objects'; import { ASTNode } from 'vscode-json-languageservice'; +import { stringify as stringifyYAML } from 'yaml'; export class YAMLHover { private shouldHover: boolean; @@ -87,11 +88,6 @@ export class YAMLHover { ); const createHover = (contents: string): Hover => { - if (this.indentation !== undefined) { - const indentationMatchRegex = new RegExp(` {${this.indentation.length}}`, 'g'); - contents = contents.replace(indentationMatchRegex, ' '); - } - const markupContent: MarkupContent = { kind: MarkupKind.Markdown, value: contents, @@ -120,12 +116,12 @@ export class YAMLHover { matchingSchemas.every((s) => { if ((s.node === node || (node.type === 'property' && node.valueNode === s.node)) && !s.inverted && s.schema) { title = title || s.schema.title || s.schema.closestTitle; - markdownDescription = markdownDescription || s.schema.markdownDescription || toMarkdown(s.schema.description); + markdownDescription = markdownDescription || s.schema.markdownDescription || this.toMarkdown(s.schema.description); if (s.schema.enum) { if (s.schema.markdownEnumDescriptions) { markdownEnumDescriptions = s.schema.markdownEnumDescriptions; } else if (s.schema.enumDescriptions) { - markdownEnumDescriptions = s.schema.enumDescriptions.map(toMarkdown); + markdownEnumDescriptions = s.schema.enumDescriptions.map(this.toMarkdown, this); } else { markdownEnumDescriptions = []; } @@ -145,7 +141,7 @@ export class YAMLHover { markdownDescription = ''; s.schema.anyOf.forEach((childSchema: JSONSchema, index: number) => { title += childSchema.title || s.schema.closestTitle || ''; - markdownDescription += childSchema.markdownDescription || toMarkdown(childSchema.description) || ''; + markdownDescription += childSchema.markdownDescription || this.toMarkdown(childSchema.description) || ''; if (index !== s.schema.anyOf.length - 1) { title += ' || '; markdownDescription += ' || '; @@ -156,7 +152,7 @@ export class YAMLHover { } if (s.schema.examples) { s.schema.examples.forEach((example) => { - markdownExamples.push(JSON.stringify(example, null, 2)); + markdownExamples.push(stringifyYAML(example, null, 2)); }); } } @@ -164,7 +160,7 @@ export class YAMLHover { }); let result = ''; if (title) { - result = '#### ' + toMarkdown(title); + result = '#### ' + this.toMarkdown(title); } if (markdownDescription) { result = ensureLineBreak(result); @@ -182,10 +178,10 @@ export class YAMLHover { }); } if (markdownExamples.length !== 0) { - result = ensureLineBreak(result); - result += 'Examples:\n\n'; markdownExamples.forEach((example) => { - result += `* \`\`\`${example}\`\`\`\n`; + result = ensureLineBreak(result); + result += 'Example:\n\n'; + result += `\`\`\`yaml\n${example}\`\`\`\n`; }); } if (result.length > 0 && schema.schema.url) { @@ -197,6 +193,21 @@ export class YAMLHover { return null; }); } + + // copied from https://github.com/microsoft/vscode-json-languageservice/blob/2ea5ad3d2ffbbe40dea11cfe764a502becf113ce/src/services/jsonHover.ts#L112 + private toMarkdown(plain: string | undefined): string | undefined { + if (plain) { + let escaped = plain.replace(/([^\n\r])(\r?\n)([^\n\r])/gm, '$1\n\n$3'); // single new lines to \n\n (Markdown paragraph) + escaped = escaped.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&'); // escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash + if (this.indentation !== undefined) { + // escape indentation whitespace to prevent it from being converted to markdown code blocks. + const indentationMatchRegex = new RegExp(` {${this.indentation.length}}`, 'g'); + escaped = escaped.replace(indentationMatchRegex, ' '); + } + return escaped; + } + return undefined; + } } interface markdownEnum { @@ -226,17 +237,6 @@ function getSchemaName(schema: JSONSchema): string { return result; } -// copied from https://github.com/microsoft/vscode-json-languageservice/blob/2ea5ad3d2ffbbe40dea11cfe764a502becf113ce/src/services/jsonHover.ts#L112 -function toMarkdown(plain: string): string; -function toMarkdown(plain: string | undefined): string | undefined; -function toMarkdown(plain: string | undefined): string | undefined { - if (plain) { - const res = plain.replace(/([^\n\r])(\r?\n)([^\n\r])/gm, '$1\n\n$3'); // single new lines to \n\n (Markdown paragraph) - return res.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&'); // escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash - } - return undefined; -} - // copied from https://github.com/microsoft/vscode-json-languageservice/blob/2ea5ad3d2ffbbe40dea11cfe764a502becf113ce/src/services/jsonHover.ts#L122 function toMarkdownCodeBlock(content: string): string { // see https://daringfireball.net/projects/markdown/syntax#precode diff --git a/test/hover.test.ts b/test/hover.test.ts index 83cf9932d..404ed6768 100644 --- a/test/hover.test.ts +++ b/test/hover.test.ts @@ -595,7 +595,14 @@ Source: [${SCHEMA_ID}](file:///${SCHEMA_ID})` type: 'string', description: 'should return this description', enum: ['cat', 'dog'], - examples: ['cat', 'dog'], + examples: [ + 'cat', + { + animal: { + type: 'dog', + }, + }, + ], }, }, }); @@ -613,10 +620,18 @@ Allowed Values: * \`cat\` * \`dog\` -Examples: +Example: + +\`\`\`yaml +cat +\`\`\` + +Example: -* \`\`\`"cat"\`\`\` -* \`\`\`"dog"\`\`\` +\`\`\`yaml +animal: + type: dog +\`\`\` Source: [${SCHEMA_ID}](file:///${SCHEMA_ID})` ); From 4b91dd31840131bec685b065e9a0c2f6814ae1e8 Mon Sep 17 00:00:00 2001 From: Petr Spacek Date: Tue, 28 May 2024 13:59:46 +0200 Subject: [PATCH 10/18] feat: unify string insert text for array and property (#934) --- src/languageservice/services/yamlCompletion.ts | 2 +- test/autoCompletion.test.ts | 2 +- test/autoCompletionFix.test.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/languageservice/services/yamlCompletion.ts b/src/languageservice/services/yamlCompletion.ts index 99e061f0b..0ef71baba 100644 --- a/src/languageservice/services/yamlCompletion.ts +++ b/src/languageservice/services/yamlCompletion.ts @@ -1205,7 +1205,7 @@ export class YamlCompletion { insertText = `\${${insertIndex++}:0}`; break; case 'string': - insertText = `\${${insertIndex++}:""}`; + insertText = `\${${insertIndex++}}`; break; case 'object': { diff --git a/test/autoCompletion.test.ts b/test/autoCompletion.test.ts index 78b14996d..dd5abe0c4 100644 --- a/test/autoCompletion.test.ts +++ b/test/autoCompletion.test.ts @@ -1047,7 +1047,7 @@ describe('Auto Completion Tests', () => { const completion = parseSetup(content, content.lastIndexOf('Ba') + 2); // pos: 3+2 completion .then(function (result) { - assert.strictEqual('fooBar:\n - ${1:""}', result.items[0].insertText); + assert.strictEqual('fooBar:\n - ${1}', result.items[0].insertText); }) .then(done, done); }); diff --git a/test/autoCompletionFix.test.ts b/test/autoCompletionFix.test.ts index 81053315b..f81c68aa7 100644 --- a/test/autoCompletionFix.test.ts +++ b/test/autoCompletionFix.test.ts @@ -482,7 +482,7 @@ objB: expect(completion.items.length).equal(1); expect(completion.items[0]).to.be.deep.equal( - createExpectedCompletion('objectWithArray', 'objectWithArray:\n - ${1:""}', 1, 4, 1, 4, 10, 2, { + createExpectedCompletion('objectWithArray', 'objectWithArray:\n - ${1}', 1, 4, 1, 4, 10, 2, { documentation: '', }) ); From e5dcce044e27dd6b6da54107f5eff092649ca002 Mon Sep 17 00:00:00 2001 From: Petr Spacek Date: Tue, 28 May 2024 14:07:20 +0200 Subject: [PATCH 11/18] fix: snippets in additionalProperties (#951) Co-authored-by: Muthurajan Sivasubramanian <93245779+msivasubramaniaan@users.noreply.github.com> --- .../services/yamlCompletion.ts | 3 ++- test/autoCompletionFix.test.ts | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/languageservice/services/yamlCompletion.ts b/src/languageservice/services/yamlCompletion.ts index 0ef71baba..be21a8bb7 100644 --- a/src/languageservice/services/yamlCompletion.ts +++ b/src/languageservice/services/yamlCompletion.ts @@ -925,7 +925,8 @@ export class YamlCompletion { if (propertySchema) { this.addSchemaValueCompletions(propertySchema, separatorAfter, collector, types, 'value'); } - } else if (s.schema.additionalProperties) { + } + if (s.schema.additionalProperties) { this.addSchemaValueCompletions(s.schema.additionalProperties, separatorAfter, collector, types, 'value'); } } diff --git a/test/autoCompletionFix.test.ts b/test/autoCompletionFix.test.ts index f81c68aa7..c720ce76d 100644 --- a/test/autoCompletionFix.test.ts +++ b/test/autoCompletionFix.test.ts @@ -1183,6 +1183,30 @@ objB: expect(completion.items[0].insertText).to.be.equal('test1'); }); + it('should suggest defaultSnippets from additionalProperties', async () => { + const schema: JSONSchema = { + type: 'object', + properties: { + id: { + type: 'string', + }, + }, + additionalProperties: { + anyOf: [ + { + type: 'string', + defaultSnippets: [{ label: 'snippet', body: 'snippetBody' }], + }, + ], + }, + }; + schemaProvider.addSchema(SCHEMA_ID, schema); + const content = 'value: |\n|'; + const completion = await parseCaret(content); + + expect(completion.items.map((i) => i.insertText)).to.be.deep.equal(['snippetBody']); + }); + describe('should suggest prop of the object (based on not completed prop name)', () => { const schema: JSONSchema = { definitions: { From 0e17579f36cc56b37d6d65b6438e64937b0f2390 Mon Sep 17 00:00:00 2001 From: Tony <68118705+Legend-Master@users.noreply.github.com> Date: Tue, 28 May 2024 20:13:42 +0800 Subject: [PATCH 12/18] Improve some special cases for selection ranges (#939) * Fix some typings * Improve a few special cases * Add tests --------- Co-authored-by: Muthurajan Sivasubramanian <93245779+msivasubramaniaan@users.noreply.github.com> --- .../services/yamlSelectionRanges.ts | 115 ++++++++++++------ src/languageservice/yamlLanguageService.ts | 2 +- test/yamlSelectionRanges.test.ts | 82 ++++++++++++- tsconfig.json | 2 +- 4 files changed, 155 insertions(+), 46 deletions(-) diff --git a/src/languageservice/services/yamlSelectionRanges.ts b/src/languageservice/services/yamlSelectionRanges.ts index b361ba8d7..f60dcc91a 100644 --- a/src/languageservice/services/yamlSelectionRanges.ts +++ b/src/languageservice/services/yamlSelectionRanges.ts @@ -3,81 +3,72 @@ import { yamlDocumentsCache } from '../parser/yaml-documents'; import { TextDocument } from 'vscode-languageserver-textdocument'; import { ASTNode } from 'vscode-json-languageservice'; -export function getSelectionRanges(document: TextDocument, positions: Position[]): SelectionRange[] | undefined { - if (!document) { - return; - } +export function getSelectionRanges(document: TextDocument, positions: Position[]): SelectionRange[] { const doc = yamlDocumentsCache.getYamlDocument(document); return positions.map((position) => { const ranges = getRanges(position); - let current: SelectionRange; + let current: SelectionRange | undefined; for (const range of ranges) { current = SelectionRange.create(range, current); } - if (!current) { - current = SelectionRange.create({ - start: position, - end: position, - }); - } - return current; + return current ?? SelectionRange.create({ start: position, end: position }); }); function getRanges(position: Position): Range[] { const offset = document.offsetAt(position); const result: Range[] = []; for (const ymlDoc of doc.documents) { - let currentNode: ASTNode; - let firstNodeOffset: number; - let isFirstNode = true; + let currentNode: ASTNode | undefined; + let overrideStartOffset: number | undefined; ymlDoc.visit((node) => { const endOffset = node.offset + node.length; // Skip if end offset doesn't even reach cursor position if (endOffset < offset) { return true; } - let startOffset = node.offset; - // Recheck start offset with the trimmed one in case of this - // key: - // - value - // ↑ - if (startOffset > offset) { - const nodePosition = document.positionAt(startOffset); - if (nodePosition.line !== position.line) { - return true; - } - const lineBeginning = { line: nodePosition.line, character: 0 }; - const text = document.getText({ - start: lineBeginning, - end: nodePosition, - }); - if (text.trim().length !== 0) { + // Skip if we're ending at new line + // times: + // - second: 1 + // millisecond: 10 + // | - second: 2 + // ↑ millisecond: 0 + // (| is actually part of { second: 1, millisecond: 10 }) + // \r\n doesn't matter here + if (getTextFromOffsets(endOffset - 1, endOffset) === '\n') { + if (endOffset - 1 < offset) { return true; } - startOffset = document.offsetAt(lineBeginning); - if (startOffset > offset) { + } + + let startOffset = node.offset; + if (startOffset > offset) { + // Recheck start offset for some special cases + const newOffset = getStartOffsetForSpecialCases(node, position); + if (!newOffset || newOffset > offset) { return true; } + startOffset = newOffset; } + // Allow equal for children to override if (!currentNode || startOffset >= currentNode.offset) { currentNode = node; - firstNodeOffset = startOffset; + overrideStartOffset = startOffset; } return true; }); while (currentNode) { - const startOffset = isFirstNode ? firstNodeOffset : currentNode.offset; + const startOffset = overrideStartOffset ?? currentNode.offset; const endOffset = currentNode.offset + currentNode.length; const range = { start: document.positionAt(startOffset), end: document.positionAt(endOffset), }; const text = document.getText(range); - const trimmedText = text.trimEnd(); - const trimmedLength = text.length - trimmedText.length; - if (trimmedLength > 0) { - range.end = document.positionAt(endOffset - trimmedLength); + const trimmedText = trimEndNewLine(text); + const trimmedEndOffset = startOffset + trimmedText.length; + if (trimmedEndOffset >= offset) { + range.end = document.positionAt(trimmedEndOffset); } // Add a jump between '' "" {} [] const isSurroundedBy = (startCharacter: string, endCharacter?: string): boolean => { @@ -95,7 +86,7 @@ export function getSelectionRanges(document: TextDocument, positions: Position[] } result.push(range); currentNode = currentNode.parent; - isFirstNode = false; + overrideStartOffset = undefined; } // A position can't be in multiple documents if (result.length > 0) { @@ -104,4 +95,48 @@ export function getSelectionRanges(document: TextDocument, positions: Position[] } return result.reverse(); } + + function getStartOffsetForSpecialCases(node: ASTNode, position: Position): number | undefined { + const nodeStartPosition = document.positionAt(node.offset); + if (nodeStartPosition.line !== position.line) { + return; + } + + if (node.parent?.type === 'array') { + // array: + // - value + // ↑ + if (getTextFromOffsets(node.offset - 2, node.offset) === '- ') { + return node.offset - 2; + } + } + + if (node.type === 'array' || node.type === 'object') { + // array: + // - value + // ↑ + const lineBeginning = { line: nodeStartPosition.line, character: 0 }; + const text = document.getText({ start: lineBeginning, end: nodeStartPosition }); + if (text.trim().length === 0) { + return document.offsetAt(lineBeginning); + } + } + } + + function getTextFromOffsets(startOffset: number, endOffset: number): string { + return document.getText({ + start: document.positionAt(startOffset), + end: document.positionAt(endOffset), + }); + } +} + +function trimEndNewLine(str: string): string { + if (str.endsWith('\r\n')) { + return str.substring(0, str.length - 2); + } + if (str.endsWith('\n')) { + return str.substring(0, str.length - 1); + } + return str; } diff --git a/src/languageservice/yamlLanguageService.ts b/src/languageservice/yamlLanguageService.ts index 539371d8b..877fde067 100644 --- a/src/languageservice/yamlLanguageService.ts +++ b/src/languageservice/yamlLanguageService.ts @@ -175,7 +175,7 @@ export interface LanguageService { deleteSchemaContent: (schemaDeletions: SchemaDeletions) => void; deleteSchemasWhole: (schemaDeletions: SchemaDeletionsAll) => void; getFoldingRanges: (document: TextDocument, context: FoldingRangesContext) => FoldingRange[] | null; - getSelectionRanges: (document: TextDocument, positions: Position[]) => SelectionRange[] | undefined; + getSelectionRanges: (document: TextDocument, positions: Position[]) => SelectionRange[]; getCodeAction: (document: TextDocument, params: CodeActionParams) => CodeAction[] | undefined; getCodeLens: (document: TextDocument) => PromiseLike | CodeLens[] | undefined; resolveCodeLens: (param: CodeLens) => PromiseLike | CodeLens; diff --git a/test/yamlSelectionRanges.test.ts b/test/yamlSelectionRanges.test.ts index 3ac78ab41..93fd67e78 100644 --- a/test/yamlSelectionRanges.test.ts +++ b/test/yamlSelectionRanges.test.ts @@ -12,14 +12,16 @@ function isRangesEqual(range1: Range, range2: Range): boolean { ); } -function expectSelections(selectionRange: SelectionRange, ranges: Range[]): void { +function expectSelections(selectionRange: SelectionRange | undefined, ranges: Range[]): void { for (const range of ranges) { - expect(selectionRange.range).eql(range); + expect(selectionRange?.range).eql(range); + // Deduplicate ranges - while (selectionRange.parent && isRangesEqual(selectionRange.range, selectionRange.parent.range)) { + while (selectionRange?.parent && isRangesEqual(selectionRange.range, selectionRange.parent.range)) { selectionRange = selectionRange.parent; } - selectionRange = selectionRange.parent; + + selectionRange = selectionRange?.parent; } } @@ -62,6 +64,20 @@ key: { start: { line: 1, character: 0 }, end: { line: 3, character: 8 } }, ]); + positions = [ + { + line: 3, + character: 3, + }, + ]; + ranges = getSelectionRanges(document, positions); + expect(ranges.length).equal(positions.length); + expectSelections(ranges[0], [ + { start: { line: 3, character: 2 }, end: { line: 3, character: 8 } }, + { start: { line: 2, character: 2 }, end: { line: 3, character: 8 } }, + { start: { line: 1, character: 0 }, end: { line: 3, character: 8 } }, + ]); + positions = [ { line: 2, @@ -76,6 +92,64 @@ key: ]); }); + it('selection ranges for array of objects', () => { + const yaml = ` +times: + - second: 1 + millisecond: 10 + - second: 2 + millisecond: 0 + `; + let positions: Position[] = [ + { + line: 4, + character: 0, + }, + ]; + const document = setupTextDocument(yaml); + let ranges = getSelectionRanges(document, positions); + expect(ranges.length).equal(positions.length); + expectSelections(ranges[0], [ + { start: { line: 2, character: 2 }, end: { line: 5, character: 18 } }, + { start: { line: 1, character: 0 }, end: { line: 5, character: 18 } }, + ]); + + positions = [ + { + line: 5, + character: 2, + }, + ]; + ranges = getSelectionRanges(document, positions); + expect(ranges.length).equal(positions.length); + expectSelections(ranges[0], [ + { start: { line: 4, character: 4 }, end: { line: 5, character: 18 } }, + { start: { line: 2, character: 2 }, end: { line: 5, character: 18 } }, + { start: { line: 1, character: 0 }, end: { line: 5, character: 18 } }, + ]); + }); + + it('selection ranges for trailing spaces', () => { + const yaml = ` +key: + - 1 + - 2 \t + `; + const positions: Position[] = [ + { + line: 2, + character: 9, + }, + ]; + const document = setupTextDocument(yaml); + const ranges = getSelectionRanges(document, positions); + expect(ranges.length).equal(positions.length); + expectSelections(ranges[0], [ + { start: { line: 2, character: 2 }, end: { line: 3, character: 9 } }, + { start: { line: 1, character: 0 }, end: { line: 3, character: 9 } }, + ]); + }); + it('selection ranges jump for "" \'\'', () => { const yaml = ` - "word" diff --git a/tsconfig.json b/tsconfig.json index 5294b2662..fa23d249a 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,7 @@ "outDir": "./out/server", "sourceMap": true, "target": "es2020", - "allowSyntheticDefaultImports": true, + "allowSyntheticDefaultImports": true, "skipLibCheck": true }, "include": [ "src", "test" ], From 0871dc12bb1d092bd08831dbe1f2179c41f55342 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Tue, 28 May 2024 08:03:39 -0500 Subject: [PATCH 13/18] Add null check for `customTags` setting (#955) Fixes #807 Signed-off-by: David Thompson Co-authored-by: Muthurajan Sivasubramanian <93245779+msivasubramaniaan@users.noreply.github.com> --- src/languageservice/services/yamlCompletion.ts | 2 +- test/autoCompletion.test.ts | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/languageservice/services/yamlCompletion.ts b/src/languageservice/services/yamlCompletion.ts index be21a8bb7..513a23d63 100644 --- a/src/languageservice/services/yamlCompletion.ts +++ b/src/languageservice/services/yamlCompletion.ts @@ -293,7 +293,7 @@ export class YamlCompletion { proposed, }; - if (this.customTags.length > 0) { + if (this.customTags && this.customTags.length > 0) { this.getCustomTagValueCompletions(collector); } diff --git a/test/autoCompletion.test.ts b/test/autoCompletion.test.ts index dd5abe0c4..eba8fa6d0 100644 --- a/test/autoCompletion.test.ts +++ b/test/autoCompletion.test.ts @@ -3126,5 +3126,10 @@ describe('Auto Completion Tests', () => { expect(result.items.map((i) => i.label)).to.have.members(['fruit', 'vegetable']); }); }); + it('Should function when settings are undefined', async () => { + languageService.configure({ completion: true }); + const content = ''; + await parseSetup(content, 0); + }); }); }); From 7203630540f35c88731bcf03ac41ca90b5919125 Mon Sep 17 00:00:00 2001 From: Gustav Eikaas <46537983+GustavEikaas@users.noreply.github.com> Date: Wed, 29 May 2024 10:02:40 +0200 Subject: [PATCH 14/18] fix: crash when url is undefined (#954) * fix: crash when url is undefined * add another null check * style: prettier fix --------- Co-authored-by: Muthurajan Sivasubramanian <93245779+msivasubramaniaan@users.noreply.github.com> --- src/languageserver/handlers/settingsHandlers.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/languageserver/handlers/settingsHandlers.ts b/src/languageserver/handlers/settingsHandlers.ts index 95ddba773..e2351ea7a 100644 --- a/src/languageserver/handlers/settingsHandlers.ts +++ b/src/languageserver/handlers/settingsHandlers.ts @@ -81,7 +81,7 @@ export class SettingsHandler { if (settings.yaml.schemaStore) { this.yamlSettings.schemaStoreEnabled = settings.yaml.schemaStore.enable; - if (settings.yaml.schemaStore.url.length !== 0) { + if (settings.yaml.schemaStore.url?.length !== 0) { this.yamlSettings.schemaStoreUrl = settings.yaml.schemaStore.url; } } @@ -180,7 +180,7 @@ export class SettingsHandler { private async setSchemaStoreSettingsIfNotSet(): Promise { const schemaStoreIsSet = this.yamlSettings.schemaStoreSettings.length !== 0; let schemaStoreUrl = ''; - if (this.yamlSettings.schemaStoreUrl.length !== 0) { + if (this.yamlSettings.schemaStoreUrl?.length !== 0) { schemaStoreUrl = this.yamlSettings.schemaStoreUrl; } else { schemaStoreUrl = JSON_SCHEMASTORE_URL; From f039273ee5b6974db5ad34b03bb24cfe09b64447 Mon Sep 17 00:00:00 2001 From: Muthurajan Sivasubramanian <93245779+msivasubramaniaan@users.noreply.github.com> Date: Thu, 6 Jun 2024 20:27:52 +0530 Subject: [PATCH 15/18] changelog updated for the release 1.15.0 (#975) * changelog updated for the release 1.15.0 * changelog updated * added missing changes --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1c381fd8..06b89ee46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +### 1.15.0 +- Fix: some small type issues [#918](https://github.com/redhat-developer/yaml-language-server/pull/918) +- Add: volar-service-yaml to clients [#920](https://github.com/redhat-developer/yaml-language-server/pull/920) +- Fix: Remove ide-yaml from known clients [#921](https://github.com/redhat-developer/yaml-language-server/pull/921) +- Fix: schema loading performance [#923](https://github.com/redhat-developer/yaml-language-server/pull/923) +- Fix: undefined error in mergingResult.problemArgs [#924](https://github.com/redhat-developer/yaml-language-server/pull/924) +- Add: unify string insert text for array and property [#934](https://github.com/redhat-developer/yaml-language-server/pull/934) +- Add: Improve some special cases for selection ranges [#939](https://github.com/redhat-developer/yaml-language-server/pull/939) +- Fix: show all enums on hover [#942](https://github.com/redhat-developer/yaml-language-server/pull/942) +- Fix: update README syntax highlighting [#945](https://github.com/redhat-developer/yaml-language-server/pull/945) +- Fix: render examples as yaml on hover [#947](https://github.com/redhat-developer/yaml-language-server/pull/947) +- Fix: snippets in additionalProperties [#951](https://github.com/redhat-developer/yaml-language-server/pull/951) +- Fix: crash when url is undefined [#954](https://github.com/redhat-developer/yaml-language-server/pull/954) +- Fix: Add null check for customTags [#955](https://github.com/redhat-developer/yaml-language-server/pull/955) + +Thanks to [Remco Haszing](https://github.com/remcohaszing), [Petr Spacek](https://github.com/p-spacek), [Tony](https://github.com/Legend-Master), [Gustav Eikaas](https://github.com/GustavEikaas), [Skip Baney](https://github.com/twelvelabs) and [Pierre Prinetti](https://github.com/pierreprinetti) for your contributions. + ### 1.14.0 - Fix: Request textDocument/hover failed with message: Invalid regular expression: /(?s).*/: Invalid group [#874](https://github.com/redhat-developer/yaml-language-server/issues/874) - Fix: nested anyof const [#888](https://github.com/redhat-developer/yaml-language-server/pull/888) From 413846c913c2cef545f97520d1629cdb5b127c57 Mon Sep 17 00:00:00 2001 From: Petr Spacek Date: Wed, 18 Dec 2024 11:06:37 +0100 Subject: [PATCH 16/18] feat: quickFix for enum, const, property (#900) * feat: quickFix for enum, const, property * feat: quickFix for enum, const, property * chore: update schema title in test --- src/languageservice/parser/jsonParser07.ts | 3 + .../services/yamlCodeActions.ts | 57 +++++++++++++++++-- test/schemaValidation.test.ts | 7 ++- test/utils/verifyError.ts | 12 +++- test/yamlCodeActions.test.ts | 55 ++++++++++++++++++ 5 files changed, 126 insertions(+), 8 deletions(-) diff --git a/src/languageservice/parser/jsonParser07.ts b/src/languageservice/parser/jsonParser07.ts index b4fdfe4b7..c17f4352c 100644 --- a/src/languageservice/parser/jsonParser07.ts +++ b/src/languageservice/parser/jsonParser07.ts @@ -888,6 +888,7 @@ function validate( ), source: getSchemaSource(schema, originalSchema), schemaUri: getSchemaUri(schema, originalSchema), + data: { values: schema.enum }, }); } } @@ -907,6 +908,7 @@ function validate( source: getSchemaSource(schema, originalSchema), schemaUri: getSchemaUri(schema, originalSchema), problemArgs: [JSON.stringify(schema.const)], + data: { values: [schema.const] }, }); validationResult.enumValueMatch = false; } else { @@ -1385,6 +1387,7 @@ function validate( length: propertyNode.keyNode.length, }, severity: DiagnosticSeverity.Warning, + code: ErrorCode.PropertyExpected, message: schema.errorMessage || localize('DisallowedExtraPropWarning', MSG_PROPERTY_NOT_ALLOWED, propertyName), source: getSchemaSource(schema, originalSchema), schemaUri: getSchemaUri(schema, originalSchema), diff --git a/src/languageservice/services/yamlCodeActions.ts b/src/languageservice/services/yamlCodeActions.ts index c0ef20b5a..da0c7eea5 100644 --- a/src/languageservice/services/yamlCodeActions.ts +++ b/src/languageservice/services/yamlCodeActions.ts @@ -28,9 +28,12 @@ import { FlowStyleRewriter } from '../utils/flow-style-rewriter'; import { ASTNode } from '../jsonASTTypes'; import * as _ from 'lodash'; import { SourceToken } from 'yaml/dist/parse/cst'; +import { ErrorCode } from 'vscode-json-languageservice'; interface YamlDiagnosticData { schemaUri: string[]; + values?: string[]; + properties?: string[]; } export class YamlCodeActions { private indentation = ' '; @@ -54,6 +57,7 @@ export class YamlCodeActions { result.push(...this.getUnusedAnchorsDelete(params.context.diagnostics, document)); result.push(...this.getConvertToBlockStyleActions(params.context.diagnostics, document)); result.push(...this.getKeyOrderActions(params.context.diagnostics, document)); + result.push(...this.getQuickFixForPropertyOrValueMismatch(params.context.diagnostics, document)); return result; } @@ -221,7 +225,7 @@ export class YamlCodeActions { const results: CodeAction[] = []; for (const diagnostic of diagnostics) { if (diagnostic.code === 'flowMap' || diagnostic.code === 'flowSeq') { - const node = getNodeforDiagnostic(document, diagnostic); + const node = getNodeForDiagnostic(document, diagnostic); if (isMap(node.internalNode) || isSeq(node.internalNode)) { const blockTypeDescription = isMap(node.internalNode) ? 'map' : 'sequence'; const rewriter = new FlowStyleRewriter(this.indentation); @@ -242,7 +246,7 @@ export class YamlCodeActions { const results: CodeAction[] = []; for (const diagnostic of diagnostics) { if (diagnostic?.code === 'mapKeyOrder') { - let node = getNodeforDiagnostic(document, diagnostic); + let node = getNodeForDiagnostic(document, diagnostic); while (node && node.type !== 'object') { node = node.parent; } @@ -292,8 +296,8 @@ export class YamlCodeActions { item.value.end.splice(newLineIndex, 1); } } else if (item.value?.type === 'block-scalar') { - const nwline = item.value.props.find((p) => p.type === 'newline'); - if (!nwline) { + const newline = item.value.props.find((p) => p.type === 'newline'); + if (!newline) { item.value.props.push({ type: 'newline', indent: 0, offset: item.value.offset, source: '\n' } as SourceToken); } } @@ -312,9 +316,52 @@ export class YamlCodeActions { } return results; } + + /** + * Check if diagnostic contains info for quick fix + * Supports Enum/Const/Property mismatch + */ + private getPossibleQuickFixValues(diagnostic: Diagnostic): string[] | undefined { + if (typeof diagnostic.data !== 'object') { + return; + } + if ( + diagnostic.code === ErrorCode.EnumValueMismatch && + 'values' in diagnostic.data && + Array.isArray((diagnostic.data as YamlDiagnosticData).values) + ) { + return (diagnostic.data as YamlDiagnosticData).values; + } else if ( + diagnostic.code === ErrorCode.PropertyExpected && + 'properties' in diagnostic.data && + Array.isArray((diagnostic.data as YamlDiagnosticData).properties) + ) { + return (diagnostic.data as YamlDiagnosticData).properties; + } + } + + private getQuickFixForPropertyOrValueMismatch(diagnostics: Diagnostic[], document: TextDocument): CodeAction[] { + const results: CodeAction[] = []; + for (const diagnostic of diagnostics) { + const values = this.getPossibleQuickFixValues(diagnostic); + if (!values?.length) { + continue; + } + for (const value of values) { + results.push( + CodeAction.create( + value, + createWorkspaceEdit(document.uri, [TextEdit.replace(diagnostic.range, value)]), + CodeActionKind.QuickFix + ) + ); + } + } + return results; + } } -function getNodeforDiagnostic(document: TextDocument, diagnostic: Diagnostic): ASTNode { +function getNodeForDiagnostic(document: TextDocument, diagnostic: Diagnostic): ASTNode { const yamlDocuments = yamlDocumentsCache.getYamlDocument(document); const startOffset = document.offsetAt(diagnostic.range.start); const yamlDoc = matchOffsetToDocument(startOffset, yamlDocuments); diff --git a/test/schemaValidation.test.ts b/test/schemaValidation.test.ts index 71268db7b..829310c19 100644 --- a/test/schemaValidation.test.ts +++ b/test/schemaValidation.test.ts @@ -26,6 +26,7 @@ import { KUBERNETES_SCHEMA_URL } from '../src/languageservice/utils/schemaUrls'; import { IProblem } from '../src/languageservice/parser/jsonParser07'; import { JSONSchema } from '../src/languageservice/jsonSchema'; import { TestTelemetry } from './utils/testsTypes'; +import { ErrorCode } from 'vscode-json-languageservice'; describe('Validation Tests', () => { let languageSettingsSetup: ServiceSetup; @@ -396,7 +397,8 @@ describe('Validation Tests', () => { 4, DiagnosticSeverity.Error, `yaml-schema: file:///${SCHEMA_ID}`, - `file:///${SCHEMA_ID}` + `file:///${SCHEMA_ID}`, + ErrorCode.PropertyExpected ) ); }) @@ -1289,7 +1291,7 @@ obj: 4, 18, DiagnosticSeverity.Error, - 'yaml-schema: Package', + 'yaml-schema: Composer Package', 'https://raw.githubusercontent.com/composer/composer/master/res/composer-schema.json' ) ); @@ -1312,6 +1314,7 @@ obj: DiagnosticSeverity.Error, 'yaml-schema: Drone CI configuration file', 'https://json.schemastore.org/drone', + ErrorCode.PropertyExpected, { properties: [ 'type', diff --git a/test/utils/verifyError.ts b/test/utils/verifyError.ts index ea7f17c54..d2769c740 100644 --- a/test/utils/verifyError.ts +++ b/test/utils/verifyError.ts @@ -39,9 +39,19 @@ export function createDiagnosticWithData( severity: DiagnosticSeverity = 1, source = 'YAML', schemaUri: string | string[], + code: string | number = ErrorCode.Undefined, data: Record = {} ): Diagnostic { - const diagnostic: Diagnostic = createExpectedError(message, startLine, startCharacter, endLine, endCharacter, severity, source); + const diagnostic: Diagnostic = createExpectedError( + message, + startLine, + startCharacter, + endLine, + endCharacter, + severity, + source, + code + ); diagnostic.data = { schemaUri: typeof schemaUri === 'string' ? [schemaUri] : schemaUri, ...data }; return diagnostic; } diff --git a/test/yamlCodeActions.test.ts b/test/yamlCodeActions.test.ts index aa2b72ce4..447cfdcbb 100644 --- a/test/yamlCodeActions.test.ts +++ b/test/yamlCodeActions.test.ts @@ -22,6 +22,7 @@ import { setupTextDocument, TEST_URI } from './utils/testHelper'; import { createDiagnosticWithData, createExpectedError, createUnusedAnchorDiagnostic } from './utils/verifyError'; import { YamlCommands } from '../src/commands'; import { LanguageSettings } from '../src'; +import { ErrorCode } from 'vscode-json-languageservice'; const expect = chai.expect; chai.use(sinonChai); @@ -377,4 +378,58 @@ animals: [dog , cat , mouse] `; ]); }); }); + + describe('Enum value or property mismatch quick fix', () => { + it('should generate proper action for enum mismatch', () => { + const doc = setupTextDocument('foo: value1'); + const diagnostic = createDiagnosticWithData( + 'message', + 0, + 5, + 0, + 11, + DiagnosticSeverity.Hint, + 'YAML', + 'schemaUri', + ErrorCode.EnumValueMismatch, + { values: ['valueX', 'valueY'] } + ); + const params: CodeActionParams = { + context: CodeActionContext.create([diagnostic]), + range: undefined, + textDocument: TextDocumentIdentifier.create(TEST_URI), + }; + const actions = new YamlCodeActions(clientCapabilities); + const result = actions.getCodeAction(doc, params); + expect(result.map((r) => r.title)).deep.equal(['valueX', 'valueY']); + expect(result[0].edit.changes[TEST_URI]).deep.equal([TextEdit.replace(Range.create(0, 5, 0, 11), 'valueX')]); + }); + + it('should generate proper action for wrong property', () => { + const doc = setupTextDocument('foo: value1'); + const diagnostic = createDiagnosticWithData( + 'message', + 0, + 0, + 0, + 3, + DiagnosticSeverity.Hint, + 'YAML', + 'schemaUri', + ErrorCode.PropertyExpected, + { + properties: ['fooX', 'fooY'], + } + ); + const params: CodeActionParams = { + context: CodeActionContext.create([diagnostic]), + range: undefined, + textDocument: TextDocumentIdentifier.create(TEST_URI), + }; + const actions = new YamlCodeActions(clientCapabilities); + const result = actions.getCodeAction(doc, params); + expect(result.map((r) => r.title)).deep.equal(['fooX', 'fooY']); + expect(result[0].edit.changes[TEST_URI]).deep.equal([TextEdit.replace(Range.create(0, 0, 0, 3), 'fooX')]); + }); + }); }); From 379bdfa4f8ae075a3218ec0c61531c24cad75a56 Mon Sep 17 00:00:00 2001 From: Remco Haszing Date: Wed, 18 Dec 2024 14:57:27 +0100 Subject: [PATCH 17/18] Update to vscode-languageserver 9 (#910) * Update to vscode-languageserver 8 * Update to vscode-languageserver 9 --------- Co-authored-by: Muthurajan Sivasubramanian <93245779+msivasubramaniaan@users.noreply.github.com> --- package.json | 2 +- test/utils/testsTypes.ts | 22 +++++++++++----- yarn.lock | 56 ++++++++++++++++++++-------------------- 3 files changed, 44 insertions(+), 36 deletions(-) diff --git a/package.json b/package.json index 62be0e23e..90c68b029 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "lodash": "4.17.21", "request-light": "^0.5.7", "vscode-json-languageservice": "4.1.8", - "vscode-languageserver": "^7.0.0", + "vscode-languageserver": "^9.0.0", "vscode-languageserver-textdocument": "^1.0.1", "vscode-languageserver-types": "^3.16.0", "vscode-nls": "^5.0.0", diff --git a/test/utils/testsTypes.ts b/test/utils/testsTypes.ts index 6dbd78bd9..96761a107 100644 --- a/test/utils/testsTypes.ts +++ b/test/utils/testsTypes.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Event, NotificationHandler, RequestHandler } from 'vscode-jsonrpc'; +import { Disposable, Event, NotificationHandler, RequestHandler } from 'vscode-jsonrpc'; import { ApplyWorkspaceEditParams, WorkspaceEdit, @@ -14,6 +14,8 @@ import { CreateFilesParams, RenameFilesParams, DeleteFilesParams, + ClientCapabilities, + ServerCapabilities, } from 'vscode-languageserver-protocol'; import { Connection, RemoteWorkspace } from 'vscode-languageserver'; import { TelemetryImpl } from '../../src/languageserver/telemetry'; @@ -27,6 +29,9 @@ export class TestWorkspace implements RemoteWorkspace { applyEdit(paramOrEdit: ApplyWorkspaceEditParams | WorkspaceEdit): Promise { throw new Error('Method not implemented.'); } + fillServerCapabilities(capabilities: ServerCapabilities): void { + throw new Error('Method not implemented.'); + } getConfiguration(): Promise; getConfiguration(section: string): Promise; getConfiguration(item: ConfigurationItem): Promise; @@ -37,23 +42,26 @@ export class TestWorkspace implements RemoteWorkspace { getWorkspaceFolders(): Promise { throw new Error('Method not implemented.'); } + initialize(capabilities: ClientCapabilities): void { + throw new Error('Method not implemented.'); + } onDidChangeWorkspaceFolders: Event; - onDidCreateFiles(handler: NotificationHandler): void { + onDidCreateFiles(handler: NotificationHandler): Disposable { throw new Error('Method not implemented.'); } - onDidRenameFiles(handler: NotificationHandler): void { + onDidRenameFiles(handler: NotificationHandler): Disposable { throw new Error('Method not implemented.'); } - onDidDeleteFiles(handler: NotificationHandler): void { + onDidDeleteFiles(handler: NotificationHandler): Disposable { throw new Error('Method not implemented.'); } - onWillCreateFiles(handler: RequestHandler): void { + onWillCreateFiles(handler: RequestHandler): Disposable { throw new Error('Method not implemented.'); } - onWillRenameFiles(handler: RequestHandler): void { + onWillRenameFiles(handler: RequestHandler): Disposable { throw new Error('Method not implemented.'); } - onWillDeleteFiles(handler: RequestHandler): void { + onWillDeleteFiles(handler: RequestHandler): Disposable { throw new Error('Method not implemented.'); } } diff --git a/yarn.lock b/yarn.lock index fd794ffda..26a60b031 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3101,45 +3101,45 @@ vscode-json-languageservice@4.1.8: vscode-nls "^5.0.0" vscode-uri "^3.0.2" -vscode-jsonrpc@6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz" - integrity sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg== +vscode-jsonrpc@8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz#f43dfa35fb51e763d17cd94dcca0c9458f35abf9" + integrity sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA== -vscode-languageserver-protocol@3.16.0: - version "3.16.0" - resolved "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz" - integrity sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A== +vscode-languageserver-protocol@3.17.5: + version "3.17.5" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz#864a8b8f390835572f4e13bd9f8313d0e3ac4bea" + integrity sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg== dependencies: - vscode-jsonrpc "6.0.0" - vscode-languageserver-types "3.16.0" + vscode-jsonrpc "8.2.0" + vscode-languageserver-types "3.17.5" vscode-languageserver-textdocument@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz" - integrity sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA== + version "1.0.11" + resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.11.tgz#0822a000e7d4dc083312580d7575fe9e3ba2e2bf" + integrity sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA== -vscode-languageserver-types@3.16.0, vscode-languageserver-types@^3.16.0: - version "3.16.0" - resolved "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz" - integrity sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA== +vscode-languageserver-types@3.17.5, vscode-languageserver-types@^3.16.0: + version "3.17.5" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz#3273676f0cf2eab40b3f44d085acbb7f08a39d8a" + integrity sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg== -vscode-languageserver@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz" - integrity sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw== +vscode-languageserver@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz#500aef82097eb94df90d008678b0b6b5f474015b" + integrity sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g== dependencies: - vscode-languageserver-protocol "3.16.0" + vscode-languageserver-protocol "3.17.5" vscode-nls@^5.0.0: - version "5.0.1" - resolved "https://registry.npmjs.org/vscode-nls/-/vscode-nls-5.0.1.tgz" - integrity sha512-hHQV6iig+M21lTdItKPkJAaWrxALQb/nqpVffakO4knJOh3DrU2SXOMzUzNgo1eADPzu3qSsJY1weCzvR52q9A== + version "5.2.0" + resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.2.0.tgz#3cb6893dd9bd695244d8a024bdf746eea665cc3f" + integrity sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng== vscode-uri@^3.0.2: - version "3.0.3" - resolved "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.3.tgz" - integrity sha512-EcswR2S8bpR7fD0YPeS7r2xXExrScVMxg4MedACaWHEtx9ftCF/qHG1xGkolzTPcEmjTavCQgbVzHUIdTMzFGA== + version "3.0.8" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.8.tgz#1770938d3e72588659a172d0fd4642780083ff9f" + integrity sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw== which-boxed-primitive@^1.0.2: version "1.0.2" From d0a72997b0293e3eb3dbf020518a49ff9b2358e8 Mon Sep 17 00:00:00 2001 From: Remco Haszing Date: Thu, 19 Dec 2024 10:00:24 +0100 Subject: [PATCH 18/18] Update to Prettier 3 (#909) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Prettier 3 is async, so related functions were made async. - Code was reformatted using Prettier. - Prettier now ships their own types, so `@types/prettier` was removed. - Prettier was moved to `dependencies`. `optionalDependencies` is for dependencies that have a `install` script that may fail. This isn’t the case for Prettier. - `eslint-config-prettier` was updated as well. - `eslint-plugin-prettier` was updated as well. --- package.json | 9 ++-- .../handlers/languageHandlers.ts | 2 +- .../handlers/requestHandlers.ts | 5 +- .../handlers/validationHandlers.ts | 6 ++- .../handlers/workspaceHandlers.ts | 5 +- src/languageservice/parser/jsonParser07.ts | 5 +- .../services/documentSymbols.ts | 5 +- src/languageservice/services/yamlCodeLens.ts | 5 +- src/languageservice/services/yamlFormatter.ts | 12 +++-- src/languageservice/services/yamlHover.ts | 5 +- .../services/yamlValidation.ts | 5 +- src/languageservice/utils/schemaUtils.ts | 4 +- src/languageservice/yamlLanguageService.ts | 2 +- test/formatter.test.ts | 27 +++++----- yarn.lock | 50 ++++++++++++------- 15 files changed, 93 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index 90c68b029..a367cafd3 100644 --- a/package.json +++ b/package.json @@ -29,12 +29,10 @@ "type": "git", "url": "https://github.com/redhat-developer/yaml-language-server.git" }, - "optionalDependencies": { - "prettier": "2.8.7" - }, "dependencies": { "ajv": "^8.11.0", "lodash": "4.17.21", + "prettier": "^3.0.0", "request-light": "^0.5.7", "vscode-json-languageservice": "4.1.8", "vscode-languageserver": "^9.0.0", @@ -49,7 +47,6 @@ "@types/chai": "^4.2.12", "@types/mocha": "8.2.2", "@types/node": "16.x", - "@types/prettier": "2.7.2", "@types/sinon": "^9.0.5", "@types/sinon-chai": "^3.2.5", "@typescript-eslint/eslint-plugin": "^5.38.0", @@ -57,9 +54,9 @@ "chai": "^4.2.0", "coveralls": "3.1.1", "eslint": "^8.24.0", - "eslint-config-prettier": "^8.5.0", + "eslint-config-prettier": "^9.0.0", "eslint-plugin-import": "^2.26.0", - "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-prettier": "^5.0.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "mocha": "9.2.2", diff --git a/src/languageserver/handlers/languageHandlers.ts b/src/languageserver/handlers/languageHandlers.ts index df7005b94..7f971167b 100644 --- a/src/languageserver/handlers/languageHandlers.ts +++ b/src/languageserver/handlers/languageHandlers.ts @@ -114,7 +114,7 @@ export class LanguageHandlers { * Called when the formatter is invoked * Returns the formatted document content using prettier */ - formatterHandler(formatParams: DocumentFormattingParams): TextEdit[] { + formatterHandler(formatParams: DocumentFormattingParams): Promise { const document = this.yamlSettings.documents.get(formatParams.textDocument.uri); if (!document) { diff --git a/src/languageserver/handlers/requestHandlers.ts b/src/languageserver/handlers/requestHandlers.ts index 120dcb124..50d21f007 100644 --- a/src/languageserver/handlers/requestHandlers.ts +++ b/src/languageserver/handlers/requestHandlers.ts @@ -14,7 +14,10 @@ import { SchemaModificationNotification } from '../../requestTypes'; export class RequestHandlers { private languageService: LanguageService; - constructor(private readonly connection: Connection, languageService: LanguageService) { + constructor( + private readonly connection: Connection, + languageService: LanguageService + ) { this.languageService = languageService; } diff --git a/src/languageserver/handlers/validationHandlers.ts b/src/languageserver/handlers/validationHandlers.ts index b0dd75f5b..e0db58d7b 100644 --- a/src/languageserver/handlers/validationHandlers.ts +++ b/src/languageserver/handlers/validationHandlers.ts @@ -14,7 +14,11 @@ export class ValidationHandler { private languageService: LanguageService; private yamlSettings: SettingsState; - constructor(private readonly connection: Connection, languageService: LanguageService, yamlSettings: SettingsState) { + constructor( + private readonly connection: Connection, + languageService: LanguageService, + yamlSettings: SettingsState + ) { this.languageService = languageService; this.yamlSettings = yamlSettings; diff --git a/src/languageserver/handlers/workspaceHandlers.ts b/src/languageserver/handlers/workspaceHandlers.ts index 448933ffb..05b808b41 100644 --- a/src/languageserver/handlers/workspaceHandlers.ts +++ b/src/languageserver/handlers/workspaceHandlers.ts @@ -7,7 +7,10 @@ import { ExecuteCommandParams, Connection } from 'vscode-languageserver'; import { CommandExecutor } from '../commandExecutor'; export class WorkspaceHandlers { - constructor(private readonly connection: Connection, private readonly commandExecutor: CommandExecutor) {} + constructor( + private readonly connection: Connection, + private readonly commandExecutor: CommandExecutor + ) {} registerHandlers(): void { this.connection.onExecuteCommand((params) => this.executeCommand(params)); diff --git a/src/languageservice/parser/jsonParser07.ts b/src/languageservice/parser/jsonParser07.ts index c17f4352c..537a9beb6 100644 --- a/src/languageservice/parser/jsonParser07.ts +++ b/src/languageservice/parser/jsonParser07.ts @@ -286,7 +286,10 @@ export interface ISchemaCollector { class SchemaCollector implements ISchemaCollector { schemas: IApplicableSchema[] = []; - constructor(private focusOffset = -1, private exclude: ASTNode = null) {} + constructor( + private focusOffset = -1, + private exclude: ASTNode = null + ) {} add(schema: IApplicableSchema): void { this.schemas.push(schema); } diff --git a/src/languageservice/services/documentSymbols.ts b/src/languageservice/services/documentSymbols.ts index 42520736b..e50c992cb 100644 --- a/src/languageservice/services/documentSymbols.ts +++ b/src/languageservice/services/documentSymbols.ts @@ -17,7 +17,10 @@ import { convertErrorToTelemetryMsg } from '../utils/objects'; export class YAMLDocumentSymbols { private jsonDocumentSymbols; - constructor(schemaService: YAMLSchemaService, private readonly telemetry?: Telemetry) { + constructor( + schemaService: YAMLSchemaService, + private readonly telemetry?: Telemetry + ) { this.jsonDocumentSymbols = new JSONDocumentSymbols(schemaService); // override 'getKeyLabel' to handle complex mapping diff --git a/src/languageservice/services/yamlCodeLens.ts b/src/languageservice/services/yamlCodeLens.ts index b1ae69d37..fdfde4fa2 100644 --- a/src/languageservice/services/yamlCodeLens.ts +++ b/src/languageservice/services/yamlCodeLens.ts @@ -15,7 +15,10 @@ import { convertErrorToTelemetryMsg } from '../utils/objects'; import { getSchemaTitle } from '../utils/schemaUtils'; export class YamlCodeLens { - constructor(private schemaService: YAMLSchemaService, private readonly telemetry?: Telemetry) {} + constructor( + private schemaService: YAMLSchemaService, + private readonly telemetry?: Telemetry + ) {} async getCodeLens(document: TextDocument): Promise { const result = []; diff --git a/src/languageservice/services/yamlFormatter.ts b/src/languageservice/services/yamlFormatter.ts index fff674444..2d9bcaf60 100644 --- a/src/languageservice/services/yamlFormatter.ts +++ b/src/languageservice/services/yamlFormatter.ts @@ -6,9 +6,8 @@ import { Range, Position, TextEdit, FormattingOptions } from 'vscode-languageserver-types'; import { CustomFormatterOptions, LanguageSettings } from '../yamlLanguageService'; -import * as prettier from 'prettier'; -import { Options } from 'prettier'; -import * as parser from 'prettier/parser-yaml'; +import { format, Options } from 'prettier'; +import * as parser from 'prettier/plugins/yaml'; import { TextDocument } from 'vscode-languageserver-textdocument'; export class YAMLFormatter { @@ -20,7 +19,10 @@ export class YAMLFormatter { } } - public format(document: TextDocument, options: Partial & CustomFormatterOptions = {}): TextEdit[] { + public async format( + document: TextDocument, + options: Partial & CustomFormatterOptions = {} + ): Promise { if (!this.formatterEnabled) { return []; } @@ -43,7 +45,7 @@ export class YAMLFormatter { printWidth: options.printWidth, }; - const formatted = prettier.format(text, prettierOptions); + const formatted = await format(text, prettierOptions); return [TextEdit.replace(Range.create(Position.create(0, 0), document.positionAt(text.length)), formatted)]; } catch (error) { diff --git a/src/languageservice/services/yamlHover.ts b/src/languageservice/services/yamlHover.ts index a0e72ce3a..f02c29d17 100644 --- a/src/languageservice/services/yamlHover.ts +++ b/src/languageservice/services/yamlHover.ts @@ -26,7 +26,10 @@ export class YAMLHover { private indentation: string; private schemaService: YAMLSchemaService; - constructor(schemaService: YAMLSchemaService, private readonly telemetry?: Telemetry) { + constructor( + schemaService: YAMLSchemaService, + private readonly telemetry?: Telemetry + ) { this.shouldHover = true; this.schemaService = schemaService; } diff --git a/src/languageservice/services/yamlValidation.ts b/src/languageservice/services/yamlValidation.ts index fd26af2e8..04c58edf5 100644 --- a/src/languageservice/services/yamlValidation.ts +++ b/src/languageservice/services/yamlValidation.ts @@ -48,7 +48,10 @@ export class YAMLValidation { private MATCHES_MULTIPLE = 'Matches multiple schemas when only one must validate.'; - constructor(schemaService: YAMLSchemaService, private readonly telemetry?: Telemetry) { + constructor( + schemaService: YAMLSchemaService, + private readonly telemetry?: Telemetry + ) { this.validationEnabled = true; this.jsonValidation = new JSONValidation(schemaService, Promise); } diff --git a/src/languageservice/utils/schemaUtils.ts b/src/languageservice/utils/schemaUtils.ts index d36166edb..bc763fb48 100644 --- a/src/languageservice/utils/schemaUtils.ts +++ b/src/languageservice/utils/schemaUtils.ts @@ -16,8 +16,8 @@ export function getSchemaTypeName(schema: JSONSchema): string { return Array.isArray(schema.type) ? schema.type.join(' | ') : closestTitleWithType - ? schema.type.concat('(', schema.closestTitle, ')') - : schema.type || schema.closestTitle; //object + ? schema.type.concat('(', schema.closestTitle, ')') + : schema.type || schema.closestTitle; //object } /** diff --git a/src/languageservice/yamlLanguageService.ts b/src/languageservice/yamlLanguageService.ts index 877fde067..457a9d09e 100644 --- a/src/languageservice/yamlLanguageService.ts +++ b/src/languageservice/yamlLanguageService.ts @@ -166,7 +166,7 @@ export interface LanguageService { findDocumentSymbols2: (document: TextDocument, context?: DocumentSymbolsContext) => DocumentSymbol[]; findLinks: (document: TextDocument) => Promise; resetSchema: (uri: string) => boolean; - doFormat: (document: TextDocument, options?: CustomFormatterOptions) => TextEdit[]; + doFormat: (document: TextDocument, options?: CustomFormatterOptions) => Promise; doDefinition: (document: TextDocument, params: DefinitionParams) => DefinitionLink[] | undefined; doDocumentOnTypeFormatting: (document: TextDocument, params: DocumentOnTypeFormattingParams) => TextEdit[] | undefined; addSchema: (schemaID: string, schema: JSONSchema) => void; diff --git a/test/formatter.test.ts b/test/formatter.test.ts index ed970a001..5ab02ae44 100644 --- a/test/formatter.test.ts +++ b/test/formatter.test.ts @@ -24,7 +24,7 @@ describe('Formatter Tests', () => { describe('Formatter', function () { describe('Test that formatter works with custom tags', function () { // eslint-disable-next-line @typescript-eslint/no-explicit-any - function parseSetup(content: string, options: any = {}): TextEdit[] { + function parseSetup(content: string, options: any = {}): Promise { const testTextDocument = setupTextDocument(content); yamlSettings.documents = new TextDocumentTestManager(); (yamlSettings.documents as TextDocumentTestManager).set(testTextDocument); @@ -35,31 +35,32 @@ describe('Formatter Tests', () => { }); } - it('Formatting works without custom tags', () => { + it('Formatting works without custom tags', async () => { const content = 'cwd: test'; - const edits = parseSetup(content); + const edits = await parseSetup(content); + console.dir({ edits }); assert.notEqual(edits.length, 0); assert.equal(edits[0].newText, 'cwd: test\n'); }); - it('Formatting works with custom tags', () => { + it('Formatting works with custom tags', async () => { const content = 'cwd: !Test test'; - const edits = parseSetup(content); + const edits = await parseSetup(content); assert.notEqual(edits.length, 0); assert.equal(edits[0].newText, 'cwd: !Test test\n'); }); - it('Formatting wraps text', () => { + it('Formatting wraps text', async () => { const content = `comments: > test test test test test test test test test test test test`; - const edits = parseSetup(content, { + const edits = await parseSetup(content, { printWidth: 20, proseWrap: 'always', }); assert.equal(edits[0].newText, 'comments: >\n test test test\n test test test\n test test test\n test test test\n'); }); - it('Formatting uses tabSize', () => { + it('Formatting uses tabSize', async () => { const content = `map: k1: v1 k2: v2 @@ -68,7 +69,7 @@ list: - item2 `; - const edits = parseSetup(content, { + const edits = await parseSetup(content, { tabSize: 5, }); @@ -82,7 +83,7 @@ list: assert.equal(edits[0].newText, expected); }); - it('Formatting uses tabWidth', () => { + it('Formatting uses tabWidth', async () => { const content = `map: k1: v1 k2: v2 @@ -91,7 +92,7 @@ list: - item2 `; - const edits = parseSetup(content, { + const edits = await parseSetup(content, { tabWidth: 5, }); @@ -105,7 +106,7 @@ list: assert.equal(edits[0].newText, expected); }); - it('Formatting uses tabWidth over tabSize', () => { + it('Formatting uses tabWidth over tabSize', async () => { const content = `map: k1: v1 k2: v2 @@ -114,7 +115,7 @@ list: - item2 `; - const edits = parseSetup(content, { + const edits = await parseSetup(content, { tabSize: 3, tabWidth: 5, }); diff --git a/yarn.lock b/yarn.lock index 26a60b031..6b3a4fe04 100644 --- a/yarn.lock +++ b/yarn.lock @@ -347,6 +347,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@pkgr/core@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" + integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== + "@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.8.1": version "1.8.3" resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz" @@ -425,11 +430,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.60.tgz#a1fbca80c18dd80c8783557304cdb7d55ac3aff5" integrity sha512-kYIYa1D1L+HDv5M5RXQeEu1o0FKA6yedZIoyugm/MBPROkLpX4L7HRxMrPVyo8bnvjpW/wDlqFNGzXNMb7AdRw== -"@types/prettier@2.7.2": - version "2.7.2" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0" - integrity sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg== - "@types/sinon-chai@^3.2.5": version "3.2.5" resolved "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.5.tgz" @@ -1153,10 +1153,10 @@ escape-string-regexp@^1.0.5: resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -eslint-config-prettier@^8.5.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" - integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== +eslint-config-prettier@^9.0.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz#31af3d94578645966c082fcb71a5846d3c94867f" + integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== eslint-import-resolver-node@^0.3.6: version "0.3.6" @@ -1193,12 +1193,13 @@ eslint-plugin-import@^2.26.0: resolve "^1.22.0" tsconfig-paths "^3.14.1" -eslint-plugin-prettier@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" - integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== +eslint-plugin-prettier@^5.0.0: + version "5.1.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz#17cfade9e732cef32b5f5be53bd4e07afd8e67e1" + integrity sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw== dependencies: prettier-linter-helpers "^1.0.0" + synckit "^0.8.6" eslint-scope@^5.1.1: version "5.1.1" @@ -2570,10 +2571,10 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@2.8.7: - version "2.8.7" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.7.tgz#bb79fc8729308549d28fe3a98fce73d2c0656450" - integrity sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw== +prettier@^3.0.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.1.tgz#e68935518dd90bb7ec4821ba970e68f8de16e1ac" + integrity sha512-7CAwy5dRsxs8PHXT3twixW9/OEll8MLE0VRPCJyl7CkS6VHGPSlsVaWTiASPTyGyYRyApxlaWTzwUxVNrhcwDg== process-on-spawn@^1.0.0: version "1.0.0" @@ -2783,7 +2784,7 @@ side-channel@^1.0.4: signal-exit@^3.0.2: version "3.0.7" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== sinon-chai@^3.5.0: @@ -2928,6 +2929,14 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +synckit@^0.8.6: + version "0.8.8" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.8.tgz#fe7fe446518e3d3d49f5e429f443cf08b6edfcd7" + integrity sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ== + dependencies: + "@pkgr/core" "^0.1.0" + tslib "^2.6.2" + test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz" @@ -2996,6 +3005,11 @@ tslib@^1.8.1: resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"