Set subdomain for project and set URL for each deployment (#52)

* Display current deployment info in overview tab

* Add assign domain dialog box in deployments

* Add empty link for project settings in assign domain dialog box

* Use react router dom link

* Add sub domain to project entity

* Add deployment url with custom generated string

* Set nano id to deployment id

* Add sub domain while creating new project

* Use same id as in url

* Update readme steps for production build

* Update README

---------

Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
Nabarun Gogoi 2024-02-05 14:56:28 +05:30 committed by GitHub
parent 0fdc2631ee
commit ac7064afa5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 460 additions and 57 deletions

View File

@ -1,5 +1,7 @@
# snowballtools # snowballtools
## Setup
- Clone the `snowballtools` repo - Clone the `snowballtools` repo
```bash ```bash
@ -18,6 +20,8 @@
yarn build --ignore frontend yarn build --ignore frontend
``` ```
## Backend
- Change directory to `packages/backend` - Change directory to `packages/backend`
```bash ```bash
@ -43,6 +47,8 @@
yarn start yarn start
``` ```
## Frontend
- Change directory to `packages/frontend` in a new terminal - Change directory to `packages/frontend` in a new terminal
```bash ```bash
@ -61,6 +67,8 @@
REACT_APP_GITHUB_CLIENT_ID = <CLIENT_ID> REACT_APP_GITHUB_CLIENT_ID = <CLIENT_ID>
``` ```
### Development
- Start the React application - Start the React application
```bash ```bash
@ -68,3 +76,17 @@
``` ```
- The React application will be running in `http://localhost:3000/` - The React application will be running in `http://localhost:3000/`
### Production
- Build the React application
```bash
yarn build
```
- Use a web server for hosting static built files
```bash
python3 -m http.server -d build 3000
```

View File

@ -15,6 +15,8 @@
"express": "^4.18.2", "express": "^4.18.2",
"fs-extra": "^11.2.0", "fs-extra": "^11.2.0",
"graphql": "^16.8.1", "graphql": "^16.8.1",
"nanoid": "3",
"nanoid-dictionary": "^5.0.0-beta.1",
"reflect-metadata": "^0.2.1", "reflect-metadata": "^0.2.1",
"toml": "^3.0.0", "toml": "^3.0.0",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",

View File

@ -4,3 +4,5 @@ export const DEFAULT_GQL_PATH = '/graphql';
// Note: temporary hardcoded user, later to be derived from auth token // Note: temporary hardcoded user, later to be derived from auth token
export const USER_ID = 1; export const USER_ID = 1;
export const PROJECT_DOMAIN = 'snowball.xyz';

View File

@ -2,6 +2,8 @@ import { DataSource, DeepPartial } from 'typeorm';
import path from 'path'; import path from 'path';
import debug from 'debug'; import debug from 'debug';
import assert from 'assert'; import assert from 'assert';
import { customAlphabet } from 'nanoid';
import { lowercase, numbers } from 'nanoid-dictionary';
import { DatabaseConfig } from './config'; import { DatabaseConfig } from './config';
import { User } from './entity/User'; import { User } from './entity/User';
@ -11,9 +13,12 @@ import { Deployment, Environment } from './entity/Deployment';
import { Permission, ProjectMember } from './entity/ProjectMember'; import { Permission, ProjectMember } from './entity/ProjectMember';
import { EnvironmentVariable } from './entity/EnvironmentVariable'; import { EnvironmentVariable } from './entity/EnvironmentVariable';
import { Domain } from './entity/Domain'; import { Domain } from './entity/Domain';
import { PROJECT_DOMAIN } from './constants';
const log = debug('snowball:database'); const log = debug('snowball:database');
const nanoid = customAlphabet(lowercase + numbers, 8);
// TODO: Fix order of methods // TODO: Fix order of methods
export class Database { export class Database {
private dataSource: DataSource; private dataSource: DataSource;
@ -90,6 +95,7 @@ export class Database {
const project = await projectRepository const project = await projectRepository
.createQueryBuilder('project') .createQueryBuilder('project')
.leftJoinAndSelect('project.deployments', 'deployments', 'deployments.isCurrent = true') .leftJoinAndSelect('project.deployments', 'deployments', 'deployments.isCurrent = true')
.leftJoinAndSelect('deployments.createdBy', 'user')
.leftJoinAndSelect('deployments.domain', 'domain') .leftJoinAndSelect('deployments.domain', 'domain')
.leftJoinAndSelect('project.owner', 'owner') .leftJoinAndSelect('project.owner', 'owner')
.leftJoinAndSelect('project.organization', 'organization') .leftJoinAndSelect('project.organization', 'organization')
@ -314,7 +320,7 @@ export class Database {
async updateDeploymentById (deploymentId: string, updates: DeepPartial<Deployment>): Promise<boolean> { async updateDeploymentById (deploymentId: string, updates: DeepPartial<Deployment>): Promise<boolean> {
const deploymentRepository = this.dataSource.getRepository(Deployment); const deploymentRepository = this.dataSource.getRepository(Deployment);
const updateResult = await deploymentRepository.update({ id: Number(deploymentId) }, updates); const updateResult = await deploymentRepository.update({ id: deploymentId }, updates);
if (updateResult.affected) { if (updateResult.affected) {
return updateResult.affected > 0; return updateResult.affected > 0;
@ -341,6 +347,8 @@ export class Database {
id: Number(projectDetails.organizationId) id: Number(projectDetails.organizationId)
}); });
newProject.subDomain = `${newProject.name}.${PROJECT_DOMAIN}`;
return projectRepository.save(newProject); return projectRepository.save(newProject);
} }
@ -364,14 +372,14 @@ export class Database {
createdBy: true createdBy: true
}, },
where: { where: {
id: Number(deploymentId) id: deploymentId
} }
}); });
if (deployment === null) { if (deployment === null) {
throw new Error('Deployment not found'); throw new Error('Deployment not found');
} }
const { id, createdAt, updatedAt, ...updatedDeployment } = deployment; const { createdAt, updatedAt, ...updatedDeployment } = deployment;
if (updatedDeployment.environment === Environment.Production) { if (updatedDeployment.environment === Environment.Production) {
// TODO: Put isCurrent field in project // TODO: Put isCurrent field in project
@ -381,7 +389,10 @@ export class Database {
}); });
} }
await deploymentRepository.update({ id: Number(deploymentId) }, { domain: null, isCurrent: false }); await deploymentRepository.update({ id: deploymentId }, { domain: null, isCurrent: false });
updatedDeployment.id = nanoid();
updatedDeployment.url = `${updatedDeployment.id}-${updatedDeployment.project.subDomain}`;
return deploymentRepository.save(updatedDeployment); return deploymentRepository.save(updatedDeployment);
} }
@ -442,7 +453,7 @@ export class Database {
const oldCurrentDeploymentUpdate = await deploymentRepository.update({ project: { id: projectId }, isCurrent: true }, { isCurrent: false, domain: null }); const oldCurrentDeploymentUpdate = await deploymentRepository.update({ project: { id: projectId }, isCurrent: true }, { isCurrent: false, domain: null });
const newCurrentDeploymentUpdate = await deploymentRepository.update({ id: Number(deploymentId) }, { isCurrent: true, domain: oldCurrentDeployment?.domain }); const newCurrentDeploymentUpdate = await deploymentRepository.update({ id: deploymentId }, { isCurrent: true, domain: oldCurrentDeployment?.domain });
if (oldCurrentDeploymentUpdate.affected && newCurrentDeploymentUpdate.affected) { if (oldCurrentDeploymentUpdate.affected && newCurrentDeploymentUpdate.affected) {
return oldCurrentDeploymentUpdate.affected > 0 && newCurrentDeploymentUpdate.affected > 0; return oldCurrentDeploymentUpdate.affected > 0 && newCurrentDeploymentUpdate.affected > 0;

View File

@ -1,6 +1,6 @@
import { import {
Entity, Entity,
PrimaryGeneratedColumn, PrimaryColumn,
Column, Column,
CreateDateColumn, CreateDateColumn,
UpdateDateColumn, UpdateDateColumn,
@ -27,8 +27,9 @@ enum Status {
@Entity() @Entity()
export class Deployment { export class Deployment {
@PrimaryGeneratedColumn() // TODO: set custom generated id
id!: number; @PrimaryColumn('varchar')
id!: string;
@ManyToOne(() => Project, { onDelete: 'CASCADE' }) @ManyToOne(() => Project, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'projectId' }) @JoinColumn({ name: 'projectId' })
@ -47,6 +48,9 @@ export class Deployment {
@Column('varchar') @Column('varchar')
title!: string; title!: string;
@Column('varchar')
url!: string;
@Column({ @Column({
enum: Environment enum: Environment
}) })

View File

@ -57,6 +57,9 @@ export class Project {
@Column('varchar') @Column('varchar')
icon!: string; icon!: string;
@Column('varchar')
subDomain!: string;
@CreateDateColumn() @CreateDateColumn()
createdAt!: Date; createdAt!: Date;

View File

@ -72,6 +72,7 @@ type Project {
updatedAt: String! updatedAt: String!
organization: Organization! organization: Organization!
icon: String icon: String
subDomain: String
} }
type ProjectMember { type ProjectMember {
@ -89,6 +90,7 @@ type Deployment {
branch: String! branch: String!
commitHash: String! commitHash: String!
title: String! title: String!
url: String!
environment: Environment! environment: Environment!
isCurrent: Boolean! isCurrent: Boolean!
status: DeploymentStatus! status: DeploymentStatus!

View File

@ -52,6 +52,7 @@ export const deploymentToGqlType = (dbDeployment: Deployment): any => {
branch: dbDeployment.branch, branch: dbDeployment.branch,
commitHash: dbDeployment.commitHash, commitHash: dbDeployment.commitHash,
title: dbDeployment.title, title: dbDeployment.title,
url: dbDeployment.url,
environment: dbDeployment.environment, environment: dbDeployment.environment,
isCurrent: dbDeployment.isCurrent, isCurrent: dbDeployment.isCurrent,
status: dbDeployment.status, status: dbDeployment.status,

View File

@ -3,110 +3,130 @@
"projectIndex": 0, "projectIndex": 0,
"domainIndex":0, "domainIndex":0,
"createdByIndex": 0, "createdByIndex": 0,
"id":"ffhae3zq",
"title": "nextjs-boilerplate-1", "title": "nextjs-boilerplate-1",
"status": "Building", "status": "Building",
"environment": "Production", "environment": "Production",
"isCurrent": true, "isCurrent": true,
"branch": "main", "branch": "main",
"commitHash": "testXyz" "commitHash": "testXyz",
"url": "testProject-ffhae3zq.testProject.snowball.xyz"
}, },
{ {
"projectIndex": 0, "projectIndex": 0,
"domainIndex":1, "domainIndex":1,
"createdByIndex": 0, "createdByIndex": 0,
"id":"vehagei8",
"title": "nextjs-boilerplate-2", "title": "nextjs-boilerplate-2",
"status": "Ready", "status": "Ready",
"environment": "Preview", "environment": "Preview",
"isCurrent": false, "isCurrent": false,
"branch": "test", "branch": "test",
"commitHash": "testXyz" "commitHash": "testXyz",
"url": "testProject-vehagei8.testProject.snowball.xyz"
}, },
{ {
"projectIndex": 0, "projectIndex": 0,
"domainIndex":2, "domainIndex":2,
"createdByIndex": 0, "createdByIndex": 0,
"id":"qmgekyte",
"title": "nextjs-boilerplate-3", "title": "nextjs-boilerplate-3",
"status": "Error", "status": "Error",
"environment": "Development", "environment": "Development",
"isCurrent": false, "isCurrent": false,
"branch": "test", "branch": "test",
"commitHash": "testXyz" "commitHash": "testXyz",
"url": "testProject-qmgekyte.testProject.snowball.xyz"
}, },
{ {
"projectIndex": 0, "projectIndex": 0,
"domainIndex": null, "domainIndex": null,
"createdByIndex": 0, "createdByIndex": 0,
"id":"f8wsyim6",
"title": "nextjs-boilerplate-4", "title": "nextjs-boilerplate-4",
"status": "Ready", "status": "Ready",
"environment": "Production", "environment": "Production",
"isCurrent": false, "isCurrent": false,
"branch": "prod", "branch": "prod",
"commitHash": "testXyz" "commitHash": "testXyz",
"url": "testProject-f8wsyim6.testProject.snowball.xyz"
}, },
{ {
"projectIndex": 1, "projectIndex": 1,
"domainIndex":3, "domainIndex":3,
"createdByIndex": 1, "createdByIndex": 1,
"id":"eO8cckxk",
"title": "nextjs-boilerplate-1", "title": "nextjs-boilerplate-1",
"status": "Building", "status": "Building",
"environment": "Production", "environment": "Production",
"isCurrent": true, "isCurrent": true,
"branch": "main", "branch": "main",
"commitHash": "testXyz" "commitHash": "testXyz",
"url": "testProject-2-eO8cckxk.testProject-2.snowball.xyz"
}, },
{ {
"projectIndex": 1, "projectIndex": 1,
"domainIndex":4, "domainIndex":4,
"createdByIndex": 1, "createdByIndex": 1,
"id":"yaq0t5yw",
"title": "nextjs-boilerplate-2", "title": "nextjs-boilerplate-2",
"status": "Ready", "status": "Ready",
"environment": "Preview", "environment": "Preview",
"isCurrent": false, "isCurrent": false,
"branch": "test", "branch": "test",
"commitHash": "testXyz" "commitHash": "testXyz",
"url": "testProject-2-yaq0t5yw.testProject-2.snowball.xyz"
}, },
{ {
"projectIndex": 1, "projectIndex": 1,
"domainIndex":5, "domainIndex":5,
"createdByIndex": 1, "createdByIndex": 1,
"id":"hwwr6sbx",
"title": "nextjs-boilerplate-3", "title": "nextjs-boilerplate-3",
"status": "Error", "status": "Error",
"environment": "Development", "environment": "Development",
"isCurrent": false, "isCurrent": false,
"branch": "test", "branch": "test",
"commitHash": "testXyz" "commitHash": "testXyz",
"url": "testProject-2-hwwr6sbx.testProject-2.snowball.xyz"
}, },
{ {
"projectIndex": 2, "projectIndex": 2,
"domainIndex":6, "domainIndex":6,
"createdByIndex": 2, "createdByIndex": 2,
"id":"ndxje48a",
"title": "nextjs-boilerplate-1", "title": "nextjs-boilerplate-1",
"status": "Building", "status": "Building",
"environment": "Production", "environment": "Production",
"isCurrent": true, "isCurrent": true,
"branch": "main", "branch": "main",
"commitHash": "testXyz" "commitHash": "testXyz",
"url": "iglootools-ndxje48a.iglootools.snowball.xyz"
}, },
{ {
"projectIndex": 2, "projectIndex": 2,
"domainIndex":7, "domainIndex":7,
"createdByIndex": 2, "createdByIndex": 2,
"id":"gtgpgvei",
"title": "nextjs-boilerplate-2", "title": "nextjs-boilerplate-2",
"status": "Ready", "status": "Ready",
"environment": "Preview", "environment": "Preview",
"isCurrent": false, "isCurrent": false,
"branch": "test", "branch": "test",
"commitHash": "testXyz" "commitHash": "testXyz",
"url": "iglootools-gtgpgvei.iglootools.snowball.xyz"
}, },
{ {
"projectIndex": 2, "projectIndex": 2,
"domainIndex":8, "domainIndex":8,
"createdByIndex": 2, "createdByIndex": 2,
"id":"b4bpthjr",
"title": "nextjs-boilerplate-3", "title": "nextjs-boilerplate-3",
"status": "Error", "status": "Error",
"environment": "Development", "environment": "Development",
"isCurrent": false, "isCurrent": false,
"branch": "test", "branch": "test",
"commitHash": "testXyz" "commitHash": "testXyz",
"url": "iglootools-b4bpthjr.iglootools.snowball.xyz"
} }
] ]

View File

@ -9,7 +9,8 @@
"template": "test", "template": "test",
"framework": "test", "framework": "test",
"webhooks": [], "webhooks": [],
"icon": "" "icon": "",
"subDomain": "testProject.snowball.xyz"
}, },
{ {
"ownerIndex": 1, "ownerIndex": 1,
@ -21,7 +22,8 @@
"template": "test-2", "template": "test-2",
"framework": "test-2", "framework": "test-2",
"webhooks": [], "webhooks": [],
"icon": "" "icon": "",
"subDomain": "testProject-2.snowball.xyz"
}, },
{ {
"ownerIndex": 2, "ownerIndex": 2,
@ -33,7 +35,8 @@
"template": "test-3", "template": "test-3",
"framework": "test-3", "framework": "test-3",
"webhooks": [], "webhooks": [],
"icon": "" "icon": "",
"subDomain": "iglootools.snowball.xyz"
}, },
{ {
"ownerIndex": 1, "ownerIndex": 1,
@ -45,7 +48,8 @@
"template": "test-4", "template": "test-4",
"framework": "test-4", "framework": "test-4",
"webhooks": [], "webhooks": [],
"icon": "" "icon": "",
"subDomain": "iglootools-2.snowball.xyz"
}, },
{ {
"ownerIndex": 0, "ownerIndex": 0,
@ -57,6 +61,7 @@
"template": "test-5", "template": "test-5",
"framework": "test-5", "framework": "test-5",
"webhooks": [], "webhooks": [],
"icon": "" "icon": "",
"subDomain": "snowball-2.snowball.xyz"
} }
] ]

View File

@ -55,8 +55,6 @@ const loadAndSaveData = async <Entity extends ObjectLiteral>(entityType: EntityT
}; };
const generateTestData = async (dataSource: DataSource) => { const generateTestData = async (dataSource: DataSource) => {
const domainRepository = await dataSource.getRepository(Domain);
const savedUsers = await loadAndSaveData(User, dataSource, path.resolve(__dirname, USER_DATA_PATH)); const savedUsers = await loadAndSaveData(User, dataSource, path.resolve(__dirname, USER_DATA_PATH));
const savedOrgs = await loadAndSaveData(Organization, dataSource, path.resolve(__dirname, ORGANIZATION_DATA_PATH)); const savedOrgs = await loadAndSaveData(Organization, dataSource, path.resolve(__dirname, ORGANIZATION_DATA_PATH));
@ -67,6 +65,8 @@ const generateTestData = async (dataSource: DataSource) => {
const savedProjects = await loadAndSaveData(Project, dataSource, path.resolve(__dirname, PROJECT_DATA_PATH), projectRelations); const savedProjects = await loadAndSaveData(Project, dataSource, path.resolve(__dirname, PROJECT_DATA_PATH), projectRelations);
const domainRepository = dataSource.getRepository(Domain);
const domainPrimaryRelations = { const domainPrimaryRelations = {
project: savedProjects project: savedProjects
}; };

View File

@ -19,6 +19,7 @@
"luxon": "^3.4.4", "luxon": "^3.4.4",
"octokit": "^3.1.2", "octokit": "^3.1.2",
"react": "^18.2.0", "react": "^18.2.0",
"react-code-blocks": "^0.1.6",
"react-day-picker": "^8.9.1", "react-day-picker": "^8.9.1",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-dropdown": "^1.11.0", "react-dropdown": "^1.11.0",

View File

@ -1,4 +1,5 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Project } from 'gql-client';
import { Button, Typography } from '@material-tailwind/react'; import { Button, Typography } from '@material-tailwind/react';
@ -16,14 +17,14 @@ const DEFAULT_FILTER_VALUE: FilterValue = {
status: StatusOptions.ALL_STATUS, status: StatusOptions.ALL_STATUS,
}; };
const DeploymentsTabPanel = ({ projectId }: { projectId: string }) => { const DeploymentsTabPanel = ({ project }: { project: Project }) => {
const client = useGQLClient(); const client = useGQLClient();
const [filterValue, setFilterValue] = useState(DEFAULT_FILTER_VALUE); const [filterValue, setFilterValue] = useState(DEFAULT_FILTER_VALUE);
const [deployments, setDeployments] = useState<DeploymentDetails[]>([]); const [deployments, setDeployments] = useState<DeploymentDetails[]>([]);
const fetchDeployments = async () => { const fetchDeployments = async () => {
const { deployments } = await client.getDeployments(projectId); const { deployments } = await client.getDeployments(project.id);
const updatedDeployments = deployments.map((deployment) => { const updatedDeployments = deployments.map((deployment) => {
return { return {
...deployment, ...deployment,
@ -91,7 +92,7 @@ const DeploymentsTabPanel = ({ projectId }: { projectId: string }) => {
key={key} key={key}
currentDeployment={currentDeployment!} currentDeployment={currentDeployment!}
onUpdate={onUpdateDeploymenToProd} onUpdate={onUpdateDeploymenToProd}
projectId={projectId} project={project}
/> />
); );
}) })

View File

@ -23,8 +23,7 @@ const OverviewTabPanel = ({ project }: OverviewProps) => {
<div className="grow"> <div className="grow">
<Typography>{project.name}</Typography> <Typography>{project.name}</Typography>
<Typography variant="small" color="gray"> <Typography variant="small" color="gray">
{project.deployments[0]?.domain?.name ?? {project.subDomain}
'No Production Deployment'}
</Typography> </Typography>
</div> </div>
</div> </div>
@ -55,6 +54,8 @@ const OverviewTabPanel = ({ project }: OverviewProps) => {
</Button> </Button>
)} )}
</div> </div>
{project.deployments.length !== 0 ? (
<>
<div className="flex justify-between p-2 text-sm"> <div className="flex justify-between p-2 text-sm">
<p>^ Source</p> <p>^ Source</p>
<p>{project.deployments[0]?.branch}</p> <p>{project.deployments[0]?.branch}</p>
@ -68,9 +69,14 @@ const OverviewTabPanel = ({ project }: OverviewProps) => {
<div className="flex justify-between p-2 text-sm"> <div className="flex justify-between p-2 text-sm">
<p>^ Created</p> <p>^ Created</p>
<p> <p>
{relativeTimeMs(project.createdAt)} by ^ {project.owner.name} {relativeTimeMs(project.deployments[0].createdAt)} by ^{' '}
{project.deployments[0].createdBy.name}
</p> </p>
</div> </div>
</>
) : (
<div>No current deployment found</div>
)}
</div> </div>
<div className="col-span-2 p-2"> <div className="col-span-2 p-2">
<div className="flex justify-between"> <div className="flex justify-between">

View File

@ -47,7 +47,7 @@ const ProjectTabs = ({ project, onUpdate }: ProjectTabsProps) => {
<OverviewTabPanel project={project} /> <OverviewTabPanel project={project} />
</TabPanel> </TabPanel>
<TabPanel> <TabPanel>
<DeploymentsTabPanel projectId={project.id} /> <DeploymentsTabPanel project={project} />
</TabPanel> </TabPanel>
<TabPanel> <TabPanel>
<Database /> <Database />

View File

@ -0,0 +1,52 @@
import React from 'react';
import { CopyBlock, atomOneLight } from 'react-code-blocks';
import { Link } from 'react-router-dom';
import {
Button,
Dialog,
DialogHeader,
DialogBody,
DialogFooter,
} from '@material-tailwind/react';
interface AssignDomainProps {
open: boolean;
handleOpen: () => void;
}
const AssignDomainDialog = ({ open, handleOpen }: AssignDomainProps) => {
return (
<Dialog open={open} handler={handleOpen}>
<DialogHeader>Assign Domain</DialogHeader>
<DialogBody>
In order to assign a domain to your production deployments, configure it
in the{' '}
{/* TODO: Navigate to settings tab panel after clicking on project settings */}
<Link to="" className="text-light-blue-800 inline">
project settings{' '}
</Link>
(recommended). If you want to assign to this specific deployment,
however, you can do so using our command-line interface:
<CopyBlock
text="snowball alias <deployment> <domain>"
language=""
showLineNumbers={false}
theme={atomOneLight}
/>
</DialogBody>
<DialogFooter className="flex justify-start">
<Button
className="rounded-3xl"
variant="gradient"
color="blue"
onClick={handleOpen}
>
<span>Okay</span>
</Button>
</DialogFooter>
</Dialog>
);
};
export default AssignDomainDialog;

View File

@ -10,11 +10,12 @@ import {
ChipProps, ChipProps,
} from '@material-tailwind/react'; } from '@material-tailwind/react';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
import { Environment } from 'gql-client'; import { Environment, Project } from 'gql-client';
import { relativeTimeMs } from '../../../../utils/time'; import { relativeTimeMs } from '../../../../utils/time';
import ConfirmDialog from '../../../shared/ConfirmDialog'; import ConfirmDialog from '../../../shared/ConfirmDialog';
import DeploymentDialogBodyCard from './DeploymentDialogBodyCard'; import DeploymentDialogBodyCard from './DeploymentDialogBodyCard';
import AssignDomainDialog from './AssignDomainDialog';
import { DeploymentDetails, Status } from '../../../../types/project'; import { DeploymentDetails, Status } from '../../../../types/project';
import { useGQLClient } from '../../../../context/GQLClientContext'; import { useGQLClient } from '../../../../context/GQLClientContext';
@ -22,7 +23,7 @@ interface DeployDetailsCardProps {
deployment: DeploymentDetails; deployment: DeploymentDetails;
currentDeployment: DeploymentDetails; currentDeployment: DeploymentDetails;
onUpdate: () => Promise<void>; onUpdate: () => Promise<void>;
projectId: string; project: Project;
} }
const STATUS_COLORS: { [key in Status]: ChipProps['color'] } = { const STATUS_COLORS: { [key in Status]: ChipProps['color'] } = {
@ -35,13 +36,14 @@ const DeploymentDetailsCard = ({
deployment, deployment,
currentDeployment, currentDeployment,
onUpdate, onUpdate,
projectId, project,
}: DeployDetailsCardProps) => { }: DeployDetailsCardProps) => {
const client = useGQLClient(); const client = useGQLClient();
const [changeToProduction, setChangeToProduction] = useState(false); const [changeToProduction, setChangeToProduction] = useState(false);
const [redeployToProduction, setRedeployToProduction] = useState(false); const [redeployToProduction, setRedeployToProduction] = useState(false);
const [rollbackDeployment, setRollbackDeployment] = useState(false); const [rollbackDeployment, setRollbackDeployment] = useState(false);
const [assignDomainDialog, setAssignDomainDialog] = useState(false);
const updateDeployment = async () => { const updateDeployment = async () => {
const isUpdated = await client.updateDeploymentToProd(deployment.id); const isUpdated = await client.updateDeploymentToProd(deployment.id);
@ -65,7 +67,7 @@ const DeploymentDetailsCard = ({
const rollbackDeploymentHandler = async () => { const rollbackDeploymentHandler = async () => {
const isRollbacked = await client.rollbackDeployment( const isRollbacked = await client.rollbackDeployment(
projectId, project.id,
deployment.id, deployment.id,
); );
if (isRollbacked) { if (isRollbacked) {
@ -80,7 +82,7 @@ const DeploymentDetailsCard = ({
<div className="grid grid-cols-4 gap-2 border-b border-gray-300 p-3 my-2"> <div className="grid grid-cols-4 gap-2 border-b border-gray-300 p-3 my-2">
<div className="col-span-2"> <div className="col-span-2">
<div className="flex"> <div className="flex">
<Typography className=" basis-3/4">{deployment.title}</Typography> <Typography className=" basis-3/4">{deployment.url}</Typography>
<Chip <Chip
value={deployment.status} value={deployment.status}
color={STATUS_COLORS[deployment.status] ?? 'gray'} color={STATUS_COLORS[deployment.status] ?? 'gray'}
@ -110,7 +112,11 @@ const DeploymentDetailsCard = ({
</MenuHandler> </MenuHandler>
<MenuList> <MenuList>
<MenuItem>^ Visit</MenuItem> <MenuItem>^ Visit</MenuItem>
<MenuItem>^ Assign domain</MenuItem> <MenuItem
onClick={() => setAssignDomainDialog(!assignDomainDialog)}
>
^ Assign domain
</MenuItem>
{!(deployment.environment === Environment.Production) && ( {!(deployment.environment === Environment.Production) && (
<MenuItem <MenuItem
onClick={() => setChangeToProduction(!changeToProduction)} onClick={() => setChangeToProduction(!changeToProduction)}
@ -235,6 +241,10 @@ const DeploymentDetailsCard = ({
</Typography> </Typography>
</div> </div>
</ConfirmDialog> </ConfirmDialog>
<AssignDomainDialog
open={assignDomainDialog}
handleOpen={() => setAssignDomainDialog(!assignDomainDialog)}
/>
</div> </div>
); );
}; };

View File

@ -27,6 +27,7 @@ query ($projectId: String!) {
repository repository
webhooks webhooks
icon icon
subDomain
organization { organization {
id id
name name
@ -54,6 +55,10 @@ query ($projectId: String!) {
id id
name name
} }
createdBy {
id
name
}
} }
} }
} }
@ -72,6 +77,7 @@ query ($organizationId: String!) {
repository repository
updatedAt updatedAt
icon icon
subDomain
deployments { deployments {
id id
branch branch
@ -121,6 +127,7 @@ query ($projectId: String!) {
branch branch
commitHash commitHash
title title
url
environment environment
isCurrent isCurrent
status status

View File

@ -63,6 +63,7 @@ export type Deployment = {
branch: string branch: string
commitHash: string commitHash: string
title: string title: string
url: string
environment: Environment environment: Environment
isCurrent: boolean isCurrent: boolean
status: DeploymentStatus status: DeploymentStatus
@ -131,6 +132,7 @@ export type Project = {
updatedAt: string updatedAt: string
organization: Organization organization: Organization
icon: string icon: string
subDomain: string
} }
export type GetProjectMembersResponse = { export type GetProjectMembersResponse = {

260
yarn.lock
View File

@ -1280,6 +1280,13 @@
resolved "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz" resolved "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz"
integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==
"@babel/runtime@^7.10.4", "@babel/runtime@^7.3.1":
version "7.23.9"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7"
integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==
dependencies:
regenerator-runtime "^0.14.0"
"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.23.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.23.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
version "7.23.5" version "7.23.5"
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz"
@ -1476,6 +1483,13 @@
resolved "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz" resolved "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz"
integrity sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw== integrity sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==
"@emotion/is-prop-valid@1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc"
integrity sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==
dependencies:
"@emotion/memoize" "^0.8.1"
"@emotion/is-prop-valid@^0.8.2": "@emotion/is-prop-valid@^0.8.2":
version "0.8.8" version "0.8.8"
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"
@ -1488,6 +1502,16 @@
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
"@emotion/memoize@^0.8.1":
version "0.8.1"
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17"
integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==
"@emotion/unitless@0.8.0":
version "0.8.0"
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.0.tgz#a4a36e9cbdc6903737cd20d38033241e1b8833db"
integrity sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==
"@eslint-community/eslint-utils@^4.1.2", "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": "@eslint-community/eslint-utils@^4.1.2", "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0":
version "4.4.0" version "4.4.0"
resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz"
@ -3224,6 +3248,13 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/hast@^2.0.0":
version "2.3.10"
resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.10.tgz#5c9d9e0b304bbb8879b857225c5ebab2d81d7643"
integrity sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==
dependencies:
"@types/unist" "^2"
"@types/html-minifier-terser@^6.0.0": "@types/html-minifier-terser@^6.0.0":
version "6.1.0" version "6.1.0"
resolved "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz" resolved "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz"
@ -3469,6 +3500,11 @@
resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz" resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz"
integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==
"@types/stylis@4.2.0":
version "4.2.0"
resolved "https://registry.yarnpkg.com/@types/stylis/-/stylis-4.2.0.tgz#199a3f473f0c3a6f6e4e1b17cdbc967f274bdc6b"
integrity sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==
"@types/testing-library__jest-dom@^5.9.1": "@types/testing-library__jest-dom@^5.9.1":
version "5.14.9" version "5.14.9"
resolved "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz" resolved "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz"
@ -3481,6 +3517,11 @@
resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz" resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz"
integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw== integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==
"@types/unist@^2":
version "2.0.10"
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.10.tgz#04ffa7f406ab628f7f7e97ca23e290cd8ab15efc"
integrity sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==
"@types/ws@^8.5.5": "@types/ws@^8.5.5":
version "8.5.10" version "8.5.10"
resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz" resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz"
@ -5145,6 +5186,11 @@ camelcase@^6.2.0, camelcase@^6.2.1, camelcase@^6.3.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
camelize@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3"
integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==
caniuse-api@^3.0.0: caniuse-api@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz" resolved "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz"
@ -5208,6 +5254,21 @@ char-regex@^2.0.0:
resolved "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz" resolved "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz"
integrity sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw== integrity sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==
character-entities-legacy@^1.0.0:
version "1.1.4"
resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1"
integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==
character-entities@^1.0.0:
version "1.2.4"
resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b"
integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==
character-reference-invalid@^1.0.0:
version "1.1.4"
resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560"
integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==
chardet@^0.7.0: chardet@^0.7.0:
version "0.7.0" version "0.7.0"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
@ -5424,6 +5485,11 @@ combined-stream@^1.0.8:
dependencies: dependencies:
delayed-stream "~1.0.0" delayed-stream "~1.0.0"
comma-separated-tokens@^1.0.0:
version "1.0.8"
resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea"
integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==
commander@^2.20.0, commander@^2.20.3: commander@^2.20.0, commander@^2.20.3:
version "2.20.3" version "2.20.3"
resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz"
@ -5735,6 +5801,11 @@ css-blank-pseudo@^3.0.3:
dependencies: dependencies:
postcss-selector-parser "^6.0.9" postcss-selector-parser "^6.0.9"
css-color-keywords@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05"
integrity sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==
css-declaration-sorter@^6.3.1: css-declaration-sorter@^6.3.1:
version "6.4.1" version "6.4.1"
resolved "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz" resolved "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz"
@ -5804,6 +5875,15 @@ css-select@^4.1.3:
domutils "^2.8.0" domutils "^2.8.0"
nth-check "^2.0.1" nth-check "^2.0.1"
css-to-react-native@3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.2.0.tgz#cdd8099f71024e149e4f6fe17a7d46ecd55f1e32"
integrity sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==
dependencies:
camelize "^1.0.0"
css-color-keywords "^1.0.0"
postcss-value-parser "^4.0.2"
css-tree@1.0.0-alpha.37: css-tree@1.0.0-alpha.37:
version "1.0.0-alpha.37" version "1.0.0-alpha.37"
resolved "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz" resolved "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz"
@ -5923,6 +6003,11 @@ cssstyle@^2.3.0:
dependencies: dependencies:
cssom "~0.3.6" cssom "~0.3.6"
csstype@3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b"
integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
csstype@^3.0.2: csstype@^3.0.2:
version "3.1.3" version "3.1.3"
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz" resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz"
@ -7309,6 +7394,13 @@ fastq@^1.6.0:
dependencies: dependencies:
reusify "^1.0.4" reusify "^1.0.4"
fault@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13"
integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==
dependencies:
format "^0.2.0"
faye-websocket@^0.11.3: faye-websocket@^0.11.3:
version "0.11.4" version "0.11.4"
resolved "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz" resolved "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz"
@ -7507,6 +7599,11 @@ form-data@^4.0.0:
combined-stream "^1.0.8" combined-stream "^1.0.8"
mime-types "^2.1.12" mime-types "^2.1.12"
format@^0.2.0:
version "0.2.2"
resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b"
integrity sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==
forwarded@0.2.0: forwarded@0.2.0:
version "0.2.0" version "0.2.0"
resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz"
@ -8041,6 +8138,22 @@ hasown@^2.0.0:
dependencies: dependencies:
function-bind "^1.1.2" function-bind "^1.1.2"
hast-util-parse-selector@^2.0.0:
version "2.2.5"
resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a"
integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==
hastscript@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640"
integrity sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==
dependencies:
"@types/hast" "^2.0.0"
comma-separated-tokens "^1.0.0"
hast-util-parse-selector "^2.0.0"
property-information "^5.0.0"
space-separated-tokens "^1.0.0"
he@^1.2.0: he@^1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz"
@ -8051,7 +8164,7 @@ hey-listen@^1.0.8:
resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68" resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68"
integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q== integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==
highlight.js@^10.7.1: highlight.js@^10.4.1, highlight.js@^10.7.1, highlight.js@~10.7.0:
version "10.7.3" version "10.7.3"
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531"
integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==
@ -8438,6 +8551,19 @@ ipaddr.js@^2.0.1:
resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz" resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz"
integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==
is-alphabetical@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d"
integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==
is-alphanumerical@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf"
integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==
dependencies:
is-alphabetical "^1.0.0"
is-decimal "^1.0.0"
is-arguments@^1.0.4, is-arguments@^1.1.1: is-arguments@^1.0.4, is-arguments@^1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz" resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz"
@ -8522,6 +8648,11 @@ is-date-object@^1.0.1, is-date-object@^1.0.5:
dependencies: dependencies:
has-tostringtag "^1.0.0" has-tostringtag "^1.0.0"
is-decimal@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5"
integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==
is-docker@^2.0.0, is-docker@^2.1.1: is-docker@^2.0.0, is-docker@^2.1.1:
version "2.2.1" version "2.2.1"
resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz"
@ -8568,6 +8699,11 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
dependencies: dependencies:
is-extglob "^2.1.1" is-extglob "^2.1.1"
is-hexadecimal@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7"
integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==
is-inside-container@^1.0.0: is-inside-container@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz" resolved "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz"
@ -9930,6 +10066,14 @@ lower-case@^2.0.2:
dependencies: dependencies:
tslib "^2.0.3" tslib "^2.0.3"
lowlight@^1.17.0:
version "1.20.0"
resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.20.0.tgz#ddb197d33462ad0d93bf19d17b6c301aa3941888"
integrity sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==
dependencies:
fault "^1.0.0"
highlight.js "~10.7.0"
"lru-cache@7.10.1 - 7.13.1": "lru-cache@7.10.1 - 7.13.1":
version "7.13.1" version "7.13.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.13.1.tgz#267a81fbd0881327c46a81c5922606a2cfe336c4" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.13.1.tgz#267a81fbd0881327c46a81c5922606a2cfe336c4"
@ -10415,7 +10559,12 @@ mz@^2.4.0, mz@^2.7.0:
object-assign "^4.0.1" object-assign "^4.0.1"
thenify-all "^1.0.0" thenify-all "^1.0.0"
nanoid@^3.3.7: nanoid-dictionary@^5.0.0-beta.1:
version "5.0.0-beta.1"
resolved "https://registry.yarnpkg.com/nanoid-dictionary/-/nanoid-dictionary-5.0.0-beta.1.tgz#f2a2aa05b04f7ac6a9327c62a96146e8aa1b025d"
integrity sha512-xBkL9zzkNjzJ/UnmWyiOUDVX/COoi05eS0oU28RYKFFQhdnzO5dTOPbVZ/fCFgIOGr1zNinDHJ68mm/KQfcgcw==
nanoid@3, nanoid@^3.3.6, nanoid@^3.3.7:
version "3.3.7" version "3.3.7"
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz" resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz"
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
@ -11137,6 +11286,18 @@ parent-module@^1.0.0:
dependencies: dependencies:
callsites "^3.0.0" callsites "^3.0.0"
parse-entities@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8"
integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==
dependencies:
character-entities "^1.0.0"
character-entities-legacy "^1.0.0"
character-reference-invalid "^1.0.0"
is-alphanumerical "^1.0.0"
is-decimal "^1.0.0"
is-hexadecimal "^1.0.0"
parse-json@^4.0.0: parse-json@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
@ -11865,11 +12026,20 @@ postcss-unique-selectors@^5.1.1:
dependencies: dependencies:
postcss-selector-parser "^6.0.5" postcss-selector-parser "^6.0.5"
postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
version "4.2.0" version "4.2.0"
resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
postcss@8.4.31:
version "8.4.31"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d"
integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==
dependencies:
nanoid "^3.3.6"
picocolors "^1.0.0"
source-map-js "^1.0.2"
postcss@^7.0.35: postcss@^7.0.35:
version "7.0.39" version "7.0.39"
resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz" resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz"
@ -11982,6 +12152,16 @@ pretty-format@^29.7.0:
ansi-styles "^5.0.0" ansi-styles "^5.0.0"
react-is "^18.0.0" react-is "^18.0.0"
prismjs@^1.27.0:
version "1.29.0"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12"
integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==
prismjs@~1.27.0:
version "1.27.0"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057"
integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==
proc-log@^3.0.0: proc-log@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-3.0.0.tgz#fb05ef83ccd64fd7b20bbe9c8c1070fc08338dd8" resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-3.0.0.tgz#fb05ef83ccd64fd7b20bbe9c8c1070fc08338dd8"
@ -12036,6 +12216,13 @@ prop-types@15.8.1, prop-types@^15.5.0, prop-types@^15.7.2, prop-types@^15.8.1:
object-assign "^4.1.1" object-assign "^4.1.1"
react-is "^16.13.1" react-is "^16.13.1"
property-information@^5.0.0:
version "5.6.0"
resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69"
integrity sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==
dependencies:
xtend "^4.0.0"
protocols@^2.0.0, protocols@^2.0.1: protocols@^2.0.0, protocols@^2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/protocols/-/protocols-2.0.1.tgz#8f155da3fc0f32644e83c5782c8e8212ccf70a86" resolved "https://registry.yarnpkg.com/protocols/-/protocols-2.0.1.tgz#8f155da3fc0f32644e83c5782c8e8212ccf70a86"
@ -12160,6 +12347,16 @@ react-app-polyfill@^3.0.0:
regenerator-runtime "^0.13.9" regenerator-runtime "^0.13.9"
whatwg-fetch "^3.6.2" whatwg-fetch "^3.6.2"
react-code-blocks@^0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/react-code-blocks/-/react-code-blocks-0.1.6.tgz#ec64e7899223d3e910eb916465a66d95ce1ae1b2"
integrity sha512-ENNuxG07yO+OuX1ChRje3ieefPRz6yrIpHmebQlaFQgzcAHbUfVeTINpOpoI9bSRSObeYo/OdHsporeToZ7fcg==
dependencies:
"@babel/runtime" "^7.10.4"
react-syntax-highlighter "^15.5.0"
styled-components "^6.1.0"
tslib "^2.6.0"
react-day-picker@^8.9.1: react-day-picker@^8.9.1:
version "8.9.1" version "8.9.1"
resolved "https://registry.yarnpkg.com/react-day-picker/-/react-day-picker-8.9.1.tgz#62dcc2bc1282ac72d057266112d9c8558334e757" resolved "https://registry.yarnpkg.com/react-day-picker/-/react-day-picker-8.9.1.tgz#62dcc2bc1282ac72d057266112d9c8558334e757"
@ -12322,6 +12519,17 @@ react-scripts@5.0.1:
optionalDependencies: optionalDependencies:
fsevents "^2.3.2" fsevents "^2.3.2"
react-syntax-highlighter@^15.5.0:
version "15.5.0"
resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz#4b3eccc2325fa2ec8eff1e2d6c18fa4a9e07ab20"
integrity sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==
dependencies:
"@babel/runtime" "^7.3.1"
highlight.js "^10.4.1"
lowlight "^1.17.0"
prismjs "^1.27.0"
refractor "^3.6.0"
react-tabs@^6.0.2: react-tabs@^6.0.2:
version "6.0.2" version "6.0.2"
resolved "https://registry.yarnpkg.com/react-tabs/-/react-tabs-6.0.2.tgz#bc1065c3828561fee285a8fd045f22e0fcdde1eb" resolved "https://registry.yarnpkg.com/react-tabs/-/react-tabs-6.0.2.tgz#bc1065c3828561fee285a8fd045f22e0fcdde1eb"
@ -12491,6 +12699,15 @@ reflect.getprototypeof@^1.0.4:
globalthis "^1.0.3" globalthis "^1.0.3"
which-builtin-type "^1.1.3" which-builtin-type "^1.1.3"
refractor@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.6.0.tgz#ac318f5a0715ead790fcfb0c71f4dd83d977935a"
integrity sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==
dependencies:
hastscript "^6.0.0"
parse-entities "^2.0.0"
prismjs "~1.27.0"
regenerate-unicode-properties@^10.1.0: regenerate-unicode-properties@^10.1.0:
version "10.1.1" version "10.1.1"
resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz" resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz"
@ -12993,6 +13210,11 @@ shallow-clone@^3.0.0:
dependencies: dependencies:
kind-of "^6.0.2" kind-of "^6.0.2"
shallowequal@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
shebang-command@^2.0.0: shebang-command@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"
@ -13156,6 +13378,11 @@ sourcemap-codec@^1.4.8:
resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz" resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz"
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
space-separated-tokens@^1.0.0:
version "1.1.5"
resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899"
integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==
spdx-correct@^3.0.0: spdx-correct@^3.0.0:
version "3.2.0" version "3.2.0"
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c"
@ -13482,6 +13709,21 @@ style-value-types@5.0.0:
hey-listen "^1.0.8" hey-listen "^1.0.8"
tslib "^2.1.0" tslib "^2.1.0"
styled-components@^6.1.0:
version "6.1.8"
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-6.1.8.tgz#c109d36aeea52d8f049e12de2f3be39a6fc86201"
integrity sha512-PQ6Dn+QxlWyEGCKDS71NGsXoVLKfE1c3vApkvDYS5KAK+V8fNWGhbSUEo9Gg2iaID2tjLXegEW3bZDUGpofRWw==
dependencies:
"@emotion/is-prop-valid" "1.2.1"
"@emotion/unitless" "0.8.0"
"@types/stylis" "4.2.0"
css-to-react-native "3.2.0"
csstype "3.1.2"
postcss "8.4.31"
shallowequal "1.1.0"
stylis "4.3.1"
tslib "2.5.0"
stylehacks@^5.1.1: stylehacks@^5.1.1:
version "5.1.1" version "5.1.1"
resolved "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz" resolved "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz"
@ -13490,6 +13732,11 @@ stylehacks@^5.1.1:
browserslist "^4.21.4" browserslist "^4.21.4"
postcss-selector-parser "^6.0.4" postcss-selector-parser "^6.0.4"
stylis@4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.1.tgz#ed8a9ebf9f76fe1e12d462f5cc3c4c980b23a7eb"
integrity sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==
sucrase@^3.32.0: sucrase@^3.32.0:
version "3.34.0" version "3.34.0"
resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz" resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz"
@ -13948,6 +14195,11 @@ tsconfig-paths@^4.1.2:
minimist "^1.2.6" minimist "^1.2.6"
strip-bom "^3.0.0" strip-bom "^3.0.0"
tslib@2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf"
integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==
tslib@^1.8.1: tslib@^1.8.1:
version "1.14.1" version "1.14.1"
resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
@ -15008,7 +15260,7 @@ xss@^1.0.8:
commander "^2.20.3" commander "^2.20.3"
cssfilter "0.0.10" cssfilter "0.0.10"
xtend@~4.0.1: xtend@^4.0.0, xtend@~4.0.1:
version "4.0.2" version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==