fix: environment and rest tab state schema migration (#5105)

This commit is contained in:
Nivedin 2025-05-29 15:13:14 +05:30 committed by GitHub
parent 052dc1708c
commit 805ac88688
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 190 additions and 51 deletions

View file

@ -26,6 +26,7 @@ import { getStatusCodeReasonPhrase } from "~/helpers/utils/statusCodes"
import {
HoppRESTResponseOriginalRequest,
HoppRESTRequestResponse,
RESTResOriginalReqSchemaVersion,
} from "@hoppscotch/data"
import { editRESTRequest } from "~/newstore/collections"
import { useToast } from "@composables/toast"
@ -94,7 +95,7 @@ const onSaveAsExample = () => {
} = response.req
const originalRequest: HoppRESTResponseOriginalRequest = {
v: "3",
v: RESTResOriginalReqSchemaVersion,
method,
endpoint,
headers,

View file

@ -4,7 +4,10 @@ import * as O from "fp-ts/Option"
import { IMPORTER_INVALID_FILE_FORMAT } from "."
import { z } from "zod"
import { NonSecretEnvironment } from "@hoppscotch/data"
import {
EnvironmentSchemaVersion,
NonSecretEnvironment,
} from "@hoppscotch/data"
import { safeParseJSONOrYAML } from "~/helpers/functional/yaml"
import { uniqueID } from "~/helpers/utils/uniqueID"
@ -67,13 +70,13 @@ export const insomniaEnvImporter = (contents: string[]) => {
if (parsedInsomniaEnv.success) {
const environment: NonSecretEnvironment = {
id: uniqueID(),
v: 2,
v: EnvironmentSchemaVersion,
name: parsedInsomniaEnv.data.name,
variables: Object.entries(parsedInsomniaEnv.data.data).map(
([key, value]) => ({
key,
initialValue: value,
currentValue: value,
currentValue: "",
secret: false,
})
),

View file

@ -20,6 +20,7 @@ import {
HoppRESTRequest,
HoppRESTRequestResponses,
HoppRESTResponseOriginalRequest,
RESTResOriginalReqSchemaVersion,
} from "@hoppscotch/data"
import { pipe, flow } from "fp-ts/function"
import * as A from "fp-ts/Array"
@ -843,7 +844,7 @@ const convertPathToHoppReqs = (
requestVariables: parseOpenAPIVariables(
(info.parameters as OpenAPIParamsType[] | undefined) ?? []
),
v: "3",
v: RESTResOriginalReqSchemaVersion,
}),
}),
metadata: {

View file

@ -10,6 +10,7 @@ import {
knownContentTypes,
makeCollection,
makeRESTRequest,
RESTResOriginalReqSchemaVersion,
ValidContentTypes,
} from "@hoppscotch/data"
import * as A from "fp-ts/Array"
@ -177,7 +178,7 @@ const getHoppResponses = (
requestVariables: getHoppReqVariables(
response.originalRequest?.url.variables ?? null
),
v: "3" as const,
v: RESTResOriginalReqSchemaVersion,
},
}
return [response.name, res]

View file

@ -1,4 +1,4 @@
import { Environment } from "@hoppscotch/data"
import { Environment, EnvironmentSchemaVersion } from "@hoppscotch/data"
import * as O from "fp-ts/Option"
import * as TE from "fp-ts/TaskEither"
import { z } from "zod"
@ -52,12 +52,12 @@ export const postmanEnvImporter = (contents: string[]) => {
const environments: Environment[] = validationResult.data.map(
({ name, values }) => ({
id: uniqueID(),
v: 2,
v: EnvironmentSchemaVersion,
name,
variables: values.map(({ key, value, type }) => ({
key,
initialValue: value,
currentValue: value,
currentValue: "",
secret: type === "secret",
})),
})

View file

@ -10,6 +10,8 @@ import {
TeamEnvironmentUpdatedDocument,
} from "../backend/graphql"
import { TeamEnvironment } from "./TeamEnvironment"
import { Environment, EnvironmentSchemaVersion } from "@hoppscotch/data"
import { entityReference } from "verzod"
type EntityType = "environment"
type EntityID = `${EntityType}-${string}`
@ -112,19 +114,27 @@ export default class TeamEnvironmentAdapter {
if (result.right.team) {
results.push(
...result.right.team.teamEnvironments.map(
(x) =>
<TeamEnvironment>{
id: x.id,
teamID: x.teamID,
environment: {
v: 2,
id: x.id,
name: x.name,
variables: JSON.parse(x.variables),
},
}
)
...result.right.team.teamEnvironments.map((x) => {
const environment = <Environment>{
id: x.id,
name: x.name,
variables: JSON.parse(x.variables),
}
const parsedEnvironment =
entityReference(Environment).safeParse(environment)
return <TeamEnvironment>{
id: x.id,
teamID: x.teamID,
environment: parsedEnvironment.success
? parsedEnvironment.data
: {
...environment,
v: EnvironmentSchemaVersion,
},
}
})
)
}

View file

@ -433,7 +433,7 @@ const HoppTestResultSchema = z
.strict(),
})
.strict(),
consoleEntries: z.array(z.record(z.string(), z.unknown()).optional()),
consoleEntries: z.optional(z.array(z.record(z.string(), z.unknown()))),
})
.strict()

View file

@ -204,7 +204,7 @@ export const translateToNewEnvironmentVariables = (
return {
key: x.key,
initialValue: x.initialValue ?? x.value ?? "",
currentValue: x.currentValue ?? x.value ?? "",
currentValue: "",
secret: false,
}
}

View file

@ -32,7 +32,7 @@ export default defineVersion({
key,
secret,
initialValue: secret ? "" : variable.value,
currentValue: secret ? "" : variable.value,
currentValue: "",
}
}),
}

View file

@ -17,9 +17,9 @@ import V7_VERSION, { HoppRESTHeaders, HoppRESTParams } from "./v/7"
import V8_VERSION from "./v/8"
import V9_VERSION from "./v/9"
import V10_VERSION, { HoppRESTReqBody } from "./v/10"
import V11_VERSION, { HoppRESTRequestResponses } from "./v/11"
import V11_VERSION from "./v/11"
import V12_VERSION from "./v/12"
import V13_VERSION, { HoppRESTAuth } from "./v/13"
import V13_VERSION, { HoppRESTAuth, HoppRESTRequestResponses } from "./v/13"
export * from "./content-types"
@ -48,19 +48,19 @@ export { HoppRESTAuthDigest, PasswordGrantTypeParams } from "./v/8"
export { FormDataKeyValue } from "./v/9"
export {
HoppRESTResponseOriginalRequest,
HoppRESTRequestResponse,
HoppRESTRequestResponses,
HoppRESTAuthOAuth2,
ClientCredentialsGrantTypeParams,
} from "./v/11"
export { HoppRESTAuthOAuth2, ClientCredentialsGrantTypeParams } from "./v/11"
export { HoppRESTReqBody } from "./v/10"
export { HoppRESTAuthHAWK, HoppRESTAuthAkamaiEdgeGrid } from "./v/12"
export { HoppRESTAuth, HoppRESTAuthJWT } from "./v/13"
export {
HoppRESTAuth,
HoppRESTAuthJWT,
HoppRESTRequestResponses,
HoppRESTResponseOriginalRequest,
HoppRESTRequestResponse,
} from "./v/13"
const versionedObject = z.object({
// v is a stringified number
@ -127,6 +127,7 @@ const HoppRESTRequestEq = Eq.struct<HoppRESTRequest>({
})
export const RESTReqSchemaVersion = "13"
export const RESTResOriginalReqSchemaVersion = "5" as const
export type HoppRESTParam = HoppRESTRequest["params"][number]
export type HoppRESTHeader = HoppRESTRequest["headers"][number]

View file

@ -12,6 +12,11 @@ import { z } from "zod"
import { defineVersion } from "verzod"
import { HoppRESTAuthOAuth2, V11_SCHEMA } from "./11"
import {
HoppRESTResponseOriginalRequest as HoppRESTResponseOriginalRequestOld,
HoppRESTRequestResponse as HoppRESTRequestResponseOld,
} from "./9"
export const HoppRESTAuthHAWK = z.object({
authType: z.literal("hawk"),
authId: z.string().catch(""),
@ -68,18 +73,56 @@ export const HoppRESTAuth = z
export type HoppRESTAuth = z.infer<typeof HoppRESTAuth>
export const HoppRESTResponseOriginalRequest =
HoppRESTResponseOriginalRequestOld.extend({
v: z.literal("4"),
auth: HoppRESTAuth,
})
export type HoppRESTResponseOriginalRequest = z.infer<
typeof HoppRESTResponseOriginalRequest
>
export const HoppRESTRequestResponse = HoppRESTRequestResponseOld.extend({
originalRequest: HoppRESTResponseOriginalRequest,
})
export type HoppRESTRequestResponse = z.infer<typeof HoppRESTRequestResponse>
export const HoppRESTRequestResponses = z.record(
z.string(),
HoppRESTRequestResponse
)
export type HoppRESTRequestResponses = z.infer<typeof HoppRESTRequestResponses>
export const V12_SCHEMA = V11_SCHEMA.extend({
v: z.literal("12"),
auth: HoppRESTAuth,
responses: HoppRESTRequestResponses,
})
export default defineVersion({
schema: V12_SCHEMA,
initial: false,
up(old: z.infer<typeof V11_SCHEMA>) {
// update the version number of response original request
const responses = Object.fromEntries(
Object.entries(old.responses).map(([key, response]) => [
key,
{
...response,
originalRequest: {
...response.originalRequest,
v: "4" as const,
},
},
])
)
return {
...old,
v: "12" as const,
responses,
}
},
})

View file

@ -14,6 +14,11 @@ import { z } from "zod"
import { defineVersion } from "verzod"
import { HoppRESTAuthOAuth2 } from "./11"
import {
HoppRESTResponseOriginalRequest as HoppRESTResponseOriginalRequestOld,
HoppRESTRequestResponse as HoppRESTRequestResponseOld,
} from "./9"
export const HoppRESTAuthJWT = z.object({
authType: z.literal("jwt"),
secret: z.string().catch(""),
@ -66,18 +71,56 @@ export const HoppRESTAuth = z
export type HoppRESTAuth = z.infer<typeof HoppRESTAuth>
export const HoppRESTResponseOriginalRequest =
HoppRESTResponseOriginalRequestOld.extend({
v: z.literal("5"),
auth: HoppRESTAuth,
})
export type HoppRESTResponseOriginalRequest = z.infer<
typeof HoppRESTResponseOriginalRequest
>
export const HoppRESTRequestResponse = HoppRESTRequestResponseOld.extend({
originalRequest: HoppRESTResponseOriginalRequest,
})
export type HoppRESTRequestResponse = z.infer<typeof HoppRESTRequestResponse>
export const HoppRESTRequestResponses = z.record(
z.string(),
HoppRESTRequestResponse
)
export type HoppRESTRequestResponses = z.infer<typeof HoppRESTRequestResponses>
export const V13_SCHEMA = V12_SCHEMA.extend({
v: z.literal("13"),
auth: HoppRESTAuth,
responses: HoppRESTRequestResponses,
})
export default defineVersion({
schema: V13_SCHEMA,
initial: false,
up(old: any) {
up(old: z.infer<typeof V12_SCHEMA>) {
// update the version number of response original request
const responses = Object.fromEntries(
Object.entries(old.responses).map(([key, response]) => [
key,
{
...response,
originalRequest: {
...response.originalRequest,
v: "5" as const,
},
},
])
)
return {
...old,
v: "13" as const,
responses,
}
},
})

View file

@ -101,7 +101,7 @@ export const HoppRESTRequestResponse = z.object({
name: z.string(),
originalRequest: HoppRESTResponseOriginalRequest,
status: z.string(),
code: z.optional(ValidCodes),
code: z.optional(ValidCodes).nullable().catch(null),
headers: HoppRESTResponseHeaders,
body: z.string(),
})

View file

@ -18,7 +18,11 @@ import { runGQLSubscription } from "@hoppscotch/common/helpers/backend/GQLClient
import { environnmentsSyncer } from "@platform/environments/desktop/sync"
import * as E from "fp-ts/Either"
import { GlobalEnvironment } from "@hoppscotch/data"
import {
Environment,
EnvironmentSchemaVersion,
GlobalEnvironment,
} from "@hoppscotch/data"
import { runDispatchWithOutSyncing } from "@lib/sync"
import {
createUserGlobalEnvironment,
@ -82,13 +86,27 @@ async function loadUserEnvironments() {
if (environments.length > 0) {
runDispatchWithOutSyncing(() => {
const formatedEnvironments = environments.map(
(env) =>
<Environment>{
id: env.id,
name: env.name,
variables: JSON.parse(env.variables),
}
)
replaceEnvironments(
environments.map(({ id, variables, name }) => ({
v: 2,
id,
name,
variables: JSON.parse(variables),
}))
formatedEnvironments.map((environment) => {
const parsedEnv =
entityReference(Environment).safeParse(environment)
return parsedEnv.success
? parsedEnv.data
: {
...environment,
v: EnvironmentSchemaVersion,
}
})
)
})
}

View file

@ -18,7 +18,11 @@ import { EnvironmentsPlatformDef } from "@hoppscotch/common/src/platform/environ
import { environnmentsSyncer } from "@platform/environments/web/sync"
import { GlobalEnvironment } from "@hoppscotch/data"
import {
Environment,
EnvironmentSchemaVersion,
GlobalEnvironment,
} from "@hoppscotch/data"
import { runDispatchWithOutSyncing } from "@lib/sync"
import {
createUserGlobalEnvironment,
@ -82,13 +86,27 @@ async function loadUserEnvironments() {
if (environments.length > 0) {
runDispatchWithOutSyncing(() => {
const formatedEnvironments = environments.map(
(env) =>
<Environment>{
id: env.id,
name: env.name,
variables: JSON.parse(env.variables),
}
)
replaceEnvironments(
environments.map(({ id, variables, name }) => ({
v: 2,
id,
name,
variables: JSON.parse(variables),
}))
formatedEnvironments.map((environment) => {
const parsedEnv =
entityReference(Environment).safeParse(environment)
return parsedEnv.success
? parsedEnv.data
: {
...environment,
v: EnvironmentSchemaVersion,
}
})
)
})
}