Path: blob/main/tools/sass-variable-explainer/ast-utils.ts
6433 views
export const walk = (node: any, cb: (node: any) => unknown) => {1if (!node || typeof node !== "object") return;2if (!cb(node)) {3return;4};5for (const key of Object.keys(node)) {6walk(node[key], cb);7}8}910export const withType = (node: any, func: (ast: any) => any) => {11if (!node?.type) {12return node;13}14return func(node);15}1617export const withTypeAndArray = (node: any, func: (ast: any) => any) => {18if (!node?.type) {19return node;20}21if (!node?.children || !Array.isArray(node.children)) {22return node;23}24return func(node);25}2627export const filterDeep = (outer: any, cb: (v: any) => boolean): any =>28withType(outer, (ast: any) => {29return Object.fromEntries(Object.entries(ast).map(([k, v]) => {30if (Array.isArray(v)) {31return [k, v.filter(cb).map((v: any) => filterDeep(v, cb))];32} else if (v && typeof v === "object") {33return [k, filterDeep(v, cb)];34} else {35return [k, v];36}37}));38});3940export const mapDeep = (outer: any, cb: (mapped: any) => any): any =>41withType(outer, (ast: any) => {42if (Array.isArray(ast.children)) {43ast.children = ast.children.map((v: any) => mapDeep(v, cb));44}45if (Array.isArray(ast.value)) {46ast.value = ast.value.map((v: any) => mapDeep(v, cb));47}48return cb(ast);49});5051export const collect = (outer: any, cb: (v: any) => boolean): any[] => {52const results: any = [];53walk(outer, (node: any) => {54if (cb(node)) {55results.push(node);56}57return true;58});59return results;60}6162export const annotateNode = (node: any, annotation: Record<string, unknown>) => {63if (!node.annotation) {64node.annotation = {};65}66Object.assign(node.annotation, annotation);67return node;68}6970