Merge pull request #3 from github/joshmgross/prettier

Run prettier on language service
This commit is contained in:
Josh Gross
2022-11-15 14:16:37 -05:00
committed by GitHub
16 changed files with 139 additions and 231 deletions
+5
View File
@@ -0,0 +1,5 @@
node_modules
dist
*.md
*.js
*.json
+1 -1
View File
@@ -6,4 +6,4 @@
"bracketSpacing": false,
"trailingComma": "none",
"arrowParens": "avoid"
}
}
+4 -2
View File
@@ -33,7 +33,9 @@
"prepublishOnly": "npm run build && npm run test",
"test": "NODE_OPTIONS=\"--experimental-vm-modules\" jest",
"test-watch": "NODE_OPTIONS=\"--experimental-vm-modules\" jest --watch",
"watch": "tsc --build tsconfig.build.json --watch"
"watch": "tsc --build tsconfig.build.json --watch",
"prettier": "prettier .",
"prettier-fix": "prettier --write ."
},
"dependencies": {
"@github/actions-workflow-parser": "*",
@@ -56,4 +58,4 @@
"ts-jest": "^29.0.3",
"typescript": "^4.8.4"
}
}
}
+13 -24
View File
@@ -1,10 +1,6 @@
import { complete } from "./complete";
import { getPositionFromCursor } from "./test-utils/cursor-position";
import {
Value,
ValueProviderConfig,
WorkflowContext,
} from "./value-providers/config";
import {complete} from "./complete";
import {getPositionFromCursor} from "./test-utils/cursor-position";
import {Value, ValueProviderConfig, WorkflowContext} from "./value-providers/config";
describe("completion", () => {
it("runs-on", async () => {
@@ -69,7 +65,7 @@ jobs:
|`;
const result = await complete(...getPositionFromCursor(input));
expect(result).not.toBeUndefined();
expect(result.map((x) => x.label)).not.toContain("runs-on");
expect(result.map(x => x.label)).not.toContain("runs-on");
});
it("one-of narrows down to a specific type", async () => {
@@ -80,22 +76,18 @@ jobs:
build:
runs-on: ubuntu-latest
|`;
const jobFactoryResult = await complete(
...getPositionFromCursor(jobFactory)
);
const jobFactoryResult = await complete(...getPositionFromCursor(jobFactory));
expect(jobFactoryResult).not.toBeUndefined();
expect(jobFactoryResult.map((x) => x.label)).not.toContain("uses");
expect(jobFactoryResult.map(x => x.label)).not.toContain("uses");
const workflowJob = `on: push
jobs:
build:
uses: octo-org/this-repo/.github/workflows/workflow-1.yml@172239021f7ba04fe7327647b213799853a9eb89
|`;
const workflowJobResult = await complete(
...getPositionFromCursor(workflowJob)
);
const workflowJobResult = await complete(...getPositionFromCursor(workflowJob));
expect(workflowJobResult).not.toBeUndefined();
expect(workflowJobResult.map((x) => x.label)).not.toContain("runs-on");
expect(workflowJobResult.map(x => x.label)).not.toContain("runs-on");
});
it("completes boolean values", async () => {
@@ -108,7 +100,7 @@ jobs:
expect(result).not.toBeUndefined();
expect(result.length).toEqual(2);
expect(result.map((x) => x.label).sort()).toEqual(["false", "true"]);
expect(result.map(x => x.label).sort()).toEqual(["false", "true"]);
});
it("completes for empty map values", async () => {
@@ -121,7 +113,7 @@ jobs:
expect(result).not.toBeUndefined();
expect(result.length).toEqual(2);
expect(result.map((x) => x.label).sort()).toEqual(["false", "true"]);
expect(result.map(x => x.label).sort()).toEqual(["false", "true"]);
});
it("does not complete empty map values when cursor is immediately after the position", async () => {
@@ -138,17 +130,14 @@ jobs:
it("custom value providers override defaults", async () => {
const input = "on: push\njobs:\n build:\n runs-on: |";
const getCustomValues = async (
key: string,
_: WorkflowContext
): Promise<Value[] | undefined> => {
const getCustomValues = async (key: string, _: WorkflowContext): Promise<Value[] | undefined> => {
if (key === "runs-on") {
return [{ label: "my-custom-label" }];
return [{label: "my-custom-label"}];
}
return [];
};
const config: ValueProviderConfig = {
getCustomValues: getCustomValues,
getCustomValues: getCustomValues
};
const result = await complete(...getPositionFromCursor(input), config);
+20 -37
View File
@@ -1,22 +1,22 @@
import { parseWorkflow } from "@github/actions-workflow-parser";
import {parseWorkflow} from "@github/actions-workflow-parser";
import {
SEQUENCE_TYPE,
STRING_TYPE,
MAPPING_TYPE,
TemplateToken,
NULL_TYPE,
NULL_TYPE
} from "@github/actions-workflow-parser/templates/tokens/index";
import { MappingToken } from "@github/actions-workflow-parser/templates/tokens/mapping-token";
import { SequenceToken } from "@github/actions-workflow-parser/templates/tokens/sequence-token";
import { StringToken } from "@github/actions-workflow-parser/templates/tokens/string-token";
import { File } from "@github/actions-workflow-parser/workflows/file";
import { Position, TextDocument } from "vscode-languageserver-textdocument";
import { CompletionItem } from "vscode-languageserver-types";
import { nullTrace } from "./nulltrace";
import { findInnerTokenAndParent } from "./utils/find-token";
import { transform } from "./utils/transform";
import { Value, ValueProviderConfig } from "./value-providers/config";
import { defaultValueProviders } from "./value-providers/default";
import {MappingToken} from "@github/actions-workflow-parser/templates/tokens/mapping-token";
import {SequenceToken} from "@github/actions-workflow-parser/templates/tokens/sequence-token";
import {StringToken} from "@github/actions-workflow-parser/templates/tokens/string-token";
import {File} from "@github/actions-workflow-parser/workflows/file";
import {Position, TextDocument} from "vscode-languageserver-textdocument";
import {CompletionItem} from "vscode-languageserver-types";
import {nullTrace} from "./nulltrace";
import {findInnerTokenAndParent} from "./utils/find-token";
import {transform} from "./utils/transform";
import {Value, ValueProviderConfig} from "./value-providers/config";
import {defaultValueProviders} from "./value-providers/default";
export async function complete(
textDocument: TextDocument,
@@ -28,19 +28,13 @@ export async function complete(
const file: File = {
name: textDocument.uri,
content: newDoc.getText(),
content: newDoc.getText()
};
const result = parseWorkflow(file.name, [file], nullTrace);
const [innerToken, parent] = findInnerTokenAndParent(newPos, result.value);
const values = await getValues(
innerToken,
parent,
newPos,
textDocument.uri,
valueProviderConfig
);
return values.map((value) => CompletionItem.create(value.label));
const values = await getValues(innerToken, parent, newPos, textDocument.uri, valueProviderConfig);
return values.map(value => CompletionItem.create(value.label));
}
async function getValues(
@@ -65,10 +59,7 @@ async function getValues(
let customValues: Value[] | undefined = undefined;
if (token?.definition?.key) {
customValues = await valueProviderConfig?.getCustomValues(
token.definition.key,
{ uri: workflowUri }
);
customValues = await valueProviderConfig?.getCustomValues(token.definition.key, {uri: workflowUri});
}
if (customValues !== undefined) {
@@ -93,10 +84,7 @@ async function getValues(
function getExistingValues(token: TemplateToken | null, parent: TemplateToken) {
// For incomplete YAML, we may only have a parent token
if (token) {
if (
token.templateTokenType !== STRING_TYPE ||
parent.templateTokenType !== SEQUENCE_TYPE
) {
if (token.templateTokenType !== STRING_TYPE || parent.templateTokenType !== SEQUENCE_TYPE) {
return;
}
@@ -127,13 +115,8 @@ function getExistingValues(token: TemplateToken | null, parent: TemplateToken) {
}
}
function filterAndSortCompletionOptions(
options: Value[],
existingValues?: Set<string>
) {
options = options.filter(
(x) => !existingValues || !existingValues.has(x.label)
);
function filterAndSortCompletionOptions(options: Value[], existingValues?: Set<string>) {
options = options.filter(x => !existingValues || !existingValues.has(x.label));
options.sort((a, b) => a.label.localeCompare(b.label));
return options;
}
+18 -24
View File
@@ -1,23 +1,17 @@
import {
parseWorkflow,
ParseWorkflowResult,
} from "@github/actions-workflow-parser";
import { TemplateToken } from "@github/actions-workflow-parser/templates/tokens/template-token";
import { MappingToken } from "@github/actions-workflow-parser/templates/tokens/mapping-token";
import { SequenceToken } from "@github/actions-workflow-parser/templates/tokens/sequence-token";
import { File } from "@github/actions-workflow-parser/workflows/file";
import { Position, TextDocument } from "vscode-languageserver-textdocument";
import { Hover } from "vscode-languageserver-types";
import { nullTrace } from "./nulltrace";
import { findInnerToken } from "./utils/find-token";
import {parseWorkflow, ParseWorkflowResult} from "@github/actions-workflow-parser";
import {TemplateToken} from "@github/actions-workflow-parser/templates/tokens/template-token";
import {MappingToken} from "@github/actions-workflow-parser/templates/tokens/mapping-token";
import {SequenceToken} from "@github/actions-workflow-parser/templates/tokens/sequence-token";
import {File} from "@github/actions-workflow-parser/workflows/file";
import {Position, TextDocument} from "vscode-languageserver-textdocument";
import {Hover} from "vscode-languageserver-types";
import {nullTrace} from "./nulltrace";
import {findInnerToken} from "./utils/find-token";
export async function hover(
document: TextDocument,
position: Position
): Promise<Hover | null> {
export async function hover(document: TextDocument, position: Position): Promise<Hover | null> {
const file: File = {
name: document.uri,
content: document.getText(),
content: document.getText()
};
const result = parseWorkflow(file.name, [file], nullTrace);
@@ -38,9 +32,9 @@ function getHover(innerToken: TemplateToken): Hover | null {
if (innerToken.definition.evaluatorContext.length > 0) {
// Only add padding if there is a description
description += `${description.length > 0 ? `\n\n` : ""}**Context:** ${
innerToken.definition.evaluatorContext.join(", ")
}`;
description += `${description.length > 0 ? `\n\n` : ""}**Context:** ${innerToken.definition.evaluatorContext.join(
", "
)}`;
}
return {
@@ -48,13 +42,13 @@ function getHover(innerToken: TemplateToken): Hover | null {
range: {
start: {
line: innerToken.range!.start[0],
character: innerToken.range!.start[1],
character: innerToken.range!.start[1]
},
end: {
line: innerToken.range!.end[0],
character: innerToken.range!.end[1],
},
},
character: innerToken.range!.end[1]
}
}
} as Hover;
}
return null;
+3 -3
View File
@@ -1,3 +1,3 @@
export { hover } from "./hover";
export { validate } from "./validate";
export { complete } from "./complete";
export {hover} from "./hover";
export {validate} from "./validate";
export {complete} from "./complete";
+4 -4
View File
@@ -1,7 +1,7 @@
import { TraceWriter } from "@github/actions-workflow-parser/templates/trace-writer";
import {TraceWriter} from "@github/actions-workflow-parser/templates/trace-writer";
export const nullTrace: TraceWriter = {
info: (x) => {},
verbose: (x) => {},
error: (x) => {},
info: x => {},
verbose: x => {},
error: x => {}
};
@@ -1,26 +1,24 @@
import { getPositionFromCursor } from "./cursor-position";
import {getPositionFromCursor} from "./cursor-position";
describe("getPositionFromCursor", () => {
it("returns the position of the cursor and the document without that cursor", () => {
const input = "on: push\njobs:|";
const [newDoc, position] = getPositionFromCursor(input);
expect(position).toEqual({ line: 1, character: 5 });
expect(position).toEqual({line: 1, character: 5});
expect(newDoc.getText()).toEqual("on: push\njobs:");
});
it("throws an error if no cursor is found", () => {
const input = "on: push\njobs:";
expect(() => getPositionFromCursor(input)).toThrowError(
"No cursor found in document"
);
expect(() => getPositionFromCursor(input)).toThrowError("No cursor found in document");
});
it("handles a cursor at the beginning of the document", () => {
const input = "|on: push\njobs:";
const [newDoc, position] = getPositionFromCursor(input);
expect(position).toEqual({ line: 0, character: 0 });
expect(position).toEqual({line: 0, character: 0});
expect(newDoc.getText()).toEqual("on: push\njobs:");
});
});
@@ -1,4 +1,4 @@
import { TextDocument, Position } from "vscode-languageserver-textdocument";
import {TextDocument, Position} from "vscode-languageserver-textdocument";
// Calculates the position of the cursor and the document without that cursor
// Cursor is represented by a `|` character
@@ -11,12 +11,7 @@ export function getPositionFromCursor(input: string): [TextDocument, Position] {
}
const position = doc.positionAt(cursorIndex);
const newDoc = TextDocument.create(
doc.uri,
doc.languageId,
doc.version,
doc.getText().replace("|", "")
);
const newDoc = TextDocument.create(doc.uri, doc.languageId, doc.version, doc.getText().replace("|", ""));
return [newDoc, position];
}
@@ -2,11 +2,11 @@ import {
TemplateToken,
MAPPING_TYPE,
SEQUENCE_TYPE,
NULL_TYPE,
NULL_TYPE
} from "@github/actions-workflow-parser/templates/tokens/index";
import { MappingToken } from "@github/actions-workflow-parser/templates/tokens/mapping-token";
import { SequenceToken } from "@github/actions-workflow-parser/templates/tokens/sequence-token";
import { Position } from "vscode-languageserver-textdocument";
import {MappingToken} from "@github/actions-workflow-parser/templates/tokens/mapping-token";
import {SequenceToken} from "@github/actions-workflow-parser/templates/tokens/sequence-token";
import {Position} from "vscode-languageserver-textdocument";
export function findInnerToken(pos: Position, root?: TemplateToken) {
const [innerToken, _] = findInnerTokenAndParent(pos, root);
@@ -41,7 +41,7 @@ export function findInnerTokenAndParent(
const mappingToken = token as MappingToken;
parent = mappingToken;
for (let i = 0; i < mappingToken.count; i++) {
const { key, value } = mappingToken.get(i);
const {key, value} = mappingToken.get(i);
// Null tokens don't have a position, we can only use the line information
if (nullNodeOnLine(pos, key, value)) {
@@ -84,21 +84,14 @@ function posInToken(pos: Position, token: TemplateToken): boolean {
// Position is within the token lines. Check character/column if pos line matches
// start or end
if (
(r.start[0] === tokenLine && tokenChar < r.start[1]) ||
(r.end[0] === tokenLine && tokenChar > r.end[1])
) {
if ((r.start[0] === tokenLine && tokenChar < r.start[1]) || (r.end[0] === tokenLine && tokenChar > r.end[1])) {
return false;
}
return true;
}
function nullNodeOnLine(
pos: Position,
key: TemplateToken,
value: TemplateToken
): boolean {
function nullNodeOnLine(pos: Position, key: TemplateToken, value: TemplateToken): boolean {
if (value.templateTokenType !== NULL_TYPE) {
return false;
}
+8 -25
View File
@@ -1,13 +1,10 @@
import { Position, TextDocument } from "vscode-languageserver-textdocument";
import {Position, TextDocument} from "vscode-languageserver-textdocument";
const DUMMY_KEY = "dummy";
// Transform a document to work around YAML parsing issues
// Based on `_transform` in https://github.com/cschleiden/github-actions-parser/blob/main/src/lib/parser/complete.ts#L311
export function transform(
doc: TextDocument,
pos: Position
): [TextDocument, Position] {
export function transform(doc: TextDocument, pos: Position): [TextDocument, Position] {
const input = doc.getText();
let offset = doc.offsetAt(pos);
// TODO: Optimize this...
@@ -15,9 +12,8 @@ export function transform(
const lineNo = input
.substring(0, offset)
.split("")
.filter((x) => x === "\n").length;
const linePos =
offset - lines.slice(0, lineNo).reduce((p, l) => p + l.length + 1, 0);
.filter(x => x === "\n").length;
const linePos = offset - lines.slice(0, lineNo).reduce((p, l) => p + l.length + 1, 0);
const line = lines[lineNo];
let partialInput = line.trim();
@@ -37,11 +33,7 @@ export function transform(
}
lines[lineNo] =
line.substring(0, linePos) +
spacer +
DUMMY_KEY +
(trimmedLine === "-" ? "" : ":") +
line.substring(linePos);
line.substring(0, linePos) + spacer + DUMMY_KEY + (trimmedLine === "-" ? "" : ":") + line.substring(linePos);
// Adjust pos by one to prevent a sequence node being marked as active
offset++;
@@ -51,22 +43,13 @@ export function transform(
}
if (trimmedLine.startsWith("-")) {
partialInput = trimmedLine
.substring(trimmedLine.indexOf("-") + 1)
.trim();
partialInput = trimmedLine.substring(trimmedLine.indexOf("-") + 1).trim();
}
} else {
partialInput = (
offset > colon ? line.substring(colon + 1) : line.substring(0, colon)
).trim();
partialInput = (offset > colon ? line.substring(colon + 1) : line.substring(0, colon)).trim();
offset = offset - 1;
}
}
const newDoc = TextDocument.create(
doc.uri,
doc.languageId,
doc.version,
lines.join("\n")
);
const newDoc = TextDocument.create(doc.uri, doc.languageId, doc.version, lines.join("\n"));
return [newDoc, newDoc.positionAt(offset)];
}
+17 -27
View File
@@ -1,6 +1,6 @@
import { parseWorkflow } from "@github/actions-workflow-parser";
import { TemplateValidationError } from "@github/actions-workflow-parser/templates/template-validation-error";
import { nullTrace } from "./nulltrace";
import {parseWorkflow} from "@github/actions-workflow-parser";
import {TemplateValidationError} from "@github/actions-workflow-parser/templates/template-validation-error";
import {nullTrace} from "./nulltrace";
describe("validation", () => {
it("valid workflow", () => {
@@ -9,8 +9,8 @@ describe("validation", () => {
[
{
name: "wf.yaml",
content: "on: push\njobs:\n build:\n runs-on: ubuntu-latest",
},
content: "on: push\njobs:\n build:\n runs-on: ubuntu-latest"
}
],
nullTrace
);
@@ -24,23 +24,18 @@ describe("validation", () => {
[
{
name: "wf.yaml",
content: "on: push",
},
content: "on: push"
}
],
nullTrace
);
expect(result.context.errors.getErrors().length).toBe(1);
expect(result.context.errors.getErrors()[0]).toEqual(
new TemplateValidationError(
"Required property is missing: jobs",
"wf.yaml (Line: 1, Col: 1)",
undefined,
{
start: [1, 1],
end: [1, 9],
}
)
new TemplateValidationError("Required property is missing: jobs", "wf.yaml (Line: 1, Col: 1)", undefined, {
start: [1, 1],
end: [1, 9]
})
);
});
@@ -56,23 +51,18 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- run: echo`,
},
- run: echo`
}
],
nullTrace
);
expect(result.context.errors.getErrors().length).toBe(1);
expect(result.context.errors.getErrors()[0]).toEqual(
new TemplateValidationError(
"Unexpected value 'unknown-key'",
"wf.yaml (Line: 2, Col: 1)",
undefined,
{
start: [2, 1],
end: [2, 12],
}
)
new TemplateValidationError("Unexpected value 'unknown-key'", "wf.yaml (Line: 2, Col: 1)", undefined, {
start: [2, 1],
end: [2, 12]
})
);
});
});
+16 -24
View File
@@ -1,13 +1,9 @@
import {
convertWorkflowTemplate,
parseWorkflow,
ParseWorkflowResult,
} from "@github/actions-workflow-parser";
import { TokenRange } from "@github/actions-workflow-parser/templates/tokens/token-range";
import { File } from "@github/actions-workflow-parser/workflows/file";
import { TextDocument } from "vscode-languageserver-textdocument";
import { Diagnostic, Range } from "vscode-languageserver-types";
import { nullTrace } from "./nulltrace";
import {convertWorkflowTemplate, parseWorkflow, ParseWorkflowResult} from "@github/actions-workflow-parser";
import {TokenRange} from "@github/actions-workflow-parser/templates/tokens/token-range";
import {File} from "@github/actions-workflow-parser/workflows/file";
import {TextDocument} from "vscode-languageserver-textdocument";
import {Diagnostic, Range} from "vscode-languageserver-types";
import {nullTrace} from "./nulltrace";
/**
* Validates a workflow file
@@ -21,15 +17,11 @@ export async function validate(
): Promise<Diagnostic[]> {
const file: File = {
name: textDocument.uri,
content: textDocument.getText(),
content: textDocument.getText()
};
try {
const result: ParseWorkflowResult = parseWorkflow(
file.name,
[file],
nullTrace
);
const result: ParseWorkflowResult = parseWorkflow(file.name, [file], nullTrace);
if (result.value) {
// Errors will be updated in the context
@@ -37,25 +29,25 @@ export async function validate(
}
// For now map parser errors directly to diagnostics
return result.context.errors.getErrors().map((error) => {
return result.context.errors.getErrors().map(error => {
let range = mapRange(error.range);
if (!range) {
// Use default range
range = {
start: {
line: 1,
character: 1,
character: 1
},
end: {
line: 1,
character: 1,
},
character: 1
}
};
}
return {
message: error.rawMessage,
range,
range
};
});
} catch (e) {
@@ -72,11 +64,11 @@ function mapRange(range: TokenRange | undefined): Range | undefined {
return {
start: {
line: range.start[0] - 1,
character: range.start[1] - 1,
character: range.start[1] - 1
},
end: {
line: range.end[0] - 1,
character: range.end[1] - 1,
},
character: range.end[1] - 1
}
};
}
@@ -9,16 +9,8 @@ export interface WorkflowContext {
uri: string;
}
export interface ValueProviderConfig {
getCustomValues: (
key: string,
context: WorkflowContext
) => Promise<Value[] | undefined>;
getActionInputs?: (
owner: string,
name: string,
ref: string,
path?: string
) => Promise<ActionInput[]>;
getCustomValues: (key: string, context: WorkflowContext) => Promise<Value[] | undefined>;
getActionInputs?: (owner: string, name: string, ref: string, path?: string) => Promise<ActionInput[]>;
}
export interface ActionInput {
@@ -1,14 +1,14 @@
import { Definition } from "@github/actions-workflow-parser/templates/schema/definition";
import { BooleanDefinition } from "@github/actions-workflow-parser/templates/schema/boolean-definition";
import { MappingDefinition } from "@github/actions-workflow-parser/templates/schema/mapping-definition";
import { OneOfDefinition } from "@github/actions-workflow-parser/templates/schema/one-of-definition";
import { getWorkflowSchema } from "@github/actions-workflow-parser/workflows/workflow-schema";
import { Value, ValueProvider } from "./config";
import {Definition} from "@github/actions-workflow-parser/templates/schema/definition";
import {BooleanDefinition} from "@github/actions-workflow-parser/templates/schema/boolean-definition";
import {MappingDefinition} from "@github/actions-workflow-parser/templates/schema/mapping-definition";
import {OneOfDefinition} from "@github/actions-workflow-parser/templates/schema/one-of-definition";
import {getWorkflowSchema} from "@github/actions-workflow-parser/workflows/workflow-schema";
import {Value, ValueProvider} from "./config";
export function defaultValueProviders(): { [key: string]: ValueProvider } {
export function defaultValueProviders(): {[key: string]: ValueProvider} {
const schema = getWorkflowSchema();
const map: { [key: string]: ValueProvider } = {};
const map: {[key: string]: ValueProvider} = {};
for (const key of Object.keys(schema.definitions)) {
const provider = definitionValueProvider(key, schema.definitions);
if (provider) {
@@ -30,15 +30,12 @@ export function defaultValueProviders(): { [key: string]: ValueProvider } {
"macos-10.15",
"macos-10.14",
"macos-10.13",
"self-hosted",
]),
"self-hosted"
])
};
}
function definitionValueProvider(
key: string,
definitions: { [key: string]: Definition }
): ValueProvider | undefined {
function definitionValueProvider(key: string, definitions: {[key: string]: Definition}): ValueProvider | undefined {
const def = definitions[key];
if (def instanceof MappingDefinition) {
return mappingValueProvider(def);
@@ -49,20 +46,15 @@ function definitionValueProvider(
}
}
function mappingValueProvider(
mappingDefinition: MappingDefinition
): ValueProvider {
function mappingValueProvider(mappingDefinition: MappingDefinition): ValueProvider {
const properties: Value[] = [];
for (const [key, value] of Object.entries(mappingDefinition.properties)) {
properties.push({ label: key, description: value.description });
properties.push({label: key, description: value.description});
}
return () => properties;
}
function oneOfValueProvider(
oneOfDefinition: OneOfDefinition,
definitions: { [key: string]: Definition }
): ValueProvider {
function oneOfValueProvider(oneOfDefinition: OneOfDefinition, definitions: {[key: string]: Definition}): ValueProvider {
return () => {
const values: Value[] = [];
for (const key of oneOfDefinition.oneOf) {
@@ -79,7 +71,7 @@ function oneOfValueProvider(
}
function stringsToValues(labels: string[]): Value[] {
return labels.map((x) => ({ label: x }));
return labels.map(x => ({label: x}));
}
function distinctValues(values: Value[]): Value[] {