refactor: versioning and migration mechanism for public data structures (#3457)

Co-authored-by: jamesgeorge007 <jamesgeorge998001@gmail.com>
This commit is contained in:
Andrew Bastin
2023-11-02 18:54:16 +05:30
committed by GitHub
parent 01df1663ad
commit cbe3e14b47
16 changed files with 758 additions and 490 deletions

View File

@@ -6,7 +6,9 @@
"main": "dist/hoppscotch-data.cjs",
"module": "dist/hoppscotch-data.js",
"types": "./dist/index.d.ts",
"files": [ "dist/*" ],
"files": [
"dist/*"
],
"scripts": {
"build:code": "vite build",
"build:decl": "tsc --project tsconfig.decl.json",
@@ -33,13 +35,15 @@
"homepage": "https://github.com/hoppscotch/hoppscotch#readme",
"devDependencies": {
"@types/lodash": "^4.14.181",
"typescript": "^4.6.3",
"typescript": "^5.2.2",
"vite": "^3.2.3"
},
"dependencies": {
"fp-ts": "^2.11.10",
"io-ts": "^2.2.16",
"lodash": "^4.17.21",
"parser-ts": "^0.6.16"
"parser-ts": "^0.6.16",
"verzod": "^0.1.1",
"zod": "^3.22.2"
}
}

View File

@@ -1,14 +1,22 @@
import { pipe } from "fp-ts/function"
import * as E from "fp-ts/Either"
import { pipe } from "fp-ts/function"
import { InferredEntity, createVersionedEntity } from "verzod"
export type Environment = {
id?: string
name: string
variables: {
key: string
value: string
}[]
}
import V0_VERSION from "./v/0"
export const Environment = createVersionedEntity({
latestVersion: 0,
versionMap: {
0: V0_VERSION
},
getVersion(x) {
return V0_VERSION.schema.safeParse(x).success
? 0
: null
}
})
export type Environment = InferredEntity<typeof Environment>
const REGEX_ENV_VAR = /<<([^>]*)>>/g // "<<myVariable>>"

View File

@@ -0,0 +1,18 @@
import { z } from "zod"
import { defineVersion } from "verzod"
export const V0_SCHEMA = z.object({
id: z.optional(z.string()),
name: z.string(),
variables: z.array(
z.object({
key: z.string(),
value: z.string(),
})
)
})
export default defineVersion({
initial: true,
schema: V0_SCHEMA
})

View File

@@ -1,43 +0,0 @@
export type HoppGQLAuthNone = {
authType: "none"
}
export type HoppGQLAuthBasic = {
authType: "basic"
username: string
password: string
}
export type HoppGQLAuthBearer = {
authType: "bearer"
token: string
}
export type HoppGQLAuthOAuth2 = {
authType: "oauth-2"
token: string
oidcDiscoveryURL: string
authURL: string
accessTokenURL: string
clientID: string
scope: string
}
export type HoppGQLAuthAPIKey = {
authType: "api-key"
key: string
value: string
addTo: string
}
export type HoppGQLAuth = { authActive: boolean } & (
| HoppGQLAuthNone
| HoppGQLAuthBasic
| HoppGQLAuthBearer
| HoppGQLAuthOAuth2
| HoppGQLAuthAPIKey
)

View File

@@ -1,51 +1,75 @@
import { HoppGQLAuth } from "./HoppGQLAuth"
import { InferredEntity, createVersionedEntity } from "verzod"
import { z } from "zod"
import V1_VERSION from "./v/1"
import V2_VERSION from "./v/2"
export * from "./HoppGQLAuth"
export { GQLHeader } from "./v/1"
export {
HoppGQLAuth,
HoppGQLAuthAPIKey,
HoppGQLAuthBasic,
HoppGQLAuthBearer,
HoppGQLAuthNone,
HoppGQLAuthOAuth2,
} from "./v/2"
export const GQL_REQ_SCHEMA_VERSION = 2
export type GQLHeader = {
key: string
value: string
active: boolean
}
const versionedObject = z.object({
v: z.number(),
})
export type HoppGQLRequest = {
id?: string
v: number
name: string
url: string
headers: GQLHeader[]
query: string
variables: string
auth: HoppGQLAuth
}
export const HoppGQLRequest = createVersionedEntity({
latestVersion: 2,
versionMap: {
1: V1_VERSION,
2: V2_VERSION,
},
getVersion(x) {
const result = versionedObject.safeParse(x)
export function translateToGQLRequest(x: any): HoppGQLRequest {
if (x.v && x.v === GQL_REQ_SCHEMA_VERSION) return x
return result.success ? result.data.v : null
},
})
// Old request
const name = x.name ?? "Untitled"
const url = x.url ?? ""
const headers = x.headers ?? []
const query = x.query ?? ""
const variables = x.variables ?? []
const auth = x.auth ?? {
authType: "none",
authActive: true,
export type HoppGQLRequest = InferredEntity<typeof HoppGQLRequest>
const DEFAULT_QUERY = `
query Request {
method
url
headers {
key
value
}
}`.trim()
export function getDefaultGQLRequest(): HoppGQLRequest {
return {
v: GQL_REQ_SCHEMA_VERSION,
name,
url,
headers,
query,
variables,
auth
name: "Untitled",
url: "https://echo.hoppscotch.io/graphql",
headers: [],
variables: `
{
"id": "1"
}`.trim(),
query: DEFAULT_QUERY,
auth: {
authType: "none",
authActive: true,
},
}
}
/**
* @deprecated This function is deprecated. Use `HoppGQLRequest` instead.
*/
export function translateToGQLRequest(x: unknown): HoppGQLRequest {
const result = HoppGQLRequest.safeParse(x)
return result.type === "ok" ? result.value : getDefaultGQLRequest()
}
export function makeGQLRequest(x: Omit<HoppGQLRequest, "v">): HoppGQLRequest {
return {
v: GQL_REQ_SCHEMA_VERSION,

View File

@@ -0,0 +1,24 @@
import { z } from "zod"
import { defineVersion } from "verzod"
export const GQLHeader = z.object({
key: z.string(),
value: z.string(),
active: z.boolean()
})
export type GQLHeader = z.infer<typeof GQLHeader>
export const V1_SCHEMA = z.object({
v: z.literal(1),
name: z.string(),
url: z.string(),
headers: z.array(GQLHeader),
query: z.string(),
variables: z.string(),
})
export default defineVersion({
initial: true,
schema: V1_SCHEMA
})

View File

@@ -0,0 +1,91 @@
import { z } from "zod"
import { defineVersion } from "verzod"
import { GQLHeader, V1_SCHEMA } from "./1"
export const HoppGQLAuthNone = z.object({
authType: z.literal("none")
})
export type HoppGQLAuthNone = z.infer<typeof HoppGQLAuthNone>
export const HoppGQLAuthBasic = z.object({
authType: z.literal("basic"),
username: z.string(),
password: z.string()
})
export type HoppGQLAuthBasic = z.infer<typeof HoppGQLAuthBasic>
export const HoppGQLAuthBearer = z.object({
authType: z.literal("bearer"),
token: z.string()
})
export type HoppGQLAuthBearer = z.infer<typeof HoppGQLAuthBearer>
export const HoppGQLAuthOAuth2 = z.object({
authType: z.literal("oauth-2"),
token: z.string(),
oidcDiscoveryURL: z.string(),
authURL: z.string(),
accessTokenURL: z.string(),
clientID: z.string(),
scope: z.string()
})
export type HoppGQLAuthOAuth2 = z.infer<typeof HoppGQLAuthOAuth2>
export const HoppGQLAuthAPIKey = z.object({
authType: z.literal("api-key"),
key: z.string(),
value: z.string(),
addTo: z.string()
})
export type HoppGQLAuthAPIKey = z.infer<typeof HoppGQLAuthAPIKey>
export const HoppGQLAuth = z.discriminatedUnion("authType", [
HoppGQLAuthNone,
HoppGQLAuthBasic,
HoppGQLAuthBearer,
HoppGQLAuthOAuth2,
HoppGQLAuthAPIKey
]).and(
z.object({
authActive: z.boolean()
})
)
export type HoppGQLAuth = z.infer<typeof HoppGQLAuth>
const V2_SCHEMA = z.object({
id: z.optional(z.string()),
v: z.literal(2),
name: z.string(),
url: z.string(),
headers: z.array(GQLHeader),
query: z.string(),
variables: z.string(),
auth: HoppGQLAuth
})
export default defineVersion({
initial: false,
schema: V2_SCHEMA,
up(old: z.infer<typeof V1_SCHEMA>) {
return <z.infer<typeof V2_SCHEMA>>{
...old,
v: 2,
auth: {
authActive: true,
authType: "none",
}
}
}
})

View File

@@ -1,43 +0,0 @@
export type HoppRESTAuthNone = {
authType: "none"
}
export type HoppRESTAuthBasic = {
authType: "basic"
username: string
password: string
}
export type HoppRESTAuthBearer = {
authType: "bearer"
token: string
}
export type HoppRESTAuthOAuth2 = {
authType: "oauth-2"
token: string
oidcDiscoveryURL: string
authURL: string
accessTokenURL: string
clientID: string
scope: string
}
export type HoppRESTAuthAPIKey = {
authType: "api-key"
key: string
value: string
addTo: string
}
export type HoppRESTAuth = { authActive: boolean } & (
| HoppRESTAuthNone
| HoppRESTAuthBasic
| HoppRESTAuthBearer
| HoppRESTAuthOAuth2
| HoppRESTAuthAPIKey
)

View File

@@ -11,3 +11,5 @@ export const knownContentTypes = {
}
export type ValidContentTypes = keyof typeof knownContentTypes
export const ValidContentTypesList = Object.keys(knownContentTypes) as ValidContentTypes[]

View File

@@ -1,66 +1,58 @@
import cloneDeep from "lodash/cloneDeep"
import * as Eq from "fp-ts/Eq"
import * as S from "fp-ts/string"
import { ValidContentTypes } from "./content-types"
import { HoppRESTAuth } from "./HoppRESTAuth"
import cloneDeep from "lodash/cloneDeep"
import V0_VERSION from "./v/0"
import V1_VERSION from "./v/1"
import { createVersionedEntity, InferredEntity } from "verzod"
import { lodashIsEqualEq, mapThenEq, undefinedEq } from "../utils/eq"
import {
HoppRESTAuth,
HoppRESTReqBody,
HoppRESTHeaders,
HoppRESTParams,
} from "./v/1"
import { z } from "zod"
export * from "./content-types"
export * from "./HoppRESTAuth"
export {
FormDataKeyValue,
HoppRESTReqBodyFormData,
HoppRESTAuth,
HoppRESTAuthAPIKey,
HoppRESTAuthBasic,
HoppRESTAuthBearer,
HoppRESTAuthNone,
HoppRESTAuthOAuth2,
HoppRESTReqBody,
} from "./v/1"
export const RESTReqSchemaVersion = "1"
const versionedObject = z.object({
// v is a stringified number
v: z.string().regex(/^\d+$/).transform(Number),
})
export type HoppRESTParam = {
key: string
value: string
active: boolean
}
export const HoppRESTRequest = createVersionedEntity({
latestVersion: 1,
versionMap: {
0: V0_VERSION,
1: V1_VERSION,
},
getVersion(data) {
// For V1 onwards we have the v string storing the number
const versionCheck = versionedObject.safeParse(data)
export type HoppRESTHeader = {
key: string
value: string
active: boolean
}
if (versionCheck.success) return versionCheck.data.v
export type FormDataKeyValue = {
key: string
active: boolean
} & ({ isFile: true; value: Blob[] } | { isFile: false; value: string })
// For V0 we have to check the schema
const result = V0_VERSION.schema.safeParse(data)
export type HoppRESTReqBodyFormData = {
contentType: "multipart/form-data"
body: FormDataKeyValue[]
}
return result.success ? 0 : null
},
})
export type HoppRESTReqBody =
| {
contentType: Exclude<ValidContentTypes, "multipart/form-data">
body: string
}
| HoppRESTReqBodyFormData
| {
contentType: null
body: null
}
export type HoppRESTRequest = InferredEntity<typeof HoppRESTRequest>
export interface HoppRESTRequest {
v: string
id?: string // Firebase Firestore ID
name: string
method: string
endpoint: string
params: HoppRESTParam[]
headers: HoppRESTHeader[]
preRequestScript: string
testScript: string
auth: HoppRESTAuth
body: HoppRESTReqBody
}
export const HoppRESTRequestEq = Eq.struct<HoppRESTRequest>({
const HoppRESTRequestEq = Eq.struct<HoppRESTRequest>({
id: undefinedEq(S.Eq),
v: S.Eq,
auth: lodashIsEqualEq,
@@ -80,6 +72,11 @@ export const HoppRESTRequestEq = Eq.struct<HoppRESTRequest>({
testScript: S.Eq,
})
export const RESTReqSchemaVersion = "1"
export type HoppRESTParam = HoppRESTRequest["params"][number]
export type HoppRESTHeader = HoppRESTRequest["headers"][number]
export const isEqualHoppRESTRequest = HoppRESTRequestEq.equals
/**
@@ -87,6 +84,9 @@ export const isEqualHoppRESTRequest = HoppRESTRequestEq.equals
* If we fail to detect certain bits, we just resolve it to the default value
* @param x The value to extract REST Request data from
* @param defaultReq The default REST Request to source from
*
* @deprecated Usage of this function is no longer recommended and is only here
* for legacy reasons and will be removed
*/
export function safelyExtractRESTRequest(
x: unknown,
@@ -94,40 +94,53 @@ export function safelyExtractRESTRequest(
): HoppRESTRequest {
const req = cloneDeep(defaultReq)
// TODO: A cleaner way to do this ?
if (!!x && typeof x === "object") {
if (x.hasOwnProperty("v") && typeof x.v === "string")
req.v = x.v
if ("id" in x && typeof x.id === "string") req.id = x.id
if (x.hasOwnProperty("id") && typeof x.id === "string")
req.id = x.id
if ("name" in x && typeof x.name === "string") req.name = x.name
if (x.hasOwnProperty("name") && typeof x.name === "string")
req.name = x.name
if ("method" in x && typeof x.method === "string") req.method = x.method
if (x.hasOwnProperty("method") && typeof x.method === "string")
req.method = x.method
if (x.hasOwnProperty("endpoint") && typeof x.endpoint === "string")
if ("endpoint" in x && typeof x.endpoint === "string")
req.endpoint = x.endpoint
if (x.hasOwnProperty("preRequestScript") && typeof x.preRequestScript === "string")
if ("preRequestScript" in x && typeof x.preRequestScript === "string")
req.preRequestScript = x.preRequestScript
if (x.hasOwnProperty("testScript") && typeof x.testScript === "string")
if ("testScript" in x && typeof x.testScript === "string")
req.testScript = x.testScript
if (x.hasOwnProperty("body") && typeof x.body === "object" && !!x.body)
req.body = x.body as any // TODO: Deep nested checks
if ("body" in x) {
const result = HoppRESTReqBody.safeParse(x.body)
if (x.hasOwnProperty("auth") && typeof x.auth === "object" && !!x.auth)
req.auth = x.auth as any // TODO: Deep nested checks
if (result.success) {
req.body = result.data
}
}
if (x.hasOwnProperty("params") && Array.isArray(x.params))
req.params = x.params // TODO: Deep nested checks
if ("auth" in x) {
const result = HoppRESTAuth.safeParse(x.auth)
if (x.hasOwnProperty("headers") && Array.isArray(x.headers))
req.headers = x.headers // TODO: Deep nested checks
if (result.success) {
req.auth = result.data
}
}
if ("params" in x) {
const result = HoppRESTParams.safeParse(x.params)
if (result.success) {
req.params = result.data
}
}
if ("headers" in x) {
const result = HoppRESTHeaders.safeParse(x.headers)
if (result.success) {
req.headers = result.data
}
}
}
return req
@@ -137,105 +150,51 @@ export function makeRESTRequest(
x: Omit<HoppRESTRequest, "v">
): HoppRESTRequest {
return {
v: RESTReqSchemaVersion,
...x,
v: RESTReqSchemaVersion,
}
}
export function isHoppRESTRequest(x: any): x is HoppRESTRequest {
return x && typeof x === "object" && "v" in x
}
function parseRequestBody(x: any): HoppRESTReqBody {
if (x.contentType === "application/json") {
return {
contentType: "application/json",
body: x.rawParams,
}
}
return {
contentType: "application/json",
body: "",
}
}
export function translateToNewRequest(x: any): HoppRESTRequest {
if (isHoppRESTRequest(x)) {
return x
} else {
// Old format
const endpoint: string = `${x?.url ?? ""}${x?.path ?? ""}`
const headers: HoppRESTHeader[] = x?.headers ?? []
// Remove old keys from params
const params: HoppRESTParam[] = (x?.params ?? []).map(
({
key,
value,
active,
}: {
key: string
value: string
active: boolean
}) => ({
key,
value,
active,
})
)
const name = x?.name ?? "Untitled request"
const method = x?.method ?? ""
const preRequestScript = x?.preRequestScript ?? ""
const testScript = x?.testScript ?? ""
const body = parseRequestBody(x)
const auth = parseOldAuth(x)
const result: HoppRESTRequest = {
name,
endpoint,
headers,
params,
method,
preRequestScript,
testScript,
body,
auth,
v: RESTReqSchemaVersion,
}
if (x.id) result.id = x.id
return result
}
}
export function parseOldAuth(x: any): HoppRESTAuth {
if (!x.auth || x.auth === "None")
export function getDefaultRESTRequest(): HoppRESTRequest {
return {
v: "1",
endpoint: "https://echo.hoppscotch.io",
name: "Untitled",
params: [],
headers: [],
method: "GET",
auth: {
authType: "none",
authActive: true,
},
preRequestScript: "",
testScript: "",
body: {
contentType: null,
body: null,
},
}
if (x.auth === "Basic Auth")
return {
authType: "basic",
authActive: true,
username: x.httpUser,
password: x.httpPassword,
}
if (x.auth === "Bearer Token")
return {
authType: "bearer",
authActive: true,
token: x.bearerToken,
}
return { authType: "none", authActive: true }
}
/**
* Checks if the given value is a HoppRESTRequest
* @param x The value to check
*
* @deprecated This function is no longer recommended and is only here for legacy reasons
* Use `HoppRESTRequest.is`/`HoppRESTRequest.isLatest` instead.
*/
export function isHoppRESTRequest(x: unknown): x is HoppRESTRequest {
return HoppRESTRequest.isLatest(x)
}
/**
* Safely parses a value into a HoppRESTRequest.
* @param x The value to check
*
* @deprecated This function is no longer recommended and is only here for
* legacy reasons. Use `HoppRESTRequest.safeParse` instead.
*/
export function translateToNewRequest(x: unknown): HoppRESTRequest {
const result = HoppRESTRequest.safeParse(x)
return result.type === "ok" ? result.value : getDefaultRESTRequest()
}

View File

@@ -0,0 +1,39 @@
import { defineVersion } from "verzod"
import { z } from "zod"
export const V0_SCHEMA = z.object({
id: z.optional(z.string()), // Firebase Firestore ID
url: z.string(),
path: z.string(),
headers: z.array(
z.object({
key: z.string(),
value: z.string(),
active: z.boolean()
})
),
params: z.array(
z.object({
key: z.string(),
value: z.string(),
active: z.boolean()
})
),
name: z.string(),
method: z.string(),
preRequestScript: z.string(),
testScript: z.string(),
contentType: z.string(),
body: z.string(),
rawParams: z.optional(z.string()),
auth: z.optional(z.string()),
httpUser: z.optional(z.string()),
httpPassword: z.optional(z.string()),
bearerToken: z.optional(z.string()),
})
export default defineVersion({
initial: true,
schema: V0_SCHEMA
})

View File

@@ -0,0 +1,209 @@
import { defineVersion } from "verzod"
import { z } from "zod"
import { V0_SCHEMA } from "./0"
export const FormDataKeyValue = z.object({
key: z.string(),
active: z.boolean()
}).and(
z.union([
z.object({
isFile: z.literal(true),
value: z.array(z.instanceof(Blob))
}),
z.object({
isFile: z.literal(false),
value: z.string()
})
])
)
export type FormDataKeyValue = z.infer<typeof FormDataKeyValue>
export const HoppRESTReqBodyFormData = z.object({
contentType: z.literal("multipart/form-data"),
body: z.array(FormDataKeyValue)
})
export type HoppRESTReqBodyFormData = z.infer<typeof HoppRESTReqBodyFormData>
export const HoppRESTReqBody = z.union([
z.object({
contentType: z.literal(null),
body: z.literal(null)
}),
z.object({
contentType: z.literal("multipart/form-data"),
body: FormDataKeyValue
}),
z.object({
contentType: z.union([
z.literal("application/json"),
z.literal("application/ld+json"),
z.literal("application/hal+json"),
z.literal("application/vnd.api+json"),
z.literal("application/xml"),
z.literal("application/x-www-form-urlencoded"),
z.literal("text/html"),
z.literal("text/plain"),
]),
body: z.string()
})
])
export type HoppRESTReqBody = z.infer<typeof HoppRESTReqBody>
export const HoppRESTAuthNone = z.object({
authType: z.literal("none")
})
export type HoppRESTAuthNone = z.infer<typeof HoppRESTAuthNone>
export const HoppRESTAuthBasic = z.object({
authType: z.literal("basic"),
username: z.string(),
password: z.string(),
})
export type HoppRESTAuthBasic = z.infer<typeof HoppRESTAuthBasic>
export const HoppRESTAuthBearer = z.object({
authType: z.literal("bearer"),
token: z.string(),
})
export type HoppRESTAuthBearer = z.infer<typeof HoppRESTAuthBearer>
export const HoppRESTAuthOAuth2 = z.object({
authType: z.literal("oauth-2"),
token: z.string(),
oidcDiscoveryURL: z.string(),
authURL: z.string(),
accessTokenURL: z.string(),
clientID: z.string(),
scope: z.string(),
})
export type HoppRESTAuthOAuth2 = z.infer<typeof HoppRESTAuthOAuth2>
export const HoppRESTAuthAPIKey = z.object({
authType: z.literal("api-key"),
key: z.string(),
value: z.string(),
addTo: z.string(),
})
export type HoppRESTAuthAPIKey = z.infer<typeof HoppRESTAuthAPIKey>
export const HoppRESTAuth = z.discriminatedUnion("authType", [
HoppRESTAuthNone,
HoppRESTAuthBasic,
HoppRESTAuthBearer,
HoppRESTAuthOAuth2,
HoppRESTAuthAPIKey
]).and(
z.object({
authActive: z.boolean(),
})
)
export type HoppRESTAuth = z.infer<typeof HoppRESTAuth>
export const HoppRESTParams = z.array(
z.object({
key: z.string(),
value: z.string(),
active: z.boolean()
})
)
export type HoppRESTParams = z.infer<typeof HoppRESTParams>
export const HoppRESTHeaders = z.array(
z.object({
key: z.string(),
value: z.string(),
active: z.boolean()
})
)
export type HoppRESTHeaders = z.infer<typeof HoppRESTHeaders>
const V1_SCHEMA = z.object({
v: z.literal("1"),
id: z.optional(z.string()), // Firebase Firestore ID
name: z.string(),
method: z.string(),
endpoint: z.string(),
params: HoppRESTParams,
headers: HoppRESTHeaders,
preRequestScript: z.string(),
testScript: z.string(),
auth: HoppRESTAuth,
body: HoppRESTReqBody
})
function parseRequestBody(x: z.infer<typeof V0_SCHEMA>): z.infer<typeof V1_SCHEMA>["body"] {
return {
contentType: "application/json",
body: x.contentType === "application/json" ? x.rawParams ?? "" : "",
}
}
export function parseOldAuth(x: z.infer<typeof V0_SCHEMA>): z.infer<typeof V1_SCHEMA>["auth"] {
if (!x.auth || x.auth === "None")
return {
authType: "none",
authActive: true,
}
if (x.auth === "Basic Auth")
return {
authType: "basic",
authActive: true,
username: x.httpUser ?? "",
password: x.httpPassword ?? "",
}
if (x.auth === "Bearer Token")
return {
authType: "bearer",
authActive: true,
token: x.bearerToken ?? "",
}
return { authType: "none", authActive: true }
}
export default defineVersion({
initial: false,
schema: V1_SCHEMA,
up(old: z.infer<typeof V0_SCHEMA>) {
const { url, path, headers, params, name, method, preRequestScript, testScript } = old
const endpoint = `${url}${path}`
const body = parseRequestBody(old)
const auth = parseOldAuth(old)
const result: z.infer<typeof V1_SCHEMA> = {
v: "1",
endpoint,
headers,
params,
name,
method,
preRequestScript,
testScript,
body,
auth,
}
if (old.id) result.id = old.id
return result
},
})

View File

@@ -2,7 +2,7 @@
"compilerOptions": {
"target": "es2017",
"module": "esnext",
"lib": ["esnext"],
"lib": ["esnext", "DOM"],
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true,

View File

@@ -2,13 +2,13 @@
"compilerOptions": {
"target": "es2017",
"module": "esnext",
"lib": ["esnext"],
"lib": ["esnext", "DOM"],
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true,
"strictNullChecks": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"resolveJsonModule": true
},
"include": ["src/*.ts"]
}

View File

@@ -1,6 +1,6 @@
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
testEnvironment: "jsdom",
collectCoverage: true,
setupFilesAfterEnv: ["./jest.setup.ts"],
}

352
pnpm-lock.yaml generated
View File

@@ -288,7 +288,7 @@ importers:
version: 29.0.5(@babel/core@7.23.0)(jest@29.4.1)(typescript@4.9.3)
ts-loader:
specifier: ^9.4.2
version: 9.4.2(typescript@4.9.3)(webpack@5.88.2)
version: 9.4.2(typescript@4.9.3)(webpack@5.89.0)
ts-node:
specifier: ^10.9.1
version: 10.9.1(@types/node@18.11.10)(typescript@4.9.3)
@@ -372,7 +372,7 @@ importers:
version: 10.1.0(openapi-types@12.1.3)
'@codemirror/autocomplete':
specifier: ^6.10.2
version: 6.10.2(@codemirror/language@6.9.2)(@codemirror/state@6.3.1)(@codemirror/view@6.21.4)(@lezer/common@1.0.4)
version: 6.10.2(@codemirror/language@6.9.2)(@codemirror/state@6.3.1)(@codemirror/view@6.21.4)(@lezer/common@1.1.0)
'@codemirror/commands':
specifier: ^6.3.0
version: 6.3.0
@@ -782,13 +782,19 @@ importers:
parser-ts:
specifier: ^0.6.16
version: 0.6.16(fp-ts@2.12.1)
verzod:
specifier: ^0.1.1
version: 0.1.1
zod:
specifier: ^3.22.2
version: 3.22.2
devDependencies:
'@types/lodash':
specifier: ^4.14.181
version: 4.14.182
typescript:
specifier: ^4.6.3
version: 4.7.4
specifier: ^5.2.2
version: 5.2.2
vite:
specifier: ^3.2.3
version: 3.2.4(@types/node@17.0.27)(sass@1.53.0)(terser@5.21.0)
@@ -1825,7 +1831,7 @@ packages:
resolution: {integrity: sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/highlight': 7.22.10
'@babel/highlight': 7.22.20
chalk: 2.4.2
dev: true
@@ -1937,7 +1943,7 @@ packages:
dependencies:
'@babel/compat-data': 7.22.9
'@babel/helper-validator-option': 7.22.5
browserslist: 4.21.10
browserslist: 4.22.1
lru-cache: 5.1.1
semver: 6.3.1
@@ -2124,7 +2130,7 @@ packages:
'@babel/helper-module-imports': 7.22.5
'@babel/helper-simple-access': 7.22.5
'@babel/helper-split-export-declaration': 7.22.6
'@babel/helper-validator-identifier': 7.22.5
'@babel/helper-validator-identifier': 7.22.20
/@babel/helper-module-transforms@7.22.9(@babel/core@7.23.0):
resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==}
@@ -2137,7 +2143,7 @@ packages:
'@babel/helper-module-imports': 7.22.5
'@babel/helper-simple-access': 7.22.5
'@babel/helper-split-export-declaration': 7.22.6
'@babel/helper-validator-identifier': 7.22.5
'@babel/helper-validator-identifier': 7.22.20
dev: true
/@babel/helper-module-transforms@7.23.0(@babel/core@7.23.0):
@@ -2321,15 +2327,6 @@ packages:
- supports-color
dev: true
/@babel/highlight@7.22.10:
resolution: {integrity: sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/helper-validator-identifier': 7.22.5
chalk: 2.4.2
js-tokens: 4.0.0
dev: true
/@babel/highlight@7.22.20:
resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==}
engines: {node: '>=6.9.0'}
@@ -3327,7 +3324,7 @@ packages:
'@babel/helper-hoist-variables': 7.22.5
'@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.10)
'@babel/helper-plugin-utils': 7.22.5
'@babel/helper-validator-identifier': 7.22.5
'@babel/helper-validator-identifier': 7.22.20
/@babel/plugin-transform-modules-systemjs@7.23.0(@babel/core@7.23.0):
resolution: {integrity: sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg==}
@@ -4191,7 +4188,7 @@ packages:
'@lezer/common': 1.0.3
dev: false
/@codemirror/autocomplete@6.10.2(@codemirror/language@6.9.2)(@codemirror/state@6.3.1)(@codemirror/view@6.21.4)(@lezer/common@1.0.4):
/@codemirror/autocomplete@6.10.2(@codemirror/language@6.9.2)(@codemirror/state@6.3.1)(@codemirror/view@6.21.4)(@lezer/common@1.1.0):
resolution: {integrity: sha512-3dCL7b0j2GdtZzWN5j7HDpRAJ26ip07R4NGYz7QYthIYMiX8I4E4TNrYcdTayPJGeVQtd/xe7lWU4XL7THFb/w==}
peerDependencies:
'@codemirror/language': ^6.0.0
@@ -4202,7 +4199,7 @@ packages:
'@codemirror/language': 6.9.2
'@codemirror/state': 6.3.1
'@codemirror/view': 6.21.4
'@lezer/common': 1.0.4
'@lezer/common': 1.1.0
dev: false
/@codemirror/commands@6.3.0:
@@ -4216,12 +4213,12 @@ packages:
/@codemirror/lang-javascript@6.2.1:
resolution: {integrity: sha512-jlFOXTejVyiQCW3EQwvKH0m99bUYIw40oPmFjSX2VS78yzfe0HELZ+NEo9Yfo1MkGRpGlj3Gnu4rdxV1EnAs5A==}
dependencies:
'@codemirror/autocomplete': 6.10.2(@codemirror/language@6.9.2)(@codemirror/state@6.3.1)(@codemirror/view@6.21.4)(@lezer/common@1.0.4)
'@codemirror/autocomplete': 6.10.2(@codemirror/language@6.9.2)(@codemirror/state@6.3.1)(@codemirror/view@6.21.4)(@lezer/common@1.1.0)
'@codemirror/language': 6.9.2
'@codemirror/lint': 6.4.2
'@codemirror/state': 6.3.1
'@codemirror/view': 6.21.4
'@lezer/common': 1.0.4
'@lezer/common': 1.1.0
'@lezer/javascript': 1.4.5
dev: false
@@ -7325,12 +7322,12 @@ packages:
extract-files: 11.0.0
graphql: 16.8.0
graphql-ws: 5.9.1(graphql@16.8.0)
isomorphic-ws: 5.0.0(ws@8.13.0)
isomorphic-ws: 5.0.0(ws@8.14.2)
meros: 1.2.0(@types/node@17.0.27)
sync-fetch: 0.4.1
tslib: 2.6.2
value-or-promise: 1.0.11
ws: 8.13.0
ws: 8.14.2
transitivePeerDependencies:
- '@types/node'
- bufferutil
@@ -8681,7 +8678,7 @@ packages:
resolution: {integrity: sha512-vodJv2JPwsFsiBBHE463yBhvUI9TmhIu5duF/8MH304xNS6FyWH/vTyG61pjhERm5f+VBP94co0eiN+afWcvXw==}
hasBin: true
dependencies:
'@lezer/common': 1.0.4
'@lezer/common': 1.1.0
'@lezer/lr': 1.3.13
dev: true
@@ -8712,7 +8709,7 @@ packages:
/@lezer/lr@1.3.13:
resolution: {integrity: sha512-RLAbau/4uSzKgIKj96mI5WUtG1qtiR0Frn0Ei9zhPj8YOkHM+1Bb8SgdVvmR/aWJCFIzjo2KFnDiRZ75Xf5NdQ==}
dependencies:
'@lezer/common': 1.0.4
'@lezer/common': 1.1.0
/@lezer/xml@1.0.2:
resolution: {integrity: sha512-dlngsWceOtQBMuBPw5wtHpaxdPJ71aVntqjbpGkFtWsp4WtQmCnuTjQGocviymydN6M18fhj6UQX3oiEtSuY7w==}
@@ -9373,7 +9370,7 @@ packages:
builtin-modules: 3.3.0
deepmerge: 4.3.1
is-module: 1.0.0
resolve: 1.22.4
resolve: 1.22.6
rollup: 2.79.1
dev: true
@@ -9430,7 +9427,7 @@ packages:
rollup:
optional: true
dependencies:
'@types/estree': 1.0.1
'@types/estree': 1.0.2
estree-walker: 2.0.2
picomatch: 2.3.1
rollup: 2.79.1
@@ -9479,7 +9476,7 @@ packages:
/@rushstack/rig-package@0.4.0:
resolution: {integrity: sha512-FnM1TQLJYwSiurP6aYSnansprK5l8WUK8VG38CmAaZs29ZeL1msjK0AP1VS4ejD33G0kE/2cpsPsS9jDenBMxw==}
dependencies:
resolve: 1.22.4
resolve: 1.22.6
strip-json-comments: 3.1.1
dev: true
@@ -9545,7 +9542,7 @@ packages:
ejs: 3.1.9
json5: 2.2.3
magic-string: 0.25.9
string.prototype.matchall: 4.0.8
string.prototype.matchall: 4.0.10
dev: true
/@swc/core-android-arm-eabi@1.2.213:
@@ -9761,8 +9758,8 @@ packages:
resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==}
dev: true
/@types/component-emitter@1.2.11:
resolution: {integrity: sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==}
/@types/component-emitter@1.2.12:
resolution: {integrity: sha512-0pGnjZ3V/D+P+dU20W7r9U9SXFIsapxMhJXQwJls0oYRA26RnTBUsidQRO0XbHBdTlBNhDLfGEEfe636El69tQ==}
dev: false
/@types/connect@3.4.35:
@@ -9833,10 +9830,10 @@ packages:
/@types/estree@1.0.1:
resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==}
dev: true
/@types/estree@1.0.2:
resolution: {integrity: sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==}
dev: true
/@types/express-serve-static-core@4.17.31:
resolution: {integrity: sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==}
@@ -10922,6 +10919,15 @@ packages:
- graphql
dev: false
/@urql/core@4.1.3(graphql@16.8.0):
resolution: {integrity: sha512-Wapa58olpEJtZzSEuZNDxzBxmOmHuivG6Hb/QPc6HjHfCJ6f36gnlWc9a9TsC8Vddle+6PsS6+quMMTuj+bj7A==}
dependencies:
'@0no-co/graphql.web': 1.0.4(graphql@16.8.0)
wonka: 6.3.4
transitivePeerDependencies:
- graphql
dev: false
/@urql/core@4.1.3(graphql@16.8.1):
resolution: {integrity: sha512-Wapa58olpEJtZzSEuZNDxzBxmOmHuivG6Hb/QPc6HjHfCJ6f36gnlWc9a9TsC8Vddle+6PsS6+quMMTuj+bj7A==}
dependencies:
@@ -10954,7 +10960,7 @@ packages:
/@urql/exchange-auth@2.1.6(graphql@16.8.0):
resolution: {integrity: sha512-snOlt7p5kYq0KnPDuXkKe2qW3/BucQZOElvTeo3svLQuk9JiNJVnm6ffQ6QGiGO+G3AtMrctnno1+X44fLtDuQ==}
dependencies:
'@urql/core': 4.1.1(graphql@16.8.0)
'@urql/core': 4.1.3(graphql@16.8.0)
wonka: 6.3.4
transitivePeerDependencies:
- graphql
@@ -11107,7 +11113,7 @@ packages:
/@vitest/snapshot@0.34.2:
resolution: {integrity: sha512-qhQ+xy3u4mwwLxltS4Pd4SR+XHv4EajiTPNY3jkIBLUApE6/ce72neJPSUQZ7bL3EBuKI+NhvzhGj3n5baRQUQ==}
dependencies:
magic-string: 0.30.3
magic-string: 0.30.4
pathe: 1.1.1
pretty-format: 29.5.0
dev: true
@@ -11415,7 +11421,7 @@ packages:
'@vue/compiler-core': 3.3.4
'@vue/shared': 3.3.4
estree-walker: 2.0.2
magic-string: 0.30.3
magic-string: 0.30.4
/@vue/reactivity@3.2.45:
resolution: {integrity: sha512-PRvhCcQcyEVohW0P8iQ7HDcIOXRjZfAsOds3N99X/Dzewy8TVhTCT4uXpAHfoKjVTJRA0O0K+6QNkDIZAxNi3A==}
@@ -11846,7 +11852,7 @@ packages:
'@windicss/config': 1.9.1
debug: 4.3.4(supports-color@9.2.2)
fast-glob: 3.3.1
magic-string: 0.30.3
magic-string: 0.30.4
micromatch: 4.0.5
windicss: 3.5.6
transitivePeerDependencies:
@@ -12199,13 +12205,14 @@ packages:
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
engines: {node: '>=8'}
/arraybuffer.prototype.slice@1.0.1:
resolution: {integrity: sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==}
/arraybuffer.prototype.slice@1.0.2:
resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==}
engines: {node: '>= 0.4'}
dependencies:
array-buffer-byte-length: 1.0.0
call-bind: 1.0.2
define-properties: 1.2.0
define-properties: 1.2.1
es-abstract: 1.22.2
get-intrinsic: 1.2.1
is-array-buffer: 3.0.2
is-shared-array-buffer: 1.0.2
@@ -12691,10 +12698,10 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
dependencies:
caniuse-lite: 1.0.30001521
electron-to-chromium: 1.4.496
caniuse-lite: 1.0.30001546
electron-to-chromium: 1.4.543
node-releases: 2.0.13
update-browserslist-db: 1.0.11(browserslist@4.21.10)
update-browserslist-db: 1.0.13(browserslist@4.21.10)
/browserslist@4.22.1:
resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==}
@@ -12705,7 +12712,6 @@ packages:
electron-to-chromium: 1.4.543
node-releases: 2.0.13
update-browserslist-db: 1.0.13(browserslist@4.22.1)
dev: true
/bs-logger@0.2.6:
resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==}
@@ -12833,12 +12839,8 @@ packages:
engines: {node: '>=10'}
dev: true
/caniuse-lite@1.0.30001521:
resolution: {integrity: sha512-fnx1grfpEOvDGH+V17eccmNjucGUnCbP6KL+l5KqBIerp26WK/+RQ7CIDE37KGJjaPyqWXXlFUyKiWmvdNNKmQ==}
/caniuse-lite@1.0.30001546:
resolution: {integrity: sha512-zvtSJwuQFpewSyRrI3AsftF6rM0X80mZkChIt1spBGEvRglCrjTniXvinc8JKRoqTwXAgvqTImaN9igfSMtUBw==}
dev: true
/capital-case@1.0.4:
resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==}
@@ -13366,7 +13368,7 @@ packages:
/core-js-compat@3.32.1:
resolution: {integrity: sha512-GSvKDv4wE0bPnQtjklV101juQ85g6H3rm5PDP20mqlS5j0kXF3pP97YvAu5hl+uFHqMictp3b2VxOHljWMAtuA==}
dependencies:
browserslist: 4.21.10
browserslist: 4.22.1
/core-js-compat@3.33.0:
resolution: {integrity: sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw==}
@@ -13760,11 +13762,6 @@ packages:
/deep-is@0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
/deepmerge@4.2.2:
resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==}
engines: {node: '>=0.10.0'}
dev: true
/deepmerge@4.3.1:
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
engines: {node: '>=0.10.0'}
@@ -13793,6 +13790,15 @@ packages:
clone: 1.0.4
dev: true
/define-data-property@1.1.0:
resolution: {integrity: sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==}
engines: {node: '>= 0.4'}
dependencies:
get-intrinsic: 1.2.1
gopd: 1.0.1
has-property-descriptors: 1.0.0
dev: true
/define-lazy-prop@3.0.0:
resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==}
engines: {node: '>=12'}
@@ -13813,6 +13819,15 @@ packages:
has-property-descriptors: 1.0.0
object-keys: 1.1.1
/define-properties@1.2.1:
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
engines: {node: '>= 0.4'}
dependencies:
define-data-property: 1.1.0
has-property-descriptors: 1.0.0
object-keys: 1.1.1
dev: true
/defu@6.1.2:
resolution: {integrity: sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ==}
dev: true
@@ -14064,12 +14079,8 @@ packages:
dependencies:
jake: 10.8.5
/electron-to-chromium@1.4.496:
resolution: {integrity: sha512-qeXC3Zbykq44RCrBa4kr8v/dWzYJA8rAwpyh9Qd+NKWoJfjG5vvJqy9XOJ9H4P/lqulZBCgUWAYi+FeK5AuJ8g==}
/electron-to-chromium@1.4.543:
resolution: {integrity: sha512-t2ZP4AcGE0iKCCQCBx/K2426crYdxD3YU6l0uK2EO3FZH0pbC4pFz/sZm2ruZsND6hQBTcDWWlo/MLpiOdif5g==}
dev: true
/emittery@0.13.1:
resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==}
@@ -14257,7 +14268,7 @@ packages:
is-shared-array-buffer: 1.0.2
is-string: 1.0.7
is-weakref: 1.0.2
object-inspect: 1.12.2
object-inspect: 1.12.3
object-keys: 1.1.1
object.assign: 4.1.4
regexp.prototype.flags: 1.5.0
@@ -14266,22 +14277,22 @@ packages:
unbox-primitive: 1.0.2
dev: true
/es-abstract@1.22.1:
resolution: {integrity: sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==}
/es-abstract@1.22.2:
resolution: {integrity: sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==}
engines: {node: '>= 0.4'}
dependencies:
array-buffer-byte-length: 1.0.0
arraybuffer.prototype.slice: 1.0.1
arraybuffer.prototype.slice: 1.0.2
available-typed-arrays: 1.0.5
call-bind: 1.0.2
es-set-tostringtag: 2.0.1
es-to-primitive: 1.2.1
function.prototype.name: 1.1.5
function.prototype.name: 1.1.6
get-intrinsic: 1.2.1
get-symbol-description: 1.0.0
globalthis: 1.0.3
gopd: 1.0.1
has: 1.0.3
has: 1.0.4
has-property-descriptors: 1.0.0
has-proto: 1.0.1
has-symbols: 1.0.3
@@ -14297,12 +14308,12 @@ packages:
object-inspect: 1.12.3
object-keys: 1.1.1
object.assign: 4.1.4
regexp.prototype.flags: 1.5.0
safe-array-concat: 1.0.0
regexp.prototype.flags: 1.5.1
safe-array-concat: 1.0.1
safe-regex-test: 1.0.0
string.prototype.trim: 1.2.7
string.prototype.trimend: 1.0.6
string.prototype.trimstart: 1.0.6
string.prototype.trim: 1.2.8
string.prototype.trimend: 1.0.7
string.prototype.trimstart: 1.0.7
typed-array-buffer: 1.0.0
typed-array-byte-length: 1.0.0
typed-array-byte-offset: 1.0.0
@@ -14334,7 +14345,7 @@ packages:
engines: {node: '>= 0.4'}
dependencies:
get-intrinsic: 1.2.1
has: 1.0.3
has: 1.0.4
has-tostringtag: 1.0.0
dev: true
@@ -15953,6 +15964,16 @@ packages:
functions-have-names: 1.2.3
dev: true
/function.prototype.name@1.1.6:
resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==}
engines: {node: '>= 0.4'}
dependencies:
call-bind: 1.0.2
define-properties: 1.2.1
es-abstract: 1.22.2
functions-have-names: 1.2.3
dev: true
/functional-red-black-tree@1.0.1:
resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==}
dev: true
@@ -16654,6 +16675,11 @@ packages:
dependencies:
function-bind: 1.1.1
/has@1.0.4:
resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==}
engines: {node: '>= 0.4.0'}
dev: true
/he@1.2.0:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
@@ -17575,6 +17601,7 @@ packages:
ws: '*'
dependencies:
ws: 8.13.0
dev: true
/isomorphic-ws@5.0.0(ws@8.14.2):
resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==}
@@ -17582,7 +17609,6 @@ packages:
ws: '*'
dependencies:
ws: 8.14.2
dev: true
/istanbul-lib-coverage@3.2.0:
resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==}
@@ -17810,7 +17836,7 @@ packages:
babel-jest: 27.5.1(@babel/core@7.22.10)
chalk: 4.1.2
ci-info: 3.3.2
deepmerge: 4.2.2
deepmerge: 4.3.1
glob: 7.2.3
graceful-fs: 4.2.11
jest-circus: 27.5.1
@@ -17854,7 +17880,7 @@ packages:
babel-jest: 29.4.1(@babel/core@7.22.10)
chalk: 4.1.2
ci-info: 3.3.2
deepmerge: 4.2.2
deepmerge: 4.3.1
glob: 7.2.3
graceful-fs: 4.2.10
jest-circus: 29.4.1
@@ -17894,7 +17920,7 @@ packages:
babel-jest: 29.4.1(@babel/core@7.22.10)
chalk: 4.1.2
ci-info: 3.3.2
deepmerge: 4.2.2
deepmerge: 4.3.1
glob: 7.2.3
graceful-fs: 4.2.10
jest-circus: 29.4.1
@@ -19417,12 +19443,6 @@ packages:
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
/magic-string@0.30.3:
resolution: {integrity: sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==}
engines: {node: '>=12'}
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
/magic-string@0.30.4:
resolution: {integrity: sha512-Q/TKtsC5BPm0kGqgBIF9oXAs/xEf2vRKiIB4wCRQTJOQIByZ1d+NnUOotvJOvNpi5RNIgVOMC3pOuaP1ZTDlVg==}
engines: {node: '>=12'}
@@ -20140,7 +20160,6 @@ packages:
pathe: 1.1.1
pkg-types: 1.0.3
ufo: 1.2.0
dev: true
/mlly@1.4.0:
resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==}
@@ -20149,6 +20168,7 @@ packages:
pathe: 1.1.1
pkg-types: 1.0.3
ufo: 1.2.0
dev: true
/mlly@1.4.2:
resolution: {integrity: sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==}
@@ -20461,10 +20481,6 @@ packages:
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
engines: {node: '>= 6'}
/object-inspect@1.12.2:
resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==}
dev: true
/object-inspect@1.12.3:
resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==}
@@ -21053,7 +21069,7 @@ packages:
resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==}
dependencies:
jsonc-parser: 3.2.0
mlly: 1.4.0
mlly: 1.2.0
pathe: 1.1.1
/pkginfo@0.4.1:
@@ -21606,7 +21622,7 @@ packages:
resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==}
engines: {node: '>= 0.10'}
dependencies:
resolve: 1.22.4
resolve: 1.22.6
dev: true
/redent@3.0.0:
@@ -21665,6 +21681,15 @@ packages:
functions-have-names: 1.2.3
dev: true
/regexp.prototype.flags@1.5.1:
resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==}
engines: {node: '>= 0.4'}
dependencies:
call-bind: 1.0.2
define-properties: 1.2.1
set-function-name: 2.0.1
dev: true
/regexpp@3.2.0:
resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==}
engines: {node: '>=8'}
@@ -21807,6 +21832,15 @@ packages:
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
/resolve@1.22.6:
resolution: {integrity: sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==}
hasBin: true
dependencies:
is-core-module: 2.13.0
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
dev: true
/restore-cursor@3.1.0:
resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==}
engines: {node: '>=8'}
@@ -21965,20 +21999,12 @@ packages:
optionalDependencies:
fsevents: 2.3.3
/rollup@3.29.3:
resolution: {integrity: sha512-T7du6Hum8jOkSWetjRgbwpM6Sy0nECYrYRSmZjayFcOddtKJWU4d17AC3HNUk7HRuqy4p+G7aEZclSHytqUmEg==}
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
hasBin: true
optionalDependencies:
fsevents: 2.3.3
/rollup@3.29.4:
resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==}
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
hasBin: true
optionalDependencies:
fsevents: 2.3.3
dev: true
/run-applescript@3.2.0:
resolution: {integrity: sha512-Ep0RsvAjnRcBX1p5vogbaBdAGu/8j/ewpvGqnQYunnLd9SM0vWcPJewPKNnWFggf0hF0pwIgwV5XK7qQ7UZ8Qg==}
@@ -22027,8 +22053,8 @@ packages:
mri: 1.2.0
dev: true
/safe-array-concat@1.0.0:
resolution: {integrity: sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==}
/safe-array-concat@1.0.1:
resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==}
engines: {node: '>=0.4'}
dependencies:
call-bind: 1.0.2
@@ -22219,6 +22245,15 @@ packages:
/set-blocking@2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
/set-function-name@2.0.1:
resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==}
engines: {node: '>= 0.4'}
dependencies:
define-data-property: 1.1.0
functions-have-names: 1.2.3
has-property-descriptors: 1.0.0
dev: true
/setimmediate@1.0.5:
resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
@@ -22396,7 +22431,7 @@ packages:
resolution: {integrity: sha512-4sIGOGOmCg3AOgGi7EEr6ZkTZRkrXwub70bBB/F0JSkMOUFpA77WsL87o34DffQQ31PkbMUIadGOk+3tx1KGbw==}
engines: {node: '>=10.0.0'}
dependencies:
'@types/component-emitter': 1.2.11
'@types/component-emitter': 1.2.12
backo2: 1.0.2
component-emitter: 1.3.0
debug: 4.3.4(supports-color@9.2.2)
@@ -22439,7 +22474,7 @@ packages:
resolution: {integrity: sha512-sNjbT9dX63nqUFIOv95tTVm6elyIU4RvB1m8dOeZt+IgWwcWklFDOdmGcfo3zSiRsnR/3pJkjY5lfoGqEe4Eig==}
engines: {node: '>=10.0.0'}
dependencies:
'@types/component-emitter': 1.2.11
'@types/component-emitter': 1.2.12
component-emitter: 1.3.0
debug: 4.3.4(supports-color@9.2.2)
transitivePeerDependencies:
@@ -22657,16 +22692,17 @@ packages:
emoji-regex: 9.2.2
strip-ansi: 7.1.0
/string.prototype.matchall@4.0.8:
resolution: {integrity: sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==}
/string.prototype.matchall@4.0.10:
resolution: {integrity: sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==}
dependencies:
call-bind: 1.0.2
define-properties: 1.2.0
es-abstract: 1.22.1
define-properties: 1.2.1
es-abstract: 1.22.2
get-intrinsic: 1.2.1
has-symbols: 1.0.3
internal-slot: 1.0.5
regexp.prototype.flags: 1.5.0
regexp.prototype.flags: 1.5.1
set-function-name: 2.0.1
side-channel: 1.0.4
dev: true
@@ -22679,13 +22715,13 @@ packages:
es-abstract: 1.20.1
dev: true
/string.prototype.trim@1.2.7:
resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==}
/string.prototype.trim@1.2.8:
resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==}
engines: {node: '>= 0.4'}
dependencies:
call-bind: 1.0.2
define-properties: 1.2.0
es-abstract: 1.22.1
define-properties: 1.2.1
es-abstract: 1.22.2
dev: true
/string.prototype.trimend@1.0.5:
@@ -22696,12 +22732,12 @@ packages:
es-abstract: 1.20.1
dev: true
/string.prototype.trimend@1.0.6:
resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==}
/string.prototype.trimend@1.0.7:
resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==}
dependencies:
call-bind: 1.0.2
define-properties: 1.2.0
es-abstract: 1.22.1
define-properties: 1.2.1
es-abstract: 1.22.2
dev: true
/string.prototype.trimstart@1.0.5:
@@ -22712,12 +22748,12 @@ packages:
es-abstract: 1.20.1
dev: true
/string.prototype.trimstart@1.0.6:
resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==}
/string.prototype.trimstart@1.0.7:
resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==}
dependencies:
call-bind: 1.0.2
define-properties: 1.2.0
es-abstract: 1.22.1
define-properties: 1.2.1
es-abstract: 1.22.2
dev: true
/string_decoder@0.10.31:
@@ -23073,30 +23109,6 @@ packages:
resolve-from: 2.0.0
dev: false
/terser-webpack-plugin@5.3.9(webpack@5.88.2):
resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==}
engines: {node: '>= 10.13.0'}
peerDependencies:
'@swc/core': '*'
esbuild: '*'
uglify-js: '*'
webpack: ^5.1.0
peerDependenciesMeta:
'@swc/core':
optional: true
esbuild:
optional: true
uglify-js:
optional: true
dependencies:
'@jridgewell/trace-mapping': 0.3.19
jest-worker: 27.5.1
schema-utils: 3.3.0
serialize-javascript: 6.0.1
terser: 5.21.0
webpack: 5.88.2
dev: true
/terser-webpack-plugin@5.3.9(webpack@5.89.0):
resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==}
engines: {node: '>= 10.13.0'}
@@ -23424,7 +23436,7 @@ packages:
yargs-parser: 21.1.1
dev: true
/ts-loader@9.4.2(typescript@4.9.3)(webpack@5.88.2):
/ts-loader@9.4.2(typescript@4.9.3)(webpack@5.89.0):
resolution: {integrity: sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==}
engines: {node: '>=12.0.0'}
peerDependencies:
@@ -23436,7 +23448,7 @@ packages:
micromatch: 4.0.5
semver: 7.3.8
typescript: 4.9.3
webpack: 5.88.2
webpack: 5.89.0
dev: true
/ts-log@2.2.4:
@@ -24321,8 +24333,8 @@ packages:
engines: {node: '>=4'}
dev: true
/update-browserslist-db@1.0.11(browserslist@4.21.10):
resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==}
/update-browserslist-db@1.0.13(browserslist@4.21.10):
resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==}
hasBin: true
peerDependencies:
browserslist: '>= 4.21.0'
@@ -24340,7 +24352,6 @@ packages:
browserslist: 4.22.1
escalade: 3.1.1
picocolors: 1.0.0
dev: true
/upper-case-first@2.0.2:
resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==}
@@ -24486,6 +24497,13 @@ packages:
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
/verzod@0.1.1:
resolution: {integrity: sha512-T0o2GHjSdERgt3FCrhGB+ctXdPhRjj/gL/mFjkb1HsYQQQr6pF10oPY1jVHI0RMsG6L2+6VKe4zDN0gAarZmzg==}
engines: {node: '>=16'}
dependencies:
zod: 3.22.2
dev: false
/vite-node@0.26.0(@types/node@17.0.27)(sass@1.53.0)(terser@5.21.0):
resolution: {integrity: sha512-nLtHWCv6reONl1oFsKhQ/LT7n3UNLpvVARAJlmGrQV6qSElht/9AdN41Pa+WSkw2Winh682UzM0Yw0GNlfqejw==}
engines: {node: '>=v14.16.0'}
@@ -25219,7 +25237,7 @@ packages:
'@types/node': 17.0.27
esbuild: 0.18.20
postcss: 8.4.28
rollup: 3.29.3
rollup: 3.29.4
sass: 1.66.0
terser: 5.21.0
optionalDependencies:
@@ -25967,46 +25985,6 @@ packages:
/webpack-virtual-modules@0.5.0:
resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==}
/webpack@5.88.2:
resolution: {integrity: sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==}
engines: {node: '>=10.13.0'}
hasBin: true
peerDependencies:
webpack-cli: '*'
peerDependenciesMeta:
webpack-cli:
optional: true
dependencies:
'@types/eslint-scope': 3.7.5
'@types/estree': 1.0.2
'@webassemblyjs/ast': 1.11.6
'@webassemblyjs/wasm-edit': 1.11.6
'@webassemblyjs/wasm-parser': 1.11.6
acorn: 8.10.0
acorn-import-assertions: 1.9.0(acorn@8.10.0)
browserslist: 4.22.1
chrome-trace-event: 1.0.3
enhanced-resolve: 5.15.0
es-module-lexer: 1.3.1
eslint-scope: 5.1.1
events: 3.3.0
glob-to-regexp: 0.4.1
graceful-fs: 4.2.11
json-parse-even-better-errors: 2.3.1
loader-runner: 4.3.0
mime-types: 2.1.35
neo-async: 2.6.2
schema-utils: 3.3.0
tapable: 2.2.1
terser-webpack-plugin: 5.3.9(webpack@5.88.2)
watchpack: 2.4.0
webpack-sources: 3.2.3
transitivePeerDependencies:
- '@swc/core'
- esbuild
- uglify-js
dev: true
/webpack@5.89.0:
resolution: {integrity: sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==}
engines: {node: '>=10.13.0'}
@@ -26598,7 +26576,6 @@ packages:
optional: true
utf-8-validate:
optional: true
dev: true
/ws@8.2.3:
resolution: {integrity: sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==}
@@ -26870,4 +26847,3 @@ packages:
/zod@3.22.2:
resolution: {integrity: sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==}
dev: true