import type { Options } from 'prettier' import type { Prettier } from './prettier' import prettier from 'prettier/esm/standalone.mjs' // import parserBabel from 'prettier/esm/parser-babel.mjs' // import parserHtml from 'prettier/esm/parser-html.mjs' // import parserMarkdown from 'prettier/esm/parser-markdown.mjs' // import parserPostcss from 'prettier/esm/parser-postcss.mjs' // import parserTypescript from 'prettier/esm/parser-typescript.mjs' import { Layer } from '../../../../packages/core/src/internal/precedence' const defaults = { semi: false, trailingComma: 'all' } const plugins = [ { detect: (parser: string) => /^[mc]?jsx?$/.test(parser) ? 'babel' : /^[mc]?tsx?$/.test(parser) ? 'babel-ts' : /^json5?$/.test(parser) && parser, load: () => import('prettier/esm/parser-babel.mjs').then((m) => m.default), }, { detect: (parser: string) => /^html?$/.test(parser) && 'html', load: () => import('prettier/esm/parser-html.mjs').then((m) => m.default), }, { detect: (parser: string) => /^(le|s?c)ss$/.test(parser) && parser, load: () => import('prettier/esm/parser-postcss.mjs').then((m) => m.default), }, ] async function getOptions(options?: Options) { let parser = options?.parser || /(?:\.([^.]+))?$/.exec(options?.filepath || '')?.[1] if (typeof parser === 'string') { for (const plugin of plugins) { const found = plugin.detect(parser) if (found) { return { ...defaults, ...options, parser: found, plugins: [await plugin.load()], } } } } return { ...defaults, ...options, plugins: Promise.all(plugins.map((plugin) => plugin.load())), } } const api: Prettier = { async format(source, options) { return prettier.format(source, await getOptions(options)) }, async formatWithCursor(source, options) { return prettier.formatWithCursor(source, await getOptions(options)) }, async formatPreviewCSS(rules) { let source = '' let lastLayerName = '' for (const rule of rules) { const match = rule.match(/^\/\*!([\da-z]+),([\da-z]+)(?:,(.+?))?\*\//) if (match) { const style = rule.slice(match[0].length) const precedence = parseInt(match[1], 36) // const name = match[3] const layer = precedence & Layer.o const layerName = layer === Layer.d ? 'defaults' : layer === Layer.b ? 'base' : layer === Layer.c ? 'components' : layer === Layer.a ? 'aliases' : layer === Layer.u ? 'utilities' : 'overrides' if (lastLayerName !== layerName) { // if (lastLayerName) { // source += `/* } */\n` // } lastLayerName = layerName source += `\n\n/* @layer ${layerName} */\n\n` } // if (name) { // source += `/* ${name} */\n` // } source += `${style}\n` } else { source += `${rule}\n` } } // if (lastLayerName) { // source += `/* } */\n` // } return this.format(source, { parser: 'css' }) }, } export default api