From 02ca084a0ca05e7eed28ffc33b81228d1abf7c0c Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sun, 23 Nov 2025 14:32:12 +0300 Subject: [PATCH] refactor: upgrade to csstree v3 (#5455) The new version is aware of modern colors and other new css features. --- @types/css-tree.d.ts | 772 ++++++++++++++++++ apps/builder/app/shared/style-object-model.ts | 9 +- apps/builder/package.json | 2 +- package.json | 3 - packages/css-data/package.json | 3 +- packages/css-data/src/parse-css-value.ts | 5 +- packages/css-data/src/parse-css.ts | 320 ++++---- packages/css-data/src/shorthands.ts | 75 +- packages/css-data/tsconfig.json | 1 + packages/dashboard/tsconfig.json | 3 +- packages/design-system/tsconfig.json | 3 +- packages/domain/tsconfig.json | 3 +- packages/project-build/tsconfig.json | 3 +- packages/project/tsconfig.json | 3 +- packages/react-sdk/tsconfig.json | 3 +- packages/sdk-cli/tsconfig.json | 3 +- .../sdk-components-animation/tsconfig.json | 3 +- .../sdk-components-react-radix/tsconfig.json | 3 +- packages/sdk-components-react/tsconfig.json | 3 +- packages/sdk/tsconfig.json | 3 +- packages/template/tsconfig.json | 1 + patches/@types__css-tree@2.3.1.patch | 97 --- patches/css-tree@2.3.1.patch | 18 - pnpm-lock.yaml | 49 +- 24 files changed, 1053 insertions(+), 335 deletions(-) create mode 100644 @types/css-tree.d.ts delete mode 100644 patches/@types__css-tree@2.3.1.patch delete mode 100644 patches/css-tree@2.3.1.patch diff --git a/@types/css-tree.d.ts b/@types/css-tree.d.ts new file mode 100644 index 0000000000..639adf35b1 --- /dev/null +++ b/@types/css-tree.d.ts @@ -0,0 +1,772 @@ +// Minimal-yet-safe TypeScript typings for css-tree v3.x +// Covers: AST node types, parse/generate, walk/find, List, lexer API, +// value definition syntax helpers, and common utils used in this project. + +declare module "css-tree" { + // ------------------------------------------------- + // Common + // ------------------------------------------------- + export interface SourceLocation { + source: string; + start: { offset: number; line: number; column: number }; + end: { offset: number; line: number; column: number }; + } + + export interface BaseNode { + type: string; + loc: SourceLocation | null; + } + + // Doubly-linked list used by csstree + export interface ListItem { + prev: ListItem | null; + next: ListItem | null; + data: T; + } + + export class List implements Iterable { + static createItem(data: T): ListItem; + + constructor(); + // iteration + [Symbol.iterator](): IterableIterator; + // props + readonly size: number; + readonly isEmpty: boolean; + readonly first: T | null; + readonly last: T | null; + // traversal helpers + forEach( + fn: (data: T, item: ListItem, list: List) => void, + thisArg?: any + ): void; + forEachRight( + fn: (data: T, item: ListItem, list: List) => void, + thisArg?: any + ): void; + // conversion + fromArray(items: T[]): this; + toArray(): T[]; + toJSON(): T[]; + // mutation (minimal surface used by walkers) + clear(): void; + remove(item: ListItem): ListItem; + insert(item: ListItem, before?: ListItem | null): void; + insertData(data: T, before?: ListItem | null): void; + append(item: ListItem): void; + appendData(data: T): void; + prepend(item: ListItem): void; + prependData(data: T): void; + replace(oldItem: ListItem, newItemOrList: ListItem | List): void; + } + + // ------------------------------------------------- + // AST Nodes (as per docs/ast.md) + // ------------------------------------------------- + export interface AnPlusB extends BaseNode { + type: "AnPlusB"; + a: string | null; + b: string | null; + } + export interface Atrule extends BaseNode { + type: "Atrule"; + name: string; + prelude: AtrulePrelude | Raw | null; + block: Block | null; + } + export interface AtrulePrelude extends BaseNode { + type: "AtrulePrelude"; + children: List; + } + export interface AttributeSelector extends BaseNode { + type: "AttributeSelector"; + name: Identifier; + matcher: string | null; + value: StringNode | Identifier | null; + flags: string | null; + } + export interface Block extends BaseNode { + type: "Block"; + children: List; + } + export interface Brackets extends BaseNode { + type: "Brackets"; + children: List; + } + export interface CDC extends BaseNode { + type: "CDC"; + } + export interface CDO extends BaseNode { + type: "CDO"; + } + export interface ClassSelector extends BaseNode { + type: "ClassSelector"; + name: string; + } + export interface Combinator extends BaseNode { + type: "Combinator"; + name: string; + } + export interface Comment extends BaseNode { + type: "Comment"; + value: string; + } + export interface Condition extends BaseNode { + type: "Condition"; + kind: string; + children: List< + | Identifier + | Feature + | FeatureFunction + | FeatureRange + | SupportsDeclaration + >; + } + export interface Declaration extends BaseNode { + type: "Declaration"; + important: boolean | string; + property: string; + value: Value | Raw; + } + export interface DeclarationList extends BaseNode { + type: "DeclarationList"; + children: List; + } + export interface Dimension extends BaseNode { + type: "Dimension"; + value: string; + unit: string; + } + export interface Feature extends BaseNode { + type: "Feature"; + kind: string; + name: string; + value: Identifier | NumberNode | Dimension | Ratio | FunctionNode | null; + } + export interface FeatureFunction extends BaseNode { + type: "FeatureFunction"; + kind: string; + feature: string; + value: Declaration | Selector; + } + export interface FeatureRange extends BaseNode { + type: "FeatureRange"; + kind: string; + left: Identifier | NumberNode | Dimension | Ratio | FunctionNode; + leftComparison: string; + middle: Identifier | NumberNode | Dimension | Ratio | FunctionNode; + rightComparison: string | null; + right: Identifier | NumberNode | Dimension | Ratio | FunctionNode | null; + } + export interface FunctionNode extends BaseNode { + type: "Function"; + name: string; + children: List; + } + export interface GeneralEnclosed extends BaseNode { + type: "GeneralEnclosed"; + kind: string; + function: string | null; + children: List; + } + export interface Hash extends BaseNode { + type: "Hash"; + value: string; + } + export interface IdSelector extends BaseNode { + type: "IdSelector"; + name: string; + } + export interface Identifier extends BaseNode { + type: "Identifier"; + name: string; + } + export interface Layer extends BaseNode { + type: "Layer"; + name: string; + } + export interface LayerList extends BaseNode { + type: "LayerList"; + children: List; + } + export interface MediaQuery extends BaseNode { + type: "MediaQuery"; + modifier: string | null; + mediaType: string | null; + condition: Condition | null; + } + export interface MediaQueryList extends BaseNode { + type: "MediaQueryList"; + children: List; + } + export interface NestingSelector extends BaseNode { + type: "NestingSelector"; + } + export interface Nth extends BaseNode { + type: "Nth"; + nth: AnPlusB | Identifier; + selector: SelectorList | null; + } + export interface NumberNode extends BaseNode { + type: "Number"; + value: string; + } + export interface Operator extends BaseNode { + type: "Operator"; + value: string; + } + export interface Parentheses extends BaseNode { + type: "Parentheses"; + children: List; + } + export interface Percentage extends BaseNode { + type: "Percentage"; + value: string; + } + export interface PseudoClassSelector extends BaseNode { + type: "PseudoClassSelector"; + name: string; + children: List | null; + } + export interface PseudoElementSelector extends BaseNode { + type: "PseudoElementSelector"; + name: string; + children: List | null; + } + export interface Ratio extends BaseNode { + type: "Ratio"; + left: NumberNode | FunctionNode; + right: NumberNode | FunctionNode | null; + } + export interface Raw extends BaseNode { + type: "Raw"; + value: string; + } + export interface Rule extends BaseNode { + type: "Rule"; + prelude: SelectorList | Raw; + block: Block; + } + export interface Scope extends BaseNode { + type: "Scope"; + root: SelectorList | Raw | null; + limit: SelectorList | Raw | null; + } + export interface Selector extends BaseNode { + type: "Selector"; + children: List< + | TypeSelector + | IdSelector + | ClassSelector + | AttributeSelector + | PseudoClassSelector + | PseudoElementSelector + | Combinator + | NestingSelector + >; + } + export interface SelectorList extends BaseNode { + type: "SelectorList"; + children: List; + } + export interface StringNode extends BaseNode { + type: "String"; + value: string; + } + export interface StyleSheet extends BaseNode { + type: "StyleSheet"; + children: List; + } + export interface SupportsDeclaration extends BaseNode { + type: "SupportsDeclaration"; + declaration: Declaration; + } + export interface TypeSelector extends BaseNode { + type: "TypeSelector"; + name: string; + } + export interface UnicodeRange extends BaseNode { + type: "UnicodeRange"; + value: string; + } + export interface Url extends BaseNode { + type: "Url"; + value: string; + } + export interface Value extends BaseNode { + type: "Value"; + children: List; + } + export interface WhiteSpace extends BaseNode { + type: "WhiteSpace"; + value: string; + } + + export type CssNode = + | AnPlusB + | Atrule + | AtrulePrelude + | AttributeSelector + | Block + | Brackets + | CDC + | CDO + | ClassSelector + | Combinator + | Comment + | Condition + | Declaration + | DeclarationList + | Dimension + | Feature + | FeatureFunction + | FeatureRange + | FunctionNode + | GeneralEnclosed + | Hash + | IdSelector + | Identifier + | Layer + | LayerList + | MediaQuery + | MediaQueryList + | NestingSelector + | Nth + | NumberNode + | Operator + | Parentheses + | Percentage + | PseudoClassSelector + | PseudoElementSelector + | Ratio + | Raw + | Rule + | Scope + | Selector + | SelectorList + | StringNode + | StyleSheet + | SupportsDeclaration + | TypeSelector + | UnicodeRange + | Url + | Value + | WhiteSpace; + + // A plain-object form where children are arrays (for JSON, etc.) + export type CssNodePlain = Omit & { + children?: CssNodePlain[] | null; + loc?: SourceLocation | null; + }; + + // ------------------------------------------------- + // Parsing / Generation + // ------------------------------------------------- + export type ParseContext = + | "stylesheet" + | "atrule" + | "atrulePrelude" + | "mediaQueryList" + | "mediaQuery" + | "rule" + | "selectorList" + | "selector" + | "block" + | "declarationList" + | "declaration" + | "value"; + + export interface ParseOptions { + context?: ParseContext; + atrule?: string | null; + positions?: boolean; + onParseError?: (error: any, fallbackNode?: Raw) => void; + onComment?: (value: string, loc: SourceLocation | null) => void; + onToken?: + | ((type: number, start: number, end: number, index: number) => void) + | Array<{ type: number; start: number; end: number }> + | null; + filename?: string; + offset?: number; + line?: number; + column?: number; + parseAtrulePrelude?: boolean; + parseRulePrelude?: boolean; + parseValue?: boolean; + parseCustomProperty?: boolean; + } + + // Strict overloads by context + export function parse(source: string): StyleSheet; + export function parse( + source: string, + options: ParseOptions & { context?: "stylesheet" } + ): StyleSheet; + export function parse( + source: string, + options: ParseOptions & { context: "atrule" } + ): Atrule; + export function parse( + source: string, + options: ParseOptions & { context: "atrulePrelude" } + ): AtrulePrelude; + export function parse( + source: string, + options: ParseOptions & { context: "mediaQueryList" } + ): MediaQueryList; + export function parse( + source: string, + options: ParseOptions & { context: "mediaQuery" } + ): MediaQuery; + export function parse( + source: string, + options: ParseOptions & { context: "rule" } + ): Rule; + export function parse( + source: string, + options: ParseOptions & { context: "selectorList" } + ): SelectorList; + export function parse( + source: string, + options: ParseOptions & { context: "selector" } + ): Selector; + export function parse( + source: string, + options: ParseOptions & { context: "block" } + ): Block; + export function parse( + source: string, + options: ParseOptions & { context: "declarationList" } + ): DeclarationList; + export function parse( + source: string, + options: ParseOptions & { context: "declaration" } + ): Declaration; + export function parse( + source: string, + options: ParseOptions & { context: "value" } + ): Value; + // Fallback + export function parse(source: string, options: ParseOptions): CssNode; + + export function generate( + ast: CssNode, + options: { + sourceMap: true; + decorator?: (node: CssNode) => any; + mode?: "spec" | "safe"; + } + ): { css: string; map: any }; + export function generate( + ast: CssNode, + options?: { + sourceMap?: false; + decorator?: (node: CssNode) => any; + mode?: "spec" | "safe"; + } + ): string; + + // ------------------------------------------------- + // Traversal helpers + // ------------------------------------------------- + export type WalkHandler = ( + node: CssNode, + item?: ListItem, + list?: List + ) => any; + export interface WalkOptions { + enter?: WalkHandler; + leave?: WalkHandler; + visit?: CssNode["type"] | null; + reverse?: boolean; + } + export function walk(ast: CssNode, options: WalkOptions | WalkHandler): void; + export function find(ast: CssNode, fn: WalkHandler): CssNode | null; + export function findLast(ast: CssNode, fn: WalkHandler): CssNode | null; + export function findAll(ast: CssNode, fn: WalkHandler): CssNode[]; + + // ------------------------------------------------- + // Utils + // ------------------------------------------------- + export function clone(ast: T): T; + export function fromPlainObject(obj: T): T; + export function toPlainObject(ast: T): T; + + export interface PropertyInfo { + basename: string; + name: string; + hack: string; + vendor: string; + prefix: string; + custom: boolean; + } + export function property(name: string): PropertyInfo; + + export interface KeywordInfo { + basename: string; + name: string; + vendor: string; + prefix: string; + custom: boolean; + } + export function keyword(name: string): KeywordInfo; + + export namespace ident { + function decode(value: string): string; + function encode(value: string): string; + } + export namespace string { + function decode(value: string): string; + function encode(value: string, preferSingleQuotes?: boolean): string; + } + export namespace url { + function decode(value: string): string; + function encode(value: string): string; + } + + // ------------------------------------------------- + // Definition syntax (values) sub-API + // ------------------------------------------------- + export namespace definitionSyntax { + // AST nodes for definition syntax are intentionally minimal here + interface Base { + type: string; + } + interface Group extends Base { + type: "Group"; + terms: Base[]; + combinator: " " | "|" | "||" | "&&"; + disallowEmpty: boolean; + explicit: boolean; + } + interface Keyword extends Base { + type: "Keyword"; + name: string; + } + interface Function extends Base { + type: "Function"; + name: string; + } + interface String extends Base { + type: "String"; + value: string; + } + interface Property extends Base { + type: "Property"; + name: string; + } + interface Type extends Base { + type: "Type"; + name: string; + opts: Range | null; + } + interface Range extends Base { + type: "Range"; + min: number | null; + max: number | null; + } + interface Multiplier extends Base { + type: "Multiplier"; + comma: boolean; + min: number; + max: number; + term: Base; + } + + type Node = + | Group + | Keyword + | Function + | String + | Property + | Type + | Range + | Multiplier + | Base; + + function parse(source: string): Node; + function walk( + node: Node, + options: + | { enter?: (n: Node) => void; leave?: (n: Node) => void } + | ((n: Node) => void), + context?: any + ): void; + function generate( + node: Node, + options?: { + forceBraces?: boolean; + compact?: boolean; + decorate?: (content: string, node: Node) => string; + } + ): string; + } + + // ------------------------------------------------- + // Lexer + // ------------------------------------------------- + export interface AtruleSyntaxConfig { + prelude?: string | definitionSyntax.Node | ((ref?: any) => any) | null; + descriptors?: Record< + string, + string | definitionSyntax.Node | ((ref?: any) => any) + > | null; + } + + export interface LexerConfig { + generic?: boolean; + cssWideKeywords?: string[]; + units?: Record; + types?: Record< + string, + string | definitionSyntax.Node | ((ref?: any) => any) + >; + atrules?: Record; + properties?: Record< + string, + string | definitionSyntax.Node | ((ref?: any) => any) + >; + } + + export interface MatchResult { + matched: any; + error: Error | null; + iterations: number; + isType(node: CssNode | null | undefined, name: string): boolean; + getTrace( + node: CssNode | null | undefined + ): Array<{ type: string; name: string }>; + } + + export interface FragmentResult { + parent: List; + nodes: List; + } + + export class Lexer { + constructor(config?: LexerConfig, syntax?: any, structure?: any); + + cssWideKeywords: string[]; + units: Record; + + checkStructure( + ast: CssNode + ): false | Array<{ node: CssNode; message: string }>; + + checkAtruleName(atruleName: string): Error | void; + checkAtrulePrelude( + atruleName: string, + prelude?: string | CssNode | null + ): Error | void; + checkAtruleDescriptorName( + atruleName: string, + descriptorName: string + ): Error | void; + checkPropertyName(propertyName: string): Error | void; + + matchAtrulePrelude( + atruleName: string, + prelude?: string | CssNode | null + ): MatchResult; + matchAtruleDescriptor( + atruleName: string, + descriptorName: string, + value: string | CssNode + ): MatchResult; + matchDeclaration(node: CssNode): MatchResult; + matchProperty(propertyName: string, value: string | CssNode): MatchResult; + matchType(typeName: string, value: string | CssNode): MatchResult; + match( + syntax: string | definitionSyntax.Node, + value: string | CssNode + ): MatchResult; + + findValueFragments( + propertyName: string, + value: Value, + type: string, + name: string + ): FragmentResult[]; + findDeclarationValueFragments( + declaration: Declaration, + type: string, + name: string + ): FragmentResult[]; + findAllFragments( + ast: CssNode, + type: string, + name: string + ): FragmentResult[]; + + // descriptor getters + getAtrule(atruleName: string, fallbackBasename?: boolean): any | null; + getAtrulePrelude( + atruleName: string, + fallbackBasename?: boolean + ): any | null; + getAtruleDescriptor(atruleName: string, name: string): any | null; + getProperty(propertyName: string, fallbackBasename?: boolean): any | null; + getType(name: string): any | null; + + validate(): null | { + errors: string[]; + types: string[]; + properties: string[]; + }; + dump(syntaxAsAst?: boolean, pretty?: boolean): any; + toString(): string; + } + + export const lexer: Lexer; + export function createLexer(config?: LexerConfig): Lexer; + + // ------------------------------------------------- + // Tokenizer / misc exports (lightly typed) + // ------------------------------------------------- + export const tokenTypes: Record; + export const tokenNames: string[]; + export function tokenize(input: string): IterableIterator; + + // Syntax factory and forking + export function createSyntax(config: any): any; + export function fork(ext?: any): any; +} + +// Optional subpath module shims to enable tree-shake-style imports +declare module "css-tree/lexer" { + export * from "css-tree"; +} +declare module "css-tree/parser" { + export type { ParseOptions, CssNode } from "css-tree"; + export { parse as default } from "css-tree"; +} +declare module "css-tree/generator" { + export { generate as default } from "css-tree"; +} +declare module "css-tree/walker" { + export { + walk, + find, + findAll, + findLast, + WalkOptions, + WalkHandler, + } from "css-tree"; +} +declare module "css-tree/definition-syntax" { + export { definitionSyntax } from "css-tree"; +} +declare module "css-tree/utils" { + export { + List, + ListItem, + clone, + fromPlainObject, + toPlainObject, + property, + keyword, + ident, + string, + url, + } from "css-tree"; +} diff --git a/apps/builder/app/shared/style-object-model.ts b/apps/builder/app/shared/style-object-model.ts index aac9a5ebce..c27f3c5776 100644 --- a/apps/builder/app/shared/style-object-model.ts +++ b/apps/builder/app/shared/style-object-model.ts @@ -1,4 +1,4 @@ -import { generate, walk } from "css-tree"; +import { generate, walk, List, type CssNode } from "css-tree"; import type { HtmlTags } from "html-tags"; import { camelCaseProperty, @@ -294,13 +294,14 @@ const substituteVars = ( enter(node, item, list) { if (node.type === "Function" && node.name === "var") { const varValue = parseCssVar(node); - if (varValue) { + if (varValue && item) { const newValue = mapper(varValue); - list.replace( + list?.replace( item, - node.children.createItem({ + List.createItem({ type: "Raw", value: toValue(newValue), + loc: null, }) ); } diff --git a/apps/builder/package.json b/apps/builder/package.json index 2389c26d74..59d665864c 100644 --- a/apps/builder/package.json +++ b/apps/builder/package.json @@ -88,7 +88,7 @@ "change-case": "^5.4.4", "colord": "^2.9.3", "cookie": "^1.0.1", - "css-tree": "^2.3.1", + "css-tree": "^3.1.0", "debug": "^4.3.7", "downshift": "^6.1.7", "entrijs": "^0.0.11", diff --git a/package.json b/package.json index 88a1125789..604f433127 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ "@storybook/addon-controls": "^8.6.4", "@storybook/react": "^8.6.4", "@storybook/react-vite": "^8.6.4", - "@types/css-tree": "^2.3.1", "@types/node": "^22.13.10", "@types/react": "^18.2.70", "esbuild": "^0.25.3", @@ -85,8 +84,6 @@ }, "patchedDependencies": { "@stitches/react@1.3.1-1": "patches/@stitches__react@1.3.1-1.patch", - "css-tree@2.3.1": "patches/css-tree@2.3.1.patch", - "@types/css-tree@2.3.1": "patches/@types__css-tree@2.3.1.patch", "@radix-ui/react-scroll-area@1.0.5": "patches/@radix-ui__react-scroll-area@1.0.5.patch", "@remix-run/dev": "patches/@remix-run__dev.patch" } diff --git a/packages/css-data/package.json b/packages/css-data/package.json index 90bca62fc4..f6f91b2d08 100644 --- a/packages/css-data/package.json +++ b/packages/css-data/package.json @@ -16,7 +16,6 @@ "css-to-ws": "./bin/css-to-ws.ts" }, "devDependencies": { - "@types/css-tree": "^2.3.1", "@webstudio-is/tsconfig": "workspace:*", "html-tags": "^4.0.0", "mdn-data": "2.23.0", @@ -36,7 +35,7 @@ "@webstudio-is/css-engine": "workspace:*", "change-case": "^5.4.4", "colord": "^2.9.3", - "css-tree": "^2.3.1", + "css-tree": "^3.1.0", "openai": "^3.2.1", "p-retry": "^6.2.1", "warn-once": "^0.1.1" diff --git a/packages/css-data/src/parse-css-value.ts b/packages/css-data/src/parse-css-value.ts index 7f5b4af8e8..f80ad5e49f 100644 --- a/packages/css-data/src/parse-css-value.ts +++ b/packages/css-data/src/parse-css-value.ts @@ -219,6 +219,7 @@ export const parseCssVar = (node: FunctionNode): undefined | VarValue => { const [name, _comma, ...fallback] = node.children; const fallbackString = generate({ type: "Value", + loc: null, children: new List().fromArray(fallback), }).trim(); if (name.type === "Identifier") { @@ -380,7 +381,7 @@ const parseLiteral = ( type: "function", args: parseShadow( node.children.toArray(), - generate({ type: "Value", children: node.children }) + generate({ type: "Value", loc: null, children: node.children }) ), name: node.name, }; @@ -469,6 +470,7 @@ export const parseCssValue = ( value: splitRepeated(nodes).map((nodes) => { const value = generate({ type: "Value", + loc: null, children: new List().fromArray(nodes), }); const parsed = parseCssValue(property, value, false) as LayerValueItem; @@ -506,6 +508,7 @@ export const parseCssValue = ( } return generate({ type: "Value", + loc: null, children: new List().fromArray(nodes), }); }), diff --git a/packages/css-data/src/parse-css.ts b/packages/css-data/src/parse-css.ts index 5af9cf0ed6..6147001b16 100644 --- a/packages/css-data/src/parse-css.ts +++ b/packages/css-data/src/parse-css.ts @@ -102,163 +102,193 @@ export const parseCss = (css: string): ParsedStyleDecl[] => { return []; } - csstree.walk(ast, function (node) { - // forbid nested at rules - if (node.type === "Atrule" && this.atrule) { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore https://github.com/csstree/csstree/blob/v2.3.1/docs/traversal.md - return this.break; - } - if (node.type !== "Declaration" || this.rule?.prelude.type === undefined) { - return; - } + // Track context as we traverse + let currentAtrule: csstree.Atrule | undefined; + let currentRule: csstree.Rule | undefined; + let nestedAtruleDepth = 0; - if (this.atrule && this.atrule.name !== "media") { - return; - } + const supportedMediaFeatures = ["min-width", "max-width"]; + const supportedUnits = ["px"]; - const supportedMediaFeatures = ["min-width", "max-width"]; - const supportedUnits = ["px"]; - let breakpoint: undefined | string; - let invalidBreakpoint = false; - if (this.atrule?.prelude?.type === "AtrulePrelude") { - csstree.walk(this.atrule.prelude, { - enter: (node, item, list) => { - if (node.type === "Identifier") { - if ( - node.name === "screen" || - node.name === "all" || - node.name === "and" - ) { - list.remove(item); + csstree.walk(ast, { + enter(node) { + if (node.type === "Atrule") { + if (currentAtrule) { + nestedAtruleDepth++; + } + currentAtrule = node; + } else if (node.type === "Rule") { + currentRule = node; + } + }, + leave(node) { + if (node.type === "Atrule") { + if (nestedAtruleDepth > 0) { + nestedAtruleDepth--; + } else { + currentAtrule = undefined; + } + } else if (node.type === "Rule") { + currentRule = undefined; + } + + // Process declarations + if ( + node.type !== "Declaration" || + !currentRule || + currentRule.prelude.type === undefined + ) { + return; + } + + // forbid nested at rules + if (nestedAtruleDepth > 0) { + return; + } + + if (currentAtrule && currentAtrule.name !== "media") { + return; + } + + let breakpoint: undefined | string; + let invalidBreakpoint = false; + + if (currentAtrule?.prelude?.type === "AtrulePrelude") { + csstree.walk(currentAtrule.prelude, { + enter: (node) => { + if (node.type === "MediaQuery") { + if (node.mediaType === "screen" || node.mediaType === "all") { + node.mediaType = null; + } + // prevent saving print styles + if (node.mediaType === "print") { + invalidBreakpoint = true; + } } - // prevent saving print styles - if (node.name === "print") { + if ( + node.type === "Feature" && + supportedMediaFeatures.includes(node.name) === false + ) { invalidBreakpoint = true; } - } - if ( - node.type === "MediaFeature" && - supportedMediaFeatures.includes(node.name) === false - ) { - invalidBreakpoint = true; - } - if ( - node.type === "Dimension" && - supportedUnits.includes(node.unit) === false - ) { - invalidBreakpoint = true; - } - }, - leave: (node) => { - // complex media queries are not supported yet - if (node.type === "MediaQuery" && node.children.size > 1) { - invalidBreakpoint = true; - } - ``; - }, - }); - const generated = csstree.generate(this.atrule.prelude); - if (generated) { - breakpoint = generated; - } - } - if (invalidBreakpoint || this.rule.prelude.type !== "SelectorList") { - return; - } - - const selectors: Selector[] = []; - - for (const node of this.rule.prelude.children) { - if (node.type !== "Selector") { - continue; - } - let selector: Selector | undefined = undefined; - const children = node.children.toArray(); - // @ts-expect-error NestingSelector is not defined in type definitions - const startsWithNesting = children[0]?.type === "NestingSelector"; - for (let index = 0; index < children.length; index += 1) { - const childNode = children[index]; - let name: string = ""; - let state: string | undefined; - switch (childNode.type) { - case "TypeSelector": - name = childNode.name; - break; - case "ClassSelector": - name = `.${childNode.name}`; - break; - case "AttributeSelector": - // for example &[data-state=active] - if (startsWithNesting && index === 1 && children.length === 2) { - state = csstree.generate(childNode); - } else { - name = csstree.generate(childNode); + if ( + node.type === "Dimension" && + supportedUnits.includes(node.unit) === false + ) { + invalidBreakpoint = true; } - break; - case "PseudoClassSelector": { - // First pseudo selector is not a state but an element selector, e.g. :root - if (selector) { - state = `:${childNode.name}`; - } else { - name = `:${childNode.name}`; + }, + leave: (node) => { + // complex media queries are not supported yet + if (node.type === "MediaQuery") { + const children = node.condition?.children; + if (children && children.size > 1) { + invalidBreakpoint = true; + } } - break; - } - case "PseudoElementSelector": - state = `::${childNode.name}`; - break; - case "Combinator": - // " " vs " > " - name = - childNode.name === " " ? childNode.name : ` ${childNode.name} `; - break; + }, + }); + const generated = csstree.generate(currentAtrule.prelude); + if (generated) { + breakpoint = generated; } + } + if (invalidBreakpoint || currentRule.prelude.type !== "SelectorList") { + return; + } + const selectors: Selector[] = []; + + for (const node of currentRule.prelude.children) { + if (node.type !== "Selector") { + continue; + } + let selector: Selector | undefined = undefined; + const children = node.children.toArray(); + const startsWithNesting = children[0]?.type === "NestingSelector"; + for (let index = 0; index < children.length; index += 1) { + const childNode = children[index]; + let name: string = ""; + let state: string | undefined; + switch (childNode.type) { + case "TypeSelector": + name = childNode.name; + break; + case "ClassSelector": + name = `.${childNode.name}`; + break; + case "AttributeSelector": + // for example &[data-state=active] + if (startsWithNesting && index === 1 && children.length === 2) { + state = csstree.generate(childNode); + } else { + name = csstree.generate(childNode); + } + break; + case "PseudoClassSelector": { + // First pseudo selector is not a state but an element selector, e.g. :root + if (selector) { + state = `:${childNode.name}`; + } else { + name = `:${childNode.name}`; + } + break; + } + case "PseudoElementSelector": + state = `::${childNode.name}`; + break; + case "Combinator": + // " " vs " > " + name = + childNode.name === " " ? childNode.name : ` ${childNode.name} `; + break; + } + + if (selector) { + selector.name += name; + if (state) { + selector.state = state; + } + } else { + selector = { name, state }; + } + } if (selector) { - selector.name += name; - if (state) { - selector.state = state; + selectors.push(selector); + selector = undefined; + } + } + + const stringValue = csstree.generate(node.value); + + const parsedCss = parseCssValue( + normalizeProperty(node.property), + stringValue + ); + + for (const { name: selector, state } of selectors) { + for (const [property, value] of parsedCss) { + const normalizedProperty = normalizeProperty(property); + const styleDecl: ParsedStyleDecl = { + selector, + property: normalizedProperty, + value, + }; + if (breakpoint) { + styleDecl.breakpoint = breakpoint; } - } else { - selector = { name, state }; + if (state) { + styleDecl.state = state; + } + + // deduplicate styles within selector and state by using map + styles.set( + `${breakpoint}:${selector}:${state}:${normalizedProperty}`, + styleDecl + ); } } - if (selector) { - selectors.push(selector); - selector = undefined; - } - } - - const stringValue = csstree.generate(node.value); - - const parsedCss = parseCssValue( - normalizeProperty(node.property), - stringValue - ); - - for (const { name: selector, state } of selectors) { - for (const [property, value] of parsedCss) { - const normalizedProperty = normalizeProperty(property); - const styleDecl: ParsedStyleDecl = { - selector, - property: normalizedProperty, - value, - }; - if (breakpoint) { - styleDecl.breakpoint = breakpoint; - } - if (state) { - styleDecl.state = state; - } - - // deduplicate styles within selector and state by using map - styles.set( - `${breakpoint}:${selector}:${state}:${normalizedProperty}`, - styleDecl - ); - } - } + }, }); return Array.from(styles.values()); @@ -276,7 +306,7 @@ export const parseMediaQuery = ( let property: undefined | "minWidth" | "maxWidth"; let value: undefined | number; csstree.walk(ast, (node) => { - if (node.type === "MediaFeature") { + if (node.type === "Feature") { if (node.name === "min-width") { property = "minWidth"; } diff --git a/packages/css-data/src/shorthands.ts b/packages/css-data/src/shorthands.ts index 506909d51c..efe8b096d6 100644 --- a/packages/css-data/src/shorthands.ts +++ b/packages/css-data/src/shorthands.ts @@ -13,33 +13,52 @@ const cssWideKeywordsSyntax = Array.from(cssWideKeywords).join(" | "); const createValueNode = (data?: CssNode[]): Value => ({ type: "Value", + loc: null, children: new List().fromArray(data ?? []), }); -const createNumber = (value: string): Value => ({ - type: "Value", - children: new List().appendData({ +const createNumber = (value: string): Value => { + const list = new List(); + list.appendData({ type: "Number", value, - }), -}); + loc: null, + }); + return { + type: "Value", + loc: null, + children: list, + }; +}; -const createDimension = (value: string, unit: string): Value => ({ - type: "Value", - children: new List().appendData({ +const createDimension = (value: string, unit: string): Value => { + const list = new List(); + list.appendData({ type: "Dimension", value, unit, - }), -}); + loc: null, + }); + return { + type: "Value", + loc: null, + children: list, + }; +}; -const createIdentifier = (name: string): Value => ({ - type: "Value", - children: new List().appendData({ +const createIdentifier = (name: string): Value => { + const list = new List(); + list.appendData({ type: "Identifier", name, - }), -}); + loc: null, + }); + return { + type: "Value", + loc: null, + children: list, + }; +}; const createInitialNode = () => createIdentifier("initial"); @@ -67,7 +86,7 @@ const joinByOperator = (list: List | CssNode[], operator: string) => { const joined: CssNode[] = []; for (const node of list) { if (joined.length > 0) { - joined.push({ type: "Operator", value: operator }); + joined.push({ type: "Operator", value: operator, loc: null }); } joined.push(...getValueList(node)); } @@ -298,7 +317,7 @@ const expandFont = function* (value: CssNode) { let fontFamily: CssNode = createInitialNode(); if (config) { if ( - lexer.match("<'font-size'> / <'line-height'> <'font-family'>", config) + lexer.match("<'font-size'> / <'line-height'> <'font-family'>#", config) .matched ) { const [fontSizeNode, _slashNode, lineHeightNode, ...fontFamilyNodes] = @@ -595,8 +614,8 @@ const expandMask = function* (value: CssNode) { reference ?? createIdentifier("none"), position ?? createValueNode([ - { type: "Dimension", value: "0", unit: "%" }, - { type: "Dimension", value: "0", unit: "%" }, + { type: "Dimension", value: "0", unit: "%", loc: null }, + { type: "Dimension", value: "0", unit: "%", loc: null }, ]), bgSize ?? createIdentifier("auto"), repeatStyle ?? createIdentifier("repeat"), @@ -802,7 +821,9 @@ const expandGrid = function* (value: CssNode) { if (autoFlowKeyword) { autoFlow = createIdentifier("row"); if (denseKeyword) { - autoFlow.children.appendList(denseKeyword.children); + denseKeyword.children.forEach((item) => { + autoFlow.children.appendData(item); + }); } } autoRows = config ?? createIdentifier("auto"); @@ -819,7 +840,9 @@ const expandGrid = function* (value: CssNode) { if (autoFlowKeyword) { autoFlow = createIdentifier("column"); if (denseKeyword) { - autoFlow.children.appendList(denseKeyword.children); + denseKeyword.children.forEach((item) => { + autoFlow.children.appendData(item); + }); } } autoColumns = config ?? createIdentifier("auto"); @@ -973,13 +996,13 @@ const expandBackground = function* (value: CssNode) { image ?? createIdentifier("none"), position ?? createValueNode([ - { type: "Dimension", value: "0", unit: "%" }, - { type: "Dimension", value: "0", unit: "%" }, + { type: "Dimension", value: "0", unit: "%", loc: null }, + { type: "Dimension", value: "0", unit: "%", loc: null }, ]), size ?? createValueNode([ - { type: "Identifier", name: "auto" }, - { type: "Identifier", name: "auto" }, + { type: "Identifier", name: "auto", loc: null }, + { type: "Identifier", name: "auto", loc: null }, ]), repeatStyle ?? createIdentifier("repeat"), attachment ?? createIdentifier("scroll"), @@ -1418,7 +1441,7 @@ const parseValue = function* (property: string, value: string) { ast.type === "Value" && ast.children.isEmpty ) { - ast.children.appendData({ type: "Identifier", name: "unset" }); + ast.children.appendData({ type: "Identifier", name: "unset", loc: null }); } yield [property, ast] as const; } catch { diff --git a/packages/css-data/tsconfig.json b/packages/css-data/tsconfig.json index 9648eaf0a1..31d2f5d187 100644 --- a/packages/css-data/tsconfig.json +++ b/packages/css-data/tsconfig.json @@ -1,5 +1,6 @@ { "extends": "@webstudio-is/tsconfig/base.json", + "include": ["**/*.ts", "**/*.tsx", "../../@types/**/*.d.ts"], "compilerOptions": { "isolatedDeclarations": true } diff --git a/packages/dashboard/tsconfig.json b/packages/dashboard/tsconfig.json index d2e5040f8f..0c8d2e7907 100644 --- a/packages/dashboard/tsconfig.json +++ b/packages/dashboard/tsconfig.json @@ -1,3 +1,4 @@ { - "extends": "@webstudio-is/tsconfig/base.json" + "extends": "@webstudio-is/tsconfig/base.json", + "include": ["**/*.ts", "**/*.tsx", "../../@types/**/*.d.ts"] } diff --git a/packages/design-system/tsconfig.json b/packages/design-system/tsconfig.json index d2e5040f8f..0c8d2e7907 100644 --- a/packages/design-system/tsconfig.json +++ b/packages/design-system/tsconfig.json @@ -1,3 +1,4 @@ { - "extends": "@webstudio-is/tsconfig/base.json" + "extends": "@webstudio-is/tsconfig/base.json", + "include": ["**/*.ts", "**/*.tsx", "../../@types/**/*.d.ts"] } diff --git a/packages/domain/tsconfig.json b/packages/domain/tsconfig.json index d2e5040f8f..0c8d2e7907 100644 --- a/packages/domain/tsconfig.json +++ b/packages/domain/tsconfig.json @@ -1,3 +1,4 @@ { - "extends": "@webstudio-is/tsconfig/base.json" + "extends": "@webstudio-is/tsconfig/base.json", + "include": ["**/*.ts", "**/*.tsx", "../../@types/**/*.d.ts"] } diff --git a/packages/project-build/tsconfig.json b/packages/project-build/tsconfig.json index d2e5040f8f..0c8d2e7907 100644 --- a/packages/project-build/tsconfig.json +++ b/packages/project-build/tsconfig.json @@ -1,3 +1,4 @@ { - "extends": "@webstudio-is/tsconfig/base.json" + "extends": "@webstudio-is/tsconfig/base.json", + "include": ["**/*.ts", "**/*.tsx", "../../@types/**/*.d.ts"] } diff --git a/packages/project/tsconfig.json b/packages/project/tsconfig.json index d2e5040f8f..0c8d2e7907 100644 --- a/packages/project/tsconfig.json +++ b/packages/project/tsconfig.json @@ -1,3 +1,4 @@ { - "extends": "@webstudio-is/tsconfig/base.json" + "extends": "@webstudio-is/tsconfig/base.json", + "include": ["**/*.ts", "**/*.tsx", "../../@types/**/*.d.ts"] } diff --git a/packages/react-sdk/tsconfig.json b/packages/react-sdk/tsconfig.json index d2e5040f8f..0c8d2e7907 100644 --- a/packages/react-sdk/tsconfig.json +++ b/packages/react-sdk/tsconfig.json @@ -1,3 +1,4 @@ { - "extends": "@webstudio-is/tsconfig/base.json" + "extends": "@webstudio-is/tsconfig/base.json", + "include": ["**/*.ts", "**/*.tsx", "../../@types/**/*.d.ts"] } diff --git a/packages/sdk-cli/tsconfig.json b/packages/sdk-cli/tsconfig.json index d2e5040f8f..0c8d2e7907 100644 --- a/packages/sdk-cli/tsconfig.json +++ b/packages/sdk-cli/tsconfig.json @@ -1,3 +1,4 @@ { - "extends": "@webstudio-is/tsconfig/base.json" + "extends": "@webstudio-is/tsconfig/base.json", + "include": ["**/*.ts", "**/*.tsx", "../../@types/**/*.d.ts"] } diff --git a/packages/sdk-components-animation/tsconfig.json b/packages/sdk-components-animation/tsconfig.json index 50abde7695..1847eeba3f 100644 --- a/packages/sdk-components-animation/tsconfig.json +++ b/packages/sdk-components-animation/tsconfig.json @@ -2,10 +2,9 @@ "extends": "@webstudio-is/tsconfig/base.json", "include": [ "src", - "../../@types/**/scroll-timeline.d.ts", "private-src", "../sdk/src/schema/animation-schema.ts", - "../../@types/navigator.d.ts" + "../../@types/**/*.d.ts" ], "exclude": ["private-src/perf/**/*"], "compilerOptions": { diff --git a/packages/sdk-components-react-radix/tsconfig.json b/packages/sdk-components-react-radix/tsconfig.json index d2e5040f8f..0c8d2e7907 100644 --- a/packages/sdk-components-react-radix/tsconfig.json +++ b/packages/sdk-components-react-radix/tsconfig.json @@ -1,3 +1,4 @@ { - "extends": "@webstudio-is/tsconfig/base.json" + "extends": "@webstudio-is/tsconfig/base.json", + "include": ["**/*.ts", "**/*.tsx", "../../@types/**/*.d.ts"] } diff --git a/packages/sdk-components-react/tsconfig.json b/packages/sdk-components-react/tsconfig.json index d2e5040f8f..0c8d2e7907 100644 --- a/packages/sdk-components-react/tsconfig.json +++ b/packages/sdk-components-react/tsconfig.json @@ -1,3 +1,4 @@ { - "extends": "@webstudio-is/tsconfig/base.json" + "extends": "@webstudio-is/tsconfig/base.json", + "include": ["**/*.ts", "**/*.tsx", "../../@types/**/*.d.ts"] } diff --git a/packages/sdk/tsconfig.json b/packages/sdk/tsconfig.json index d2e5040f8f..0c8d2e7907 100644 --- a/packages/sdk/tsconfig.json +++ b/packages/sdk/tsconfig.json @@ -1,3 +1,4 @@ { - "extends": "@webstudio-is/tsconfig/base.json" + "extends": "@webstudio-is/tsconfig/base.json", + "include": ["**/*.ts", "**/*.tsx", "../../@types/**/*.d.ts"] } diff --git a/packages/template/tsconfig.json b/packages/template/tsconfig.json index 9648eaf0a1..31d2f5d187 100644 --- a/packages/template/tsconfig.json +++ b/packages/template/tsconfig.json @@ -1,5 +1,6 @@ { "extends": "@webstudio-is/tsconfig/base.json", + "include": ["**/*.ts", "**/*.tsx", "../../@types/**/*.d.ts"], "compilerOptions": { "isolatedDeclarations": true } diff --git a/patches/@types__css-tree@2.3.1.patch b/patches/@types__css-tree@2.3.1.patch deleted file mode 100644 index 0670d5ac12..0000000000 --- a/patches/@types__css-tree@2.3.1.patch +++ /dev/null @@ -1,97 +0,0 @@ -diff --git a/index.d.ts b/index.d.ts -index e6a09d2756a7d942d7dbf2d6b9437deb06e8eb31..46120815179b6176100a045a599b92ecaa6be89c 100755 ---- a/index.d.ts -+++ b/index.d.ts -@@ -546,48 +546,7 @@ export interface WalkOptionsVisit { - reverse?: boolean | undefined; - } - --export type WalkOptions = -- WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsVisit -- | WalkOptionsNoVisit; -+export type WalkOptions = WalkOptionsNoVisit; - - export function walk(ast: CssNode, options: EnterOrLeaveFn | WalkOptions): void; - -@@ -851,9 +810,30 @@ export class SyntaxReferenceError extends SyntaxError { - reference: string; - } - --export interface LexerMatchResult { -- error: Error | SyntaxMatchError | SyntaxReferenceError | null; --} -+type Match = -+ | { -+ syntax: DSNodeProperty; -+ match: Match[]; -+ } -+ | { -+ syntax: DSNodeType; -+ match: Match[]; -+ } -+ | { -+ syntax: DSNodeKeyword; -+ token: string; -+ } -+ | { syntax: null }; -+ -+export type LexerMatchResult = -+ | { -+ matched: null; -+ error: Error | SyntaxMatchError | SyntaxReferenceError; -+ } -+ | { -+ matched: Match; -+ error: null; -+ }; - - export class Lexer { - matchAtruleDescriptor(atruleName: string, descriptorName: string, value: CssNode | string): LexerMatchResult; -@@ -864,6 +844,8 @@ export class Lexer { - match(syntax: DSNode | string, value: CssNode | string): LexerMatchResult; - } - -+export declare const lexer: Lexer; -+ - export function fork(extension: { - atrules?: Record | undefined, - properties?: Record | undefined, \ No newline at end of file diff --git a/patches/css-tree@2.3.1.patch b/patches/css-tree@2.3.1.patch deleted file mode 100644 index 5a7894d523..0000000000 --- a/patches/css-tree@2.3.1.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff --git a/package.json b/package.json -index 934e699f19c6f1a265c1ef29121c6dde92cd25ed..a54e28a44de8e1adcf775be9564c2ad8b15b5c98 100644 ---- a/package.json -+++ b/package.json -@@ -18,11 +18,11 @@ - "validation" - ], - "type": "module", -- "module": "./lib/index.js", -+ "module": "./dist/csstree.esm.js", - "main": "./cjs/index.cjs", - "exports": { - ".": { -- "import": "./lib/index.js", -+ "import": "./dist/csstree.esm.js", - "require": "./cjs/index.cjs" - }, - "./dist/*": "./dist/*.js", \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 328dd2fe70..138f96251b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,12 +20,6 @@ patchedDependencies: '@stitches/react@1.3.1-1': hash: knml42mpr6mlzseo3d6gjljiq4 path: patches/@stitches__react@1.3.1-1.patch - '@types/css-tree@2.3.1': - hash: ac22lciodhaj6xmoeignv36gyq - path: patches/@types__css-tree@2.3.1.patch - css-tree@2.3.1: - hash: epgcmebti7rfrc2ej4odb3t4jy - path: patches/css-tree@2.3.1.patch importers: @@ -61,9 +55,6 @@ importers: '@storybook/react-vite': specifier: ^8.6.4 version: 8.6.4(react-dom@18.3.0-canary-14898b6a9-20240318(react@18.3.0-canary-14898b6a9-20240318))(react@18.3.0-canary-14898b6a9-20240318)(rollup@4.40.0)(storybook@8.6.4(prettier@3.5.3))(typescript@5.8.2)(vite@6.3.4(@types/node@22.13.10)(jiti@2.4.2)(tsx@4.19.3)) - '@types/css-tree': - specifier: ^2.3.1 - version: 2.3.1(patch_hash=ac22lciodhaj6xmoeignv36gyq) '@types/node': specifier: ^22.13.10 version: 22.13.10 @@ -326,8 +317,8 @@ importers: specifier: ^1.0.1 version: 1.0.1 css-tree: - specifier: ^2.3.1 - version: 2.3.1(patch_hash=epgcmebti7rfrc2ej4odb3t4jy) + specifier: ^3.1.0 + version: 3.1.0 debug: specifier: ^4.3.7 version: 4.3.7 @@ -1241,8 +1232,8 @@ importers: specifier: ^2.9.3 version: 2.9.3 css-tree: - specifier: ^2.3.1 - version: 2.3.1(patch_hash=epgcmebti7rfrc2ej4odb3t4jy) + specifier: ^3.1.0 + version: 3.1.0 openai: specifier: ^3.2.1 version: 3.2.1 @@ -1253,9 +1244,6 @@ importers: specifier: ^0.1.1 version: 0.1.1 devDependencies: - '@types/css-tree': - specifier: ^2.3.1 - version: 2.3.1(patch_hash=ac22lciodhaj6xmoeignv36gyq) '@webstudio-is/tsconfig': specifier: workspace:* version: link:../tsconfig @@ -5375,9 +5363,6 @@ packages: '@types/cookie@0.6.0': resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} - '@types/css-tree@2.3.1': - resolution: {integrity: sha512-3m636Jz4d9d+lHVMp6FNLsUWQrfOx1xpm1SBxPbQYSNNgXMe+XswcsDeo1ldyULiuzYyWKk1kmvkLTgNq+215Q==} - '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} @@ -6101,6 +6086,10 @@ packages: resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + css-tree@3.1.0: + resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + css-what@6.1.0: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} @@ -7313,6 +7302,9 @@ packages: mdn-data@2.0.30: resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + mdn-data@2.12.2: + resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} + mdn-data@2.23.0: resolution: {integrity: sha512-786vq1+4079JSeu2XdcDjrhi/Ry7BWtjDl9WtGPWLiIHb2T66GvIVflZTBoSNZ5JqTtJGYEVMuFA/lbQlMOyDQ==} @@ -12591,7 +12583,7 @@ snapshots: '@svgo/jsx@0.4.2': dependencies: - css-tree: 2.3.1(patch_hash=epgcmebti7rfrc2ej4odb3t4jy) + css-tree: 2.3.1 svgo: 3.0.2 '@swc/helpers@0.5.15': @@ -12678,8 +12670,6 @@ snapshots: '@types/cookie@0.6.0': {} - '@types/css-tree@2.3.1(patch_hash=ac22lciodhaj6xmoeignv36gyq)': {} - '@types/debug@4.1.12': dependencies: '@types/ms': 0.7.31 @@ -13527,13 +13517,18 @@ snapshots: css-tree@2.2.1: dependencies: mdn-data: 2.0.28 - source-map-js: 1.2.0 + source-map-js: 1.2.1 - css-tree@2.3.1(patch_hash=epgcmebti7rfrc2ej4odb3t4jy): + css-tree@2.3.1: dependencies: mdn-data: 2.0.30 source-map-js: 1.2.0 + css-tree@3.1.0: + dependencies: + mdn-data: 2.12.2 + source-map-js: 1.2.1 + css-what@6.1.0: {} cssesc@3.0.0: {} @@ -14995,6 +14990,8 @@ snapshots: mdn-data@2.0.30: {} + mdn-data@2.12.2: {} + mdn-data@2.23.0: {} media-query-parser@2.0.2: @@ -16644,7 +16641,7 @@ snapshots: '@trysound/sax': 0.2.0 commander: 7.2.0 css-select: 5.1.0 - css-tree: 2.3.1(patch_hash=epgcmebti7rfrc2ej4odb3t4jy) + css-tree: 2.3.1 csso: 5.0.5 picocolors: 1.1.1 @@ -16653,7 +16650,7 @@ snapshots: '@trysound/sax': 0.2.0 commander: 7.2.0 css-select: 5.1.0 - css-tree: 2.3.1(patch_hash=epgcmebti7rfrc2ej4odb3t4jy) + css-tree: 2.3.1 css-what: 6.1.0 csso: 5.0.5 picocolors: 1.1.1