diff --git a/__stubs__/asts.ts b/__stubs__/asts.ts new file mode 100644 index 0000000..380d2fe --- /dev/null +++ b/__stubs__/asts.ts @@ -0,0 +1,656 @@ +export const regularAST = { + type: "File", + start: 0, + end: 265, + loc: { start: { line: 1, column: 0, index: 0 }, end: { line: 13, column: 4, index: 265 } }, + errors: [], + program: { + type: "Program", + start: 0, + end: 265, + loc: { start: { line: 1, column: 0, index: 0 }, end: { line: 13, column: 4, index: 265 } }, + sourceType: "module", + interpreter: null, + body: [ + { + type: "ImportDeclaration", + start: 7, + end: 45, + loc: { start: { line: 2, column: 6, index: 7 }, end: { line: 2, column: 44, index: 45 } }, + importKind: "value", + specifiers: [ + { + type: "ImportDefaultSpecifier", + start: 14, + end: 20, + loc: { start: { line: 2, column: 13, index: 14 }, end: { line: 2, column: 19, index: 20 } }, + local: { + type: "Identifier", + start: 14, + end: 20, + loc: { + start: { line: 2, column: 13, index: 14 }, + end: { line: 2, column: 19, index: 20 }, + identifierName: "styled", + }, + name: "styled", + }, + }, + { + type: "ImportSpecifier", + local: { type: "Identifier", name: "styled" }, + imported: { type: "Identifier", name: "styled" }, + }, + ], + source: { + type: "StringLiteral", + start: 26, + end: 45, + loc: { start: { line: 2, column: 25, index: 26 }, end: { line: 2, column: 44, index: 45 } }, + extra: { rawValue: "styled-components", raw: "'styled-components'" }, + value: "styled-components", + }, + }, + { + type: "VariableDeclaration", + start: 53, + end: 260, + loc: { start: { line: 4, column: 6, index: 53 }, end: { line: 12, column: 7, index: 260 } }, + declarations: [ + { + type: "VariableDeclarator", + start: 59, + end: 260, + loc: { start: { line: 4, column: 12, index: 59 }, end: { line: 12, column: 7, index: 260 } }, + id: { + type: "Identifier", + start: 59, + end: 65, + loc: { + start: { line: 4, column: 12, index: 59 }, + end: { line: 4, column: 18, index: 65 }, + identifierName: "Button", + }, + name: "Button", + }, + init: { + type: "TaggedTemplateExpression", + start: 68, + end: 260, + loc: { start: { line: 4, column: 21, index: 68 }, end: { line: 12, column: 7, index: 260 } }, + tag: { + type: "MemberExpression", + start: 68, + end: 81, + loc: { start: { line: 4, column: 21, index: 68 }, end: { line: 4, column: 34, index: 81 } }, + object: { + type: "Identifier", + start: 68, + end: 74, + loc: { + start: { line: 4, column: 21, index: 68 }, + end: { line: 4, column: 27, index: 74 }, + identifierName: "styled", + }, + name: "styled", + }, + computed: false, + property: { + type: "Identifier", + start: 75, + end: 81, + loc: { + start: { line: 4, column: 28, index: 75 }, + end: { line: 4, column: 34, index: 81 }, + identifierName: "button", + }, + name: "button", + }, + }, + quasi: { + type: "TemplateLiteral", + start: 81, + end: 260, + loc: { start: { line: 4, column: 34, index: 81 }, end: { line: 12, column: 7, index: 260 } }, + expressions: [], + quasis: [ + { + type: "TemplateElement", + start: 82, + end: 259, + loc: { start: { line: 4, column: 35, index: 82 }, end: { line: 12, column: 6, index: 259 } }, + value: { + raw: "\n background: white;\n color: palevioletred;\n font-size: 1em;\n &:hover {\n background: palevioletred;\n color: white;\n }\n ", + cooked: + "\n background: white;\n color: palevioletred;\n font-size: 1em;\n &:hover {\n background: palevioletred;\n color: white;\n }\n ", + }, + tail: true, + }, + ], + }, + }, + }, + ], + kind: "const", + }, + ], + directives: [], + }, + comments: [], +} + +export const multipleDeclarationsAST = { + type: "File", + start: 0, + end: 427, + loc: { start: { line: 1, column: 0, index: 0 }, end: { line: 15, column: 4, index: 427 } }, + errors: [], + program: { + type: "Program", + start: 0, + end: 427, + loc: { start: { line: 1, column: 0, index: 0 }, end: { line: 15, column: 4, index: 427 } }, + sourceType: "module", + interpreter: null, + body: [ + { + type: "VariableDeclaration", + start: 7, + end: 333, + loc: { start: { line: 2, column: 6, index: 7 }, end: { line: 9, column: 7, index: 333 } }, + declarations: [ + { + type: "VariableDeclarator", + start: 13, + end: 333, + loc: { start: { line: 2, column: 12, index: 13 }, end: { line: 9, column: 7, index: 333 } }, + id: { + type: "Identifier", + start: 13, + end: 19, + loc: { + start: { line: 2, column: 12, index: 13 }, + end: { line: 2, column: 18, index: 19 }, + identifierName: "Button", + }, + name: "Button", + }, + init: { + type: "TaggedTemplateExpression", + start: 22, + end: 333, + loc: { start: { line: 2, column: 21, index: 22 }, end: { line: 9, column: 7, index: 333 } }, + tag: { + type: "MemberExpression", + start: 22, + end: 35, + loc: { start: { line: 2, column: 21, index: 22 }, end: { line: 2, column: 34, index: 35 } }, + object: { + type: "Identifier", + start: 22, + end: 28, + loc: { + start: { line: 2, column: 21, index: 22 }, + end: { line: 2, column: 27, index: 28 }, + identifierName: "styled", + }, + name: "styled", + }, + computed: false, + property: { + type: "Identifier", + start: 29, + end: 35, + loc: { + start: { line: 2, column: 28, index: 29 }, + end: { line: 2, column: 34, index: 35 }, + identifierName: "button", + }, + name: "button", + }, + }, + quasi: { + type: "TemplateLiteral", + start: 35, + end: 333, + loc: { start: { line: 2, column: 34, index: 35 }, end: { line: 9, column: 7, index: 333 } }, + expressions: [ + { + type: "ArrowFunctionExpression", + start: 59, + end: 100, + loc: { start: { line: 3, column: 22, index: 59 }, end: { line: 3, column: 63, index: 100 } }, + id: null, + generator: false, + async: false, + params: [ + { + type: "Identifier", + start: 59, + end: 64, + loc: { + start: { line: 3, column: 22, index: 59 }, + end: { line: 3, column: 27, index: 64 }, + identifierName: "props", + }, + name: "props", + }, + ], + body: { + type: "ConditionalExpression", + start: 68, + end: 100, + loc: { start: { line: 3, column: 31, index: 68 }, end: { line: 3, column: 63, index: 100 } }, + test: { + type: "MemberExpression", + start: 68, + end: 81, + loc: { start: { line: 3, column: 31, index: 68 }, end: { line: 3, column: 44, index: 81 } }, + object: { + type: "Identifier", + start: 68, + end: 73, + loc: { + start: { line: 3, column: 31, index: 68 }, + end: { line: 3, column: 36, index: 73 }, + identifierName: "props", + }, + name: "props", + }, + computed: false, + property: { + type: "Identifier", + start: 74, + end: 81, + loc: { + start: { line: 3, column: 37, index: 74 }, + end: { line: 3, column: 44, index: 81 }, + identifierName: "primary", + }, + name: "primary", + }, + }, + consequent: { + type: "StringLiteral", + start: 84, + end: 90, + loc: { start: { line: 3, column: 47, index: 84 }, end: { line: 3, column: 53, index: 90 } }, + extra: { rawValue: "blue", raw: "'blue'" }, + value: "blue", + }, + alternate: { + type: "StringLiteral", + start: 93, + end: 100, + loc: { start: { line: 3, column: 56, index: 93 }, end: { line: 3, column: 63, index: 100 } }, + extra: { rawValue: "white", raw: "'white'" }, + value: "white", + }, + }, + }, + { + type: "ArrowFunctionExpression", + start: 120, + end: 162, + loc: { start: { line: 4, column: 17, index: 120 }, end: { line: 4, column: 59, index: 162 } }, + id: null, + generator: false, + async: false, + params: [ + { + type: "Identifier", + start: 120, + end: 125, + loc: { + start: { line: 4, column: 17, index: 120 }, + end: { line: 4, column: 22, index: 125 }, + identifierName: "props", + }, + name: "props", + }, + ], + body: { + type: "ConditionalExpression", + start: 129, + end: 162, + loc: { start: { line: 4, column: 26, index: 129 }, end: { line: 4, column: 59, index: 162 } }, + test: { + type: "MemberExpression", + start: 129, + end: 142, + loc: { start: { line: 4, column: 26, index: 129 }, end: { line: 4, column: 39, index: 142 } }, + object: { + type: "Identifier", + start: 129, + end: 134, + loc: { + start: { line: 4, column: 26, index: 129 }, + end: { line: 4, column: 31, index: 134 }, + identifierName: "props", + }, + name: "props", + }, + computed: false, + property: { + type: "Identifier", + start: 135, + end: 142, + loc: { + start: { line: 4, column: 32, index: 135 }, + end: { line: 4, column: 39, index: 142 }, + identifierName: "primary", + }, + name: "primary", + }, + }, + consequent: { + type: "StringLiteral", + start: 145, + end: 152, + loc: { start: { line: 4, column: 42, index: 145 }, end: { line: 4, column: 49, index: 152 } }, + extra: { rawValue: "white", raw: "'white'" }, + value: "white", + }, + alternate: { + type: "StringLiteral", + start: 155, + end: 162, + loc: { start: { line: 4, column: 52, index: 155 }, end: { line: 4, column: 59, index: 162 } }, + extra: { rawValue: "black", raw: "'black'" }, + value: "black", + }, + }, + }, + { + type: "Identifier", + start: 186, + end: 194, + loc: { + start: { line: 5, column: 21, index: 186 }, + end: { line: 5, column: 29, index: 194 }, + identifierName: "fontSize", + }, + name: "fontSize", + }, + { + type: "ArrowFunctionExpression", + start: 254, + end: 295, + loc: { start: { line: 7, column: 28, index: 254 }, end: { line: 7, column: 69, index: 295 } }, + id: null, + generator: false, + async: false, + params: [ + { + type: "Identifier", + start: 254, + end: 259, + loc: { + start: { line: 7, column: 28, index: 254 }, + end: { line: 7, column: 33, index: 259 }, + identifierName: "props", + }, + name: "props", + }, + ], + body: { + type: "ConditionalExpression", + start: 263, + end: 295, + loc: { start: { line: 7, column: 37, index: 263 }, end: { line: 7, column: 69, index: 295 } }, + test: { + type: "MemberExpression", + start: 263, + end: 276, + loc: { start: { line: 7, column: 37, index: 263 }, end: { line: 7, column: 50, index: 276 } }, + object: { + type: "Identifier", + start: 263, + end: 268, + loc: { + start: { line: 7, column: 37, index: 263 }, + end: { line: 7, column: 42, index: 268 }, + identifierName: "props", + }, + name: "props", + }, + computed: false, + property: { + type: "Identifier", + start: 269, + end: 276, + loc: { + start: { line: 7, column: 43, index: 269 }, + end: { line: 7, column: 50, index: 276 }, + identifierName: "primary", + }, + name: "primary", + }, + }, + consequent: { + type: "StringLiteral", + start: 279, + end: 285, + loc: { start: { line: 7, column: 53, index: 279 }, end: { line: 7, column: 59, index: 285 } }, + extra: { rawValue: "blue", raw: "'blue'" }, + value: "blue", + }, + alternate: { + type: "StringLiteral", + start: 288, + end: 295, + loc: { start: { line: 7, column: 62, index: 288 }, end: { line: 7, column: 69, index: 295 } }, + extra: { rawValue: "black", raw: "'black'" }, + value: "black", + }, + }, + }, + ], + quasis: [ + { + type: "TemplateElement", + start: 36, + end: 57, + loc: { start: { line: 2, column: 35, index: 36 }, end: { line: 3, column: 20, index: 57 } }, + value: { raw: "\n background: ", cooked: "\n background: " }, + tail: false, + }, + { + type: "TemplateElement", + start: 101, + end: 118, + loc: { start: { line: 3, column: 64, index: 101 }, end: { line: 4, column: 15, index: 118 } }, + value: { raw: ";\n color: ", cooked: ";\n color: " }, + tail: false, + }, + { + type: "TemplateElement", + start: 163, + end: 184, + loc: { start: { line: 4, column: 60, index: 163 }, end: { line: 5, column: 19, index: 184 } }, + value: { raw: ";\n font-size: ", cooked: ";\n font-size: " }, + tail: false, + }, + { + type: "TemplateElement", + start: 195, + end: 252, + loc: { start: { line: 5, column: 30, index: 195 }, end: { line: 7, column: 26, index: 252 } }, + value: { + raw: ";\n padding: 0.25em 1em;\n border: 2px solid ", + cooked: ";\n padding: 0.25em 1em;\n border: 2px solid ", + }, + tail: false, + }, + { + type: "TemplateElement", + start: 296, + end: 332, + loc: { start: { line: 7, column: 70, index: 296 }, end: { line: 9, column: 6, index: 332 } }, + value: { + raw: ";\n border-radius: 3px;\n ", + cooked: ";\n border-radius: 3px;\n ", + }, + tail: true, + }, + ], + }, + }, + }, + ], + kind: "const", + }, + { + type: "VariableDeclaration", + start: 341, + end: 422, + loc: { start: { line: 11, column: 6, index: 341 }, end: { line: 14, column: 7, index: 422 } }, + declarations: [ + { + type: "VariableDeclarator", + start: 347, + end: 422, + loc: { start: { line: 11, column: 12, index: 347 }, end: { line: 14, column: 7, index: 422 } }, + id: { + type: "Identifier", + start: 347, + end: 353, + loc: { + start: { line: 11, column: 12, index: 347 }, + end: { line: 11, column: 18, index: 353 }, + identifierName: "Header", + }, + name: "Header", + }, + init: { + type: "TaggedTemplateExpression", + start: 356, + end: 422, + loc: { start: { line: 11, column: 21, index: 356 }, end: { line: 14, column: 7, index: 422 } }, + tag: { + type: "MemberExpression", + start: 356, + end: 365, + loc: { start: { line: 11, column: 21, index: 356 }, end: { line: 11, column: 30, index: 365 } }, + object: { + type: "Identifier", + start: 356, + end: 362, + loc: { + start: { line: 11, column: 21, index: 356 }, + end: { line: 11, column: 27, index: 362 }, + identifierName: "styled", + }, + name: "styled", + }, + computed: false, + property: { + type: "Identifier", + start: 363, + end: 365, + loc: { + start: { line: 11, column: 28, index: 363 }, + end: { line: 11, column: 30, index: 365 }, + identifierName: "h1", + }, + name: "h1", + }, + }, + quasi: { + type: "TemplateLiteral", + start: 365, + end: 422, + loc: { start: { line: 11, column: 30, index: 365 }, end: { line: 14, column: 7, index: 422 } }, + expressions: [], + quasis: [ + { + type: "TemplateElement", + start: 366, + end: 421, + loc: { start: { line: 11, column: 31, index: 366 }, end: { line: 14, column: 6, index: 421 } }, + value: { + raw: "\n font-size: 1rem;\n padding: 4rem;\n ", + cooked: "\n font-size: 1rem;\n padding: 4rem;\n ", + }, + tail: true, + }, + ], + }, + }, + }, + ], + kind: "const", + }, + ], + directives: [], + }, + comments: [], +} + +export const nestedTemplateAST = { + type: "TaggedTemplateExpression", + tag: { + type: "MemberExpression", + object: { + type: "Identifier", + name: "styled", + }, + property: { + type: "Identifier", + name: "section", + }, + }, + quasi: { + type: "TemplateLiteral", + quasis: [ + { + type: "TemplateElement", + value: { + raw: "\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100vh;\n background: linear-gradient(\n 145deg,\n rgba(253, 38, 71, 1) 0%,\n rgba(252, 128, 45, 1) 75%,\n rgba(250, 167, 43, 1) 100%\n );\n\n ", + cooked: + "\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100vh;\n background: linear-gradient(\n 145deg,\n rgba(253, 38, 71, 1) 0%,\n rgba(252, 128, 45, 1) 75%,\n rgba(250, 167, 43, 1) 100%\n );\n\n ", + }, + tail: false, + }, + { + type: "TemplateElement", + value: { + raw: "\n\n ", + cooked: "\n\n ", + }, + tail: false, + }, + { + type: "TemplateElement", + value: { + raw: "\n", + cooked: "\n", + }, + tail: true, + }, + ], + expressions: [ + { + type: "TaggedTemplateExpression", + tag: { + type: "Identifier", + name: "css", + }, + quasi: { + type: "TemplateLiteral", + quasis: [ + { + type: "TemplateElement", + value: { + raw: "\n margin-bottom: 2em;\n ", + cooked: "\n margin-bottom: 2em;\n ", + }, + tail: true, + }, + ], + expressions: [], + }, + }, + ], + }, +} diff --git a/package.json b/package.json index 6a247db..a2ee666 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "type": "module", "scripts": { "build": "tsc", + "convertToAST": "node dist/styledComponentsToAST.js", "test": "vitest", "coverage": "vitest run --coverage" }, @@ -12,7 +13,13 @@ "author": "Blazity", "license": "MIT", "devDependencies": { + "@babel/core": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5", "@total-typescript/ts-reset": "^0.4.2", + "@types/babel__core": "^7.20.1", + "@types/babel__traverse": "^7.20.1", + "@types/lodash": "^4.14.195", "@types/node": "^20.3.1", "@typescript-eslint/eslint-plugin": "^5.60.0", "@typescript-eslint/parser": "^5.60.0", @@ -22,5 +29,8 @@ "prettier-plugin-tailwindcss": "^0.3.0", "typescript": "^5.1.3", "vitest": "^0.32.2" + }, + "dependencies": { + "lodash": "^4.17.21" } } diff --git a/src/ASTtoCSS.ts b/src/ASTtoCSS.ts new file mode 100644 index 0000000..8347fb3 --- /dev/null +++ b/src/ASTtoCSS.ts @@ -0,0 +1,63 @@ +import { Node } from "@babel/core" +import * as t from "@babel/types" + +export function generateCSSFromAST(ast: Node): string { + let cssCode = "" + const generatedSelectors: Set = new Set() + + function generateRandomSelector(): string { + const characters = "abcdefghijklmnopqrstuvwxyz" + let randomSelector = "" + + for (let i = 0; i < 5; i++) { + const randomIndex = Math.floor(Math.random() * characters.length) + randomSelector += characters.charAt(randomIndex) + } + + return randomSelector + } + + function traverseAST(node: Node, selectorPrefix = "") { + if (t.isTaggedTemplateExpression(node)) { + const cssRule = node.quasi.quasis + .map((element) => element.value.raw) + .join("") + .trim() + + if (cssRule.length > 0) { + let randomSelector + + do { + randomSelector = generateRandomSelector() + } while (generatedSelectors.has(randomSelector)) + + const selector = `${selectorPrefix}.${randomSelector}` + generatedSelectors.add(randomSelector) + cssCode += `${selector} { ${cssRule} }\n` + } + } + + Object.values(node).forEach((childNode) => { + if (!childNode || typeof childNode !== "object") return + + if (Array.isArray(childNode)) { + childNode.forEach((child) => traverseAST(child, selectorPrefix)) + } else if (t.isJSXElement(childNode)) { + const { openingElement, closingElement } = childNode + + ;[openingElement, closingElement].forEach((element) => { + if (!element || !t.isJSXIdentifier(element.name)) return + + const childSelector = `${selectorPrefix} ${element.name.name}` + traverseAST(element, childSelector) + }) + } else { + traverseAST(childNode, selectorPrefix) + } + }) + } + + traverseAST(ast) + + return cssCode +} diff --git a/src/CSStoTailwind.ts b/src/CSStoTailwind.ts new file mode 100644 index 0000000..c1657e4 --- /dev/null +++ b/src/CSStoTailwind.ts @@ -0,0 +1,81 @@ +import _ from "lodash" + +export function convertToTailwindCSS(cssCode: string): string { + const CSS_BLOCKS = cssCode.split("}").map((block) => block.trim()) + + const tailwindClasses = CSS_BLOCKS.filter((block) => block.includes("{")).map((block) => { + const [selectors, declarations] = block.split("{").map((part) => part.trim()) + const selectorClasses = extractSelectorClasses(selectors) + const declarationClasses = extractDeclarationClasses(declarations) + + return selectorClasses ? `${selectorClasses} { ${declarationClasses.join(" ")} }` : declarationClasses.join(" ") + }) + + return tailwindClasses.join(" ") +} + +function extractSelectorClasses(selectors: string): string { + const classes = selectors.split(",").map((item) => item.trim()) + + return classes.join(", ") +} + +function extractDeclarationClasses(declarations: string): string[] { + const properties = declarations.split(";").map((declaration) => declaration.trim()) + + return properties + .filter((property) => property.includes(":")) + .map((property) => { + const [propertyKey, propertyValue] = property.split(":").map((part) => part.trim()) + const tailwindClass = getTailwindClass(propertyKey, propertyValue) + + return tailwindClass ? tailwindClass : `${getPropertyAlias(propertyKey)}-${wrapWithArbitraryValue(propertyValue)}` + }) +} + +function getTailwindClass(property: string, value: string): string | null { + const propertyMappings: Record> = { + backgroundColor: { + transparent: "bg-transparent", + current: "bg-current", + black: "bg-black", + white: "bg-white", + default: `bg-[${value}]`, + }, + margin: { + "4rem": "m-16", + default: `m-[${value}]`, + }, + fontSize: { + "1rem": "text-base", + default: `text-[${value}]`, + }, + color: { + red: "text-red-500", + default: `text-[${value}]`, + }, + padding: { + "0.25rem": "p-1", + default: `p-[${value}]`, + }, + } + + const propertyMapping = propertyMappings[property] || propertyMappings[_.camelCase(property)] + + return propertyMapping && propertyMapping[value] ? propertyMapping[value] : null +} + +function getPropertyAlias(property: string): string { + const propertyAliases: Record = { + backgroundColor: "bg", + color: "text", + fontSize: "text", + fontWeight: "font", + } + + return propertyAliases[property] || property +} + +function wrapWithArbitraryValue(value: string): string { + return `[${value}]` +} diff --git a/src/index.ts b/src/index.ts deleted file mode 100644 index b9d3e23..0000000 --- a/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -console.log('Hello world!'); diff --git a/src/styledComponentsToAST.ts b/src/styledComponentsToAST.ts new file mode 100644 index 0000000..3f0d201 --- /dev/null +++ b/src/styledComponentsToAST.ts @@ -0,0 +1,73 @@ +/* eslint-disable no-prototype-builtins */ +import { parse, ParserOptions } from "@babel/parser" +import { traverse } from "@babel/core" +import { NodePath } from "@babel/traverse" +import * as t from "@babel/types" + +export function transformCodeToAST(input: string) { + if (!input) { + throw new Error("Provided input is empty") + } + + let ast: t.Node + try { + ast = parse(input, { + sourceType: "module", + plugins: ["jsx", "typescript"], + } as ParserOptions) + } catch (error) { + throw new Error("Input is not valid JavaScript code") + } + + const styledIdentifier = t.identifier("styled") + const styledProperty = t.identifier("styled") + + traverse(ast, { + TaggedTemplateExpression(path: NodePath) { + const { tag, quasi } = path.node + + if ( + t.isMemberExpression(tag) && + t.isIdentifier(tag.object, { name: styledIdentifier.name }) && + t.isIdentifier(tag.property, { name: styledProperty.name }) + ) { + const styledCallExpression = t.callExpression(t.memberExpression(styledIdentifier, styledProperty), [ + tag.object, + tag.property, + quasi, + ]) + + path.replaceWith(styledCallExpression) + } + }, + + VariableDeclaration(path: NodePath) { + const { declarations } = path.node + + declarations.forEach((declaration) => { + const { init } = declaration + + if (t.isCallExpression(init) && t.isIdentifier(init.callee, { name: styledIdentifier.name })) { + const styledCallExpression = t.callExpression( + t.memberExpression(styledIdentifier, styledProperty), + init.arguments + ) + + declaration.init = styledCallExpression + } + }) + }, + + ImportDeclaration(path: NodePath) { + const { source, specifiers } = path.node + + if (source.value === "styled-components") { + const importSpecifier = t.importSpecifier(styledIdentifier, styledProperty) + + specifiers.push(importSpecifier) + } + }, + }) + + return ast +} diff --git a/test/ASTtoCSS.test.js b/test/ASTtoCSS.test.js new file mode 100644 index 0000000..f6bd7f7 --- /dev/null +++ b/test/ASTtoCSS.test.js @@ -0,0 +1,50 @@ +import { describe, it, expect } from "vitest" +import { generateCSSFromAST } from "../src/ASTtoCSS" +import { stripWhitespace } from "./test-utils" +import { regularAST, multipleDeclarationsAST, nestedTemplateAST } from "../__stubs__/asts" + +describe("#generateCSSFromAST", () => { + it("should generate valid CSS from correct AST input", () => { + const result = stripWhitespace(generateCSSFromAST(regularAST)) + + expect(result).toEqual( + expect.stringContaining( + "background:white;color:palevioletred;font-size:1em;&:hover{background:palevioletred;color:white;" + ) + ) + }) + + it("should generate valid CSS from empty AST input", () => { + const input = "" + + const result = stripWhitespace(generateCSSFromAST(input)) + + expect(result).toEqual("") // Expect an empty string since there are no CSS rules + }) + + it("should generate valid CSS from AST input with multiple tagged template expressions", () => { + const result = stripWhitespace(generateCSSFromAST(multipleDeclarationsAST)) + + expect(result).toEqual( + expect.stringContaining( + stripWhitespace("background:;color:;font-size:;padding:0.25em1em;border:2pxsolid;border-radius:3px;") + ) + ) + + expect(result).toEqual(expect.stringContaining(stripWhitespace("font-size:1rem;padding:4rem;"))) + }) + + it("should generate valid CSS from AST input with nested tagged template expressions", () => { + const result = stripWhitespace(generateCSSFromAST(nestedTemplateAST)) + + expect(result).toEqual( + expect.stringContaining( + stripWhitespace( + "display: flex; justify-content:center;align-items:center;height:100vh;background:linear-gradient(145deg,rgba(253, 38, 71, 1) 0%,rgba(252, 128, 45, 1)75%,rgba(250, 167, 43, 1)100%);" + ) + ) + ) + + expect(result).toEqual(expect.stringContaining(stripWhitespace("margin-bottom: 2em;"))) + }) +}) diff --git a/test/CSStoTailwind.test.js b/test/CSStoTailwind.test.js new file mode 100644 index 0000000..674d02a --- /dev/null +++ b/test/CSStoTailwind.test.js @@ -0,0 +1,42 @@ +import { describe, expect, it } from "vitest" +import { convertToTailwindCSS } from "../src/CSStoTailwind" +import { stripWhitespace } from "./test-utils" + +describe("#convertToTailwind", () => { + it("should convert CSS input to Tailwind", () => { + const input = ` + .button { + background-color: white; + font-size: 16px; + padding: 7px; + } + ` + + const result = stripWhitespace(convertToTailwindCSS(input)) + + expect(result).toEqual(expect.stringContaining("{bg-whitefont-size-[16px]padding-[7px]}")) + }) + + it("should convert CSS code generated from AST to valid TailwindCSS", () => { + const input = stripWhitespace(".mzoqw { background-color: white; color: red; font-size: 1rem; margin: 4rem; }") + const result = convertToTailwindCSS(input) + + expect(result).toEqual(expect.stringContaining("{ bg-white text-red-500 text-base m-16 }")) + }) + + it("should convert invalid CSS properties to TailwindCSS", () => { + // TODO: Not yet. 🦇 + }) + + it("should convert prefixed CSS properties (i.e. --webkit) to TailwindCSS", () => { + // TODO: Not yet. 🦇 + }) + + it("should convert shorthand CSS properties (i.e. padding: 1px 0 3px 5px) to TailwindCSS", () => { + // TODO: Not yet. 🦇 + }) + + it("should convert CSS properties with a decimal to TailwindCSS", () => { + // TODO: Not yet. 🦇 + }) +}) diff --git a/test/index.test.js b/test/index.test.js new file mode 100644 index 0000000..378e2ef --- /dev/null +++ b/test/index.test.js @@ -0,0 +1,37 @@ +import { describe, it, expect } from "vitest" +import { stripWhitespace } from "./test-utils" +import { transformCodeToAST } from "../src/styledComponentsToAST" +import { generateCSSFromAST } from "../src/ASTtoCSS" +import { convertToTailwindCSS } from "../src/CSStoTailwind" + +describe("styled-components to TailwindCSS converter flow", () => { + it("should correctly transform valid JS input including styled-components into TailwindCSS utility classes", () => { + const input = ` + import styled from 'styled-components' + const Button = styled.button\` + backgroundColor: white; + color: palevioletred; + font-size: 1rem; + padding: 0.25rem; + \` + ` + // styled-components to TailwindCSS flow showcase + console.log(`Initial input:\n${input}\n\n`) + + const generatedAST = transformCodeToAST(input) + + console.log(`Generated AST:\n\n${JSON.stringify(generatedAST)}\n\n\n`) + + const generatedCSS = generateCSSFromAST(generatedAST) + + console.log(`Generated CSS:\n\n${generatedCSS}\n\n\n`) + + const generatedTailwindCSS = convertToTailwindCSS(generatedCSS) + + console.log(`Generated TailwindCSS:\n\n${generatedTailwindCSS}\n`) + + expect(stripWhitespace(generatedTailwindCSS)).toEqual( + expect.stringContaining("{bg-whitetext-[palevioletred]text-basep-1}") + ) + }) +}) diff --git a/test/index.test.ts b/test/index.test.ts deleted file mode 100644 index f19bbde..0000000 --- a/test/index.test.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { expect, test } from 'vitest'; - -test('Square root', () => { - expect(Math.sqrt(4)).toBe(2); - expect(Math.sqrt(144)).toBe(12); - expect(Math.sqrt(2)).toBe(Math.SQRT2); -}); diff --git a/test/styledComponentsToAST.test.js b/test/styledComponentsToAST.test.js new file mode 100644 index 0000000..659ffb2 --- /dev/null +++ b/test/styledComponentsToAST.test.js @@ -0,0 +1,86 @@ +import { describe, it, expect } from "vitest" +import { transformCodeToAST } from "../src/styledComponentsToAST" +import { findPropertyByValue } from "./test-utils" + +describe("#transformCodeToAST", () => { + it("should contain a valid TemplateElement type", () => { + const input = ` + import styled from 'styled-components' + const Button = styled.button\` + background: white; + color: palevioletred; + font-size: 1em; + padding: 0.25em 1em; + border: 2px solid palevioletred; + border-radius: 3px; + \` + ` + + expect(findPropertyByValue(transformCodeToAST(input), "type", "TemplateElement")).toBeTruthy() + }) + + it("should contain properties that are equal to the input code", () => { + const input = ` + const Button = \` + background: white; + color: palevioletred; + font-size: 1em; + padding: 0.25em 1em; + border: 2px solid palevioletred; + border-radius: 3px; + \` + ` + + const result = findPropertyByValue(transformCodeToAST(input), "value", { + raw: "\nbackground: white;\n color: palevioletred;\nfont-size: 1em;\npadding: 0.25em 1em;\nborder: 2px solid palevioletred;\nborder-radius: 3px;\n", + cooked: + "\nbackground: white;\ncolor: palevioletred;\nfont-size: 1em;\npadding: 0.25em 1em;\nborder: 2px solid palevioletred;\nborder-radius: 3px;\n", + }) + + expect(result).toBeTruthy() + }) + + it("should throw an error if the input is empty", () => { + const input = "" + + expect(() => transformCodeToAST(input)).toThrowError(/^Provided input is empty$/) + expect(() => transformCodeToAST(input)).not.toThrowError(/^Any other error/) + }) + + it("should throw an error if the input is not valid JavaScript code", () => { + const input = ` + import styled from 'styled + + const Button = styled.button\` + background: \${props => props.primary ? 'blue' : 'white'}; + color: \${props => props.primary ? 'white' : 'black'}; + font-size: \${fontSize}; + padding: 0.25em 1em; + border: 2px solid \${props => props.primary ? 'blue' : 'black'}; + border-radius: 3px; + \` + ` + + expect(() => transformCodeToAST(input)).toThrowError(/^Input is not valid JavaScript code/) + }) + + it("should transform styled-component CSS interpolation into AST", () => { + const input = ` + const Button = styled.button\` + background: \${props => props.primary ? 'blue' : 'white'}; + color: \${props => props.primary ? 'white' : 'black'}; + font-size: \${fontSize}; + padding: 0.25em 1em; + border: 2px solid \${props => props.primary ? 'blue' : 'black'}; + border-radius: 3px; + \` + ` + + const ast = transformCodeToAST(input) + + expect(findPropertyByValue(ast, "type", "TemplateElement")).toBeTruthy() + expect(findPropertyByValue(ast, "value", { raw: "\nbackground:", cooked: "\nbackground:" })).toBeTruthy() + expect(findPropertyByValue(ast, "type", "Identifier")).toBeTruthy() + expect(findPropertyByValue(ast, "name", "props")).toBeTruthy() + }) +}) diff --git a/test/test-utils.js b/test/test-utils.js new file mode 100644 index 0000000..0dfe6a3 --- /dev/null +++ b/test/test-utils.js @@ -0,0 +1,41 @@ +/* eslint-disable no-prototype-builtins */ +import _ from "lodash" + +export function stripWhitespace(str) { + return str.replace(/\s+/g, "") +} + +function normalizeValue(value) { + if (typeof value === "string") { + return stripWhitespace(value) + } else if (Array.isArray(value)) { + return value.map(normalizeValue) + } else if (typeof value === "object" && value !== null) { + const newValue = {} + for (const key in value) { + newValue[key] = normalizeValue(value[key]) + } + return newValue + } else { + return value + } +} + +export function findPropertyByValue(object, propertyName, value) { + const normalizedValue = normalizeValue(value) + + if (object.hasOwnProperty(propertyName) && _.isEqual(normalizeValue(object[propertyName]), normalizedValue)) { + return object + } + + for (let prop in object) { + if (object[prop] && typeof object[prop] === "object") { + let result = findPropertyByValue(object[prop], propertyName, value) + if (result) { + return result + } + } + } + + return undefined +} diff --git a/tsconfig.json b/tsconfig.json index e471385..27dd51d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,9 @@ "moduleResolution": "NodeNext", "target": "ES2020", "sourceMap": true, - "outDir": "dist" + "outDir": "dist", + "skipLibCheck": true }, - "include": ["src/**/*"] + "include": ["src", "dist/exampleInput.jsx", "dist/index.js"], + "exclude": ["dist", "node_modules"] } diff --git a/yarn.lock b/yarn.lock index 4f5f5f6..1a9a2c8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -"@ampproject/remapping@^2.2.1": +"@ampproject/remapping@^2.2.0", "@ampproject/remapping@^2.2.1": version "2.2.1" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== @@ -10,6 +10,187 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" +"@babel/code-frame@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" + integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== + dependencies: + "@babel/highlight" "^7.22.5" + +"@babel/compat-data@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.5.tgz#b1f6c86a02d85d2dd3368a2b67c09add8cd0c255" + integrity sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA== + +"@babel/core@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.5.tgz#d67d9747ecf26ee7ecd3ebae1ee22225fe902a89" + integrity sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helpers" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.2" + semver "^6.3.0" + +"@babel/generator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.5.tgz#1e7bf768688acfb05cf30b2369ef855e82d984f7" + integrity sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA== + dependencies: + "@babel/types" "^7.22.5" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz#fc7319fc54c5e2fa14b2909cf3c5fd3046813e02" + integrity sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw== + dependencies: + "@babel/compat-data" "^7.22.5" + "@babel/helper-validator-option" "^7.22.5" + browserslist "^4.21.3" + lru-cache "^5.1.1" + semver "^6.3.0" + +"@babel/helper-environment-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" + integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== + +"@babel/helper-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" + integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== + dependencies: + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" + integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-transforms@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz#0f65daa0716961b6e96b164034e737f60a80d2ef" + integrity sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz#88cf11050edb95ed08d596f7a044462189127a08" + integrity sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + +"@babel/helper-validator-identifier@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" + integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== + +"@babel/helper-validator-option@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" + integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== + +"@babel/helpers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.5.tgz#74bb4373eb390d1ceed74a15ef97767e63120820" + integrity sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q== + dependencies: + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/highlight@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" + integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== + dependencies: + "@babel/helper-validator-identifier" "^7.22.5" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.5.tgz#721fd042f3ce1896238cf1b341c77eb7dee7dbea" + integrity sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q== + +"@babel/template@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" + integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/traverse@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.5.tgz#44bd276690db6f4940fdb84e1cb4abd2f729ccd1" + integrity sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe" + integrity sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -181,7 +362,7 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jridgewell/gen-mapping@^0.3.0": +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": version "0.3.3" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== @@ -210,7 +391,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": version "0.3.18" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== @@ -244,6 +425,39 @@ resolved "https://registry.yarnpkg.com/@total-typescript/ts-reset/-/ts-reset-0.4.2.tgz#c564c173ba09973968e1046c93965b7a257878a4" integrity sha512-vqd7ZUDSrXFVT1n8b2kc3LnklncDQFPvR58yUS1kEP23/nHPAO9l1lMjUfnPrXYYk4Hj54rrLKMW5ipwk7k09A== +"@types/babel__core@^7.20.1": + version "7.20.1" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.1.tgz#916ecea274b0c776fec721e333e55762d3a9614b" + integrity sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.4" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" + integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.20.1": + version "7.20.1" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.1.tgz#dd6f1d2411ae677dcb2db008c962598be31d6acf" + integrity sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg== + dependencies: + "@babel/types" "^7.20.7" + "@types/chai-subset@^1.3.3": version "1.3.3" resolved "https://registry.yarnpkg.com/@types/chai-subset/-/chai-subset-1.3.3.tgz#97893814e92abd2c534de422cb377e0e0bdaac94" @@ -266,6 +480,11 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== +"@types/lodash@^4.14.195": + version "4.14.195" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.195.tgz#bafc975b252eb6cea78882ce8a7b6bf22a6de632" + integrity sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg== + "@types/node@*", "@types/node@^20.3.1": version "20.3.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.1.tgz#e8a83f1aa8b649377bb1fb5d7bac5cb90e784dfe" @@ -451,6 +670,13 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" @@ -503,6 +729,16 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" +browserslist@^4.21.3: + version "4.21.9" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.9.tgz#e11bdd3c313d7e2a9e87e8b4b0c7872b13897635" + integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg== + dependencies: + caniuse-lite "^1.0.30001503" + electron-to-chromium "^1.4.431" + node-releases "^2.0.12" + update-browserslist-db "^1.0.11" + cac@^6.7.14: version "6.7.14" resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" @@ -513,6 +749,11 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== +caniuse-lite@^1.0.30001503: + version "1.0.30001508" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001508.tgz#4461bbc895c692a96da399639cc1e146e7302a33" + integrity sha512-sdQZOJdmt3GJs1UMNpCCCyeuS2IEGLXnHyAo9yIO5JJDjbjoVRij4M1qep6P6gFpptD1PqIYgzM+gwJbOi92mw== + chai@^4.3.7: version "4.3.7" resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51" @@ -526,6 +767,15 @@ chai@^4.3.7: pathval "^1.1.1" type-detect "^4.0.5" +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + chalk@^4.0.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -539,6 +789,13 @@ check-error@^1.0.2: resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + color-convert@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" @@ -546,6 +803,11 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" @@ -570,7 +832,7 @@ concordance@^5.0.4: semver "^7.3.2" well-known-symbols "^2.0.0" -convert-source-map@^1.6.0: +convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.9.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== @@ -591,7 +853,7 @@ date-time@^3.1.0: dependencies: time-zone "^1.0.0" -debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: +debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -629,6 +891,11 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +electron-to-chromium@^1.4.431: + version "1.4.441" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.441.tgz#94dd9c1cbf081d83f032a4f1cd9f787e21fc24ce" + integrity sha512-LlCgQ8zgYZPymf5H4aE9itwiIWH4YlCiv1HFLmmcBeFYi5E+3eaIFnjHzYtcFQbaKfAW+CqZ9pgxo33DZuoqPg== + esbuild@^0.17.5: version "0.17.19" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.19.tgz#087a727e98299f0462a3d0bcdd9cd7ff100bd955" @@ -657,6 +924,16 @@ esbuild@^0.17.5: "@esbuild/win32-ia32" "0.17.19" "@esbuild/win32-x64" "0.17.19" +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" @@ -849,6 +1126,11 @@ fsevents@~2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + get-func-name@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" @@ -880,6 +1162,11 @@ glob@^7.1.3, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + globals@^13.19.0: version "13.20.0" resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" @@ -909,6 +1196,11 @@ graphemer@^1.4.0: resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" @@ -1013,6 +1305,11 @@ js-string-escape@^1.0.1: resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" integrity sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg== +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" @@ -1020,6 +1317,11 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -1030,6 +1332,11 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== +json5@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + jsonc-parser@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" @@ -1060,7 +1367,7 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash@^4.17.15: +lodash@^4.17.15, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -1072,6 +1379,13 @@ loupe@^2.3.1, loupe@^2.3.6: dependencies: get-func-name "^2.0.0" +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -1150,6 +1464,11 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== +node-releases@^2.0.12: + version "2.0.12" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.12.tgz#35627cc224a23bfb06fb3380f2b3afaaa7eb1039" + integrity sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ== + once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -1325,7 +1644,7 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -semver@^6.0.0: +semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -1398,6 +1717,13 @@ strip-literal@^1.0.1: dependencies: acorn "^8.8.2" +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -1439,6 +1765,11 @@ tinyspy@^2.1.0: resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-2.1.1.tgz#9e6371b00c259e5c5b301917ca18c01d40ae558c" integrity sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w== +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -1485,6 +1816,14 @@ ufo@^1.1.2: resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.1.2.tgz#d0d9e0fa09dece0c31ffd57bd363f030a35cfe76" integrity sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ== +update-browserslist-db@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -1585,6 +1924,11 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"