fix: refactor core helpers

This commit is contained in:
wwsun
2023-09-06 16:49:17 +08:00
parent 468910afde
commit f9c9cbefae
18 changed files with 21087 additions and 206 deletions
+2 -1
View File
@@ -2,8 +2,9 @@
"extends": ["eslint-config-ali/typescript/react", "prettier"],
"ignorePatterns": ["**/dist/**/*", "**/lib/**/*", "**/node_modules/**/*", "scripts/**/*"],
"rules": {
"import/no-cycle": "off",
"@typescript-eslint/dot-notation": "off",
"@typescript-eslint/no-unused-vars": "warn",
"import/no-cycle": "off",
"no-nested-ternary": "off"
}
}
+4 -4
View File
@@ -24,10 +24,10 @@
"prepublishOnly": "yarn build"
},
"dependencies": {
"@babel/generator": "^7.21.3",
"@babel/parser": "^7.21.3",
"@babel/traverse": "^7.21.3",
"@babel/types": "^7.21.3",
"@babel/generator": "^7.22.15",
"@babel/parser": "^7.22.15",
"@babel/traverse": "^7.22.15",
"@babel/types": "^7.22.15",
"@music163/tango-helpers": "^0.1.1",
"@types/babel__generator": "^7.6.4",
"@types/babel__traverse": "^7.18.3",
-47
View File
@@ -1,47 +0,0 @@
import { TangoViewNodeDataType } from '../types';
/**
* 合并变量数组
* @param list
* @returns
*/
export function mergeVariableArray(...list: any[]) {
const ret: any[] = [];
for (const sub of list) {
if (Array.isArray(sub)) {
sub.forEach((item: any) => {
if (item && item.children && item.children.length) {
ret.push(item);
}
});
}
}
return ret;
}
/**
* 将输入值转换为 tree data 嵌套数组
* @param list
*/
export function toTreeData(list: TangoViewNodeDataType[]) {
const map: Record<string, TangoViewNodeDataType> = {};
list.forEach((item) => {
// 如果不存在,则初始化
if (!map[item.id]) {
map[item.id] = {
...item,
children: [],
};
}
// 是否找到父节点,找到则塞进去
if (item.parentId && map[item.parentId]) {
map[item.parentId].children.push(map[item.id]);
}
});
// 保留根节点
const ret = Object.values(map).filter((item) => !item.parentId);
return ret;
}
+1 -1
View File
@@ -8,8 +8,8 @@ import {
isValidObjectString,
isVariableString,
getVariableContent,
isPlainObject,
} from '@music163/tango-helpers';
import { isPlainObject } from '../object';
// @see https://babeljs.io/docs/en/babel-parser#pluginss
const babelParserConfig: ParserOptions = {
+2 -1
View File
@@ -11,6 +11,7 @@ import {
StringOrNumber,
Dict,
parseDndId,
upperCamelCase
} from '@music163/tango-helpers';
import {
keyNode2value,
@@ -28,7 +29,7 @@ import {
code2expression,
object2node,
} from './parse';
import { upperCamelCase, isValidComponentName } from '../string';
import { isValidComponentName } from '../string';
import { isDefineService, isDefineStore } from '../assert';
import type {
RouteDataType,
-1
View File
@@ -1,4 +1,3 @@
export * from './array';
export * from './ast';
export * from './assert';
export * from './string';
-60
View File
@@ -1,65 +1,5 @@
import { ComponentPrototypeType } from '@music163/tango-helpers';
import { ImportDeclarationPayloadType } from '../types';
/**
* 是否是简单的 js 对象
* @param value
* @returns
* @see https://github.com/sindresorhus/is-plain-obj/blob/main/index.js
*/
export function isPlainObject(value: any) {
if (typeof value !== 'object' || value === null) {
return false;
}
const prototype = Object.getPrototypeOf(value);
return (
(prototype === null ||
prototype === Object.prototype ||
Object.getPrototypeOf(prototype) === null) &&
!(Symbol.toStringTag in value) &&
!(Symbol.iterator in value)
);
}
/**
* 拷贝对象
* @param obj 原始对象
* @param omitKeys 忽略掉 key 列表
* @returns 返回拷贝后的对象
*/
export function copyObject(obj: object, omitKeys: string[]) {
const ret = {};
Object.keys(obj).forEach((key) => {
if (!omitKeys.includes(key)) {
ret[key] = obj[key];
}
});
return ret;
}
/**
* 将对象的序列化字符串转为原始的 js 对象
* @param str
* @param defaultValue
* @returns
*/
export function string2object(str: string, defaultValue?: any) {
// eslint-disable-next-line no-new-func
let ret = new Function(`return ${str}`);
ret = ret ? ret() : defaultValue;
return ret;
}
/**
* 获得传入对象的类型
* @param obj
* @returns
*/
export function typeOf(obj?: any) {
return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}
/**
* 导入列表解析为导入声明对象
* @param names
+1 -24
View File
@@ -1,4 +1,5 @@
import path from 'path';
import { camelCase, upperCamelCase } from '@music163/tango-helpers';
import { value2node, expression2code } from './ast';
import { FileType } from './../types';
@@ -89,30 +90,6 @@ export function isValidComponentName(name: string) {
return firstChar === firstChar.toUpperCase();
}
/**
* 转为驼峰
* @example foo -> foo
* @example foo-bar -> fooBar
* @param str
* @returns
*/
export function camelCase(str: string) {
return str.replace(/\W+(.)/g, (match, chr) => {
return chr.toUpperCase();
});
}
/**
* 将输入字符串转换为大驼峰格式
* @example about -> About
* @example not-found -> NotFound
* @param str
*/
export function upperCamelCase(str: string) {
const text = camelCase(str.toLowerCase());
return text.charAt(0).toUpperCase() + text.slice(1);
}
/**
* 从 filename 中解析获得 moduleName
* @example /stores/user.js -> user
+4 -4
View File
@@ -108,15 +108,15 @@ export class TangoJsonFile extends TangoFile {
if (isNil(code)) {
// 基于最新的 json 同步代码
let code = JSON.stringify(this._object);
let newCode = JSON.stringify(this._object);
try {
code = formatCode(code, 'json');
newCode = formatCode(newCode, 'json');
} catch (err) {
logger.error(err);
return;
}
this._code = code;
this._cleanCode = code;
this._code = newCode;
this._cleanCode = newCode;
} else {
try {
// 基于传入的代码,同步 json 对象
+5
View File
@@ -2,5 +2,10 @@ export * from './engine';
export * from './workspace';
export * from './designer';
export * from './drop-target';
export * from './select-source';
export * from './drag-source';
export * from './history';
export * from './file';
export * from './module';
export * from './node';
export * from './interfaces';
+28 -2
View File
@@ -11,7 +11,6 @@ import {
traverseStoreEntryFile,
addStoreToEntryFile,
updateServiceConfigToServiceFile,
toTreeData,
removeJSXElement,
insertSiblingAfterJSXElement,
getModuleNameByFilename,
@@ -382,7 +381,7 @@ export class TangoViewModule extends TangoModule implements IViewFile {
this._nodes.set(cur.id, node);
});
this._nodesTree = toTreeData(nodes);
this._nodesTree = nodeListToTreeData(nodes);
}
/**
@@ -580,6 +579,33 @@ export class TangoViewModule extends TangoModule implements IViewFile {
}
}
/**
* 将节点列表转换为 tree data 嵌套数组
* @param list
*/
export function nodeListToTreeData(list: TangoViewNodeDataType[]) {
const map: Record<string, TangoViewNodeDataType> = {};
list.forEach((item) => {
// 如果不存在,则初始化
if (!map[item.id]) {
map[item.id] = {
...item,
children: [],
};
}
// 是否找到父节点,找到则塞进去
if (item.parentId && map[item.parentId]) {
map[item.parentId].children.push(map[item.id]);
}
});
// 保留根节点
const ret = Object.values(map).filter((item) => !item.parentId);
return ret;
}
/**
* 数据服务模块
*/
+6 -4
View File
@@ -126,6 +126,7 @@ export class Workspace extends EventTarget implements IWorkspace {
/**
* appJson.json 文件
* FIXME: 是否保留 ???
*/
appJson: TangoJsonFile;
@@ -379,7 +380,7 @@ export class Workspace extends EventTarget implements IWorkspace {
module = new TangoStoreEntryModule(this, props);
this.storeEntryModule = module;
break;
case FileType.RouteModule:
case FileType.RouteModule: {
module = new TangoRouteModule(this, props);
this.routeModule = module;
// check if activeRoute exists
@@ -388,6 +389,7 @@ export class Workspace extends EventTarget implements IWorkspace {
this.setActiveRoute(module.routes[0]?.path);
}
break;
}
case FileType.JsxViewModule:
module = new TangoViewModule(this, props);
break;
@@ -398,7 +400,7 @@ export class Workspace extends EventTarget implements IWorkspace {
case FileType.StoreModule:
module = new TangoStoreModule(this, props);
break;
case FileType.BlockEntryModule:
case FileType.BlockEntryModule: {
const blockName = getBlockNameByFilename(props.filename);
const prototype: ComponentPrototypeType = {
name: blockName,
@@ -410,6 +412,7 @@ export class Workspace extends EventTarget implements IWorkspace {
this.componentPrototypes.set(blockName, prototype);
module = new TangoViewModule(this, props);
break;
}
case FileType.Module:
module = new TangoJsModule(this, props);
break;
@@ -620,7 +623,6 @@ export class Workspace extends EventTarget implements IWorkspace {
if (file instanceof TangoViewModule) {
return file.getNode(id);
}
return;
}
/**
@@ -1111,7 +1113,7 @@ export class Workspace extends EventTarget implements IWorkspace {
}
// TODO: 这里需要一个额外的信息,DropTarget 的最近容器节点,用于判断目标元素是否可以被置入容器中
let dragSourcePrototype = dragSource.prototype;
const dragSourcePrototype = dragSource.prototype;
let newNode;
if (dragSource.id) {
-41
View File
@@ -5,9 +5,7 @@ import {
value2node,
value2code,
expression2code,
upperCamelCase,
expressionCode2ast,
typeOf,
isPathnameMatchRoute,
namesToImportDeclarations,
getBlockNameByFilename,
@@ -16,10 +14,8 @@ import {
isValidComponentName,
getFilepath,
getPrivilegeCode,
isPlainObject,
getJSXElementAttributes,
inferFileType,
camelCase,
deepCloneNode,
} from '../src/helpers';
import { FileType } from '../src/types';
@@ -130,15 +126,6 @@ describe('helpers', () => {
});
describe('string helpers', () => {
it('camelCase', () => {
expect(camelCase('foo')).toEqual('foo');
expect(camelCase('foo-bar')).toEqual('fooBar');
});
it('upperCamelCase', () => {
expect(upperCamelCase('foo')).toEqual('Foo');
expect(upperCamelCase('foo-bar')).toEqual('FooBar');
});
it('value2code: empty array', () => {
expect(value2code([])).toEqual('[]');
@@ -152,15 +139,6 @@ describe('string helpers', () => {
expect(value2code({ width: 200 })).toEqual('{ width: 200 }');
});
it('typeOf', () => {
expect(typeOf()).toBe('undefined');
expect(typeOf('')).toBe('string');
expect(typeOf('hello')).toBe('string');
expect(typeOf(5)).toBe('number');
expect(typeOf({})).toBe('object');
expect(typeOf([])).toBe('array');
});
it('isPathnameMatchRoute', () => {
expect(isPathnameMatchRoute('/user/123', '/user/:id')).toBeTruthy();
expect(isPathnameMatchRoute('/user/123?foo=bar', '/user/:id')).toBeTruthy();
@@ -221,24 +199,6 @@ describe('string helpers', () => {
expect(isValidComponentName('Button.Group')).toBeTruthy();
});
it('upperCamelCase', () => {
expect(upperCamelCase('about')).toBe('About');
expect(upperCamelCase('not-found')).toBe('NotFound');
expect(upperCamelCase('@music/input')).toBe('MusicInput');
expect(upperCamelCase('@music/ct-input')).toBe('MusicCtInput');
// TODO: FIXME
// expect(upperCamelCase('-not-found')).toBe('NotFound');
// expect(upperCamelCase('not_found')).toBe('NotFound');
// expect(upperCamelCase('_not_found')).toBe('NotFound');
});
it('isPlainObject', () => {
expect(isPlainObject({})).toBeTruthy();
expect(isPlainObject({ foo: 'foo' })).toBeTruthy();
expect(isPlainObject(null)).toBeFalsy();
expect(isPlainObject(undefined)).toBeFalsy();
});
it('inferFileType', () => {
expect(inferFileType('/src/pages/template.js')).toBe(FileType.JsxViewModule);
expect(inferFileType('/src/pages/template.jsx')).toBe(FileType.JsxViewModule);
@@ -274,7 +234,6 @@ describe('schema helpers', () => {
],
};
const cloned = deepCloneNode(schema);
console.log(cloned);
expect(cloned.props.id).toBe(schema.props.id);
expect(cloned.children[0].props.id).toBe(schema.children[0].props.id);
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -27,7 +27,8 @@
"prepublishOnly": "yarn build"
},
"peerDependencies": {
"react": ">= 16.8.0"
"react": ">= 16.8.0",
"styled-components": "5"
},
"dependencies": {
"@ant-design/icons": "^4.8.0",
+20 -8
View File
@@ -1,12 +1,25 @@
/**
* @example camelCase('button') -> Button
* @example camelCase('date-picker') -> DatePicker
* 转为驼峰 (lowerCamelCase)
* @example foo -> foo
* @example foo-bar -> fooBar
* @param str
* @returns
*/
export function camelCase(str = '') {
return str.split('-').reduce((prev, cur) => {
const word = cur.charAt(0).toUpperCase() + cur.slice(1);
return `${prev}${word}`;
}, '');
export function camelCase(str: string) {
return str.replace(/\W+(.)/g, (match, chr) => {
return chr.toUpperCase();
});
}
/**
* 将输入字符串转换为大驼峰格式(PascalCase)
* @example about -> About
* @example not-found -> NotFound
* @param str
*/
export function upperCamelCase(str: string) {
const text = camelCase(str.toLowerCase());
return text.charAt(0).toUpperCase() + text.slice(1);
}
/**
@@ -258,5 +271,4 @@ export function getCodeBlockFormMarkdown(markdown: string) {
if (match && match.length) {
return match[2];
}
return;
}
+10 -3
View File
@@ -8,13 +8,20 @@ import {
parseDndId,
isValidUrl,
getCodeBlockFormMarkdown,
upperCamelCase,
} from '../src/helpers';
describe('string', () => {
it('camelCase', () => {
expect(camelCase('-button')).toBe('Button');
expect(camelCase('button')).toBe('Button');
expect(camelCase('date-picker')).toBe('DatePicker');
expect(camelCase('foo')).toEqual('foo');
expect(camelCase('foo-bar')).toEqual('fooBar');
});
it('upperCamelCase', () => {
expect(upperCamelCase('about')).toBe('About');
expect(upperCamelCase('not-found')).toBe('NotFound');
expect(upperCamelCase('@music/input')).toBe('MusicInput');
expect(upperCamelCase('@music/ct-input')).toBe('MusicCtInput');
});
it('isValidUrl', () => {
+66 -4
View File
@@ -194,6 +194,14 @@
"@babel/highlight" "^7.22.10"
chalk "^2.4.2"
"@babel/code-frame@^7.22.13":
version "7.22.13"
resolved "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e"
integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==
dependencies:
"@babel/highlight" "^7.22.13"
chalk "^2.4.2"
"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9":
version "7.22.9"
resolved "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.22.9.tgz"
@@ -242,7 +250,7 @@
json5 "^2.2.2"
semver "^6.3.1"
"@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.18.7", "@babel/generator@^7.21.3", "@babel/generator@^7.22.10", "@babel/generator@^7.7.2":
"@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.18.7", "@babel/generator@^7.22.10", "@babel/generator@^7.7.2":
version "7.22.10"
resolved "https://registry.npmmirror.com/@babel/generator/-/generator-7.22.10.tgz"
integrity sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==
@@ -252,6 +260,16 @@
"@jridgewell/trace-mapping" "^0.3.17"
jsesc "^2.5.1"
"@babel/generator@^7.22.15":
version "7.22.15"
resolved "https://registry.npmmirror.com/@babel/generator/-/generator-7.22.15.tgz#1564189c7ec94cb8f77b5e8a90c4d200d21b2339"
integrity sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==
dependencies:
"@babel/types" "^7.22.15"
"@jridgewell/gen-mapping" "^0.3.2"
"@jridgewell/trace-mapping" "^0.3.17"
jsesc "^2.5.1"
"@babel/helper-annotate-as-pure@^7.18.6", "@babel/helper-annotate-as-pure@^7.22.5":
version "7.22.5"
resolved "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz"
@@ -432,6 +450,11 @@
resolved "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz"
integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==
"@babel/helper-validator-identifier@^7.22.15":
version "7.22.15"
resolved "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz#601fa28e4cc06786c18912dca138cec73b882044"
integrity sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==
"@babel/helper-validator-identifier@^7.22.5":
version "7.22.5"
resolved "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz"
@@ -469,11 +492,25 @@
chalk "^2.4.2"
js-tokens "^4.0.0"
"@babel/parser@^7.1.0", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.18.8", "@babel/parser@^7.20.7", "@babel/parser@^7.21.3", "@babel/parser@^7.22.10", "@babel/parser@^7.22.5":
"@babel/highlight@^7.22.13":
version "7.22.13"
resolved "https://registry.npmmirror.com/@babel/highlight/-/highlight-7.22.13.tgz#9cda839e5d3be9ca9e8c26b6dd69e7548f0cbf16"
integrity sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==
dependencies:
"@babel/helper-validator-identifier" "^7.22.5"
chalk "^2.4.2"
js-tokens "^4.0.0"
"@babel/parser@^7.1.0", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.18.8", "@babel/parser@^7.20.7", "@babel/parser@^7.22.10", "@babel/parser@^7.22.5":
version "7.22.10"
resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.22.10.tgz"
integrity sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==
"@babel/parser@^7.22.15":
version "7.22.15"
resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.22.15.tgz#d34592bfe288a32e741aa0663dbc4829fcd55160"
integrity sha512-RWmQ/sklUN9BvGGpCDgSubhHWfAx24XDTDObup4ffvxaYsptOg2P3KG0j+1eWKLxpkX0j0uHxmpq2Z1SP/VhxA==
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.5":
version "7.22.5"
resolved "https://registry.npmmirror.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz"
@@ -1385,7 +1422,7 @@
"@babel/parser" "^7.22.5"
"@babel/types" "^7.22.5"
"@babel/traverse@^7.1.6", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.18.8", "@babel/traverse@^7.21.3", "@babel/traverse@^7.22.10", "@babel/traverse@^7.4.5":
"@babel/traverse@^7.1.6", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.18.8", "@babel/traverse@^7.22.10", "@babel/traverse@^7.4.5":
version "7.22.10"
resolved "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.22.10.tgz"
integrity sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==
@@ -1401,7 +1438,23 @@
debug "^4.1.0"
globals "^11.1.0"
"@babel/types@^7.0.0", "@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.2.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.21.3", "@babel/types@^7.22.10", "@babel/types@^7.22.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
"@babel/traverse@^7.22.15":
version "7.22.15"
resolved "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.22.15.tgz#75be4d2d6e216e880e93017f4e2389aeb77ef2d9"
integrity sha512-DdHPwvJY0sEeN4xJU5uRLmZjgMMDIvMPniLuYzUVXj/GGzysPl0/fwt44JBkyUIzGJPV8QgHMcQdQ34XFuKTYQ==
dependencies:
"@babel/code-frame" "^7.22.13"
"@babel/generator" "^7.22.15"
"@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.6"
"@babel/parser" "^7.22.15"
"@babel/types" "^7.22.15"
debug "^4.1.0"
globals "^11.1.0"
"@babel/types@^7.0.0", "@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.2.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.22.10", "@babel/types@^7.22.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
version "7.22.10"
resolved "https://registry.npmmirror.com/@babel/types/-/types-7.22.10.tgz"
integrity sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==
@@ -1410,6 +1463,15 @@
"@babel/helper-validator-identifier" "^7.22.5"
to-fast-properties "^2.0.0"
"@babel/types@^7.22.15":
version "7.22.15"
resolved "https://registry.npmmirror.com/@babel/types/-/types-7.22.15.tgz#266cb21d2c5fd0b3931e7a91b6dd72d2f617d282"
integrity sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==
dependencies:
"@babel/helper-string-parser" "^7.22.5"
"@babel/helper-validator-identifier" "^7.22.15"
to-fast-properties "^2.0.0"
"@base2/pretty-print-object@1.0.1":
version "1.0.1"
resolved "https://registry.npmmirror.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz"