diff --git a/scripts/generate-schema.js b/scripts/generate-schema.js index 798668a7..e05d8db8 100755 --- a/scripts/generate-schema.js +++ b/scripts/generate-schema.js @@ -2,14 +2,17 @@ "use strict"; -const prettier = require(".."); - -console.log( - prettier.format( - JSON.stringify(generateSchema(prettier.getSupportInfo().options)), - { parser: "json" } - ) -); +if (require.main !== module) { + module.exports = generateSchema; +} else { + const prettier = require(".."); + console.log( + prettier.format( + JSON.stringify(generateSchema(prettier.getSupportInfo().options)), + { parser: "json" } + ) + ); +} function generateSchema(options) { return { @@ -75,25 +78,36 @@ function optionToSchema(option) { description: option.description, default: option.default }, - option.type === "choice" - ? { oneOf: option.choices.map(choiceToSchema) } - : { type: optionTypeToSchemaType(option.type) } + (option.array ? wrapWithArraySchema : identity)( + option.type === "choice" + ? { oneOf: option.choices.map(choiceToSchema) } + : { type: optionTypeToSchemaType(option.type) } + ) ); } +function identity(x) { + return x; +} + +function wrapWithArraySchema(items) { + return { type: "array", items }; +} + function optionTypeToSchemaType(optionType) { switch (optionType) { case "int": return "integer"; - case "array": case "boolean": return optionType; case "choice": throw new Error( "Please use `oneOf` instead of `enum` for better description support." ); - default: + case "path": return "string"; + default: + throw new Error(`Unexpected optionType '${optionType}'`); } } diff --git a/tests_integration/__tests__/__snapshots__/schema.js.snap b/tests_integration/__tests__/__snapshots__/schema.js.snap new file mode 100644 index 00000000..e721d9c3 --- /dev/null +++ b/tests_integration/__tests__/__snapshots__/schema.js.snap @@ -0,0 +1,286 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`schema 1`] = ` +Object { + "$schema": "http://json-schema.org/draft-04/schema#", + "allOf": Array [ + Object { + "$ref": "#/definitions/optionsDefinition", + }, + Object { + "$ref": "#/definitions/overridesDefinition", + }, + ], + "definitions": Object { + "optionsDefinition": Object { + "properties": Object { + "arrowParens": Object { + "default": "avoid", + "description": "Include parentheses around a sole arrow function parameter.", + "oneOf": Array [ + Object { + "description": "Omit parens when possible. Example: \`x => x\`", + "enum": Array [ + "avoid", + ], + }, + Object { + "description": "Always include parens. Example: \`(x) => x\`", + "enum": Array [ + "always", + ], + }, + ], + }, + "bracketSpacing": Object { + "default": true, + "description": "Print spaces between brackets.", + "type": "boolean", + }, + "cursorOffset": Object { + "default": -1, + "description": "Print (to stderr) where a cursor at the given position would move to after formatting. +This option cannot be used with --range-start and --range-end.", + "type": "integer", + }, + "filepath": Object { + "default": undefined, + "description": "Specify the input filepath. This will be used to do parser inference.", + "type": "string", + }, + "insertPragma": Object { + "default": false, + "description": "Insert @format pragma into file's first docblock comment.", + "type": "boolean", + }, + "jsxBracketSameLine": Object { + "default": false, + "description": "Put > on the last line instead of at a new line.", + "type": "boolean", + }, + "parser": Object { + "default": "babylon", + "description": "Which parser to use.", + "oneOf": Array [ + Object { + "description": "Flow", + "enum": Array [ + "flow", + ], + }, + Object { + "description": "JavaScript", + "enum": Array [ + "babylon", + ], + }, + Object { + "description": "TypeScript", + "enum": Array [ + "typescript", + ], + }, + Object { + "description": "CSS", + "enum": Array [ + "css", + ], + }, + Object { + "description": "Less", + "enum": Array [ + "less", + ], + }, + Object { + "description": "SCSS", + "enum": Array [ + "scss", + ], + }, + Object { + "description": "JSON", + "enum": Array [ + "json", + ], + }, + Object { + "description": "GraphQL", + "enum": Array [ + "graphql", + ], + }, + Object { + "description": "Markdown", + "enum": Array [ + "markdown", + ], + }, + Object { + "description": "Vue", + "enum": Array [ + "vue", + ], + }, + ], + }, + "plugins": Object { + "default": Array [], + "description": "Add a plugin. Multiple plugins can be passed as separate \`--plugin\`s.", + "items": Object { + "type": "string", + }, + "type": "array", + }, + "printWidth": Object { + "default": 80, + "description": "The line length where Prettier will try wrap.", + "type": "integer", + }, + "proseWrap": Object { + "default": "preserve", + "description": "How to wrap prose. (markdown)", + "oneOf": Array [ + Object { + "description": "Wrap prose if it exceeds the print width.", + "enum": Array [ + "always", + ], + }, + Object { + "description": "Do not wrap prose.", + "enum": Array [ + "never", + ], + }, + Object { + "description": "Wrap prose as-is.", + "enum": Array [ + "preserve", + ], + }, + ], + }, + "rangeEnd": Object { + "default": Infinity, + "description": "Format code ending at a given character offset (exclusive). +The range will extend forwards to the end of the selected statement. +This option cannot be used with --cursor-offset.", + "type": "integer", + }, + "rangeStart": Object { + "default": 0, + "description": "Format code starting at a given character offset. +The range will extend backwards to the start of the first line containing the selected statement. +This option cannot be used with --cursor-offset.", + "type": "integer", + }, + "requirePragma": Object { + "default": false, + "description": "Require either '@prettier' or '@format' to be present in the file's first docblock comment +in order for it to be formatted.", + "type": "boolean", + }, + "semi": Object { + "default": true, + "description": "Print semicolons.", + "type": "boolean", + }, + "singleQuote": Object { + "default": false, + "description": "Use single quotes instead of double quotes.", + "type": "boolean", + }, + "tabWidth": Object { + "default": 2, + "description": "Number of spaces per indentation level.", + "type": "integer", + }, + "trailingComma": Object { + "default": "none", + "description": "Print trailing commas wherever possible when multi-line.", + "oneOf": Array [ + Object { + "description": "No trailing commas.", + "enum": Array [ + "none", + ], + }, + Object { + "description": "Trailing commas where valid in ES5 (objects, arrays, etc.)", + "enum": Array [ + "es5", + ], + }, + Object { + "description": "Trailing commas wherever possible (including function arguments).", + "enum": Array [ + "all", + ], + }, + ], + }, + "useTabs": Object { + "default": false, + "description": "Indent with tabs instead of spaces.", + "type": "boolean", + }, + }, + "type": "object", + }, + "overridesDefinition": Object { + "properties": Object { + "overrides": Object { + "description": "Provide a list of patterns to override prettier configuration.", + "items": Object { + "additionalProperties": false, + "properties": Object { + "excludeFiles": Object { + "description": "Exclude these files from this override.", + "oneOf": Array [ + Object { + "type": "string", + }, + Object { + "items": Object { + "type": "string", + }, + "type": "array", + }, + ], + }, + "files": Object { + "description": "Include these files in this override.", + "oneOf": Array [ + Object { + "type": "string", + }, + Object { + "items": Object { + "type": "string", + }, + "type": "array", + }, + ], + }, + "options": Object { + "$ref": "#/definitions/optionsDefinition", + "description": "The options to apply for this override.", + "type": "object", + }, + }, + "required": Array [ + "files", + ], + "type": "object", + }, + "type": "array", + }, + }, + "type": "object", + }, + }, + "title": "Schema for .prettierrc", + "type": "object", +} +`; diff --git a/tests_integration/__tests__/schema.js b/tests_integration/__tests__/schema.js new file mode 100644 index 00000000..d46eb366 --- /dev/null +++ b/tests_integration/__tests__/schema.js @@ -0,0 +1,8 @@ +"use strict"; + +const prettier = require("../.."); +const generateSchema = require("../../scripts/generate-schema"); + +test("schema", () => { + expect(generateSchema(prettier.getSupportInfo().options)).toMatchSnapshot(); +});