diff --git a/playground/package.json b/playground/package.json index 5bbd83dc..ed6421c1 100644 --- a/playground/package.json +++ b/playground/package.json @@ -17,6 +17,7 @@ "@chakra-ui/cli": "^2.1.8", "@chakra-ui/styled-system": "^2.3.4", "@iconify/json": "^2.1.132", + "@types/json-schema": "^7.0.11", "@types/lz-string": "^1.3.34", "@types/react": "^18.0.18", "@types/react-dom": "^18.0.6", diff --git a/playground/src/Playground/Playground.consts.ts b/playground/src/Playground/Playground.consts.ts index af76f95e..eddf433f 100644 --- a/playground/src/Playground/Playground.consts.ts +++ b/playground/src/Playground/Playground.consts.ts @@ -3,6 +3,12 @@ import type { OptionsFormValues } from "../components/OptionsForm"; export type PresetTemplate = { name: string; preset: string; template: string; options?: Partial }; export const presetTemplateList = [ { name: "Default", preset: "default", template: "template-default", options: { groupStrategy: "none" } }, + { + name: "Default - Schemas only", + preset: "schemas-only", + template: "template-schemas-only", + options: { groupStrategy: "none", shouldExportAllSchemas: true }, + }, { name: "Grouped by tag", preset: "grouped-tag", template: "template-grouped", options: { groupStrategy: "tag" } }, { name: "Grouped by method", @@ -10,12 +16,6 @@ export const presetTemplateList = [ template: "template-grouped", options: { groupStrategy: "method" }, }, - { - name: "Schemas only", - preset: "schemas-only", - template: "template-schemas-only", - options: { groupStrategy: "none", shouldExportAllSchemas: true }, - }, { name: "Grouped by tag (split files)", preset: "grouped-tag-file", diff --git a/playground/src/Playground/Playground.tsx b/playground/src/Playground/Playground.tsx index ee332bbe..20d0a321 100644 --- a/playground/src/Playground/Playground.tsx +++ b/playground/src/Playground/Playground.tsx @@ -14,9 +14,10 @@ import { Kbd, Menu, MenuButton, + MenuDivider, + MenuGroup, MenuItem, MenuItemOption, - MenuGroup, MenuList, MenuOptionGroup, ModalFooter, @@ -26,12 +27,11 @@ import { PopoverTrigger, Tab, TabList, + TabProps, Tabs, useClipboard, useColorMode, useModalContext, - MenuDivider, - TabProps, } from "@chakra-ui/react"; import Editor, { EditorProps } from "@monaco-editor/react"; import { BaseField, Field, FieldProps, FormDialog, FormLayout, useFormContext, useWatch } from "@saas-ui/react"; @@ -40,26 +40,19 @@ import type { TemplateContextOptions } from "openapi-zod-client"; import { match } from "ts-pattern"; import { defaultOptionValues, OptionsForm, OptionsFormValues } from "../components/OptionsForm"; import { SplitPane } from "../components/SplitPane/SplitPane"; +import type { GetLanguageSchemasData } from "../macros/get-language-schemas"; +import { isValidDocumentName, isValidPrettierConfig, isValidTemplateName } from "./Playground.asserts"; import { presetTemplateList } from "./Playground.consts"; import { FileTabData, usePlaygroundContext } from "./Playground.machine"; import { presets } from "./presets"; -import { isValidDocumentName, isValidTemplateName, isValidPrettierConfig } from "./Playground.asserts"; // TODO // template context explorer -> copy ctx as JSON to clipboard + open https://jsoncrack.com/editor -// input = getZodSchema // TODO diff editor + collect warnings // https://reactflow.dev/ + dependency graph -// monaco settings (theme + inline diff or not / minimap / etc) - -// -> prettier schema for autocomplete on options -// https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-configure-json-defaults -// -> openapi schema for yaml/json ? // when hovering on output, show source schema in input ? // https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-hover-provider-example -// https://github.com/OAI/OpenAPI-Specification/blob/main/schemas/v3.0/schema.json -// https://github.com/SchemaStore/schemastore/blob/master/src/schemas/json/prettierrc.json export const Playground = () => { const service = usePlaygroundContext(); @@ -133,6 +126,24 @@ export const Playground = () => { }); }} theme={colorMode === "dark" ? "vs-dark" : "vs-light"} + beforeMount={(monaco) => { + const schemas: GetLanguageSchemasData = import.meta.compileTime( + "../macros/get-language-schemas.ts" + ); + + const prettierUri = new monaco.Uri().with({ path: inputList[2].name }); + + monaco.languages.json.jsonDefaults.setDiagnosticsOptions({ + validate: true, + schemas: [ + { + uri: schemas.prettier.id, + fileMatch: [prettierUri.toString()], + schema: schemas.prettier, + }, + ], + }); + }} /> @@ -302,7 +313,7 @@ const SelectPresetTemplateMenu = () => { return ( - Select handlebars template + Select template preset @@ -482,6 +493,7 @@ const FieldEditor = ({ name, language, ...props }: FieldProps & Pick form.setValue(name, content)} onMount={() => form.register(name)} theme={colorMode === "dark" ? "vs-dark" : "vs-light"} diff --git a/playground/src/macros/get-language-schemas.ts b/playground/src/macros/get-language-schemas.ts new file mode 100644 index 00000000..3f0f0c6e --- /dev/null +++ b/playground/src/macros/get-language-schemas.ts @@ -0,0 +1,21 @@ +import { parse } from "yaml"; +import { JSONSchema7 } from "json-schema"; +import schemaPrettier from "./schema-prettierrc.json"; +import { AwaitFn } from "pastable"; + +const getLanguageSchemas = async () => { + return { + data: { + // https://github.com/SchemaStore/schemastore/blob/1d89c46b81e34e0f6ff9914085eb2ba44808145c/src/schemas/json/prettierrc.json + prettier: schemaPrettier, + // https://github.com/OAI/OpenAPI-Specification/blob/157a4c81ae537ef793b2bee368bc00d88b461de8/schemas/v3.0/schema.yaml + // commented since @monaco-editor/react isn't compatible with monaco-yaml + // hopefully it will be fixed in the future + // openApiV3: (await parse("./schema-openapi-v3.0.yaml")) as Omit & { id: string }, + }, + }; +}; + +export default getLanguageSchemas; + +export type GetLanguageSchemasData = AwaitFn["data"]; diff --git a/playground/src/macros/get-package-version.ts b/playground/src/macros/get-package-version.ts index 0bf5ef52..bfe3cc6e 100644 --- a/playground/src/macros/get-package-version.ts +++ b/playground/src/macros/get-package-version.ts @@ -1,4 +1,3 @@ -import { safeJSONParse } from "pastable"; import packageJson from "../../../lib/package.json"; const getPackageJsonVersion = () => ({ data: packageJson.version }); diff --git a/playground/src/macros/schema-openapi-v3.0.yaml b/playground/src/macros/schema-openapi-v3.0.yaml new file mode 100644 index 00000000..8aa9afe9 --- /dev/null +++ b/playground/src/macros/schema-openapi-v3.0.yaml @@ -0,0 +1,1022 @@ +id: https://spec.openapis.org/oas/3.0/schema/2021-09-28 +$schema: http://json-schema.org/draft-04/schema# +description: The description of OpenAPI v3.0.x documents, as defined by https://spec.openapis.org/oas/v3.0.3 +type: object +required: + - openapi + - info + - paths +properties: + openapi: + type: string + pattern: ^3\.0\.\d(-.+)?$ + info: + $ref: "#/definitions/Info" + externalDocs: + $ref: "#/definitions/ExternalDocumentation" + servers: + type: array + items: + $ref: "#/definitions/Server" + security: + type: array + items: + $ref: "#/definitions/SecurityRequirement" + tags: + type: array + items: + $ref: "#/definitions/Tag" + uniqueItems: true + paths: + $ref: "#/definitions/Paths" + components: + $ref: "#/definitions/Components" +patternProperties: + "^x-": {} +additionalProperties: false +definitions: + Reference: + type: object + required: + - $ref + patternProperties: + '^\$ref$': + type: string + format: uri-reference + Info: + type: object + required: + - title + - version + properties: + title: + type: string + description: + type: string + termsOfService: + type: string + format: uri-reference + contact: + $ref: "#/definitions/Contact" + license: + $ref: "#/definitions/License" + version: + type: string + patternProperties: + "^x-": {} + additionalProperties: false + + Contact: + type: object + properties: + name: + type: string + url: + type: string + format: uri-reference + email: + type: string + format: email + patternProperties: + "^x-": {} + additionalProperties: false + + License: + type: object + required: + - name + properties: + name: + type: string + url: + type: string + format: uri-reference + patternProperties: + "^x-": {} + additionalProperties: false + + Server: + type: object + required: + - url + properties: + url: + type: string + description: + type: string + variables: + type: object + additionalProperties: + $ref: "#/definitions/ServerVariable" + patternProperties: + "^x-": {} + additionalProperties: false + + ServerVariable: + type: object + required: + - default + properties: + enum: + type: array + items: + type: string + default: + type: string + description: + type: string + patternProperties: + "^x-": {} + additionalProperties: false + + Components: + type: object + properties: + schemas: + type: object + patternProperties: + '^[a-zA-Z0-9\.\-_]+$': + oneOf: + - $ref: "#/definitions/Schema" + - $ref: "#/definitions/Reference" + responses: + type: object + patternProperties: + '^[a-zA-Z0-9\.\-_]+$': + oneOf: + - $ref: "#/definitions/Reference" + - $ref: "#/definitions/Response" + parameters: + type: object + patternProperties: + '^[a-zA-Z0-9\.\-_]+$': + oneOf: + - $ref: "#/definitions/Reference" + - $ref: "#/definitions/Parameter" + examples: + type: object + patternProperties: + '^[a-zA-Z0-9\.\-_]+$': + oneOf: + - $ref: "#/definitions/Reference" + - $ref: "#/definitions/Example" + requestBodies: + type: object + patternProperties: + '^[a-zA-Z0-9\.\-_]+$': + oneOf: + - $ref: "#/definitions/Reference" + - $ref: "#/definitions/RequestBody" + headers: + type: object + patternProperties: + '^[a-zA-Z0-9\.\-_]+$': + oneOf: + - $ref: "#/definitions/Reference" + - $ref: "#/definitions/Header" + securitySchemes: + type: object + patternProperties: + '^[a-zA-Z0-9\.\-_]+$': + oneOf: + - $ref: "#/definitions/Reference" + - $ref: "#/definitions/SecurityScheme" + links: + type: object + patternProperties: + '^[a-zA-Z0-9\.\-_]+$': + oneOf: + - $ref: "#/definitions/Reference" + - $ref: "#/definitions/Link" + callbacks: + type: object + patternProperties: + '^[a-zA-Z0-9\.\-_]+$': + oneOf: + - $ref: "#/definitions/Reference" + - $ref: "#/definitions/Callback" + patternProperties: + "^x-": {} + additionalProperties: false + + Schema: + type: object + properties: + title: + type: string + multipleOf: + type: number + minimum: 0 + exclusiveMinimum: true + maximum: + type: number + exclusiveMaximum: + type: boolean + default: false + minimum: + type: number + exclusiveMinimum: + type: boolean + default: false + maxLength: + type: integer + minimum: 0 + minLength: + type: integer + minimum: 0 + default: 0 + pattern: + type: string + format: regex + maxItems: + type: integer + minimum: 0 + minItems: + type: integer + minimum: 0 + default: 0 + uniqueItems: + type: boolean + default: false + maxProperties: + type: integer + minimum: 0 + minProperties: + type: integer + minimum: 0 + default: 0 + required: + type: array + items: + type: string + minItems: 1 + uniqueItems: true + enum: + type: array + items: {} + minItems: 1 + uniqueItems: false + type: + type: string + enum: + - array + - boolean + - integer + - number + - object + - string + not: + oneOf: + - $ref: "#/definitions/Schema" + - $ref: "#/definitions/Reference" + allOf: + type: array + items: + oneOf: + - $ref: "#/definitions/Schema" + - $ref: "#/definitions/Reference" + oneOf: + type: array + items: + oneOf: + - $ref: "#/definitions/Schema" + - $ref: "#/definitions/Reference" + anyOf: + type: array + items: + oneOf: + - $ref: "#/definitions/Schema" + - $ref: "#/definitions/Reference" + items: + oneOf: + - $ref: "#/definitions/Schema" + - $ref: "#/definitions/Reference" + properties: + type: object + additionalProperties: + oneOf: + - $ref: "#/definitions/Schema" + - $ref: "#/definitions/Reference" + additionalProperties: + oneOf: + - $ref: "#/definitions/Schema" + - $ref: "#/definitions/Reference" + - type: boolean + default: true + description: + type: string + format: + type: string + default: {} + nullable: + type: boolean + default: false + discriminator: + $ref: "#/definitions/Discriminator" + readOnly: + type: boolean + default: false + writeOnly: + type: boolean + default: false + example: {} + externalDocs: + $ref: "#/definitions/ExternalDocumentation" + deprecated: + type: boolean + default: false + xml: + $ref: "#/definitions/XML" + patternProperties: + "^x-": {} + additionalProperties: false + + Discriminator: + type: object + required: + - propertyName + properties: + propertyName: + type: string + mapping: + type: object + additionalProperties: + type: string + + XML: + type: object + properties: + name: + type: string + namespace: + type: string + format: uri + prefix: + type: string + attribute: + type: boolean + default: false + wrapped: + type: boolean + default: false + patternProperties: + "^x-": {} + additionalProperties: false + + Response: + type: object + required: + - description + properties: + description: + type: string + headers: + type: object + additionalProperties: + oneOf: + - $ref: "#/definitions/Header" + - $ref: "#/definitions/Reference" + content: + type: object + additionalProperties: + $ref: "#/definitions/MediaType" + links: + type: object + additionalProperties: + oneOf: + - $ref: "#/definitions/Link" + - $ref: "#/definitions/Reference" + patternProperties: + "^x-": {} + additionalProperties: false + + MediaType: + type: object + properties: + schema: + oneOf: + - $ref: "#/definitions/Schema" + - $ref: "#/definitions/Reference" + example: {} + examples: + type: object + additionalProperties: + oneOf: + - $ref: "#/definitions/Example" + - $ref: "#/definitions/Reference" + encoding: + type: object + additionalProperties: + $ref: "#/definitions/Encoding" + patternProperties: + "^x-": {} + additionalProperties: false + allOf: + - $ref: "#/definitions/ExampleXORExamples" + + Example: + type: object + properties: + summary: + type: string + description: + type: string + value: {} + externalValue: + type: string + format: uri-reference + patternProperties: + "^x-": {} + additionalProperties: false + + Header: + type: object + properties: + description: + type: string + required: + type: boolean + default: false + deprecated: + type: boolean + default: false + allowEmptyValue: + type: boolean + default: false + style: + type: string + enum: + - simple + default: simple + explode: + type: boolean + allowReserved: + type: boolean + default: false + schema: + oneOf: + - $ref: "#/definitions/Schema" + - $ref: "#/definitions/Reference" + content: + type: object + additionalProperties: + $ref: "#/definitions/MediaType" + minProperties: 1 + maxProperties: 1 + example: {} + examples: + type: object + additionalProperties: + oneOf: + - $ref: "#/definitions/Example" + - $ref: "#/definitions/Reference" + patternProperties: + "^x-": {} + additionalProperties: false + allOf: + - $ref: "#/definitions/ExampleXORExamples" + - $ref: "#/definitions/SchemaXORContent" + + Paths: + type: object + patternProperties: + '^\/': + $ref: "#/definitions/PathItem" + "^x-": {} + additionalProperties: false + + PathItem: + type: object + properties: + $ref: + type: string + summary: + type: string + description: + type: string + get: + $ref: "#/definitions/Operation" + put: + $ref: "#/definitions/Operation" + post: + $ref: "#/definitions/Operation" + delete: + $ref: "#/definitions/Operation" + options: + $ref: "#/definitions/Operation" + head: + $ref: "#/definitions/Operation" + patch: + $ref: "#/definitions/Operation" + trace: + $ref: "#/definitions/Operation" + servers: + type: array + items: + $ref: "#/definitions/Server" + parameters: + type: array + items: + oneOf: + - $ref: "#/definitions/Parameter" + - $ref: "#/definitions/Reference" + uniqueItems: true + patternProperties: + "^x-": {} + additionalProperties: false + + Operation: + type: object + required: + - responses + properties: + tags: + type: array + items: + type: string + summary: + type: string + description: + type: string + externalDocs: + $ref: "#/definitions/ExternalDocumentation" + operationId: + type: string + parameters: + type: array + items: + oneOf: + - $ref: "#/definitions/Parameter" + - $ref: "#/definitions/Reference" + uniqueItems: true + requestBody: + oneOf: + - $ref: "#/definitions/RequestBody" + - $ref: "#/definitions/Reference" + responses: + $ref: "#/definitions/Responses" + callbacks: + type: object + additionalProperties: + oneOf: + - $ref: "#/definitions/Callback" + - $ref: "#/definitions/Reference" + deprecated: + type: boolean + default: false + security: + type: array + items: + $ref: "#/definitions/SecurityRequirement" + servers: + type: array + items: + $ref: "#/definitions/Server" + patternProperties: + "^x-": {} + additionalProperties: false + + Responses: + type: object + properties: + default: + oneOf: + - $ref: "#/definitions/Response" + - $ref: "#/definitions/Reference" + patternProperties: + '^[1-5](?:\d{2}|XX)$': + oneOf: + - $ref: "#/definitions/Response" + - $ref: "#/definitions/Reference" + "^x-": {} + minProperties: 1 + additionalProperties: false + + SecurityRequirement: + type: object + additionalProperties: + type: array + items: + type: string + + Tag: + type: object + required: + - name + properties: + name: + type: string + description: + type: string + externalDocs: + $ref: "#/definitions/ExternalDocumentation" + patternProperties: + "^x-": {} + additionalProperties: false + + ExternalDocumentation: + type: object + required: + - url + properties: + description: + type: string + url: + type: string + format: uri-reference + patternProperties: + "^x-": {} + additionalProperties: false + + ExampleXORExamples: + description: Example and examples are mutually exclusive + not: + required: [example, examples] + + SchemaXORContent: + description: Schema and content are mutually exclusive, at least one is required + not: + required: [schema, content] + oneOf: + - required: [schema] + - required: [content] + description: Some properties are not allowed if content is present + allOf: + - not: + required: [style] + - not: + required: [explode] + - not: + required: [allowReserved] + - not: + required: [example] + - not: + required: [examples] + + Parameter: + type: object + properties: + name: + type: string + in: + type: string + description: + type: string + required: + type: boolean + default: false + deprecated: + type: boolean + default: false + allowEmptyValue: + type: boolean + default: false + style: + type: string + explode: + type: boolean + allowReserved: + type: boolean + default: false + schema: + oneOf: + - $ref: "#/definitions/Schema" + - $ref: "#/definitions/Reference" + content: + type: object + additionalProperties: + $ref: "#/definitions/MediaType" + minProperties: 1 + maxProperties: 1 + example: {} + examples: + type: object + additionalProperties: + oneOf: + - $ref: "#/definitions/Example" + - $ref: "#/definitions/Reference" + patternProperties: + "^x-": {} + additionalProperties: false + required: + - name + - in + allOf: + - $ref: "#/definitions/ExampleXORExamples" + - $ref: "#/definitions/SchemaXORContent" + - $ref: "#/definitions/ParameterLocation" + + ParameterLocation: + description: Parameter location + oneOf: + - description: Parameter in path + required: + - required + properties: + in: + enum: [path] + style: + enum: [matrix, label, simple] + default: simple + required: + enum: [true] + + - description: Parameter in query + properties: + in: + enum: [query] + style: + enum: [form, spaceDelimited, pipeDelimited, deepObject] + default: form + + - description: Parameter in header + properties: + in: + enum: [header] + style: + enum: [simple] + default: simple + + - description: Parameter in cookie + properties: + in: + enum: [cookie] + style: + enum: [form] + default: form + + RequestBody: + type: object + required: + - content + properties: + description: + type: string + content: + type: object + additionalProperties: + $ref: "#/definitions/MediaType" + required: + type: boolean + default: false + patternProperties: + "^x-": {} + additionalProperties: false + + SecurityScheme: + oneOf: + - $ref: "#/definitions/APIKeySecurityScheme" + - $ref: "#/definitions/HTTPSecurityScheme" + - $ref: "#/definitions/OAuth2SecurityScheme" + - $ref: "#/definitions/OpenIdConnectSecurityScheme" + + APIKeySecurityScheme: + type: object + required: + - type + - name + - in + properties: + type: + type: string + enum: + - apiKey + name: + type: string + in: + type: string + enum: + - header + - query + - cookie + description: + type: string + patternProperties: + "^x-": {} + additionalProperties: false + + HTTPSecurityScheme: + type: object + required: + - scheme + - type + properties: + scheme: + type: string + bearerFormat: + type: string + description: + type: string + type: + type: string + enum: + - http + patternProperties: + "^x-": {} + additionalProperties: false + oneOf: + - description: Bearer + properties: + scheme: + type: string + pattern: ^[Bb][Ee][Aa][Rr][Ee][Rr]$ + + - description: Non Bearer + not: + required: [bearerFormat] + properties: + scheme: + not: + type: string + pattern: ^[Bb][Ee][Aa][Rr][Ee][Rr]$ + + OAuth2SecurityScheme: + type: object + required: + - type + - flows + properties: + type: + type: string + enum: + - oauth2 + flows: + $ref: "#/definitions/OAuthFlows" + description: + type: string + patternProperties: + "^x-": {} + additionalProperties: false + + OpenIdConnectSecurityScheme: + type: object + required: + - type + - openIdConnectUrl + properties: + type: + type: string + enum: + - openIdConnect + openIdConnectUrl: + type: string + format: uri-reference + description: + type: string + patternProperties: + "^x-": {} + additionalProperties: false + + OAuthFlows: + type: object + properties: + implicit: + $ref: "#/definitions/ImplicitOAuthFlow" + password: + $ref: "#/definitions/PasswordOAuthFlow" + clientCredentials: + $ref: "#/definitions/ClientCredentialsFlow" + authorizationCode: + $ref: "#/definitions/AuthorizationCodeOAuthFlow" + patternProperties: + "^x-": {} + additionalProperties: false + + ImplicitOAuthFlow: + type: object + required: + - authorizationUrl + - scopes + properties: + authorizationUrl: + type: string + format: uri-reference + refreshUrl: + type: string + format: uri-reference + scopes: + type: object + additionalProperties: + type: string + patternProperties: + "^x-": {} + additionalProperties: false + + PasswordOAuthFlow: + type: object + required: + - tokenUrl + - scopes + properties: + tokenUrl: + type: string + format: uri-reference + refreshUrl: + type: string + format: uri-reference + scopes: + type: object + additionalProperties: + type: string + patternProperties: + "^x-": {} + additionalProperties: false + + ClientCredentialsFlow: + type: object + required: + - tokenUrl + - scopes + properties: + tokenUrl: + type: string + format: uri-reference + refreshUrl: + type: string + format: uri-reference + scopes: + type: object + additionalProperties: + type: string + patternProperties: + "^x-": {} + additionalProperties: false + + AuthorizationCodeOAuthFlow: + type: object + required: + - authorizationUrl + - tokenUrl + - scopes + properties: + authorizationUrl: + type: string + format: uri-reference + tokenUrl: + type: string + format: uri-reference + refreshUrl: + type: string + format: uri-reference + scopes: + type: object + additionalProperties: + type: string + patternProperties: + "^x-": {} + additionalProperties: false + + Link: + type: object + properties: + operationId: + type: string + operationRef: + type: string + format: uri-reference + parameters: + type: object + additionalProperties: {} + requestBody: {} + description: + type: string + server: + $ref: "#/definitions/Server" + patternProperties: + "^x-": {} + additionalProperties: false + not: + description: Operation Id and Operation Ref are mutually exclusive + required: [operationId, operationRef] + + Callback: + type: object + additionalProperties: + $ref: "#/definitions/PathItem" + patternProperties: + "^x-": {} + + Encoding: + type: object + properties: + contentType: + type: string + headers: + type: object + additionalProperties: + oneOf: + - $ref: "#/definitions/Header" + - $ref: "#/definitions/Reference" + style: + type: string + enum: + - form + - spaceDelimited + - pipeDelimited + - deepObject + explode: + type: boolean + allowReserved: + type: boolean + default: false + additionalProperties: false diff --git a/playground/src/macros/schema-prettierrc.json b/playground/src/macros/schema-prettierrc.json new file mode 100644 index 00000000..1e95678e --- /dev/null +++ b/playground/src/macros/schema-prettierrc.json @@ -0,0 +1,408 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "definitions": { + "optionsDefinition": { + "type": "object", + "properties": { + "arrowParens": { + "description": "Include parentheses around a sole arrow function parameter.", + "default": "always", + "oneOf": [ + { + "enum": ["always"], + "description": "Always include parens. Example: `(x) => x`" + }, + { + "enum": ["avoid"], + "description": "Omit parens when possible. Example: `x => x`" + } + ] + }, + "bracketSameLine": { + "description": "Put > of opening tags on the last line instead of on a new line.", + "default": false, + "type": "boolean" + }, + "bracketSpacing": { + "description": "Print spaces between brackets.", + "default": true, + "type": "boolean" + }, + "cursorOffset": { + "description": "Print (to stderr) where a cursor at the given position would move to after formatting.\nThis option cannot be used with --range-start and --range-end.", + "default": -1, + "type": "integer" + }, + "editorconfig": { + "description": "Whether parse the .editorconfig file in your project and convert its properties to the corresponding Prettier configuration. This configuration will be overridden by .prettierrc, etc.", + "default": false, + "type": "boolean" + }, + "embeddedLanguageFormatting": { + "description": "Control how Prettier formats quoted code embedded in the file.", + "default": "auto", + "oneOf": [ + { + "enum": ["auto"], + "description": "Format embedded code if Prettier can automatically identify it." + }, + { + "enum": ["off"], + "description": "Never automatically format embedded code." + } + ] + }, + "endOfLine": { + "description": "Which end of line characters to apply.", + "default": "lf", + "oneOf": [ + { + "enum": ["lf"], + "description": "Line Feed only (\\n), common on Linux and macOS as well as inside git repos" + }, + { + "enum": ["crlf"], + "description": "Carriage Return + Line Feed characters (\\r\\n), common on Windows" + }, + { + "enum": ["cr"], + "description": "Carriage Return character only (\\r), used very rarely" + }, + { + "enum": ["auto"], + "description": "Maintain existing\n(mixed values within one file are normalised by looking at what's used after the first line)" + } + ] + }, + "filepath": { + "description": "Specify the input filepath. This will be used to do parser inference.", + "type": "string" + }, + "htmlWhitespaceSensitivity": { + "description": "How to handle whitespaces in HTML.", + "default": "css", + "oneOf": [ + { + "enum": ["css"], + "description": "Respect the default value of CSS display property." + }, + { + "enum": ["strict"], + "description": "Whitespaces are considered sensitive." + }, + { + "enum": ["ignore"], + "description": "Whitespaces are considered insensitive." + } + ] + }, + "insertPragma": { + "description": "Insert @format pragma into file's first docblock comment.", + "default": false, + "type": "boolean" + }, + "jsxSingleQuote": { + "description": "Use single quotes in JSX.", + "default": false, + "type": "boolean" + }, + "parser": { + "description": "Which parser to use.", + "anyOf": [ + { + "enum": ["flow"], + "description": "Flow" + }, + { + "enum": ["babel"], + "description": "JavaScript" + }, + { + "enum": ["babel-flow"], + "description": "Flow" + }, + { + "enum": ["babel-ts"], + "description": "TypeScript" + }, + { + "enum": ["typescript"], + "description": "TypeScript" + }, + { + "enum": ["acorn"], + "description": "JavaScript" + }, + { + "enum": ["espree"], + "description": "JavaScript" + }, + { + "enum": ["meriyah"], + "description": "JavaScript" + }, + { + "enum": ["css"], + "description": "CSS" + }, + { + "enum": ["less"], + "description": "Less" + }, + { + "enum": ["scss"], + "description": "SCSS" + }, + { + "enum": ["json"], + "description": "JSON" + }, + { + "enum": ["json5"], + "description": "JSON5" + }, + { + "enum": ["json-stringify"], + "description": "JSON.stringify" + }, + { + "enum": ["graphql"], + "description": "GraphQL" + }, + { + "enum": ["markdown"], + "description": "Markdown" + }, + { + "enum": ["mdx"], + "description": "MDX" + }, + { + "enum": ["vue"], + "description": "Vue" + }, + { + "enum": ["yaml"], + "description": "YAML" + }, + { + "enum": ["glimmer"], + "description": "Ember / Handlebars" + }, + { + "enum": ["html"], + "description": "HTML" + }, + { + "enum": ["angular"], + "description": "Angular" + }, + { + "enum": ["lwc"], + "description": "Lightning Web Components" + }, + { + "type": "string", + "description": "Custom parser" + } + ] + }, + "pluginSearchDirs": { + "description": "Custom directory that contains prettier plugins in node_modules subdirectory.\nOverrides default behavior when plugins are searched relatively to the location of Prettier.\nMultiple values are accepted.", + "default": [], + "oneOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "enum": [false], + "description": "Disable plugin autoloading." + } + ] + }, + "plugins": { + "description": "Add a plugin. Multiple plugins can be passed as separate `--plugin`s.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "printWidth": { + "description": "The line length where Prettier will try wrap.", + "default": 80, + "type": "integer" + }, + "proseWrap": { + "description": "How to wrap prose.", + "default": "preserve", + "oneOf": [ + { + "enum": ["always"], + "description": "Wrap prose if it exceeds the print width." + }, + { + "enum": ["never"], + "description": "Do not wrap prose." + }, + { + "enum": ["preserve"], + "description": "Wrap prose as-is." + } + ] + }, + "quoteProps": { + "description": "Change when properties in objects are quoted.", + "default": "as-needed", + "oneOf": [ + { + "enum": ["as-needed"], + "description": "Only add quotes around object properties where required." + }, + { + "enum": ["consistent"], + "description": "If at least one property in an object requires quotes, quote all properties." + }, + { + "enum": ["preserve"], + "description": "Respect the input use of quotes in object properties." + } + ] + }, + "rangeEnd": { + "description": "Format code ending at a given character offset (exclusive).\nThe range will extend forwards to the end of the selected statement.\nThis option cannot be used with --cursor-offset.", + "default": null, + "type": "integer" + }, + "rangeStart": { + "description": "Format code starting at a given character offset.\nThe range will extend backwards to the start of the first line containing the selected statement.\nThis option cannot be used with --cursor-offset.", + "default": 0, + "type": "integer" + }, + "requirePragma": { + "description": "Require either '@prettier' or '@format' to be present in the file's first docblock comment\nin order for it to be formatted.", + "default": false, + "type": "boolean" + }, + "semi": { + "description": "Print semicolons.", + "default": true, + "type": "boolean" + }, + "singleAttributePerLine": { + "description": "Enforce single attribute per line in HTML, Vue and JSX.", + "default": false, + "type": "boolean" + }, + "singleQuote": { + "description": "Use single quotes instead of double quotes.", + "default": false, + "type": "boolean" + }, + "tabWidth": { + "description": "Number of spaces per indentation level.", + "default": 2, + "type": "integer" + }, + "trailingComma": { + "description": "Print trailing commas wherever possible when multi-line.", + "default": "es5", + "oneOf": [ + { + "enum": ["es5"], + "description": "Trailing commas where valid in ES5 (objects, arrays, etc.)" + }, + { + "enum": ["none"], + "description": "No trailing commas." + }, + { + "enum": ["all"], + "description": "Trailing commas wherever possible (including function arguments)." + } + ] + }, + "useTabs": { + "description": "Indent with tabs instead of spaces.", + "default": false, + "type": "boolean" + }, + "vueIndentScriptAndStyle": { + "description": "Indent script and style tags in Vue files.", + "default": false, + "type": "boolean" + } + } + }, + "overridesDefinition": { + "type": "object", + "properties": { + "overrides": { + "type": "array", + "description": "Provide a list of patterns to override prettier configuration.", + "items": { + "type": "object", + "required": ["files"], + "properties": { + "files": { + "description": "Include these files in this override.", + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "excludeFiles": { + "description": "Exclude these files from this override.", + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "options": { + "type": "object", + "description": "The options to apply for this override.", + "$ref": "#/definitions/optionsDefinition" + } + }, + "additionalProperties": false + } + } + } + } + }, + "id": "https://json.schemastore.org/prettierrc.json", + "oneOf": [ + { + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/optionsDefinition" + }, + { + "$ref": "#/definitions/overridesDefinition" + } + ] + }, + { + "type": "string" + } + ], + "title": "Schema for .prettierrc" +} diff --git a/playground/vite.config.ts b/playground/vite.config.ts index e500bb1d..e9bb7c06 100644 --- a/playground/vite.config.ts +++ b/playground/vite.config.ts @@ -4,6 +4,7 @@ import compileTime from "vite-plugin-compile-time"; import UnoCSS from "unocss/vite"; import presetIcons from "@unocss/preset-icons"; +// TODO pwa ? export default defineConfig((_env) => ({ plugins: [ UnoCSS({ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9c40b6b3..6533aba6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -126,6 +126,7 @@ importers: '@monaco-editor/react': ^4.4.6 '@saas-ui/react': ^1.4.5 '@tanstack/react-query': ^4.14.1 + '@types/json-schema': ^7.0.11 '@types/lz-string': ^1.3.34 '@types/react': ^18.0.18 '@types/react-dom': ^18.0.6 @@ -184,6 +185,7 @@ importers: '@chakra-ui/cli': 2.1.8_typescript@4.8.4 '@chakra-ui/styled-system': 2.3.4 '@iconify/json': 2.1.132 + '@types/json-schema': 7.0.11 '@types/lz-string': 1.3.34 '@types/react': 18.0.24 '@types/react-dom': 18.0.8