Merge pull request from bluesky-social/ts-server

Convert server to Typescript
This commit is contained in:
Daniel Holmgren 2022-01-28 14:08:17 -07:00 committed by GitHub
commit a70dc03ccc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 472 additions and 205 deletions

@ -120,7 +120,7 @@ Binary [CAR file](https://github.com/ipld/go-car) representing a valid user stor
A valid Ucan with attenuation for the following resource:
```
{
'twitter': '${USERNAME}'
'bluesky': '${USERNAME}'
'cap': 'POST'
}
```

@ -7,7 +7,7 @@
"@ipld/car": "^3.2.3",
"@ipld/dag-cbor": "^7.0.0",
"axios": "^0.24.0",
"multiformats": "^9.5.6",
"multiformats": "^9.6.2",
"ucans": "^0.9.0-alpha3"
}
}

@ -0,0 +1,29 @@
import { capabilities, Capability, CapabilitySemantics, CapabilityEscalation, Chained } from "ucans"
export interface BlueskyCapability {
bluesky: string
cap: "POST"
}
export const blueskySemantics: CapabilitySemantics<BlueskyCapability> = {
tryParsing(cap: Capability): BlueskyCapability | null {
if (typeof cap.bluesky === "string" && cap.cap === "POST") {
return {
bluesky: cap.bluesky,
cap: cap.cap,
}
}
return null
},
tryDelegating<T extends BlueskyCapability>(parentCap: T, childCap: T): T | null | CapabilityEscalation<BlueskyCapability> {
// potency is always "POST" for now, so doesn't need to be checked
return childCap.bluesky === parentCap.bluesky ? childCap : null
},
}
export function blueskyCapabilities(ucan: Chained) {
return capabilities(ucan, blueskySemantics)
}

@ -5,3 +5,4 @@ export * from './types'
export * as check from './type-check'
export * as service from './service'
export * as util from './util'
export * as ucanCheck from './ucan-checks'

@ -1,9 +1,9 @@
import * as car from '@ipld/car'
import { CarWriter } from '@ipld/car'
import { BlockWriter } from '@ipld/car/lib/writer-browser'
import { CID } from 'multiformats/cid'
import { flattenUint8Arrays } from './util'
import { streamToArray } from './util'
let globalDB: MemoryDB | null = null
export class MemoryDB {
map: Map<string, any>
@ -12,11 +12,18 @@ export class MemoryDB {
this.map = new Map()
}
async get(k: CID) {
static getGlobal(): MemoryDB {
if (globalDB === null) {
globalDB = new MemoryDB()
}
return globalDB
}
async get(k: CID): Promise<Uint8Array> {
return this.map.get(k.toString())
}
async put(k: CID, v: Uint8Array) {
async put(k: CID, v: Uint8Array): Promise<void> {
this.map.set(k.toString(), v)
}
@ -34,11 +41,7 @@ export class MemoryDB {
}
async getCarFile(root: CID): Promise<Uint8Array> {
const arrays = []
for await (const chunk of this.getCarStream(root)) {
arrays.push(chunk)
}
return flattenUint8Arrays(arrays)
return streamToArray(this.getCarStream(root))
}
}

@ -4,7 +4,7 @@ const SERVER_URL = 'http://localhost:2583'
const THIRD_PARTY_URL = 'http://localhost:2584'
export const register = async (car: Uint8Array, authToken: string): Promise<void> => {
await axios.post(`${SERVER_URL}/register`, car, {
await axios.post(`${SERVER_URL}/user/register`, car, {
headers: {
'Content-Type': 'application/octet-stream',
'Authorization': `Bearer ${authToken}`
@ -13,7 +13,7 @@ export const register = async (car: Uint8Array, authToken: string): Promise<void
}
export const updateUser = async (car: Uint8Array, authToken: string): Promise<void> => {
await axios.post(`${SERVER_URL}/update`, car, {
await axios.post(`${SERVER_URL}/user/update`, car, {
headers: {
'Content-Type': 'application/octet-stream',
'Authorization': `Bearer ${authToken}`

@ -1,7 +1,7 @@
import { Request } from "express"
import * as ucan from "ucans"
import { Chained, isCapabilityEscalation, Ucan } from "ucans"
import { twitterCapabilities }from './twitter-capability'
import { Chained, isCapabilityEscalation } from "ucans"
import { blueskyCapabilities }from './bluesky-capability'
type Check = (ucan: Chained) => Error | null
@ -25,6 +25,13 @@ export const checkUcan = async (req: Request, ...checks: Check[]): Promise<Chain
return decoded
}
export const isRoot = () => (token: Chained): Error | null => {
if (token.proofs && token.proofs.length > 0) {
throw new Error("Ucan is an attenuation and not the root")
}
return null
}
export const hasAudience = (did: string) => (token: Chained): Error | null => {
if(token.audience() !== did) {
return new Error("Ucan audience does not match server Did")
@ -33,9 +40,9 @@ export const hasAudience = (did: string) => (token: Chained): Error | null => {
}
export const hasPostingPermission = (username: string, rootDid: string) => (token: Chained): Error | null => {
for(const cap of twitterCapabilities(token)) {
// has a properly formatted capability for posting to user's twitter account
if(!isCapabilityEscalation(cap) && cap.capability.twitter === username && cap.capability.cap === 'POST') {
for(const cap of blueskyCapabilities(token)) {
// has a properly formatted capability for posting to user's bluesky account
if(!isCapabilityEscalation(cap) && cap.capability.bluesky === username && cap.capability.cap === 'POST') {
if(cap.info.originator !== rootDid) {
return new Error(`Posting permission does not come from the user's root DID: ${rootDid}`)
} else if (cap.info.expiresAt < Date.now() / 1000) {

@ -3,13 +3,16 @@ import IpldStore from "./ipld-store"
import { CID } from 'multiformats/cid'
import { sha256 as blockHasher } from 'multiformats/hashes/sha2'
import * as blockCodec from '@ipld/dag-cbor'
import { CarReader, CarWriter } from '@ipld/car'
import { BlockWriter } from '@ipld/car/lib/writer-browser'
import * as hashmap from 'ipld-hashmap'
import { Didable, Keypair } from "ucans"
import * as hashmap from 'ipld-hashmap'
import { User, Post } from "./types"
import { CarReader } from '@ipld/car'
import { streamToArray } from './util'
export class UserStore {
@ -61,7 +64,7 @@ export class UserStore {
return new UserStore(db, ipldStore, postMap, root, posts, keypair)
}
static async fromCarFile(buf: Uint8Array, keypair: Keypair) {
static async fromCarFile(buf: Uint8Array, db: MemoryDB, keypair: Keypair) {
const car = await CarReader.fromBytes(buf)
const roots = await car.getRoots()
@ -70,7 +73,6 @@ export class UserStore {
}
const root = roots[0]
const db = new MemoryDB()
for await (const block of car.blocks()) {
await db.put(block.cid, block.bytes)
}
@ -118,10 +120,28 @@ export class UserStore {
return posts
}
async getCarFile(): Promise<Uint8Array> {
return this.db.getCarFile(this.root)
getCarStream(): AsyncIterable<Uint8Array> {
const writeDB = async (car: BlockWriter) => {
const addCid = async (cid: CID) => {
car.put({ cid, bytes: await this.db.get(cid) })
}
await addCid(this.root)
const rootObj = await this.ipldStore.getSignedRoot(this.root)
await addCid(rootObj.user)
for await (const cid of this.postMap.cids()) {
await addCid(cid)
}
car.close()
}
const { writer, out } = CarWriter.create([this.root])
writeDB(writer)
return out
}
async getCarFile(): Promise<Uint8Array> {
return streamToArray(this.getCarStream())
}
}
export default UserStore

@ -10,3 +10,11 @@ export const flattenUint8Arrays = (arrs: Uint8Array[]): Uint8Array => {
})
return flattened
}
export const streamToArray = async (stream: AsyncIterable<Uint8Array>): Promise<Uint8Array> => {
const arrays = []
for await (const chunk of stream) {
arrays.push(chunk)
}
return flattenUint8Arrays(arrays)
}

@ -21,9 +21,9 @@ function Register(props: Props) {
const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault()
const keypair = await ucan.EdKeypair.create({ exportable: true })
const twitterDid = await service.getServerDid()
const blueskyDid = await service.getServerDid()
const token = await ucan.build({
audience: twitterDid,
audience: blueskyDid,
issuer: keypair
})
const userStore = await UserStore.create(username, keypair)

@ -2,7 +2,7 @@ import styles from "@components/App.module.scss";
import * as React from "react";
import { service, UserStore, LocalUser, Post } from '@bluesky-demo/common'
import { service, UserStore, MemoryDB, LocalUser, Post } from '@bluesky-demo/common'
import * as ucan from 'ucans'
import App from "@components/App"
@ -20,12 +20,12 @@ function Home(props: {}) {
const addPost = async (post: Post) => {
await store.addPost(post)
const car = await store.getCarFile()
const twitterDid = await service.getServerDid()
const blueskyDid = await service.getServerDid()
const token = await ucan.build({
audience: twitterDid,
audience: blueskyDid,
issuer: localUser.keypair,
capabilities: [{
'twitter': localUser.username,
'bluesky': localUser.username,
'cap': 'POST'
}]
})
@ -38,8 +38,9 @@ function Home(props: {}) {
let userStore: UserStore
try {
const car = await service.fetchUser(localUser.keypair.did())
userStore = await UserStore.fromCarFile(car, localUser.keypair)
userStore = await UserStore.fromCarFile(car, MemoryDB.getGlobal(), localUser.keypair)
} catch (_err) {
// @TODO: show error instead of an empty store
userStore = await createNewStore()
}
setStore(userStore)
@ -66,7 +67,7 @@ function Home(props: {}) {
audience,
issuer: localUser.keypair,
capabilities: [{
'twitter': localUser.username,
'bluesky': localUser.username,
'cap': 'POST'
}]
})
@ -102,9 +103,7 @@ function Home(props: {}) {
// Going to display all users on a server to follow
const loadAllUsers = async () => {
console.log("In loadAllUsers")
let users = await service.fetchUsers()
console.log("All users fetched from server:", users)
setAllUsers(users)
}

@ -246,7 +246,7 @@ var listUsersCmd = &cli.Command{
return err
}
if resp.StatusCode != 200 {
if resp.StatusCode != 200 {
return fmt.Errorf("Error: Non-200 status code: %d", resp.StatusCode)
}
@ -321,7 +321,7 @@ var registerCmd = &cli.Command{
return err
}
req, err := http.NewRequest("POST", r.Account.Server+"/register", buf)
req, err := http.NewRequest("POST", r.Account.Server+"/user/register", buf)
if err != nil {
return err
}
@ -431,7 +431,7 @@ func PushUpdate(ctx context.Context, acc *Account, oldroot cid.Cid, bs blockstor
return err
}
req, err := http.NewRequest("POST", acc.Server+"/update", buf)
req, err := http.NewRequest("POST", acc.Server+"/user/update", buf)
if err != nil {
return err
}

@ -9,6 +9,7 @@
"workspaces": [
"common",
"frontend",
"third-party"
"third-party",
"server"
]
}

22
server/package.json Normal file

@ -0,0 +1,22 @@
{
"name": "@bluesky-demo/server",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"dev": "esr src/index.ts",
"build": "esbuild src/index.ts --outfile=dist/index.js"
},
"devDependencies": {
"@bluesky-demo/common": "*",
"esbuild": "^0.14.10",
"esbuild-runner": "^2.2.1"
},
"dependencies": {
"axios": "^0.24.0",
"cors": "^2.8.5",
"express": "^4.17.2",
"multiformats": "^9.6.2",
"ucans": "0.9.0-alpha3"
}
}

14
server/src/index.ts Normal file

@ -0,0 +1,14 @@
import express from 'express'
import cors from 'cors'
import Routes from './routes'
const app = express()
app.use(express.json())
app.use(cors())
app.use('/', Routes)
const PORT = 2583
app.listen(PORT, () => {
console.log(`🐦 Bluesky server is running at http://localhost:${PORT}`)
})

@ -0,0 +1,12 @@
import express from 'express'
import WellKnown from './well-known'
import User from './user'
import Users from './users'
const router = express.Router()
router.use('/.well-known', WellKnown)
router.use('/user', User)
router.use('/users', Users)
export default router

89
server/src/routes/user.ts Normal file

@ -0,0 +1,89 @@
import express from 'express'
import * as ucan from 'ucans'
import { ucanCheck, UserStore, MemoryDB } from '@bluesky-demo/common'
import * as UserDids from '../user-dids'
import * as UserRoots from '../user-roots'
import { readReqBytes } from '../util'
import { SERVER_KEYPAIR, SERVER_DID } from '../server-identity'
const router = express.Router()
router.post('/register', async (req, res) => {
// We look for a simple Ucan with no capabilities as proof the user is in possession of the given key
let u: ucan.Chained
try {
u = await ucanCheck.checkUcan(
req,
ucanCheck.hasAudience(SERVER_DID),
ucanCheck.isRoot()
)
} catch(err) {
return res.status(401).send(`Invalid Ucan: ${err.toString()}`)
}
let userStore: UserStore
try {
const bytes = await readReqBytes(req)
// @TODO: make a read-only vesion of user store that doesn't require keypair
userStore = await UserStore.fromCarFile(bytes, MemoryDB.getGlobal(), SERVER_KEYPAIR)
}catch(err) {
return res.status(400).send("Could not parse UserStore from CAR File")
}
const user = await userStore.getUser()
const currDid = await UserDids.get(user.name)
if (currDid !== null) {
return res.status(409).send(`Username ${user.name} already taken.`)
}
await Promise.all([
UserDids.set(user.name, u.issuer()),
UserRoots.set(u.issuer(), userStore.root)
])
return res.sendStatus(200)
})
router.post('/update', async (req, res) => {
let userStore: UserStore
try {
const bytes = await readReqBytes(req)
userStore = await UserStore.fromCarFile(bytes, MemoryDB.getGlobal(), SERVER_KEYPAIR)
}catch(err) {
return res.status(400).send("Could not parse UserStore from CAR File")
}
const user = await userStore.getUser()
const userDid = await UserDids.get(user.name)
let u: ucan.Chained
try {
u = await ucanCheck.checkUcan(
req,
ucanCheck.hasAudience(SERVER_DID),
ucanCheck.hasPostingPermission(user.name, userDid)
)
} catch(err) {
return res.status(401).send(err)
}
// @TODO: verify signature on data structure
await UserRoots.set(userDid, userStore.root)
return res.sendStatus(200)
})
router.get('/:id', async (req, res) => {
const { id } = req.params
const userRoot = await UserRoots.get(id)
const userStore = await UserStore.get(userRoot, MemoryDB.getGlobal(), SERVER_KEYPAIR)
const bytes = await userStore.getCarFile()
return res.status(200).send(Buffer.from(bytes))
})
export default router

@ -0,0 +1,11 @@
import express from 'express'
import * as UserDids from '../user-dids'
const router = express.Router()
router.get('/', async (req, res) => {
const dids = await UserDids.listDids()
res.status(200).send(dids)
})
export default router

@ -0,0 +1,28 @@
import express from 'express'
import { SERVER_DID } from '../server-identity'
import * as UserDids from '../user-dids'
const router = express.Router()
// Return the server's did
router.get('/did.json', (_req, res) => {
return res.send({ id: SERVER_DID })}
)
// Retrieve a user's DID by their username
router.get('/webfinger', async (req, res) => {
const { resource } = req.query
if(typeof resource !== 'string') {
return res.status(400).send("Bad param: expected `resource` to be a string")
}
const did = await UserDids.get(resource)
if (!did) {
return res.status(404).send("User DID not found")
}
// @TODO: sketch out more of a webfinger doc
return res.status(200).send({ id: did })
})
export default router

@ -0,0 +1,6 @@
import * as ucan from 'ucans'
// @TODO: For demo only, do not actually store secret keys in plaintext.
const SECRET_KEY = 'JjiTSPfawSBQrxSTEakN8GPvNxwb30MF+R3guCzu78hrzKHjNcFqkF6lTyYuLVpbMCVpPKFJTyju27mw1TA1aQ=='
export const SERVER_KEYPAIR = ucan.EdKeypair.fromSecretKey(SECRET_KEY)
export const SERVER_DID = SERVER_KEYPAIR.did()

14
server/src/user-dids.ts Normal file

@ -0,0 +1,14 @@
const userDids: {[username: string]: string} = {}
// these fns will be async in the future
export const set = async (username: string, did: string): Promise<void> => {
userDids[username] = did
}
export const get = async (username: string): Promise<string | null> => {
return userDids[username] || null
}
export const listDids = async (): Promise<string[]> => {
return Object.values(userDids)
}

12
server/src/user-roots.ts Normal file

@ -0,0 +1,12 @@
import { CID } from 'multiformats/cid'
const userRoots: {[did: string]: CID} = {}
// these fns will be async in the future
export const set = async (did: string, cid: CID): Promise<void> => {
userRoots[did] = cid
}
export const get = async (did: string): Promise<CID | null> => {
return userRoots[did] || null
}

17
server/src/util.ts Normal file

@ -0,0 +1,17 @@
import { Request } from "express";
export const readReqBytes = async (req: Request): Promise<Uint8Array> => {
return new Promise((resolve) => {
const chunks: Buffer[] = []
req.on('data', (chunk) => {
chunks.push(chunk)
})
req.on('end', () => {
resolve(
new Uint8Array(Buffer.concat(chunks))
)
})
})
}

@ -1,13 +1,12 @@
import express from 'express'
import cors from 'cors'
import * as ucan from 'ucans'
import * as check from './ucan-checks'
import { service, UserStore } from '@bluesky-demo/common'
import { service, UserStore, MemoryDB, ucanCheck } from '@bluesky-demo/common'
// WARNING: For demo only, do not actually store secret keys in plaintext.
const SECRET_KEY = 'I0HyDksQcCRdJBGVuE78Ts34SzyF7+xNprEQw/IRa51OuFZQc5ugqfgjeWRMehyfr7A1vXICRoUD5kqVadsRHA=='
const SERVER_KEY = ucan.EdKeypair.fromSecretKey(SECRET_KEY)
const SERVER_DID = SERVER_KEY.did()
const SERVER_KEYPAIR = ucan.EdKeypair.fromSecretKey(SECRET_KEY)
const SERVER_DID = SERVER_KEYPAIR.did()
const app = express()
app.use(express.json())
@ -25,7 +24,7 @@ app.post('/post', async (req, res) => {
return res.status(400).send("Bad param: 'username' should be a string")
}
// Get the user's root DID from twitter
// Get the user's root DID from bluesky
const userDid = await service.fetchUserDid(username)
if (!userDid) {
return res.status(401).send("User DID not found")
@ -34,23 +33,27 @@ app.post('/post', async (req, res) => {
// Check that it's a valid ucan, that it's meant for this server, and that it has permission to post for the given username
let u: ucan.Chained
try {
u = await check.checkUcan(req, check.hasAudience(SERVER_DID), check.hasPostingPermission(username, userDid))
u = await ucanCheck.checkUcan(
req,
ucanCheck.hasAudience(SERVER_DID),
ucanCheck.hasPostingPermission(username, userDid)
)
} catch (err) {
return res.status(401).send(err)
}
// Create a new Ucan to send to twitter using the user's Ucan as proof that we have permission to post on their behalf
const twitterDid = await service.getServerDid()
// Create a new Ucan to send to bluesky using the user's Ucan as proof that we have permission to post on their behalf
const blueskyDid = await service.getServerDid()
const extendUcan = await ucan.build({
audience: twitterDid,
issuer: SERVER_KEY,
audience: blueskyDid,
issuer: SERVER_KEYPAIR,
capabilities: u.attenuation(),
proofs: [u.encoded()]
})
const encoded = ucan.encode(extendUcan)
const car = await service.fetchUser(userDid)
const userStore = await UserStore.fromCarFile(car, SERVER_KEY)
const userStore = await UserStore.fromCarFile(car, MemoryDB.getGlobal(), SERVER_KEYPAIR)
await userStore.addPost({
user: username,
text: `Hey there! I'm posting on ${username}'s behalf`

@ -1,29 +0,0 @@
import { capabilities, Capability, CapabilitySemantics, CapabilityEscalation, Chained } from "ucans"
export interface TwitterCapability {
twitter: string
cap: "POST"
}
export const twitterSemantics: CapabilitySemantics<TwitterCapability> = {
tryParsing(cap: Capability): TwitterCapability | null {
if (typeof cap.twitter === "string" && cap.cap === "POST") {
return {
twitter: cap.twitter,
cap: cap.cap,
}
}
return null
},
tryDelegating<T extends TwitterCapability>(parentCap: T, childCap: T): T | null | CapabilityEscalation<TwitterCapability> {
// potency is always "POST" for now, so doesn't need to be checked
return childCap.twitter === parentCap.twitter ? childCap : null
},
}
export function twitterCapabilities(ucan: Chained) {
return capabilities(ucan, twitterSemantics)
}

254
yarn.lock

@ -20,9 +20,9 @@
integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==
"@babel/highlight@^7.10.4":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.7.tgz#81a01d7d675046f0d96f82450d9d9578bdfd6b0b"
integrity sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==
version "7.16.10"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88"
integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==
dependencies:
"@babel/helper-validator-identifier" "^7.16.7"
chalk "^2.0.0"
@ -233,9 +233,9 @@
integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==
"@types/express-serve-static-core@^4.17.18":
version "4.17.27"
resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.27.tgz#7a776191e47295d2a05962ecbb3a4ce97e38b401"
integrity sha512-e/sVallzUTPdyOTiqi8O8pMdBBphscvI6E4JYaKlja4Lm+zh7UFSSdW5VMkRbhDtmrONqOUHOXRguPsDckzxNA==
version "4.17.28"
resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz#c47def9f34ec81dc6328d0b1b5303d1ec98d86b8"
integrity sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==
dependencies:
"@types/node" "*"
"@types/qs" "*"
@ -257,9 +257,9 @@
integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==
"@types/node@*":
version "17.0.8"
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.8.tgz#50d680c8a8a78fe30abe6906453b21ad8ab0ad7b"
integrity sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg==
version "17.0.12"
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.12.tgz#f7aa331b27f08244888c47b7df126184bc2339c5"
integrity sha512-4YpbAsnJXWYK/fpTVFlMIcUIho2AYCi4wg5aNPrG1ng7fn/1/RZfCIpRCiBX+12RVa34RluilnvCqD+g3KiSiA==
"@types/prop-types@*":
version "15.7.4"
@ -641,14 +641,14 @@ camelcase@^6.2.0:
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
caniuse-lite@^1.0.30001202, caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001228:
version "1.0.30001296"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001296.tgz#d99f0f3bee66544800b93d261c4be55a35f1cec8"
integrity sha512-WfrtPEoNSoeATDlf4y3QvkwiELl9GyPLISV5GejTbbQRtQx4LhsXmc9IQ6XCL2d7UxCyEzToEZNMeqR79OUw8Q==
version "1.0.30001302"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001302.tgz#da57ce61c51177ef3661eeed7faef392d3790aaa"
integrity sha512-YYTMO+tfwvgUN+1ZnRViE53Ma1S/oETg+J2lISsqi/ZTNThj3ZYBOKP2rHwJc37oCsPqAzJ3w2puZHn0xlLPPw==
cborg@^1.5.4, cborg@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/cborg/-/cborg-1.6.0.tgz#07975681efb2a1ee33c696c5b7bf62092fddc542"
integrity sha512-zNgXCO0jlGDKh8EQO34PziChBZhOoLf3qjkS0VtKy4jEKjEX/PbrKYQ1QP+960rxmC3fUuN1yOeq4Frf2E9RTw==
version "1.6.1"
resolved "https://registry.yarnpkg.com/cborg/-/cborg-1.6.1.tgz#d5c6f6cfa8539588918c3936814caddc65e8e5ec"
integrity sha512-dOGlTG610S6t3j7EYFxPBH7KiF1OlSAdWtMI4Iv1dabcId/L/nUvkfOEPge+vDp9YoPerEMiDoy5+Vm2oEqmQw==
chalk@2.4.2, chalk@^2.0.0:
version "2.4.2"
@ -691,9 +691,9 @@ chokidar@3.5.1:
fsevents "~2.3.1"
"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.2:
version "3.5.2"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75"
integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==
version "3.5.3"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
dependencies:
anymatch "~3.1.2"
braces "~3.0.2"
@ -1032,9 +1032,9 @@ ee-first@1.1.1:
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
electron-to-chromium@^1.3.723:
version "1.4.35"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.35.tgz#69aabb73d7030733e71c1e970ec16f5ceefbaea4"
integrity sha512-wzTOMh6HGFWeALMI3bif0mzgRrVGyP1BdFRx7IvWukFrSC5QVQELENuy+Fm2dCrAdQH9T3nuqr07n94nPDFBWA==
version "1.4.53"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.53.tgz#5d80a91c399b44952ef485857fb5b9d4387d2e60"
integrity sha512-rFveSKQczlcav+H3zkKqykU6ANseFwXwkl855jOIap5/0gnEcuIhv2ecz6aoTrXavF6I/CEBeRnBnkB51k06ew==
elliptic@^6.5.3:
version "6.5.4"
@ -1126,75 +1126,75 @@ es6-object-assign@^1.1.0:
resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c"
integrity sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=
esbuild-android-arm64@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.10.tgz#c854db57dc2d4df6f4f62185ca812f26a132bf1e"
integrity sha512-vzkTafHKoiMX4uIN1kBnE/HXYLpNT95EgGanVk6DHGeYgDolU0NBxjO7yZpq4ZGFPOx8384eAdDrBYhO11TAlQ==
esbuild-android-arm64@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.14.tgz#3705f32f209deeb11c275af47c298c8783dd5f0c"
integrity sha512-be/Uw6DdpQiPfula1J4bdmA+wtZ6T3BRCZsDMFB5X+k0Gp8TIh9UvmAcqvKNnbRAafSaXG3jPCeXxDKqnc8hFQ==
esbuild-darwin-64@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.10.tgz#c44fab6b8bfc83e5d083f513e4acbff14fb82eac"
integrity sha512-DJwzFVB95ZV7C3PQbf052WqaUuuMFXJeZJ0LKdnP1w+QOU0rlbKfX0tzuhoS//rOXUj1TFIwRuRsd0FX6skR7A==
esbuild-darwin-64@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.14.tgz#c07e4eae6d938300a2d330ea82494c55bcea84e5"
integrity sha512-BEexYmjWafcISK8cT6O98E3TfcLuZL8DKuubry6G54n2+bD4GkoRD6HYUOnCkfl2p7jodA+s4369IjSFSWjtHg==
esbuild-darwin-arm64@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.10.tgz#9454b3763b36407dc395c4c3529fb5ddd4a6225f"
integrity sha512-RNaaoZDg3nsqs5z56vYCjk/VJ76npf752W0rOaCl5lO5TsgV9zecfdYgt7dtUrIx8b7APhVaNYud+tGsDOVC9g==
esbuild-darwin-arm64@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.14.tgz#a8631e13a51a6f784fb0906e2a64c6ab53988755"
integrity sha512-tnBKm41pDOB1GtZ8q/w26gZlLLRzVmP8fdsduYjvM+yFD7E2DLG4KbPAqFMWm4Md9B+DitBglP57FY7AznxbTg==
esbuild-freebsd-64@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.10.tgz#04eef46d5d5e4152c6b5a6a12f432db0fe7c89de"
integrity sha512-10B3AzW894u6bGZZhWiJOHw1uEHb4AFbUuBdyml1Ht0vIqd+KqWW+iY/yMwQAzILr2WJZqEhbOXRkJtY8aRqOw==
esbuild-freebsd-64@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.14.tgz#c280c2b944746b27ee6c6487c2691865c90bed2e"
integrity sha512-Q9Rx6sgArOHalQtNwAaIzJ6dnQ8A+I7f/RsQsdkS3JrdzmnlFo8JEVofTmwVQLoIop7OKUqIVOGP4PoQcwfVMA==
esbuild-freebsd-arm64@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.10.tgz#67ca88529543ada948737c95819253ead16494a7"
integrity sha512-mSQrKB7UaWvuryBTCo9leOfY2uEUSimAvcKIaUWbk5Hth9Sg+Try+qNA/NibPgs/vHkX0KFo/Rce6RPea+P15g==
esbuild-freebsd-arm64@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.14.tgz#aa4e21276efcf20e5ab2487e91ca1d789573189b"
integrity sha512-TJvq0OpLM7BkTczlyPIphcvnwrQwQDG1HqxzoYePWn26SMUAlt6wrLnEvxdbXAvNvDLVzG83kA+JimjK7aRNBA==
esbuild-linux-32@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.10.tgz#8f3d5fb0b9b616d6b604da781d71767d7679f64f"
integrity sha512-lktF09JgJLZ63ANYHIPdYe339PDuVn19Q/FcGKkXWf+jSPkn5xkYzAabboNGZNUgNqSJ/vY7VrOn6UrBbJjgYA==
esbuild-linux-32@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.14.tgz#3db4d929239203ce38a9060d5419ac6a6d28846c"
integrity sha512-h/CrK9Baimt5VRbu8gqibWV7e1P9l+mkanQgyOgv0Ng3jHT1NVFC9e6rb1zbDdaJVmuhWX5xVliUA5bDDCcJeg==
esbuild-linux-64@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.10.tgz#c1c60a079c4709164bdd89fbb007a2edeea7c34a"
integrity sha512-K+gCQz2oLIIBI8ZM77e9sYD5/DwEpeYCrOQ2SYXx+R4OU2CT9QjJDi4/OpE7ko4AcYMlMW7qrOCuLSgAlEj4Wg==
esbuild-linux-64@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.14.tgz#f880026254c1f565a7a10fdebb7cff9b083a127d"
integrity sha512-IC+wAiIg/egp5OhQp4W44D9PcBOH1b621iRn1OXmlLzij9a/6BGr9NMIL4CRwz4j2kp3WNZu5sT473tYdynOuQ==
esbuild-linux-arm64@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.10.tgz#d8f1f89190f6d8b6e06a1214aafba454e5daa990"
integrity sha512-+qocQuQvcp5wo/V+OLXxqHPc+gxHttJEvbU/xrCGE03vIMqraL4wMua8JQx0SWEnJCWP+Nhf//v8OSwz1Xr5kA==
esbuild-linux-arm64@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.14.tgz#a34bc3076e50b109c3b8c8bad9c146e35942322b"
integrity sha512-6QVul3RI4M5/VxVIRF/I5F+7BaxzR3DfNGoqEVSCZqUbgzHExPn+LXr5ly1C7af2Kw4AHpo+wDqx8A4ziP9avw==
esbuild-linux-arm@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.10.tgz#43192a00019a4553fb44e67f628fff0f560f16c2"
integrity sha512-BYa60dZ/KPmNKYxtHa3LSEdfKWHcm/RzP0MjB4AeBPhjS0D6/okhaBesZIY9kVIGDyeenKsJNOmnVt4+dhNnvQ==
esbuild-linux-arm@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.14.tgz#231ffd12fef69ee06365d4c94b69850e4830e927"
integrity sha512-gxpOaHOPwp7zSmcKYsHrtxabScMqaTzfSQioAMUaB047YiMuDBzqVcKBG8OuESrYkGrL9DDljXr/mQNg7pbdaQ==
esbuild-linux-mips64le@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.10.tgz#f57bb8b2f1a3063cc91cfd787c8a9130cf863c16"
integrity sha512-nmUd2xoBXpGo4NJCEWoaBj+n4EtDoLEvEYc8Z3aSJrY0Oa6s04czD1flmhd0I/d6QEU8b7GQ9U0g/rtBfhtxBg==
esbuild-linux-mips64le@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.14.tgz#bd00570e3a30422224b732c7a5f262146c357403"
integrity sha512-4Jl5/+xoINKbA4cesH3f4R+q0vltAztZ6Jm8YycS8lNhN1pgZJBDxWfI6HUMIAdkKlIpR1PIkA9aXQgZ8sxFAg==
esbuild-linux-ppc64le@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.10.tgz#becd965bfe3425d41e026f1c4678b393127fecbd"
integrity sha512-vsOWZjm0rZix7HSmqwPph9arRVCyPtUpcURdayQDuIhMG2/UxJxpbdRaa//w4zYqcJzAWwuyH2PAlyy0ZNuxqQ==
esbuild-linux-ppc64le@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.14.tgz#430609413fd9e04d9def4e3f06726b031b23d825"
integrity sha512-BitW37GxeebKxqYNl4SVuSdnIJAzH830Lr6Mkq3pBHXtzQay0vK+IeOR/Ele1GtNVJ+/f8wYM53tcThkv5SC5w==
esbuild-linux-s390x@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.10.tgz#cc4228ac842febc48b84757814bed964a619be62"
integrity sha512-knArKKZm0ypIYWOWyOT7+accVwbVV1LZnl2FWWy05u9Tyv5oqJ2F5+X2Vqe/gqd61enJXQWqoufXopvG3zULOg==
esbuild-linux-s390x@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.14.tgz#2f0d8cbfe53cf3cb97f6372549a41a8051dbd689"
integrity sha512-vLj6p76HOZG3wfuTr5MyO3qW5iu8YdhUNxuY+tx846rPo7GcKtYSPMusQjeVEfZlJpSYoR+yrNBBxq+qVF9zrw==
esbuild-netbsd-64@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.10.tgz#6ec50d9e4547a7579f447307b19f66bbedfd868b"
integrity sha512-6Gg8neVcLeyq0yt9bZpReb8ntZ8LBEjthxrcYWVrBElcltnDjIy1hrzsujt0+sC2rL+TlSsE9dzgyuvlDdPp2w==
esbuild-netbsd-64@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.14.tgz#3e44de35e1add7e9582f3c0d2558d86aafbc813b"
integrity sha512-fn8looXPQhpVqUyCBWUuPjesH+yGIyfbIQrLKG05rr1Kgm3rZD/gaYrd3Wpmf5syVZx70pKZPvdHp8OTA+y7cQ==
esbuild-openbsd-64@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.10.tgz#925ac3d2326cc219d514e1ca806e80e5143aa043"
integrity sha512-9rkHZzp10zI90CfKbFrwmQjqZaeDmyQ6s9/hvCwRkbOCHuto6RvMYH9ghQpcr5cUxD5OQIA+sHXi0zokRNXjcg==
esbuild-openbsd-64@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.14.tgz#04710ef1d01cd9f15d54f50d20b5a3778f8306a2"
integrity sha512-HdAnJ399pPff3SKbd8g+P4o5znseni5u5n5rJ6Z7ouqOdgbOwHe2ofZbMow17WMdNtz1IyOZk2Wo9Ve6/lZ4Rg==
esbuild-runner@^2.2.1:
version "2.2.1"
@ -1204,49 +1204,49 @@ esbuild-runner@^2.2.1:
source-map-support "0.5.19"
tslib "2.3.1"
esbuild-sunos-64@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.10.tgz#8d3576d8cac5c4f9f2a84be81b9078d424dbc739"
integrity sha512-mEU+pqkhkhbwpJj5DiN3vL0GUFR/yrL3qj8ER1amIVyRibKbj02VM1QaIuk1sy5DRVIKiFXXgCaHvH3RNWCHIw==
esbuild-sunos-64@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.14.tgz#8e583dd92c5c7ac4303ddc37f588e44211e04e19"
integrity sha512-bmDHa99ulsGnYlh/xjBEfxoGuC8CEG5OWvlgD+pF7bKKiVTbtxqVCvOGEZeoDXB+ja6AvHIbPxrEE32J+m5nqQ==
esbuild-windows-32@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.10.tgz#8a67fca4cb594a340566d66eef3f568f65057a48"
integrity sha512-Z5DieUL1N6s78dOSdL95KWf8Y89RtPGxIoMF+LEy8ChDsX+pZpz6uAVCn+YaWpqQXO+2TnrcbgBIoprq2Mco1g==
esbuild-windows-32@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.14.tgz#6d293ddfb71229f21cc13d85d5d2f43e8131693b"
integrity sha512-6tVooQcxJCNenPp5GHZBs/RLu31q4B+BuF4MEoRxswT+Eq2JGF0ZWDRQwNKB8QVIo3t6Svc5wNGez+CwKNQjBg==
esbuild-windows-64@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.10.tgz#5e6d7c475ff6a71ad0aa4046894364e6c40a9249"
integrity sha512-LE5Mm62y0Bilu7RDryBhHIX8rK3at5VwJ6IGM3BsASidCfOBTzqcs7Yy0/Vkq39VKeTmy9/66BAfVoZRNznoDw==
esbuild-windows-64@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.14.tgz#08a36844b69542f8ec1cb33a5ddcea02b9d0b2e8"
integrity sha512-kl3BdPXh0/RD/dad41dtzj2itMUR4C6nQbXQCyYHHo4zoUoeIXhpCrSl7BAW1nv5EFL8stT1V+TQVXGZca5A2A==
esbuild-windows-arm64@0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.10.tgz#50ab9a83f6ccf71c272e58489ecc4d7375075f32"
integrity sha512-OJOyxDtabvcUYTc+O4dR0JMzLBz6G9+gXIHA7Oc5d5Fv1xiYa0nUeo8+W5s2e6ZkPRdIwOseYoL70rZz80S5BA==
esbuild-windows-arm64@0.14.14:
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.14.tgz#ca747ce4066d5b8a79dbe48fe6ecd92d202e5366"
integrity sha512-dCm1wTOm6HIisLanmybvRKvaXZZo4yEVrHh1dY0v582GThXJOzuXGja1HIQgV09RpSHYRL3m4KoUBL00l6SWEg==
esbuild@^0.14.10:
version "0.14.10"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.10.tgz#10268d2b576b25ed6f8554553413988628a7767b"
integrity sha512-ibZb+NwFqBwHHJlpnFMtg4aNmVK+LUtYMFC9CuKs6lDCBEvCHpqCFZFEirpqt1jOugwKGx8gALNGvX56lQyfew==
version "0.14.14"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.14.tgz#3b99f20d628013c3e2ae90e67687e03f1d6eb071"
integrity sha512-aiK4ddv+uui0k52OqSHu4xxu+SzOim7Rlz4i25pMEiC8rlnGU0HJ9r+ZMfdWL5bzifg+nhnn7x4NSWTeehYblg==
optionalDependencies:
esbuild-android-arm64 "0.14.10"
esbuild-darwin-64 "0.14.10"
esbuild-darwin-arm64 "0.14.10"
esbuild-freebsd-64 "0.14.10"
esbuild-freebsd-arm64 "0.14.10"
esbuild-linux-32 "0.14.10"
esbuild-linux-64 "0.14.10"
esbuild-linux-arm "0.14.10"
esbuild-linux-arm64 "0.14.10"
esbuild-linux-mips64le "0.14.10"
esbuild-linux-ppc64le "0.14.10"
esbuild-linux-s390x "0.14.10"
esbuild-netbsd-64 "0.14.10"
esbuild-openbsd-64 "0.14.10"
esbuild-sunos-64 "0.14.10"
esbuild-windows-32 "0.14.10"
esbuild-windows-64 "0.14.10"
esbuild-windows-arm64 "0.14.10"
esbuild-android-arm64 "0.14.14"
esbuild-darwin-64 "0.14.14"
esbuild-darwin-arm64 "0.14.14"
esbuild-freebsd-64 "0.14.14"
esbuild-freebsd-arm64 "0.14.14"
esbuild-linux-32 "0.14.14"
esbuild-linux-64 "0.14.14"
esbuild-linux-arm "0.14.14"
esbuild-linux-arm64 "0.14.14"
esbuild-linux-mips64le "0.14.14"
esbuild-linux-ppc64le "0.14.14"
esbuild-linux-s390x "0.14.14"
esbuild-netbsd-64 "0.14.14"
esbuild-openbsd-64 "0.14.14"
esbuild-sunos-64 "0.14.14"
esbuild-windows-32 "0.14.14"
esbuild-windows-64 "0.14.14"
esbuild-windows-arm64 "0.14.14"
escalade@^3.1.1:
version "3.1.1"
@ -1360,9 +1360,9 @@ find-up@^4.0.0:
path-exists "^4.0.0"
follow-redirects@^1.14.4:
version "1.14.6"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.6.tgz#8cfb281bbc035b3c067d6cd975b0f6ade6e855cd"
integrity sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==
version "1.14.7"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685"
integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==
foreach@^2.0.5:
version "2.0.5"
@ -2061,15 +2061,15 @@ ms@2.1.3, ms@^2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
multiformats@^9.1.2, multiformats@^9.4.2, multiformats@^9.5.4, multiformats@^9.5.6:
version "9.5.6"
resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.5.6.tgz#316c702117b21f5f53ed0f2857a117b361ae5af2"
integrity sha512-FAM5VaBdBl9Ya+DssXsWgZ+Nao07RtFUc+w0IgEuyHrg1b1ms+QoMUw8h7rtKcLuaJwfYJdf3Ms1205nq+j+Zg==
multiformats@^9.1.2, multiformats@^9.4.2, multiformats@^9.5.4, multiformats@^9.6.2:
version "9.6.2"
resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.6.2.tgz#3dd8f696171a367fa826b7c432851da850eb115e"
integrity sha512-1dKng7RkBelbEZQQD2zvdzYKgUmtggpWl+GXQBYhnEGGkV6VIYfWgV3VSeyhcUFFEelI5q4D0etCJZ7fbuiamQ==
nanoid@^3.1.23:
version "3.1.30"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362"
integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==
version "3.2.0"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c"
integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==
native-url@0.3.4:
version "0.3.4"
@ -3109,9 +3109,9 @@ typedarray-to-buffer@^3.1.5:
is-typedarray "^1.0.0"
typescript@^4.4.2:
version "4.5.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8"
integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==
version "4.5.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.5.tgz#d8c953832d28924a9e3d37c73d729c846c5896f3"
integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==
ucans@0.9.0-alpha3, ucans@^0.9.0-alpha3:
version "0.9.0-alpha3"