Merge pull request #646 from spotify/rugvip/graphiql
[Plugin] Add GraphiQL Plugin
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: [require.resolve('@backstage/cli/config/eslint')],
|
||||
rules: {
|
||||
// Prefer to use rendered.getBy*, which will throw an error
|
||||
'jest/expect-expect': 0,
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,64 @@
|
||||
# @backstage/plugin-graphiql
|
||||
|
||||
This plugin integrates [GraphiQL](https://github.com/graphql/graphiql) as a tool to browse GraphiQL endpoints inside Backstage.
|
||||
|
||||
The purpose of the plugin is to provide a convenient way for developers to try out GraphQL queries in their own environment.
|
||||
By exposing GraphiQL as a plugin instead of a standalone app, it's possible to provide a preconfigured environment for engineers, and also tie into authentication providers already inside Backstage.
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Installing the plugin
|
||||
|
||||
Start out by installing the plugin in your Backstage app:
|
||||
|
||||
```bash
|
||||
yarn add @backstage/plugin-graphiql
|
||||
```
|
||||
|
||||
Then add an entry to your App's `plugins.ts` to import the plugin.
|
||||
|
||||
The plugin registers a `/graphiql` route, which you can link to from the Sidebar if desired.
|
||||
|
||||
### Adding GraphQL endpoints
|
||||
|
||||
For the plugin to function, you need to supply GraphQL endpoints through the GraphQLBrowse API, which is done by implementing the `GraphQLBrowseApi` exported by this plugin.
|
||||
|
||||
If all you need is a static list of endpoints, the plugin exports a `GraphQLEndpoints` class that implements the `GraphQLBrowseApi` for you. Here's and example of how you could expose two GraphQL endpoints in your App:
|
||||
|
||||
```tsx
|
||||
import {
|
||||
graphQlBrowseApiRef,
|
||||
GraphQLEndpoints,
|
||||
} from '@backstage/plugin-graphiql';
|
||||
|
||||
// Implement the Graph QL browse API using a static list of endpoints
|
||||
const graphQlBrowseApi = GraphQLEndpoints.from([
|
||||
// Use the .create function if all you need is a static URL and headers.
|
||||
GraphQLEndpoints.create({
|
||||
id: 'gitlab',
|
||||
title: 'GitLab',
|
||||
url: 'https://gitlab.com/api/graphql',
|
||||
// Optional extra headers
|
||||
headers: { Extra: 'Header' },
|
||||
}),
|
||||
{
|
||||
id: 'hooli-search',
|
||||
title: 'Hooli Search',
|
||||
// Custom fetch function, this one is equivalent to using GraphQLEndpoints.create()
|
||||
// with url set to https://internal.hooli.com/search
|
||||
fetcher: async (params: any) => {
|
||||
return fetch('https://internal.hooli.com/search', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(params),
|
||||
}).then(res => res.json());
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
// ApiRegistry builder created somewhere in your App
|
||||
const builder = ApiRegistry.builder();
|
||||
|
||||
// Add the instance to the API registry
|
||||
builder.add(graphQlBrowseApiRef, graphQlBrowseApi);
|
||||
```
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { FC } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import HomeIcon from '@material-ui/icons/Home';
|
||||
import { ThemeProvider, CssBaseline } from '@material-ui/core';
|
||||
import {
|
||||
createApp,
|
||||
SidebarPage,
|
||||
Sidebar,
|
||||
SidebarItem,
|
||||
SidebarSpacer,
|
||||
ApiRegistry,
|
||||
} from '@backstage/core';
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
import { plugin, GraphQLEndpoints, graphQlBrowseApiRef } from '../src';
|
||||
|
||||
const graphQlBrowseApi = GraphQLEndpoints.from([
|
||||
GraphQLEndpoints.create({
|
||||
id: 'gitlab',
|
||||
title: 'GitLab',
|
||||
url: 'https://gitlab.com/api/graphql',
|
||||
}),
|
||||
GraphQLEndpoints.create({
|
||||
id: 'countries',
|
||||
title: 'Countries',
|
||||
url: 'https://countries.trevorblades.com/',
|
||||
}),
|
||||
]);
|
||||
|
||||
const app = createApp();
|
||||
app.registerApis(ApiRegistry.from([[graphQlBrowseApiRef, graphQlBrowseApi]]));
|
||||
app.registerPlugin(plugin);
|
||||
const AppComponent = app.build();
|
||||
|
||||
const App: FC<{}> = () => {
|
||||
return (
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<CssBaseline>
|
||||
<BrowserRouter>
|
||||
<SidebarPage>
|
||||
<Sidebar>
|
||||
<SidebarSpacer />
|
||||
<SidebarItem icon={HomeIcon} to="/graphiql" text="Home" />
|
||||
</Sidebar>
|
||||
<AppComponent />
|
||||
</SidebarPage>
|
||||
</BrowserRouter>
|
||||
</CssBaseline>
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById('root'));
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"name": "@backstage/plugin-graphiql",
|
||||
"description": "Backstage plugin for browsing GraphQL APIs",
|
||||
"version": "0.1.1-alpha.4",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"homepage": "https://github.com/spotify/backstage/tree/master/plugins/graphiql#readme",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spotify/backstage",
|
||||
"directory": "plugins/graphiql"
|
||||
},
|
||||
"keywords": [
|
||||
"backstage"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
"build": "backstage-cli plugin:build",
|
||||
"start": "backstage-cli plugin:serve",
|
||||
"lint": "backstage-cli lint",
|
||||
"test": "backstage-cli test",
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.1.1-alpha.4",
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.3.2",
|
||||
"@testing-library/user-event": "^7.1.2",
|
||||
"@types/jest": "^24.0.0",
|
||||
"@types/node": "^12.0.0",
|
||||
"@types/testing-library__jest-dom": "5.0.2",
|
||||
"jest-fetch-mock": "^3.0.3",
|
||||
"react-router-dom": "^5.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/core": "^0.1.1-alpha.4",
|
||||
"@backstage/test-utils": "^0.1.1-alpha.4",
|
||||
"@backstage/theme": "^0.1.1-alpha.4",
|
||||
"@material-ui/core": "^4.9.1",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.45",
|
||||
"graphiql": "^1.0.0-alpha.8",
|
||||
"graphql": "15.0.0",
|
||||
"react": "16.13.1",
|
||||
"react-dom": "16.13.1",
|
||||
"react-use": "^13.0.0"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { GraphiQLBrowser } from './GraphiQLBrowser';
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
|
||||
jest.mock('graphiql', () => () => '<GraphiQL />');
|
||||
|
||||
describe('GraphiQLBrowser', () => {
|
||||
it('should render error text if there are no endpoints', () => {
|
||||
const rendered = render(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<GraphiQLBrowser endpoints={[]} />
|
||||
</ThemeProvider>,
|
||||
);
|
||||
rendered.getByText('No endpoints available');
|
||||
});
|
||||
|
||||
it('should render endpoint tabs', () => {
|
||||
const rendered = render(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<GraphiQLBrowser
|
||||
endpoints={[
|
||||
{
|
||||
id: 'a',
|
||||
title: 'Endpoint A',
|
||||
async fetcher() {},
|
||||
},
|
||||
{
|
||||
id: 'b',
|
||||
title: 'Endpoint B',
|
||||
async fetcher() {},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</ThemeProvider>,
|
||||
);
|
||||
rendered.getByText('Endpoint A');
|
||||
rendered.getByText('Endpoint B');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { FC, useState } from 'react';
|
||||
import { Tabs, Tab, makeStyles, Typography, Divider } from '@material-ui/core';
|
||||
import 'graphiql/graphiql.css';
|
||||
import GraphiQL from 'graphiql';
|
||||
import { StorageBucket } from 'lib/storage';
|
||||
import { GraphQLEndpoint } from 'lib/api';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
|
||||
const useStyles = makeStyles<BackstageTheme>(theme => ({
|
||||
root: {
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexFlow: 'column nowrap',
|
||||
},
|
||||
tabs: {
|
||||
background: theme.palette.background.paper,
|
||||
},
|
||||
graphiQlWrapper: {
|
||||
flex: 1,
|
||||
'@global': {
|
||||
'.graphiql-container': {
|
||||
boxSizing: 'initial',
|
||||
},
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
type GraphiQLBrowserProps = {
|
||||
endpoints: GraphQLEndpoint[];
|
||||
};
|
||||
|
||||
export const GraphiQLBrowser: FC<GraphiQLBrowserProps> = ({ endpoints }) => {
|
||||
const classes = useStyles();
|
||||
const [tabIndex, setTabIndex] = useState(0);
|
||||
|
||||
if (!endpoints.length) {
|
||||
return <Typography variant="h4">No endpoints available</Typography>;
|
||||
}
|
||||
|
||||
const { id, fetcher } = endpoints[tabIndex];
|
||||
const storage = StorageBucket.forLocalStorage(`plugin/graphiql/data/${id}`);
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<Tabs
|
||||
classes={{ root: classes.tabs }}
|
||||
value={tabIndex}
|
||||
onChange={(_, value) => setTabIndex(value)}
|
||||
indicatorColor="primary"
|
||||
>
|
||||
{endpoints.map(({ title }, index) => (
|
||||
<Tab key={index} label={title} value={index} />
|
||||
))}
|
||||
</Tabs>
|
||||
<Divider />
|
||||
<div className={classes.graphiQlWrapper}>
|
||||
<GraphiQL key={tabIndex} fetcher={fetcher} storage={storage} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './GraphiQLBrowser';
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { GraphiQLPage } from './GraphiQLPage';
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
import { ApiProvider, ApiRegistry } from '@backstage/core';
|
||||
import { renderWithEffects } from '@backstage/test-utils';
|
||||
import { GraphQLBrowseApi, graphQlBrowseApiRef } from 'lib/api';
|
||||
|
||||
jest.mock('components/GraphiQLBrowser', () => ({
|
||||
GraphiQLBrowser: () => '<GraphiQLBrowser />',
|
||||
}));
|
||||
|
||||
describe('GraphiQLPage', () => {
|
||||
it('should show progress', async () => {
|
||||
const loadingApi: GraphQLBrowseApi = {
|
||||
async getEndpoints() {
|
||||
await new Promise(() => {});
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
||||
const rendered = await renderWithEffects(
|
||||
<ApiProvider apis={ApiRegistry.from([[graphQlBrowseApiRef, loadingApi]])}>
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<GraphiQLPage />
|
||||
</ThemeProvider>
|
||||
,
|
||||
</ApiProvider>,
|
||||
);
|
||||
|
||||
rendered.getByText('GraphiQL');
|
||||
rendered.getByTestId('progress');
|
||||
});
|
||||
|
||||
it('should show error', async () => {
|
||||
const loadingApi: GraphQLBrowseApi = {
|
||||
async getEndpoints() {
|
||||
throw new Error('NOPE');
|
||||
},
|
||||
};
|
||||
|
||||
const rendered = await renderWithEffects(
|
||||
<ApiProvider apis={ApiRegistry.from([[graphQlBrowseApiRef, loadingApi]])}>
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<GraphiQLPage />
|
||||
</ThemeProvider>
|
||||
</ApiProvider>,
|
||||
);
|
||||
|
||||
rendered.getByText('GraphiQL');
|
||||
rendered.getByText('Failed to load GraphQL endpoints, Error: NOPE');
|
||||
});
|
||||
|
||||
it('should show GraphiQLBrowser', async () => {
|
||||
const loadingApi: GraphQLBrowseApi = {
|
||||
async getEndpoints() {
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
||||
const rendered = await renderWithEffects(
|
||||
<ApiProvider apis={ApiRegistry.from([[graphQlBrowseApiRef, loadingApi]])}>
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<GraphiQLPage />
|
||||
</ThemeProvider>
|
||||
</ApiProvider>,
|
||||
);
|
||||
|
||||
rendered.getByText('GraphiQL');
|
||||
rendered.getByText('<GraphiQLBrowser />');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { FC } from 'react';
|
||||
import {
|
||||
Content,
|
||||
Header,
|
||||
HeaderLabel,
|
||||
Page,
|
||||
Progress,
|
||||
pageTheme,
|
||||
useApi,
|
||||
} from '@backstage/core';
|
||||
import { useAsync } from 'react-use';
|
||||
import 'graphiql/graphiql.css';
|
||||
import { graphQlBrowseApiRef } from 'lib/api';
|
||||
import { GraphiQLBrowser } from 'components';
|
||||
import { Typography } from '@material-ui/core';
|
||||
|
||||
export const GraphiQLPage: FC<{}> = () => {
|
||||
const graphQlBrowseApi = useApi(graphQlBrowseApiRef);
|
||||
const endpoints = useAsync(() => graphQlBrowseApi.getEndpoints());
|
||||
|
||||
let content: JSX.Element;
|
||||
|
||||
if (endpoints.loading) {
|
||||
content = (
|
||||
<Content>
|
||||
<Progress />
|
||||
</Content>
|
||||
);
|
||||
} else if (endpoints.error) {
|
||||
content = (
|
||||
<Content>
|
||||
<Typography variant="h4" color="error">
|
||||
{/* TODO: provide a proper error component */}
|
||||
Failed to load GraphQL endpoints, {String(endpoints.error)}
|
||||
</Typography>
|
||||
</Content>
|
||||
);
|
||||
} else {
|
||||
content = (
|
||||
<Content noPadding>
|
||||
<GraphiQLBrowser endpoints={endpoints.value!} />
|
||||
</Content>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Page theme={pageTheme.tool}>
|
||||
<Header title="GraphiQL">
|
||||
<HeaderLabel label="Owner" value="Spotify" />
|
||||
<HeaderLabel label="Lifecycle" value="Alpha" />
|
||||
</Header>
|
||||
{content}
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './GraphiQLPage';
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './GraphiQLPage';
|
||||
export * from './GraphiQLBrowser';
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { plugin } from './plugin';
|
||||
export * from './lib/api';
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { GraphQLBrowseApi, GraphQLEndpoint } from './types';
|
||||
|
||||
// Helper for generic http endpoints
|
||||
export type EndpointConfig = {
|
||||
id: string;
|
||||
title: string;
|
||||
// Endpoint URL
|
||||
url: string;
|
||||
// only supports POST right now
|
||||
method?: 'POST';
|
||||
// Defaults to setting Content-Type to application/json
|
||||
headers?: { [name in string]: string };
|
||||
};
|
||||
|
||||
export class GraphQLEndpoints implements GraphQLBrowseApi {
|
||||
// Create a support
|
||||
static create(config: EndpointConfig): GraphQLEndpoint {
|
||||
const { id, title, url, method = 'POST' } = config;
|
||||
return {
|
||||
id,
|
||||
title,
|
||||
fetcher: async (params: any) => {
|
||||
const body = JSON.stringify(params);
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
...config.headers,
|
||||
};
|
||||
const res = await fetch(url, {
|
||||
method,
|
||||
headers,
|
||||
body,
|
||||
});
|
||||
return res.json();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static from(endpoints: GraphQLEndpoint[]) {
|
||||
return new GraphQLEndpoints(endpoints);
|
||||
}
|
||||
|
||||
private constructor(private readonly endpoints: GraphQLEndpoint[]) {}
|
||||
|
||||
async getEndpoints() {
|
||||
return this.endpoints;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './GraphQLEndpoints';
|
||||
export * from './types';
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ApiRef } from '@backstage/core';
|
||||
|
||||
export type GraphQLEndpoint = {
|
||||
// Will be used as unique key for storing history and query data
|
||||
id: string;
|
||||
|
||||
// Displayed to the user to identify the source.
|
||||
title: string;
|
||||
|
||||
// Method used send a GraphQL query.
|
||||
// The body parameter is equivalent to the POST body to be JSON-serialized, and the
|
||||
// return value should be the equivalent of a parsed JSON response from that POST.
|
||||
fetcher: (body: any) => Promise<any>;
|
||||
};
|
||||
|
||||
export type GraphQLBrowseApi = {
|
||||
getEndpoints(): Promise<GraphQLEndpoint[]>;
|
||||
};
|
||||
|
||||
export const graphQlBrowseApiRef = new ApiRef<GraphQLBrowseApi>({
|
||||
id: 'plugin.graphiql.browse',
|
||||
description: 'Used to supply GraphQL endpoints for browsing',
|
||||
});
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { StorageBucket } from './StorageBucket';
|
||||
|
||||
describe('StorageBucket', () => {
|
||||
it('should forbid access to unknown keys', () => {
|
||||
const bucket = StorageBucket.forStorage(localStorage, 'hello');
|
||||
|
||||
expect(() => {
|
||||
bucket['dunno-this-one'] = 'nope';
|
||||
}).toThrow('Direct property access is not allowed for StorageBuckets');
|
||||
expect(() => {
|
||||
return bucket['dunno-this-one'];
|
||||
}).toThrow('Direct property access is not allowed for StorageBuckets');
|
||||
});
|
||||
|
||||
it('should not implement all methods', () => {
|
||||
const bucket = StorageBucket.forLocalStorage('hello');
|
||||
|
||||
expect(() => bucket.length).toThrow('Method not implemented.');
|
||||
expect(() => bucket.key()).toThrow('Method not implemented.');
|
||||
});
|
||||
|
||||
describe('with mocked underlying storage', () => {
|
||||
const mockStorage = {
|
||||
getItem: jest.fn(),
|
||||
setItem: jest.fn(),
|
||||
removeItem: jest.fn(),
|
||||
};
|
||||
const bucket = StorageBucket.forStorage(
|
||||
(mockStorage as unknown) as Storage,
|
||||
'my-bucket',
|
||||
);
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it('should set a first item', () => {
|
||||
bucket.setItem('x', 'a');
|
||||
|
||||
expect(mockStorage.getItem).toHaveBeenCalledTimes(1);
|
||||
expect(mockStorage.getItem).toHaveBeenLastCalledWith('my-bucket');
|
||||
expect(mockStorage.setItem).toHaveBeenCalledTimes(1);
|
||||
expect(mockStorage.setItem).toHaveBeenLastCalledWith(
|
||||
'my-bucket',
|
||||
JSON.stringify({ x: 'a' }),
|
||||
);
|
||||
expect(mockStorage.removeItem).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('should set a second item', () => {
|
||||
mockStorage.getItem.mockReturnValueOnce(JSON.stringify({ y: 'b' }));
|
||||
bucket.setItem('x', 'a');
|
||||
|
||||
expect(mockStorage.getItem).toHaveBeenCalledTimes(1);
|
||||
expect(mockStorage.getItem).toHaveBeenLastCalledWith('my-bucket');
|
||||
expect(mockStorage.setItem).toHaveBeenCalledTimes(1);
|
||||
expect(mockStorage.setItem).toHaveBeenLastCalledWith(
|
||||
'my-bucket',
|
||||
JSON.stringify({ y: 'b', x: 'a' }),
|
||||
);
|
||||
expect(mockStorage.removeItem).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('should clear the bucket', () => {
|
||||
bucket.clear();
|
||||
|
||||
expect(mockStorage.getItem).toHaveBeenCalledTimes(0);
|
||||
expect(mockStorage.setItem).toHaveBeenCalledTimes(0);
|
||||
expect(mockStorage.removeItem).toHaveBeenCalledTimes(1);
|
||||
expect(mockStorage.removeItem).toHaveBeenLastCalledWith('my-bucket');
|
||||
});
|
||||
|
||||
it('should get an item', () => {
|
||||
mockStorage.getItem.mockReturnValueOnce(JSON.stringify({ x: 'X' }));
|
||||
expect(bucket.getItem('x')).toBe('X');
|
||||
|
||||
expect(mockStorage.getItem).toHaveBeenCalledTimes(1);
|
||||
expect(mockStorage.getItem).toHaveBeenLastCalledWith('my-bucket');
|
||||
expect(mockStorage.setItem).toHaveBeenCalledTimes(0);
|
||||
expect(mockStorage.removeItem).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('should remove an item', () => {
|
||||
mockStorage.getItem.mockReturnValueOnce(
|
||||
JSON.stringify({ x: 'X', y: 'Y' }),
|
||||
);
|
||||
bucket.removeItem('x');
|
||||
|
||||
expect(mockStorage.getItem).toHaveBeenCalledTimes(1);
|
||||
expect(mockStorage.getItem).toHaveBeenLastCalledWith('my-bucket');
|
||||
expect(mockStorage.setItem).toHaveBeenCalledTimes(1);
|
||||
expect(mockStorage.setItem).toHaveBeenLastCalledWith(
|
||||
'my-bucket',
|
||||
JSON.stringify({ y: 'Y' }),
|
||||
);
|
||||
expect(mockStorage.removeItem).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('should not bother to write when deleting a missing key', () => {
|
||||
mockStorage.getItem.mockReturnValueOnce(JSON.stringify({ y: 'Y' }));
|
||||
bucket.removeItem('x');
|
||||
|
||||
expect(mockStorage.getItem).toHaveBeenCalledTimes(1);
|
||||
expect(mockStorage.getItem).toHaveBeenLastCalledWith('my-bucket');
|
||||
expect(mockStorage.setItem).toHaveBeenCalledTimes(0);
|
||||
expect(mockStorage.removeItem).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('should ignore bad data', () => {
|
||||
mockStorage.getItem.mockReturnValue('derp');
|
||||
|
||||
expect(bucket.getItem('x')).toBe(null);
|
||||
|
||||
expect(mockStorage.getItem).toHaveBeenCalledTimes(1);
|
||||
expect(mockStorage.getItem).toHaveBeenLastCalledWith('my-bucket');
|
||||
expect(mockStorage.setItem).toHaveBeenCalledTimes(0);
|
||||
expect(mockStorage.removeItem).toHaveBeenCalledTimes(0);
|
||||
|
||||
bucket.removeItem('x');
|
||||
|
||||
expect(mockStorage.getItem).toHaveBeenCalledTimes(2);
|
||||
expect(mockStorage.getItem).toHaveBeenLastCalledWith('my-bucket');
|
||||
expect(mockStorage.setItem).toHaveBeenCalledTimes(0);
|
||||
expect(mockStorage.removeItem).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
type BucketData = { [key in string]: string };
|
||||
|
||||
export class StorageBucket implements Storage {
|
||||
private static noPropAccessProxyHandler: ProxyHandler<StorageBucket> = {
|
||||
get(target, prop) {
|
||||
if (prop in target) {
|
||||
return target[prop as any];
|
||||
}
|
||||
throw new Error(
|
||||
'Direct property access is not allowed for StorageBuckets',
|
||||
);
|
||||
},
|
||||
set() {
|
||||
throw new Error(
|
||||
'Direct property access is not allowed for StorageBuckets',
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
static forStorage(storage: Storage, bucket: string) {
|
||||
const storageBucket = new StorageBucket(storage, bucket);
|
||||
return new Proxy(storageBucket, StorageBucket.noPropAccessProxyHandler);
|
||||
}
|
||||
|
||||
static forLocalStorage(bucket: string): StorageBucket {
|
||||
return StorageBucket.forStorage(localStorage, bucket);
|
||||
}
|
||||
|
||||
private constructor(
|
||||
private readonly storage: Storage,
|
||||
private readonly bucket: string,
|
||||
) {}
|
||||
|
||||
[name: string]: any;
|
||||
|
||||
get length(): number {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
this.storage.removeItem(this.bucket);
|
||||
}
|
||||
|
||||
getItem(key: string): string | null {
|
||||
return this.read()?.[key] ?? null;
|
||||
}
|
||||
|
||||
key(): never {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
removeItem(key: string): void {
|
||||
const data = this.read();
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (key in data) {
|
||||
delete data[key];
|
||||
this.write(data);
|
||||
}
|
||||
}
|
||||
|
||||
setItem(key: string, value: string): void {
|
||||
const data = this.read() ?? {};
|
||||
data[key] = value;
|
||||
this.write(data);
|
||||
}
|
||||
|
||||
private read(): BucketData | undefined {
|
||||
const bucketValue = this.storage.getItem(this.bucket);
|
||||
if (!bucketValue) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(bucketValue);
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private write(data: BucketData) {
|
||||
this.storage.setItem(this.bucket, JSON.stringify(data));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './StorageBucket';
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { plugin } from './plugin';
|
||||
|
||||
describe('graphiql', () => {
|
||||
it('should export plugin', () => {
|
||||
expect(plugin).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createPlugin } from '@backstage/core';
|
||||
import { GraphiQLPage } from './components';
|
||||
|
||||
export const plugin = createPlugin({
|
||||
id: 'graphiql',
|
||||
register({ router }) {
|
||||
router.registerRoute('/graphiql', GraphiQLPage);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import '@testing-library/jest-dom/extend-expect';
|
||||
require('jest-fetch-mock').enableMocks();
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["src", "dev"],
|
||||
"compilerOptions": {
|
||||
"baseUrl": "src"
|
||||
}
|
||||
}
|
||||
@@ -1166,7 +1166,7 @@
|
||||
"@emotion/utils" "0.11.3"
|
||||
"@emotion/weak-memoize" "0.2.5"
|
||||
|
||||
"@emotion/core@^10.0.20":
|
||||
"@emotion/core@^10.0.0", "@emotion/core@^10.0.20", "@emotion/core@^10.0.28":
|
||||
version "10.0.28"
|
||||
resolved "https://registry.npmjs.org/@emotion/core/-/core-10.0.28.tgz#bb65af7262a234593a9e952c041d0f1c9b9bef3d"
|
||||
integrity sha512-pH8UueKYO5jgg0Iq+AmCLxBsvuGtvlmiDCOuv8fGNYn3cowFpLN98L8zO56U0H1PjDIyAlXymgL3Wu7u7v6hbA==
|
||||
@@ -1192,14 +1192,14 @@
|
||||
resolved "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413"
|
||||
integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==
|
||||
|
||||
"@emotion/is-prop-valid@0.8.8":
|
||||
"@emotion/is-prop-valid@0.8.8", "@emotion/is-prop-valid@^0.8.1":
|
||||
version "0.8.8"
|
||||
resolved "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"
|
||||
integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
|
||||
dependencies:
|
||||
"@emotion/memoize" "0.7.4"
|
||||
|
||||
"@emotion/memoize@0.7.4":
|
||||
"@emotion/memoize@0.7.4", "@emotion/memoize@^0.7.1":
|
||||
version "0.7.4"
|
||||
resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
|
||||
integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
|
||||
@@ -1230,7 +1230,7 @@
|
||||
"@emotion/serialize" "^0.11.15"
|
||||
"@emotion/utils" "0.11.3"
|
||||
|
||||
"@emotion/styled@^10.0.17":
|
||||
"@emotion/styled@^10.0.0", "@emotion/styled@^10.0.17":
|
||||
version "10.0.27"
|
||||
resolved "https://registry.npmjs.org/@emotion/styled/-/styled-10.0.27.tgz#12cb67e91f7ad7431e1875b1d83a94b814133eaf"
|
||||
integrity sha512-iK/8Sh7+NLJzyp9a5+vIQIXTYxfT4yB/OJbjzQanB2RZpvmzBQOHZWhpAMZWYEKRNNbsD6WfBw5sVWkb6WzS/Q==
|
||||
@@ -2491,6 +2491,11 @@
|
||||
prop-types "^15.7.2"
|
||||
react-is "^16.8.0"
|
||||
|
||||
"@mdx-js/react@^1.0.0", "@mdx-js/react@^1.5.2":
|
||||
version "1.5.9"
|
||||
resolved "https://registry.npmjs.org/@mdx-js/react/-/react-1.5.9.tgz#31873ab097fbe58c61c7585fc0be64e83182b6df"
|
||||
integrity sha512-rengdUSedIdIQbXPSeafItCacTYocARAjUA51b6R1KNHmz+59efz7UmyTKr73viJQZ98ouu7iRGmOTtjRrbbWA==
|
||||
|
||||
"@mrmlnc/readdir-enhanced@^2.2.1":
|
||||
version "2.2.1"
|
||||
resolved "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
|
||||
@@ -3401,6 +3406,105 @@
|
||||
telejson "^3.2.0"
|
||||
util-deprecate "^1.0.2"
|
||||
|
||||
"@styled-system/background@^5.1.2":
|
||||
version "5.1.2"
|
||||
resolved "https://registry.npmjs.org/@styled-system/background/-/background-5.1.2.tgz#75c63d06b497ab372b70186c0bf608d62847a2ba"
|
||||
integrity sha512-jtwH2C/U6ssuGSvwTN3ri/IyjdHb8W9X/g8Y0JLcrH02G+BW3OS8kZdHphF1/YyRklnrKrBT2ngwGUK6aqqV3A==
|
||||
dependencies:
|
||||
"@styled-system/core" "^5.1.2"
|
||||
|
||||
"@styled-system/border@^5.1.5":
|
||||
version "5.1.5"
|
||||
resolved "https://registry.npmjs.org/@styled-system/border/-/border-5.1.5.tgz#0493d4332d2b59b74bb0d57d08c73eb555761ba6"
|
||||
integrity sha512-JvddhNrnhGigtzWRCVuAHepniyVi6hBlimxWDVAdcTuk7aRn9BYJUwfHslURtwYFsF5FoEs8Zmr1oZq2M1AP0A==
|
||||
dependencies:
|
||||
"@styled-system/core" "^5.1.2"
|
||||
|
||||
"@styled-system/color@^5.1.2":
|
||||
version "5.1.2"
|
||||
resolved "https://registry.npmjs.org/@styled-system/color/-/color-5.1.2.tgz#b8d6b4af481faabe4abca1a60f8daa4ccc2d9f43"
|
||||
integrity sha512-1kCkeKDZkt4GYkuFNKc7vJQMcOmTl3bJY3YBUs7fCNM6mMYJeT1pViQ2LwBSBJytj3AB0o4IdLBoepgSgGl5MA==
|
||||
dependencies:
|
||||
"@styled-system/core" "^5.1.2"
|
||||
|
||||
"@styled-system/core@^5.1.2":
|
||||
version "5.1.2"
|
||||
resolved "https://registry.npmjs.org/@styled-system/core/-/core-5.1.2.tgz#b8b7b86455d5a0514f071c4fa8e434b987f6a772"
|
||||
integrity sha512-XclBDdNIy7OPOsN4HBsawG2eiWfCcuFt6gxKn1x4QfMIgeO6TOlA2pZZ5GWZtIhCUqEPTgIBta6JXsGyCkLBYw==
|
||||
dependencies:
|
||||
object-assign "^4.1.1"
|
||||
|
||||
"@styled-system/css@^5.1.5":
|
||||
version "5.1.5"
|
||||
resolved "https://registry.npmjs.org/@styled-system/css/-/css-5.1.5.tgz#0460d5f3ff962fa649ea128ef58d9584f403bbbc"
|
||||
integrity sha512-XkORZdS5kypzcBotAMPBoeckDs9aSZVkvrAlq5K3xP8IMAUek+x2O4NtwoSgkYkWWzVBu6DGdFZLR790QWGG+A==
|
||||
|
||||
"@styled-system/flexbox@^5.1.2":
|
||||
version "5.1.2"
|
||||
resolved "https://registry.npmjs.org/@styled-system/flexbox/-/flexbox-5.1.2.tgz#077090f43f61c3852df63da24e4108087a8beecf"
|
||||
integrity sha512-6hHV52+eUk654Y1J2v77B8iLeBNtc+SA3R4necsu2VVinSD7+XY5PCCEzBFaWs42dtOEDIa2lMrgL0YBC01mDQ==
|
||||
dependencies:
|
||||
"@styled-system/core" "^5.1.2"
|
||||
|
||||
"@styled-system/grid@^5.1.2":
|
||||
version "5.1.2"
|
||||
resolved "https://registry.npmjs.org/@styled-system/grid/-/grid-5.1.2.tgz#7165049877732900b99cd00759679fbe45c6c573"
|
||||
integrity sha512-K3YiV1KyHHzgdNuNlaw8oW2ktMuGga99o1e/NAfTEi5Zsa7JXxzwEnVSDSBdJC+z6R8WYTCYRQC6bkVFcvdTeg==
|
||||
dependencies:
|
||||
"@styled-system/core" "^5.1.2"
|
||||
|
||||
"@styled-system/layout@^5.1.2":
|
||||
version "5.1.2"
|
||||
resolved "https://registry.npmjs.org/@styled-system/layout/-/layout-5.1.2.tgz#12d73e79887e10062f4dbbbc2067462eace42339"
|
||||
integrity sha512-wUhkMBqSeacPFhoE9S6UF3fsMEKFv91gF4AdDWp0Aym1yeMPpqz9l9qS/6vjSsDPF7zOb5cOKC3tcKKOMuDCPw==
|
||||
dependencies:
|
||||
"@styled-system/core" "^5.1.2"
|
||||
|
||||
"@styled-system/position@^5.1.2":
|
||||
version "5.1.2"
|
||||
resolved "https://registry.npmjs.org/@styled-system/position/-/position-5.1.2.tgz#56961266566836f57a24d8e8e33ce0c1adb59dd3"
|
||||
integrity sha512-60IZfMXEOOZe3l1mCu6sj/2NAyUmES2kR9Kzp7s2D3P4qKsZWxD1Se1+wJvevb+1TP+ZMkGPEYYXRyU8M1aF5A==
|
||||
dependencies:
|
||||
"@styled-system/core" "^5.1.2"
|
||||
|
||||
"@styled-system/shadow@^5.1.2":
|
||||
version "5.1.2"
|
||||
resolved "https://registry.npmjs.org/@styled-system/shadow/-/shadow-5.1.2.tgz#beddab28d7de03cd0177a87ac4ed3b3b6d9831fd"
|
||||
integrity sha512-wqniqYb7XuZM7K7C0d1Euxc4eGtqEe/lvM0WjuAFsQVImiq6KGT7s7is+0bNI8O4Dwg27jyu4Lfqo/oIQXNzAg==
|
||||
dependencies:
|
||||
"@styled-system/core" "^5.1.2"
|
||||
|
||||
"@styled-system/should-forward-prop@^5.1.2":
|
||||
version "5.1.5"
|
||||
resolved "https://registry.npmjs.org/@styled-system/should-forward-prop/-/should-forward-prop-5.1.5.tgz#c392008c6ae14a6eb78bf1932733594f7f7e5c76"
|
||||
integrity sha512-+rPRomgCGYnUIaFabDoOgpSDc4UUJ1KsmlnzcEp0tu5lFrBQKgZclSo18Z1URhaZm7a6agGtS5Xif7tuC2s52Q==
|
||||
dependencies:
|
||||
"@emotion/is-prop-valid" "^0.8.1"
|
||||
"@emotion/memoize" "^0.7.1"
|
||||
styled-system "^5.1.5"
|
||||
|
||||
"@styled-system/space@^5.1.2":
|
||||
version "5.1.2"
|
||||
resolved "https://registry.npmjs.org/@styled-system/space/-/space-5.1.2.tgz#38925d2fa29a41c0eb20e65b7c3efb6e8efce953"
|
||||
integrity sha512-+zzYpR8uvfhcAbaPXhH8QgDAV//flxqxSjHiS9cDFQQUSznXMQmxJegbhcdEF7/eNnJgHeIXv1jmny78kipgBA==
|
||||
dependencies:
|
||||
"@styled-system/core" "^5.1.2"
|
||||
|
||||
"@styled-system/typography@^5.1.2":
|
||||
version "5.1.2"
|
||||
resolved "https://registry.npmjs.org/@styled-system/typography/-/typography-5.1.2.tgz#65fb791c67d50cd2900d234583eaacdca8c134f7"
|
||||
integrity sha512-BxbVUnN8N7hJ4aaPOd7wEsudeT7CxarR+2hns8XCX1zp0DFfbWw4xYa/olA0oQaqx7F1hzDg+eRaGzAJbF+jOg==
|
||||
dependencies:
|
||||
"@styled-system/core" "^5.1.2"
|
||||
|
||||
"@styled-system/variant@^5.1.5":
|
||||
version "5.1.5"
|
||||
resolved "https://registry.npmjs.org/@styled-system/variant/-/variant-5.1.5.tgz#8446d8aad06af3a4c723d717841df2dbe4ddeafd"
|
||||
integrity sha512-Yn8hXAFoWIro8+Q5J8YJd/mP85Teiut3fsGVR9CAxwgNfIAiqlYxsk5iHU7VHJks/0KjL4ATSjmbtCDC/4l1qw==
|
||||
dependencies:
|
||||
"@styled-system/core" "^5.1.2"
|
||||
"@styled-system/css" "^5.1.5"
|
||||
|
||||
"@svgr/babel-plugin-add-jsx-attribute@^4.2.0":
|
||||
version "4.2.0"
|
||||
resolved "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz#dadcb6218503532d6884b210e7f3c502caaa44b1"
|
||||
@@ -3566,6 +3670,61 @@
|
||||
resolved "https://registry.npmjs.org/@testing-library/user-event/-/user-event-7.2.1.tgz#2ad4e844175a3738cb9e7064be5ea070b8863a1c"
|
||||
integrity sha512-oZ0Ib5I4Z2pUEcoo95cT1cr6slco9WY7yiPpG+RGNkj8YcYgJnM7pXmYmorNOReh8MIGcKSqXyeGjxnr8YiZbA==
|
||||
|
||||
"@theme-ui/color-modes@^0.3.1":
|
||||
version "0.3.1"
|
||||
resolved "https://registry.npmjs.org/@theme-ui/color-modes/-/color-modes-0.3.1.tgz#8c2b18fb170e6c998287b7381240a8b9cca8b0d1"
|
||||
integrity sha512-WuZGgFW7M5wOWSse1PVZCEfM0OZip15/D6U3bB3B9KmWax7qiSnAm1yAMLRQKC+QYhndrjq3xU+WAQm11KnhIw==
|
||||
dependencies:
|
||||
"@emotion/core" "^10.0.0"
|
||||
"@theme-ui/core" "^0.3.1"
|
||||
"@theme-ui/css" "^0.3.1"
|
||||
deepmerge "^4.2.2"
|
||||
|
||||
"@theme-ui/components@^0.3.1":
|
||||
version "0.3.1"
|
||||
resolved "https://registry.npmjs.org/@theme-ui/components/-/components-0.3.1.tgz#fe023e156c1e1c076d5f2258466426e94adc2765"
|
||||
integrity sha512-uG4dUM61s4tWv6N34uxs5VIh24bJyA/7TrYJ75WDiI+s72zbcNG7aGRpvX/hSZnAhxjdXpuskdEM3eEgOabdEg==
|
||||
dependencies:
|
||||
"@emotion/core" "^10.0.0"
|
||||
"@emotion/styled" "^10.0.0"
|
||||
"@styled-system/color" "^5.1.2"
|
||||
"@styled-system/should-forward-prop" "^5.1.2"
|
||||
"@styled-system/space" "^5.1.2"
|
||||
"@theme-ui/css" "^0.3.1"
|
||||
|
||||
"@theme-ui/core@^0.3.1":
|
||||
version "0.3.1"
|
||||
resolved "https://registry.npmjs.org/@theme-ui/core/-/core-0.3.1.tgz#dbe9800b9d6e923e1a7417e6adebce21524f8c02"
|
||||
integrity sha512-cK6EVSOx0Kyx1Xpi4qb0JTLIxywx0DRh+53Ln1foXMplF2qKaDsFi3vD6duHIlT331E3CNOa9dftHHNM7y4rbA==
|
||||
dependencies:
|
||||
"@emotion/core" "^10.0.0"
|
||||
"@theme-ui/css" "^0.3.1"
|
||||
deepmerge "^4.2.2"
|
||||
|
||||
"@theme-ui/css@^0.3.1":
|
||||
version "0.3.1"
|
||||
resolved "https://registry.npmjs.org/@theme-ui/css/-/css-0.3.1.tgz#b85c7e8fae948dc0de65aa30b853368993e25cb3"
|
||||
integrity sha512-QB2/fZBpo4inaLHL3OrB8NOBgNfwnj8GtHzXWHb9iQSRjmtNX8zPXBe32jLT7qQP0+y8JxPT4YChZIkm5ZyIdg==
|
||||
|
||||
"@theme-ui/mdx@^0.3.0":
|
||||
version "0.3.0"
|
||||
resolved "https://registry.npmjs.org/@theme-ui/mdx/-/mdx-0.3.0.tgz#8bb1342204acfaa69914d6b6567c5c49d9a8c1e6"
|
||||
integrity sha512-/GHBNKqmUptWwkmF+zIASVQtjYs81XMEwtqPCHnHuaaCzhZxcXrtCwvcAgmCXF8hpRttCXVVxw1X3Gt0mhzaTQ==
|
||||
dependencies:
|
||||
"@emotion/core" "^10.0.0"
|
||||
"@emotion/styled" "^10.0.0"
|
||||
"@mdx-js/react" "^1.0.0"
|
||||
|
||||
"@theme-ui/theme-provider@^0.3.1":
|
||||
version "0.3.1"
|
||||
resolved "https://registry.npmjs.org/@theme-ui/theme-provider/-/theme-provider-0.3.1.tgz#910bc43454fd61b1047d7bb0dce05e36ffb6b44b"
|
||||
integrity sha512-Sjj6lD0gPxBi+hcGCkawcGZECeESV/mW2YfmPqjNgmc296x5tulfNc+0/N5CJwLVOmnkn8zR5KNWZ8BjndfeTg==
|
||||
dependencies:
|
||||
"@emotion/core" "^10.0.0"
|
||||
"@theme-ui/color-modes" "^0.3.1"
|
||||
"@theme-ui/core" "^0.3.1"
|
||||
"@theme-ui/mdx" "^0.3.0"
|
||||
|
||||
"@tootallnate/once@1":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.0.0.tgz#9c13c2574c92d4503b005feca8f2e16cc1611506"
|
||||
@@ -4483,6 +4642,11 @@
|
||||
resolved "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.4.tgz#a7dce20b7465bcad29cd6bbb557695e4ea7863cb"
|
||||
integrity sha512-o12FCQt/X5n3pgKEWGpt0f/7Eg4mfv3uRwPUrctiOT8ZuxbH3cNLGWfH/8y6KxVJg4L2885ucuXQ6XECZzUiJA==
|
||||
|
||||
"@xobotyi/scrollbar-width@1.9.5":
|
||||
version "1.9.5"
|
||||
resolved "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz#80224a6919272f405b87913ca13b92929bdf3c4d"
|
||||
integrity sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==
|
||||
|
||||
"@xtuc/ieee754@^1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
|
||||
@@ -6473,6 +6637,19 @@ code-point-at@^1.0.0:
|
||||
resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
||||
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
|
||||
|
||||
codemirror-graphql@^0.12.0-alpha.7:
|
||||
version "0.12.0-alpha.7"
|
||||
resolved "https://registry.npmjs.org/codemirror-graphql/-/codemirror-graphql-0.12.0-alpha.7.tgz#fb8a8e633f5e416a9736df2fa697312a0955db20"
|
||||
integrity sha512-LOsHnAc/pWOqqUEfQX5tNn10jStqIe8il6/vHq7m81uyGcp7tx5Np3O7zwGKQ/HdewDUMjeqXnva5tFGYaKzVg==
|
||||
dependencies:
|
||||
graphql-language-service-interface "^2.4.0-alpha.7"
|
||||
graphql-language-service-parser "^1.6.0-alpha.3"
|
||||
|
||||
codemirror@^5.52.2:
|
||||
version "5.53.2"
|
||||
resolved "https://registry.npmjs.org/codemirror/-/codemirror-5.53.2.tgz#9799121cf8c50809cca487304e9de3a74d33f428"
|
||||
integrity sha512-wvSQKS4E+P8Fxn/AQ+tQtJnF1qH5UOlxtugFLpubEZ5jcdH2iXTVinb+Xc/4QjshuOxRm4fUsU2QPF1JJKiyXA==
|
||||
|
||||
collapse-white-space@^1.0.2:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287"
|
||||
@@ -7618,6 +7795,11 @@ deep-object-diff@^1.1.0:
|
||||
resolved "https://registry.npmjs.org/deep-object-diff/-/deep-object-diff-1.1.0.tgz#d6fabf476c2ed1751fc94d5ca693d2ed8c18bc5a"
|
||||
integrity sha512-b+QLs5vHgS+IoSNcUE4n9HP2NwcHj7aqnJWsjPtuG75Rh5TOaGt0OjAYInh77d5T16V5cRDC+Pw/6ZZZiETBGw==
|
||||
|
||||
deepmerge@^4.2.2:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
|
||||
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
|
||||
|
||||
default-gateway@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b"
|
||||
@@ -8188,7 +8370,7 @@ entities@^1.1.1, entities@^1.1.2:
|
||||
resolved "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
|
||||
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
|
||||
|
||||
entities@^2.0.0:
|
||||
entities@^2.0.0, entities@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4"
|
||||
integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==
|
||||
@@ -9968,6 +10150,55 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3
|
||||
resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423"
|
||||
integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==
|
||||
|
||||
graphiql@^1.0.0-alpha.8:
|
||||
version "1.0.0-alpha.8"
|
||||
resolved "https://registry.npmjs.org/graphiql/-/graphiql-1.0.0-alpha.8.tgz#a9cc594a8666e372c919a5c86a32835bc37499ff"
|
||||
integrity sha512-6cR4NUtR79P2ShXt2P5d4OSIlsqiHzb7fK27LSm4JHIx0uBLYWrlJwHcjjF+Ucujr3fbVn4miyNF+ypvMJp53g==
|
||||
dependencies:
|
||||
"@emotion/core" "^10.0.28"
|
||||
"@mdx-js/react" "^1.5.2"
|
||||
codemirror "^5.52.2"
|
||||
codemirror-graphql "^0.12.0-alpha.7"
|
||||
copy-to-clipboard "^3.2.0"
|
||||
entities "^2.0.0"
|
||||
markdown-it "^10.0.0"
|
||||
regenerator-runtime "^0.13.5"
|
||||
theme-ui "^0.3.1"
|
||||
|
||||
graphql-language-service-interface@^2.4.0-alpha.7:
|
||||
version "2.4.0-alpha.7"
|
||||
resolved "https://registry.npmjs.org/graphql-language-service-interface/-/graphql-language-service-interface-2.4.0-alpha.7.tgz#5458f1f17a79dde5b51dab0d21eda63dff48a918"
|
||||
integrity sha512-X5jwTI4AlcKB/t9/hZBn9O69uG9WPbkFnZivhNfztzeudKV+cXHYR6behsR47bR2nzF3YEu7Nv+3HExXKQAlWg==
|
||||
dependencies:
|
||||
graphql-language-service-parser "^1.6.0-alpha.3"
|
||||
graphql-language-service-types "^1.6.0-alpha.5"
|
||||
graphql-language-service-utils "^2.4.0-alpha.6"
|
||||
vscode-languageserver-types "^3.15.1"
|
||||
|
||||
graphql-language-service-parser@^1.6.0-alpha.3:
|
||||
version "1.6.0-alpha.3"
|
||||
resolved "https://registry.npmjs.org/graphql-language-service-parser/-/graphql-language-service-parser-1.6.0-alpha.3.tgz#671643018fb4b24f409997a05b021030948562fb"
|
||||
integrity sha512-gx2u6b2m9X9DjvlfEjmBQ67GtZxPPWAtVb63BQ21u2MPxqYjKsBJkKLq9PiC2u57bJhv+h4MoL4OLJ/vkmq6Ig==
|
||||
dependencies:
|
||||
graphql-language-service-types "^1.6.0-alpha.5"
|
||||
|
||||
graphql-language-service-types@^1.6.0-alpha.5:
|
||||
version "1.6.0-alpha.5"
|
||||
resolved "https://registry.npmjs.org/graphql-language-service-types/-/graphql-language-service-types-1.6.0-alpha.5.tgz#113a92c7544d98c8a8b8c3e04c9f982d3dbe1a00"
|
||||
integrity sha512-Q/pTif29xM6OiFV9RsYLwX2uDeCMdSG36n4G0aDvfbWxbOBj48vSlLL5R8Gpt/DjocG9Kkv51CZay6pMPtmAfg==
|
||||
|
||||
graphql-language-service-utils@^2.4.0-alpha.6:
|
||||
version "2.4.0-alpha.6"
|
||||
resolved "https://registry.npmjs.org/graphql-language-service-utils/-/graphql-language-service-utils-2.4.0-alpha.6.tgz#5c3b30150e4905517b84b71f84956851c2c883e1"
|
||||
integrity sha512-/+crYcPhOoeu1qpHhH2FZpI7w4i3q4Kq7jzbodXxOZBAqJFd3FSHTnVBYEAfgTgkTbIC7yIXVwnIwXtqDFTNDQ==
|
||||
dependencies:
|
||||
graphql-language-service-types "^1.6.0-alpha.5"
|
||||
|
||||
graphql@15.0.0:
|
||||
version "15.0.0"
|
||||
resolved "https://registry.npmjs.org/graphql/-/graphql-15.0.0.tgz#042a5eb5e2506a2e2111ce41eb446a8e570b8be9"
|
||||
integrity sha512-ZyVO1xIF9F+4cxfkdhOJINM+51B06Friuv4M66W7HzUOeFd+vNzUn4vtswYINPi6sysjf1M2Ri/rwZALqgwbaQ==
|
||||
|
||||
growly@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
|
||||
@@ -12910,6 +13141,13 @@ lines-and-columns@^1.1.6:
|
||||
resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
|
||||
integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
|
||||
|
||||
linkify-it@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf"
|
||||
integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==
|
||||
dependencies:
|
||||
uc.micro "^1.0.1"
|
||||
|
||||
lint-staged@^10.0.4:
|
||||
version "10.0.8"
|
||||
resolved "https://registry.npmjs.org/lint-staged/-/lint-staged-10.0.8.tgz#0f7849cdc336061f25f5d4fcbcfa385701ff4739"
|
||||
@@ -13464,6 +13702,17 @@ markdown-escapes@^1.0.0:
|
||||
resolved "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535"
|
||||
integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==
|
||||
|
||||
markdown-it@^10.0.0:
|
||||
version "10.0.0"
|
||||
resolved "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz#abfc64f141b1722d663402044e43927f1f50a8dc"
|
||||
integrity sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==
|
||||
dependencies:
|
||||
argparse "^1.0.7"
|
||||
entities "~2.0.0"
|
||||
linkify-it "^2.0.0"
|
||||
mdurl "^1.0.1"
|
||||
uc.micro "^1.0.5"
|
||||
|
||||
markdown-to-jsx@^6.9.1, markdown-to-jsx@^6.9.3:
|
||||
version "6.11.0"
|
||||
resolved "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-6.11.0.tgz#a2e3f2bc781c3402d8bb0f8e0a12a186474623b0"
|
||||
@@ -13515,6 +13764,11 @@ mdn-data@2.0.6:
|
||||
resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz#852dc60fcaa5daa2e8cf6c9189c440ed3e042978"
|
||||
integrity sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==
|
||||
|
||||
mdurl@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
|
||||
integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=
|
||||
|
||||
meant@~1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/meant/-/meant-1.0.1.tgz#66044fea2f23230ec806fb515efea29c44d2115d"
|
||||
@@ -16967,6 +17221,25 @@ react-transition-group@^4.3.0:
|
||||
loose-envify "^1.4.0"
|
||||
prop-types "^15.6.2"
|
||||
|
||||
react-use@^13.0.0:
|
||||
version "13.27.1"
|
||||
resolved "https://registry.npmjs.org/react-use/-/react-use-13.27.1.tgz#e2ae2b708dafc7893c4772628801589aab9de370"
|
||||
integrity sha512-bAwdqDMXs5lovEanXnL1izledfrPEUUv1afoTVB59eUiYcDyKul+M/dT/2WcgHjoY/R6QlrTcZoW4R7ifwvBfw==
|
||||
dependencies:
|
||||
"@types/js-cookie" "2.2.5"
|
||||
"@xobotyi/scrollbar-width" "1.9.5"
|
||||
copy-to-clipboard "^3.2.0"
|
||||
fast-deep-equal "^3.1.1"
|
||||
fast-shallow-equal "^1.0.0"
|
||||
js-cookie "^2.2.1"
|
||||
nano-css "^5.2.1"
|
||||
resize-observer-polyfill "^1.5.1"
|
||||
screenfull "^5.0.0"
|
||||
set-harmonic-interval "^1.0.1"
|
||||
throttle-debounce "^2.1.0"
|
||||
ts-easing "^0.2.0"
|
||||
tslib "^1.10.0"
|
||||
|
||||
react-use@^13.24.0:
|
||||
version "13.27.0"
|
||||
resolved "https://registry.npmjs.org/react-use/-/react-use-13.27.0.tgz#53a619dc9213e2cbe65d6262e8b0e76641ade4aa"
|
||||
@@ -17290,7 +17563,7 @@ regenerator-runtime@^0.11.0:
|
||||
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
|
||||
integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
|
||||
|
||||
regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4:
|
||||
regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.5:
|
||||
version "0.13.5"
|
||||
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697"
|
||||
integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==
|
||||
@@ -19023,6 +19296,25 @@ style-loader@^1.0.0:
|
||||
loader-utils "^1.2.3"
|
||||
schema-utils "^2.6.4"
|
||||
|
||||
styled-system@^5.1.5:
|
||||
version "5.1.5"
|
||||
resolved "https://registry.npmjs.org/styled-system/-/styled-system-5.1.5.tgz#e362d73e1dbb5641a2fd749a6eba1263dc85075e"
|
||||
integrity sha512-7VoD0o2R3RKzOzPK0jYrVnS8iJdfkKsQJNiLRDjikOpQVqQHns/DXWaPZOH4tIKkhAT7I6wIsy9FWTWh2X3q+A==
|
||||
dependencies:
|
||||
"@styled-system/background" "^5.1.2"
|
||||
"@styled-system/border" "^5.1.5"
|
||||
"@styled-system/color" "^5.1.2"
|
||||
"@styled-system/core" "^5.1.2"
|
||||
"@styled-system/flexbox" "^5.1.2"
|
||||
"@styled-system/grid" "^5.1.2"
|
||||
"@styled-system/layout" "^5.1.2"
|
||||
"@styled-system/position" "^5.1.2"
|
||||
"@styled-system/shadow" "^5.1.2"
|
||||
"@styled-system/space" "^5.1.2"
|
||||
"@styled-system/typography" "^5.1.2"
|
||||
"@styled-system/variant" "^5.1.5"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
stylehacks@^4.0.0:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5"
|
||||
@@ -19294,6 +19586,18 @@ text-table@0.2.0, text-table@^0.2.0, text-table@~0.2.0:
|
||||
resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
|
||||
|
||||
theme-ui@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.npmjs.org/theme-ui/-/theme-ui-0.3.1.tgz#b00ee2c03eb3d820536af8b121c64d13b3777cf0"
|
||||
integrity sha512-My/TSALqp7Dst5Ez7nJA+94Q8zJhc26Z0qGo8kEWyoqHHJ5TU8xdhjLPBltTdQck3T32cSq5USIeSKU3JtxYUQ==
|
||||
dependencies:
|
||||
"@theme-ui/color-modes" "^0.3.1"
|
||||
"@theme-ui/components" "^0.3.1"
|
||||
"@theme-ui/core" "^0.3.1"
|
||||
"@theme-ui/css" "^0.3.1"
|
||||
"@theme-ui/mdx" "^0.3.0"
|
||||
"@theme-ui/theme-provider" "^0.3.1"
|
||||
|
||||
thenify-all@^1.0.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
|
||||
@@ -19722,6 +20026,11 @@ ua-parser-js@^0.7.18:
|
||||
resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz#853cf9ce93f642f67174273cc34565ae6f308777"
|
||||
integrity sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==
|
||||
|
||||
uc.micro@^1.0.1, uc.micro@^1.0.5:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
|
||||
integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
|
||||
|
||||
uglify-js@3.4.x:
|
||||
version "3.4.10"
|
||||
resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f"
|
||||
@@ -20176,6 +20485,11 @@ vm-browserify@^1.0.1:
|
||||
resolved "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
|
||||
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
|
||||
|
||||
vscode-languageserver-types@^3.15.1:
|
||||
version "3.15.1"
|
||||
resolved "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz#17be71d78d2f6236d414f0001ce1ef4d23e6b6de"
|
||||
integrity sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==
|
||||
|
||||
w3c-hr-time@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"
|
||||
|
||||
Reference in New Issue
Block a user