refactor(dx): auto-generate types for frontend objects and responses #2388

This commit is contained in:
upsiflu 2025-01-29 14:11:36 +01:00
parent a3d1dd8c16
commit 7eae134085
6 changed files with 182 additions and 198 deletions

View File

@ -6,10 +6,10 @@
"description": "Funkwhale front-end",
"author": "Funkwhale Collective <contact@funkwhale.audio>",
"scripts": {
"dev": "vite",
"dev": "yarn run update-schema && vite",
"dev:docs": "VP_DOCS=true vitepress dev ui-docs",
"build": "vite build --mode development",
"build:deployment": "vite build",
"build": "yarn run update-schema && vite build --mode development",
"build:deployment": "yarn run update-schema && vite build",
"build:docs": "VP_DOCS=true vitepress build ui-docs",
"serve:docs": "VP_DOCS=true vitepress serve ui-docs",
"serve": "vite preview",
@ -17,7 +17,8 @@
"test:unit": "vitest run --coverage",
"test:generate-mock-server": "msw-auto-mock ../docs/schema.yml -o test/msw-server.ts --node",
"lint": "eslint --cache --cache-strategy content --ext .ts,.js,.vue,.json,.html src test cypress public/embed.html",
"lint:tsc": "vue-tsc --noEmit --incremental && tsc --noEmit --incremental -p cypress"
"lint:tsc": "vue-tsc --noEmit --incremental && tsc --noEmit --incremental -p cypress",
"update-schema": "yarn run openapi-typescript https://docs.funkwhale.audio/develop/swagger/schema.yml -o src/generated/types.ts"
},
"dependencies": {
"@sentry/tracing": "7.47.0",
@ -106,6 +107,7 @@
"jsonc-eslint-parser": "2.4.0",
"msw": "2.2.1",
"msw-auto-mock": "0.18.0",
"openapi-typescript": "7.6.0",
"patch-package": "8.0.0",
"rollup-plugin-visualizer": "5.9.0",
"sass": "1.68.0",

View File

@ -12,7 +12,9 @@ import Link from '~/components/ui/Link.vue'
import TagsList from '~/components/tags/List.vue'
import Spacer from '~/components/ui/Spacer.vue'
import type { Album } from '~/types'
import { type components } from '~/generated/types.ts'
type Album = components['schemas']['Album']
const play = defineEmit<[album: Album]>()

View File

@ -1,6 +1,7 @@
<script setup lang="ts">
import type { OrderingProps } from '~/composables/navigation/useOrdering'
import type { Artist, BackendResponse } from '~/types'
import type { Album, PaginatedAlbumList } from '~/types'
import { type operations } from '~/generated/types.ts'
import type { RouteRecordName } from 'vue-router'
import type { OrderingField } from '~/store/ui'
@ -55,7 +56,7 @@ const q = useRouteQuery('query', '')
const query = ref(q.value)
syncRef(q, query, { direction: 'ltr' })
const result = ref<BackendResponse<Album>>()
const result = ref<PaginatedAlbumList>()
const orderingOptions: [OrderingField, keyof typeof sharedLabels.filters][] = [
['creation_date', 'creation_date'],
@ -71,21 +72,22 @@ const { onOrderingUpdate, orderingString, paginateBy, ordering, orderingDirectio
const isLoading = ref(false)
const fetchData = async () => {
isLoading.value = true
const params = {
const params : operations['get_album_fetches_2']['parameters']['query'] = {
scope: props.scope,
page: page.value,
page_size: paginateBy.value,
q: query.value,
// @ts-ignore
ordering: orderingString.value,
playable: 'true',
playable: true,
tag: tags.value,
include_channels: 'true',
include_channels: true,
content_category: 'music'
}
const measureLoading = logger.time('Fetching albums')
try {
const response = await axios.get('albums/', {
const response = await axios.get<PaginatedAlbumList>('albums/', {
params,
paramsSerializer: {
indexes: null
@ -216,7 +218,7 @@ const paginateOptions = computed(() => sortedUniq([12, 30, 50, paginateBy.value]
small
primary
@click="store.commit('ui/toggleModal', 'upload')"
:aria-pressed="store.state.ui.modalsOpen.has('upload') || undefine"
:aria-pressed="store.state.ui.modalsOpen.has('upload') || undefined"
>
<template #image>
<i class="bi bi-upload" style="font-size: 100px; position: relative; top: 50px;" />

View File

@ -0,0 +1,4 @@
/**
* Cannot commit this file because it is too large.
* Run `yarn update-schema` to regenerate it.
*/

View File

@ -4,6 +4,9 @@ import type { Router } from 'vue-router'
import type { AxiosError } from 'axios'
import type { RootState } from '~/store'
// App types are synced from the backend. Run `yarn update-schema`.
import { type components } from '~/generated/types.ts'
// eslint-disable-next-line
import type { ComponentPublicInstance } from '@vue/runtime-core'
import type { QueueTrack } from '~/composables/audio/queue'
@ -41,190 +44,47 @@ export interface ThemeEntry {
// Track stuff
export type ContentCategory = 'podcast' | 'music'
export interface Artist {
id: number
fid: string
mbid?: string
name: string
description: Content
cover?: Cover
channel?: Channel
// TODO (wvffle): Check if it's Tag[] or string[]
tags: string[]
// Use backend-defined schema types
content_category: ContentCategory
albums: Album[]
tracks_count: number
attributed_to: Actor
is_local: boolean
is_playable: boolean
modification_date?: string
}
export type APIActor = components['schemas']['APIActor']
export type Activity = components['schemas']['Activity']
export type Album = components['schemas']['Album']
export type ArtistCredit = components['schemas']['ArtistCredit']
export type Channel = components['schemas']['Channel']
export type Library = components['schemas']['Library']
export type License = components['schemas']['License']
export type Listening = components['schemas']['Listening']
export type Playlist = components['schemas']['Playlist']
export type PlaylistTrack = components['schemas']['PlaylistTrack']
export type PrivacyLevelEnum = components['schemas']['PrivacyLevelEnum']
export type Radio = components['schemas']['Radio']
export type SearchResult = components['schemas']['SearchResult']
export type Tag = components['schemas']['Tag']
export type Track = components['schemas']['Track']
export type Usage = components['schemas']['Usage']
export type LibraryScan = components['schemas']['LibraryScan']
export type LibraryFollow = components["schemas"]["LibraryFollow"]
export type Cover = components["schemas"]["CoverField"]
export type RateLimitStatus = components["schemas"]["RateLimit"]
export type PaginatedAlbumList = components["schemas"]["PaginatedAlbumList"]
export interface ArtistCredit {
artist: Artist
credit: string
joinphrase: string
index: number
}
// export type Artist = components['schemas']['Artist']
export interface Album {
id: number
fid: string
mbid?: string
export type PrivacyLevel = components['schemas']['LibraryPrivacyLevelEnum']
title: string
description: Content
release_date?: string
cover?: Cover
tags: string[]
export type ImportStatus = components['schemas']['ImportStatusEnum']
artist_credit: ArtistCredit[]
tracks_count: number
tracks: Track[]
// TODO: Find out which type: `Follow` or `LibraryFollow`
// export interface UserFollow {
// uuid: string
// approved: boolean
is_playable: boolean
is_local: boolean
}
// name: string
// type?: 'federation.Actor' | 'federation.UserFollow'
// target?: Actor
// }
export interface Track {
id: number
fid: string
mbid?: string
title: string
description: Content
cover?: Cover
position?: number
copyright?: string
license?: License
tags: string[]
uploads: Upload[]
downloads_count: number
album?: Album
artist_credit: ArtistCredit[]
disc_number: number
listen_url: string
creation_date: string
attributed_to: Actor
is_playable: boolean
is_local: boolean
}
export interface Channel {
id: number
uuid: string
artist?: Artist
actor: Actor
attributed_to: Actor
url?: string
rss_url: string
subscriptions_count: number
downloads_count: number
content_category: ContentCategory
metadata?: {
itunes_category?: unknown
itunes_subcategory?: unknown
language?: string
owner_name?: string
owner_email?: string
}
}
export type PrivacyLevel = 'everyone' | 'instance' | 'me'
export interface Library {
id: number
uuid: string
fid?: string
name: string
actor: Actor
uploads_count: number
size: number
description: string
privacy_level: PrivacyLevel
creation_date: string
follow?: LibraryFollow
latest_scan: LibraryScan
}
export type ImportStatus = 'scanning' | 'pending' | 'finished' | 'errored' | 'draft' | 'skipped'
export interface LibraryScan {
processed_files: number
total_files: number
status: ImportStatus
errored_files: number
modification_date: string
}
export interface LibraryFollow {
uuid: string
approved: boolean
name: string
type?: 'music.Library' | 'federation.LibraryFollow'
target: Library
}
export interface UserFollow {
uuid: string
approved: boolean
name: string
type?: 'federation.Actor' | 'federation.UserFollow'
target?: Actor
}
export interface Cover {
uuid: string
urls: {
original: string
medium_square_crop: string
large_square_crop: string
}
}
export interface License {
code: string
name: string
url: string
}
export interface Playlist {
id: number
name: string
modification_date: string
actor: Actor
privacy_level: PrivacyLevel
tracks_count: number
duration: number
album_covers: string[]
is_playable: boolean
}
export interface PlaylistTrack {
track: Track
position?: number
}
export interface Radio {
id: number
name: string
user: User
}
export interface Listening {
id: number
track: Track
user: User
actor: Actor
creation_date: string
}
// API stuff
// eslint-disable-next-line
@ -236,20 +96,15 @@ export interface BackendError extends AxiosError {
rawPayload?: APIErrorResponse
}
// Backend response now contains pagination fields.
// Example: PaginatedArtistWithAlbumsList
// Example: PaginatedAlbumsList
export interface BackendResponse<T> {
count: number
results: T[]
}
export interface RateLimitStatus {
limit?: string
scope?: string
remaining?: string
duration?: string
availableSeconds: number
reset?: string
resetSeconds?: string
}
// WebSocket stuff

View File

@ -238,6 +238,15 @@
"@babel/highlight" "^7.25.9"
picocolors "^1.0.0"
"@babel/code-frame@^7.22.13":
version "7.26.2"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85"
integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==
dependencies:
"@babel/helper-validator-identifier" "^7.25.9"
js-tokens "^4.0.0"
picocolors "^1.0.0"
"@babel/code-frame@^7.24.7", "@babel/code-frame@^7.25.7":
version "7.25.7"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.25.7.tgz#438f2c524071531d643c6f0188e1e28f130cebc7"
@ -2475,6 +2484,37 @@
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.24.tgz#58601079e11784d20f82d0585865bb42305c4df3"
integrity sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==
"@redocly/ajv@^8.11.2":
version "8.11.2"
resolved "https://registry.yarnpkg.com/@redocly/ajv/-/ajv-8.11.2.tgz#46e1bf321ec0ac1e0fd31dea41a3d1fcbdcda0b5"
integrity sha512-io1JpnwtIcvojV7QKDUSIuMN/ikdOUd1ReEnUnMKGfDVridQZ31J0MmIuqwuRjWDZfmvr+Q0MqCcfHM2gTivOg==
dependencies:
fast-deep-equal "^3.1.1"
json-schema-traverse "^1.0.0"
require-from-string "^2.0.2"
uri-js-replace "^1.0.1"
"@redocly/config@^0.20.1":
version "0.20.3"
resolved "https://registry.yarnpkg.com/@redocly/config/-/config-0.20.3.tgz#a8250528c3c7d61430119ef79efcbdb536bd56ff"
integrity sha512-Nyyv1Bj7GgYwj/l46O0nkH1GTKWbO3Ixe7KFcn021aZipkZd+z8Vlu1BwkhqtVgivcKaClaExtWU/lDHkjBzag==
"@redocly/openapi-core@^1.27.2":
version "1.27.2"
resolved "https://registry.yarnpkg.com/@redocly/openapi-core/-/openapi-core-1.27.2.tgz#109163901fd8a2853e805877fe234b65e3c5753a"
integrity sha512-qVrDc27DHpeO2NRCMeRdb4299nijKQE3BY0wrA+WUHlOLScorIi/y7JzammLk22IaTvjR9Mv9aTAdjE1aUwJnA==
dependencies:
"@redocly/ajv" "^8.11.2"
"@redocly/config" "^0.20.1"
colorette "^1.2.0"
https-proxy-agent "^7.0.4"
js-levenshtein "^1.1.6"
js-yaml "^4.1.0"
minimatch "^5.0.1"
node-fetch "^2.6.1"
pluralize "^8.0.0"
yaml-ast-parser "0.0.43"
"@rollup/plugin-babel@^5.2.0":
version "5.3.1"
resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283"
@ -4902,6 +4942,11 @@ agent-base@^7.0.2, agent-base@^7.1.0:
dependencies:
debug "^4.3.4"
agent-base@^7.1.2:
version "7.1.3"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.3.tgz#29435eb821bc4194633a5b89e5bc4703bafc25a1"
integrity sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==
aggregate-error@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
@ -4954,7 +4999,7 @@ algoliasearch@^5.12.0:
"@algolia/requester-fetch" "5.15.0"
"@algolia/requester-node-http" "5.15.0"
ansi-colors@^4.1.1:
ansi-colors@^4.1.1, ansi-colors@^4.1.3:
version "4.1.3"
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b"
integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==
@ -5600,6 +5645,11 @@ chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
change-case@^5.4.4:
version "5.4.4"
resolved "https://registry.yarnpkg.com/change-case/-/change-case-5.4.4.tgz#0d52b507d8fb8f204343432381d1a6d7bff97a02"
integrity sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==
character-entities-html4@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz#1f1adb940c971a4b22ba39ddca6b618dc6e56b2b"
@ -5722,6 +5772,11 @@ color-name@~1.1.4:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
colorette@^1.2.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40"
integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==
colorette@^2.0.16, colorette@^2.0.20:
version "2.0.20"
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a"
@ -7542,6 +7597,14 @@ https-proxy-agent@^7.0.2:
agent-base "^7.0.2"
debug "4"
https-proxy-agent@^7.0.4:
version "7.0.6"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz#da8dfeac7da130b05c2ba4b59c9b6cd66611a6b9"
integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==
dependencies:
agent-base "^7.1.2"
debug "4"
human-signals@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
@ -7607,6 +7670,11 @@ indent-string@^4.0.0:
resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"
integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==
index-to-position@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/index-to-position/-/index-to-position-0.1.2.tgz#e11bfe995ca4d8eddb1ec43274488f3c201a7f09"
integrity sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
@ -8005,6 +8073,11 @@ js-beautify@1.14.9:
glob "^8.1.0"
nopt "^6.0.0"
js-levenshtein@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d"
integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==
js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@ -9035,6 +9108,18 @@ open@^8.4.0:
is-docker "^2.1.1"
is-wsl "^2.2.0"
openapi-typescript@7.6.0:
version "7.6.0"
resolved "https://registry.yarnpkg.com/openapi-typescript/-/openapi-typescript-7.6.0.tgz#2c5b03b2a5c5ccd5813e8dd3cf78342179e3ee24"
integrity sha512-p/xxKcWFR7aZDOAdnqYBQ1NdNyWdine+gHKHKvjxGXmlq8JT1G9+SkY8I5csKaktLHMbDDH6ZDeWQpydwBHa+Q==
dependencies:
"@redocly/openapi-core" "^1.27.2"
ansi-colors "^4.1.3"
change-case "^5.4.4"
parse-json "^8.1.0"
supports-color "^9.4.0"
yargs-parser "^21.1.1"
optionator@^0.9.3:
version "0.9.3"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64"
@ -9128,6 +9213,15 @@ parse-json@^5.0.0:
json-parse-even-better-errors "^2.3.0"
lines-and-columns "^1.1.6"
parse-json@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-8.1.0.tgz#91cdc7728004e955af9cb734de5684733b24a717"
integrity sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==
dependencies:
"@babel/code-frame" "^7.22.13"
index-to-position "^0.1.2"
type-fest "^4.7.1"
parse5-htmlparser2-tree-adapter@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6"
@ -9312,6 +9406,11 @@ pkg-types@^1.2.1:
mlly "^1.7.2"
pathe "^1.1.2"
pluralize@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1"
integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==
pofile@1.0.x:
version "1.0.11"
resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.0.11.tgz#35aff58c17491d127a07336d5522ebc9df57c954"
@ -10482,6 +10581,11 @@ supports-color@^8.1.1:
dependencies:
has-flag "^4.0.0"
supports-color@^9.4.0:
version "9.4.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-9.4.0.tgz#17bfcf686288f531db3dea3215510621ccb55954"
integrity sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==
supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
@ -10754,6 +10858,11 @@ type-fest@^0.21.3:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
type-fest@^4.7.1:
version "4.33.0"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.33.0.tgz#2da0c135b9afa76cf8b18ecfd4f260ecd414a432"
integrity sha512-s6zVrxuyKbbAsSAD5ZPTB77q4YIdRctkTbJ2/Dqlinwz+8ooH2gd+YA7VA6Pa93KML9GockVvoxjZ2vHP+mu8g==
type-fest@^4.9.0:
version "4.10.2"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.10.2.tgz#3abdb144d93c5750432aac0d73d3e85fcab45738"
@ -11060,6 +11169,11 @@ update-browserslist-db@^1.1.0:
escalade "^3.2.0"
picocolors "^1.1.0"
uri-js-replace@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/uri-js-replace/-/uri-js-replace-1.0.1.tgz#c285bb352b701c9dfdaeffc4da5be77f936c9048"
integrity sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==
uri-js@^4.2.2:
version "4.4.1"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
@ -11875,6 +11989,11 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yaml-ast-parser@0.0.43:
version "0.0.43"
resolved "https://registry.yarnpkg.com/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz#e8a23e6fb4c38076ab92995c5dca33f3d3d7c9bb"
integrity sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==
yaml-eslint-parser@^1.0.0, yaml-eslint-parser@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/yaml-eslint-parser/-/yaml-eslint-parser-1.2.2.tgz#1a9673ebe254328cfc2fa99f297f6d8c9364ccd8"