mirror of
https://github.com/ershisan99/DevToysWeb.git
synced 2025-12-17 12:32:56 +00:00
feat: add Json <> Yaml converter
This commit is contained in:
@@ -23,12 +23,15 @@
|
|||||||
"@fontsource/roboto": "^4.5.3",
|
"@fontsource/roboto": "^4.5.3",
|
||||||
"@mui/icons-material": "^5.5.1",
|
"@mui/icons-material": "^5.5.1",
|
||||||
"@mui/material": "^5.5.1",
|
"@mui/material": "^5.5.1",
|
||||||
|
"ace-builds": "^1.4.14",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"fuse.js": "^6.5.3",
|
"fuse.js": "^6.5.3",
|
||||||
"next": "12.1.0",
|
"next": "12.1.0",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
|
"react-ace": "^9.5.0",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
"recoil": "^0.6.1"
|
"recoil": "^0.6.1",
|
||||||
|
"yaml": "^1.10.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@emotion/babel-plugin": "^11.7.2",
|
"@emotion/babel-plugin": "^11.7.2",
|
||||||
|
|||||||
32
src/components/common/CodeEditor.tsx
Normal file
32
src/components/common/CodeEditor.tsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { Paper } from "@mui/material";
|
||||||
|
import { config } from "ace-builds";
|
||||||
|
import { ComponentPropsWithoutRef, memo } from "react";
|
||||||
|
import AceEditor from "react-ace";
|
||||||
|
|
||||||
|
// https://github.com/securingsincity/react-ace/issues/725
|
||||||
|
config.set("basePath", "https://cdn.jsdelivr.net/npm/ace-builds@1.4.14/src-min-noconflict/");
|
||||||
|
config.setModuleUrl(
|
||||||
|
"ace/mode/javascript_worker",
|
||||||
|
"https://cdn.jsdelivr.net/npm/ace-builds@1.4.14/src-min-noconflict/worker-javascript.js"
|
||||||
|
);
|
||||||
|
|
||||||
|
type Props = ComponentPropsWithoutRef<typeof AceEditor>;
|
||||||
|
|
||||||
|
const StyledComponent = (props: Props) => (
|
||||||
|
<Paper>
|
||||||
|
<AceEditor
|
||||||
|
wrapEnabled
|
||||||
|
theme="textmate"
|
||||||
|
showPrintMargin={false}
|
||||||
|
highlightActiveLine={false}
|
||||||
|
editorProps={{ $blockScrolling: true }}
|
||||||
|
setOptions={{ mergeUndoDeltas: false }}
|
||||||
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Component = memo(StyledComponent);
|
||||||
|
|
||||||
|
export default Component;
|
||||||
26
src/components/common/CodeEditorHalf.tsx
Normal file
26
src/components/common/CodeEditorHalf.tsx
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { useTheme } from "@mui/material/styles";
|
||||||
|
import { ComponentPropsWithoutRef, memo } from "react";
|
||||||
|
|
||||||
|
import { drawerWidth } from "@/components/layout/Drawer";
|
||||||
|
import { headerHeight } from "@/components/layout/Header";
|
||||||
|
|
||||||
|
import CodeEditor from "./CodeEditor";
|
||||||
|
|
||||||
|
type Props = Omit<ComponentPropsWithoutRef<typeof CodeEditor>, "width">;
|
||||||
|
|
||||||
|
const StyledComponent = (props: Props) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CodeEditor
|
||||||
|
height={`calc(100vh - ${headerHeight}px - ${theme.spacing(6 * 2)} - 192px`}
|
||||||
|
width={`calc(calc(100vw - ${drawerWidth}px - ${theme.spacing(6 * 2)} - 18px) / 2)`}
|
||||||
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Component = memo(StyledComponent);
|
||||||
|
|
||||||
|
export default Component;
|
||||||
26
src/components/common/CodeEditorHalfLoading.tsx
Normal file
26
src/components/common/CodeEditorHalfLoading.tsx
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { Skeleton } from "@mui/material";
|
||||||
|
import { useTheme } from "@mui/material/styles";
|
||||||
|
import { ComponentPropsWithoutRef, memo } from "react";
|
||||||
|
|
||||||
|
import { drawerWidth } from "@/components/layout/Drawer";
|
||||||
|
import { headerHeight } from "@/components/layout/Header";
|
||||||
|
|
||||||
|
type Props = Omit<ComponentPropsWithoutRef<typeof Skeleton>, "width">;
|
||||||
|
|
||||||
|
const StyledComponent = (props: Props) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Skeleton
|
||||||
|
variant="rectangular"
|
||||||
|
height={`calc(100vh - ${headerHeight}px - ${theme.spacing(6 * 2)} - 192px`}
|
||||||
|
width={`calc(calc(100vw - ${drawerWidth}px - ${theme.spacing(6 * 2)} - 18px) / 2)`}
|
||||||
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Component = memo(StyledComponent);
|
||||||
|
|
||||||
|
export default Component;
|
||||||
30
src/components/common/Configuration.tsx
Normal file
30
src/components/common/Configuration.tsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { Box, Paper, Stack, Typography } from "@mui/material";
|
||||||
|
import { css, Theme } from "@mui/material/styles";
|
||||||
|
import { memo, ReactNode } from "react";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
icon: ReactNode;
|
||||||
|
title: string;
|
||||||
|
input: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
const paper = (theme: Theme) => css`
|
||||||
|
padding: ${theme.spacing(2)};
|
||||||
|
height: ${theme.spacing(8)};
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledComponent = ({ icon, title, input }: Props) => (
|
||||||
|
<Paper css={paper}>
|
||||||
|
<Stack direction="row" alignItems="center" height={theme => theme.spacing(4)}>
|
||||||
|
<Stack direction="row" spacing={2}>
|
||||||
|
{icon}
|
||||||
|
<Typography>{title}</Typography>
|
||||||
|
</Stack>
|
||||||
|
<Box marginLeft="auto">{input}</Box>
|
||||||
|
</Stack>
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Component = memo(StyledComponent);
|
||||||
|
|
||||||
|
export default Component;
|
||||||
21
src/components/common/Configurations.tsx
Normal file
21
src/components/common/Configurations.tsx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { Stack } from "@mui/material";
|
||||||
|
import equal from "fast-deep-equal";
|
||||||
|
import { ComponentPropsWithoutRef, memo } from "react";
|
||||||
|
|
||||||
|
import Configuration from "./Configuration";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
configurations: ComponentPropsWithoutRef<typeof Configuration>[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const StyledComponent = ({ configurations }: Props) => (
|
||||||
|
<Stack spacing={1}>
|
||||||
|
{configurations.map(({ icon, title, input }) => (
|
||||||
|
<Configuration key={title} {...{ icon, title, input }} />
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Component = memo(StyledComponent, equal);
|
||||||
|
|
||||||
|
export default Component;
|
||||||
19
src/components/common/MainItem.tsx
Normal file
19
src/components/common/MainItem.tsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { Box, Typography } from "@mui/material";
|
||||||
|
import { memo, PropsWithChildren } from "react";
|
||||||
|
|
||||||
|
type Props = PropsWithChildren<{
|
||||||
|
title: string;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
const StyledComponent = ({ children, title }: Props) => (
|
||||||
|
<Box>
|
||||||
|
<Typography variant="h6" component="h2">
|
||||||
|
{title}
|
||||||
|
</Typography>
|
||||||
|
{children}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Component = memo(StyledComponent);
|
||||||
|
|
||||||
|
export default Component;
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import CodeEditorHalfLoading from "./CodeEditorHalfLoading";
|
||||||
|
import Configurations from "./Configurations";
|
||||||
import Main from "./Main";
|
import Main from "./Main";
|
||||||
|
import MainItem from "./MainItem";
|
||||||
|
|
||||||
export { Main };
|
export { CodeEditorHalfLoading, Configurations, Main, MainItem };
|
||||||
|
|||||||
@@ -47,7 +47,12 @@ const toolGroups = [
|
|||||||
icon: <Transform />,
|
icon: <Transform />,
|
||||||
title: "Converters",
|
title: "Converters",
|
||||||
tools: [
|
tools: [
|
||||||
{ icon: <Transform />, title: "Json <> Yaml", href: pagesPath.$url(), disabled: true },
|
{
|
||||||
|
icon: <Transform />,
|
||||||
|
title: "Json <> Yaml",
|
||||||
|
href: pagesPath.converters.json_yaml.$url(),
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
{ icon: <Numbers />, title: "Number Base", href: pagesPath.$url(), disabled: true },
|
{ icon: <Numbers />, title: "Number Base", href: pagesPath.$url(), disabled: true },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
50
src/components/pages/converters/json-yaml/Configuration.tsx
Normal file
50
src/components/pages/converters/json-yaml/Configuration.tsx
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import { SpaceBar } from "@mui/icons-material";
|
||||||
|
import { FormControl, MenuItem, Select } from "@mui/material";
|
||||||
|
import { SelectInputProps } from "@mui/material/Select/SelectInput";
|
||||||
|
import { css } from "@mui/material/styles";
|
||||||
|
import { memo } from "react";
|
||||||
|
|
||||||
|
import { Configurations } from "@/components/common";
|
||||||
|
|
||||||
|
const spacesArray = [2, 4] as const;
|
||||||
|
export type Spaces = typeof spacesArray[number];
|
||||||
|
export const isSpaces = (x: number): x is Spaces => spacesArray.includes(x as Spaces);
|
||||||
|
|
||||||
|
type OnSelectChange<T> = NonNullable<SelectInputProps<T>["onChange"]>;
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
spaces: Spaces;
|
||||||
|
onSpacesChange: OnSelectChange<Spaces>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const select = css`
|
||||||
|
& .MuiSelect-select:focus {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledComponent = ({ spaces, onSpacesChange }: Props) => (
|
||||||
|
<Configurations
|
||||||
|
configurations={[
|
||||||
|
{
|
||||||
|
icon: <SpaceBar />,
|
||||||
|
title: "Indentation",
|
||||||
|
input: (
|
||||||
|
<FormControl variant="standard">
|
||||||
|
<Select value={spaces} onChange={onSpacesChange} css={select}>
|
||||||
|
{spacesArray.map(value => (
|
||||||
|
<MenuItem key={value} {...{ value }}>
|
||||||
|
{value} spaces
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Component = memo(StyledComponent);
|
||||||
|
|
||||||
|
export default Component;
|
||||||
128
src/components/pages/converters/json-yaml/Content.tsx
Normal file
128
src/components/pages/converters/json-yaml/Content.tsx
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
import { Stack } from "@mui/material";
|
||||||
|
import dynamic from "next/dynamic";
|
||||||
|
import { ComponentPropsWithoutRef, memo, useCallback, useState } from "react";
|
||||||
|
import YAML from "yaml";
|
||||||
|
|
||||||
|
import { CodeEditorHalfLoading, Main, MainItem } from "@/components/common";
|
||||||
|
|
||||||
|
import Configuration, { isSpaces, Spaces } from "./Configuration";
|
||||||
|
|
||||||
|
// https://github.com/securingsincity/react-ace/issues/27
|
||||||
|
const CodeEditorHalf = dynamic(
|
||||||
|
async () => {
|
||||||
|
const ace = await import("@/components/common/CodeEditorHalf");
|
||||||
|
await Promise.all([
|
||||||
|
import("ace-builds/src-noconflict/mode-json"),
|
||||||
|
import("ace-builds/src-noconflict/mode-yaml"),
|
||||||
|
]);
|
||||||
|
return ace;
|
||||||
|
},
|
||||||
|
{ ssr: false, loading: () => <CodeEditorHalfLoading /> }
|
||||||
|
);
|
||||||
|
|
||||||
|
type CodeValue = NonNullable<ComponentPropsWithoutRef<typeof CodeEditorHalf>["value"]>;
|
||||||
|
type OnCodeChange = NonNullable<ComponentPropsWithoutRef<typeof CodeEditorHalf>["onChange"]>;
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
json: CodeValue;
|
||||||
|
yaml: CodeValue;
|
||||||
|
onJsonChange: OnCodeChange;
|
||||||
|
onYamlChange: OnCodeChange;
|
||||||
|
} & ComponentPropsWithoutRef<typeof Configuration>;
|
||||||
|
|
||||||
|
const StyledComponent = ({
|
||||||
|
json,
|
||||||
|
yaml,
|
||||||
|
spaces,
|
||||||
|
onJsonChange,
|
||||||
|
onYamlChange,
|
||||||
|
onSpacesChange,
|
||||||
|
}: Props) => (
|
||||||
|
<Main title="Json <> Yaml Converter">
|
||||||
|
<MainItem title="Configuration">
|
||||||
|
<Configuration {...{ spaces, onSpacesChange }} />
|
||||||
|
</MainItem>
|
||||||
|
<Stack direction="row" spacing={2}>
|
||||||
|
<MainItem title="Json">
|
||||||
|
<CodeEditorHalf
|
||||||
|
name="json"
|
||||||
|
mode="json"
|
||||||
|
value={json}
|
||||||
|
tabSize={spaces}
|
||||||
|
onChange={onJsonChange}
|
||||||
|
/>
|
||||||
|
</MainItem>
|
||||||
|
<MainItem title="Yaml">
|
||||||
|
<CodeEditorHalf
|
||||||
|
name="yaml"
|
||||||
|
mode="yaml"
|
||||||
|
value={yaml}
|
||||||
|
tabSize={spaces}
|
||||||
|
onChange={onYamlChange}
|
||||||
|
/>
|
||||||
|
</MainItem>
|
||||||
|
</Stack>
|
||||||
|
</Main>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Component = memo(StyledComponent);
|
||||||
|
|
||||||
|
const Container = () => {
|
||||||
|
const [json, setJson] = useState('{\n "foo": "bar"\n}');
|
||||||
|
const [yaml, setYaml] = useState("foo: bar");
|
||||||
|
const [spaces, setSpaces] = useState<Spaces>(2);
|
||||||
|
|
||||||
|
const onJsonChange: Props["onJsonChange"] = useCallback(
|
||||||
|
value => {
|
||||||
|
setJson(value);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(value) as unknown;
|
||||||
|
setYaml(YAML.stringify(parsed, { indent: spaces, simpleKeys: true }));
|
||||||
|
} catch {
|
||||||
|
setYaml("");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[spaces]
|
||||||
|
);
|
||||||
|
|
||||||
|
const onYamlChange: Props["onYamlChange"] = useCallback(
|
||||||
|
value => {
|
||||||
|
setYaml(value);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const parsed = YAML.parse(value, { merge: true }) as unknown;
|
||||||
|
setJson(JSON.stringify(parsed, null, spaces));
|
||||||
|
} catch {
|
||||||
|
setJson("");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[spaces]
|
||||||
|
);
|
||||||
|
|
||||||
|
const onSpacesChange: Props["onSpacesChange"] = useCallback(
|
||||||
|
({ target: { value } }) => {
|
||||||
|
const newSpaces = Number(value);
|
||||||
|
|
||||||
|
if (!isSpaces(newSpaces)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setSpaces(newSpaces);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(json) as unknown;
|
||||||
|
setJson(JSON.stringify(parsed, null, newSpaces));
|
||||||
|
setYaml(YAML.stringify(parsed, { indent: newSpaces, simpleKeys: true }));
|
||||||
|
} catch {
|
||||||
|
setJson("");
|
||||||
|
setYaml("");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[json]
|
||||||
|
);
|
||||||
|
|
||||||
|
return <Component {...{ json, yaml, spaces, onJsonChange, onYamlChange, onSpacesChange }} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Container;
|
||||||
3
src/components/pages/converters/json-yaml/index.ts
Normal file
3
src/components/pages/converters/json-yaml/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import Content from "./Content";
|
||||||
|
|
||||||
|
export { Content };
|
||||||
@@ -31,8 +31,8 @@ const tools = [
|
|||||||
title: "Json <> Yaml Converter",
|
title: "Json <> Yaml Converter",
|
||||||
description: "Convert Json data to Yaml and vice versa",
|
description: "Convert Json data to Yaml and vice versa",
|
||||||
keywords: "json yaml converter",
|
keywords: "json yaml converter",
|
||||||
href: pagesPath.$url(),
|
href: pagesPath.converters.json_yaml.$url(),
|
||||||
disabled: true,
|
disabled: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: <Numbers />,
|
icon: <Numbers />,
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
export const pagesPath = {
|
export const pagesPath = {
|
||||||
|
converters: {
|
||||||
|
json_yaml: {
|
||||||
|
$url: (url?: { hash?: string }) => ({
|
||||||
|
pathname: "/converters/json-yaml" as const,
|
||||||
|
hash: url?.hash,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
$url: (url?: { hash?: string }) => ({ pathname: "/" as const, hash: url?.hash }),
|
$url: (url?: { hash?: string }) => ({ pathname: "/" as const, hash: url?.hash }),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
7
src/pages/converters/json-yaml.tsx
Normal file
7
src/pages/converters/json-yaml.tsx
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import type { NextPage } from "next";
|
||||||
|
|
||||||
|
import { Content } from "@/components/pages/converters/json-yaml";
|
||||||
|
|
||||||
|
const Page: NextPage = Content;
|
||||||
|
|
||||||
|
export default Page;
|
||||||
33
yarn.lock
33
yarn.lock
@@ -527,6 +527,11 @@
|
|||||||
"@typescript-eslint/types" "5.15.0"
|
"@typescript-eslint/types" "5.15.0"
|
||||||
eslint-visitor-keys "^3.0.0"
|
eslint-visitor-keys "^3.0.0"
|
||||||
|
|
||||||
|
ace-builds@^1.4.13, ace-builds@^1.4.14:
|
||||||
|
version "1.4.14"
|
||||||
|
resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.4.14.tgz#2c41ccbccdd09e665d3489f161a20baeb3a3c852"
|
||||||
|
integrity sha512-NBOQlm9+7RBqRqZwimpgquaLeTJFayqb9UEPtTkpC3TkkwDnlsT/TwsCC0svjt9kEZ6G9mH5AEOHSz6Q/HrzQQ==
|
||||||
|
|
||||||
acorn-jsx@^5.3.1:
|
acorn-jsx@^5.3.1:
|
||||||
version "5.3.2"
|
version "5.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
||||||
@@ -863,6 +868,11 @@ define-properties@^1.1.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
object-keys "^1.0.12"
|
object-keys "^1.0.12"
|
||||||
|
|
||||||
|
diff-match-patch@^1.0.5:
|
||||||
|
version "1.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz#abb584d5f10cd1196dfc55aa03701592ae3f7b37"
|
||||||
|
integrity sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==
|
||||||
|
|
||||||
dir-glob@^3.0.1:
|
dir-glob@^3.0.1:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
|
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
|
||||||
@@ -1695,6 +1705,16 @@ locate-path@^2.0.0:
|
|||||||
p-locate "^2.0.0"
|
p-locate "^2.0.0"
|
||||||
path-exists "^3.0.0"
|
path-exists "^3.0.0"
|
||||||
|
|
||||||
|
lodash.get@^4.4.2:
|
||||||
|
version "4.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
|
||||||
|
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
|
||||||
|
|
||||||
|
lodash.isequal@^4.5.0:
|
||||||
|
version "4.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||||
|
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
|
||||||
|
|
||||||
lodash.merge@^4.6.2:
|
lodash.merge@^4.6.2:
|
||||||
version "4.6.2"
|
version "4.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||||
@@ -2072,6 +2092,17 @@ queue-microtask@^1.2.2:
|
|||||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||||
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
||||||
|
|
||||||
|
react-ace@^9.5.0:
|
||||||
|
version "9.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-ace/-/react-ace-9.5.0.tgz#b6c32b70d404dd821a7e01accc2d76da667ff1f7"
|
||||||
|
integrity sha512-4l5FgwGh6K7A0yWVMQlPIXDItM4Q9zzXRqOae8KkCl6MkOob7sC1CzHxZdOGvV+QioKWbX2p5HcdOVUv6cAdSg==
|
||||||
|
dependencies:
|
||||||
|
ace-builds "^1.4.13"
|
||||||
|
diff-match-patch "^1.0.5"
|
||||||
|
lodash.get "^4.4.2"
|
||||||
|
lodash.isequal "^4.5.0"
|
||||||
|
prop-types "^15.7.2"
|
||||||
|
|
||||||
react-dom@17.0.2:
|
react-dom@17.0.2:
|
||||||
version "17.0.2"
|
version "17.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
|
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
|
||||||
@@ -2578,7 +2609,7 @@ yallist@^4.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
|
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
|
||||||
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
||||||
|
|
||||||
yaml@^1.7.2:
|
yaml@^1.10.2, yaml@^1.7.2:
|
||||||
version "1.10.2"
|
version "1.10.2"
|
||||||
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
|
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
|
||||||
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
|
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
|
||||||
|
|||||||
Reference in New Issue
Block a user