refactor: move collection data structures and utility functions to hopp/data

This commit is contained in:
Andrew Bastin
2022-01-20 23:55:23 +05:30
parent 6b0494ddba
commit 5043606701
17 changed files with 156 additions and 124 deletions

View File

@@ -164,7 +164,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch } from "@nuxtjs/composition-api" import { computed, ref, watch } from "@nuxtjs/composition-api"
import * as E from "fp-ts/Either" import * as E from "fp-ts/Either"
import { HoppRESTRequest } from "@hoppscotch/data" import { HoppRESTRequest, HoppCollection } from "@hoppscotch/data"
import { apolloClient } from "~/helpers/apollo" import { apolloClient } from "~/helpers/apollo"
import { import {
useAxios, useAxios,
@@ -174,11 +174,7 @@ import {
} from "~/helpers/utils/composables" } from "~/helpers/utils/composables"
import { currentUser$ } from "~/helpers/fb/auth" import { currentUser$ } from "~/helpers/fb/auth"
import * as teamUtils from "~/helpers/teams/utils" import * as teamUtils from "~/helpers/teams/utils"
import { import { appendRESTCollections, restCollections$ } from "~/newstore/collections"
appendRESTCollections,
Collection,
restCollections$,
} from "~/newstore/collections"
import { RESTCollectionImporters } from "~/helpers/import-export/import/importers" import { RESTCollectionImporters } from "~/helpers/import-export/import/importers"
import { StepReturnValue } from "~/helpers/import-export/steps" import { StepReturnValue } from "~/helpers/import-export/steps"
@@ -285,7 +281,7 @@ watch(mySelectedCollectionID, (newValue) => {
const importingMyCollections = ref(false) const importingMyCollections = ref(false)
const importToTeams = async (content: Collection<HoppRESTRequest>) => { const importToTeams = async (content: HoppCollection<HoppRESTRequest>) => {
importingMyCollections.value = true importingMyCollections.value = true
if (props.collectionsType.type !== "team-collections") return if (props.collectionsType.type !== "team-collections") return
await teamUtils await teamUtils

View File

@@ -34,8 +34,8 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from "@nuxtjs/composition-api" import { defineComponent } from "@nuxtjs/composition-api"
import { HoppGQLRequest } from "@hoppscotch/data" import { HoppGQLRequest, makeCollection } from "@hoppscotch/data"
import { addGraphqlCollection, makeCollection } from "~/newstore/collections" import { addGraphqlCollection } from "~/newstore/collections"
export default defineComponent({ export default defineComponent({
props: { props: {

View File

@@ -5,14 +5,16 @@ import {
onSnapshot, onSnapshot,
setDoc, setDoc,
} from "firebase/firestore" } from "firebase/firestore"
import {
translateToNewRESTCollection,
translateToNewGQLCollection,
} from "@hoppscotch/data"
import { currentUser$ } from "./auth" import { currentUser$ } from "./auth"
import { import {
restCollections$, restCollections$,
graphqlCollections$, graphqlCollections$,
setRESTCollections, setRESTCollections,
setGraphqlCollections, setGraphqlCollections,
translateToNewRESTCollection,
translateToNewGQLCollection,
} from "~/newstore/collections" } from "~/newstore/collections"
import { settingsStore } from "~/newstore/settings" import { settingsStore } from "~/newstore/settings"

View File

@@ -1,10 +1,9 @@
import { HoppRESTRequest } from "@hoppscotch/data" import { HoppRESTRequest, HoppCollection } from "@hoppscotch/data"
import { pipe } from "fp-ts/function" import { pipe } from "fp-ts/function"
import * as TE from "fp-ts/TaskEither" import * as TE from "fp-ts/TaskEither"
import { HoppExporter } from "." import { HoppExporter } from "."
import { Collection } from "~/newstore/collections"
const exporter: HoppExporter<Collection<HoppRESTRequest>> = (content) => const exporter: HoppExporter<HoppCollection<HoppRESTRequest>> = (content) =>
pipe(content, JSON.stringify, TE.right) pipe(content, JSON.stringify, TE.right)
export default exporter export default exporter

View File

@@ -1,6 +1,5 @@
import * as TE from "fp-ts/TaskEither" import * as TE from "fp-ts/TaskEither"
import { HoppRESTRequest } from "@hoppscotch/data" import { HoppRESTRequest, HoppCollection } from "@hoppscotch/data"
import { Collection } from "~/newstore/collections"
export type HoppExporter<T> = (content: T) => TE.TaskEither<string, string> export type HoppExporter<T> = (content: T) => TE.TaskEither<string, string>
@@ -10,7 +9,7 @@ export type HoppExporterDefintion<T> = {
} }
export const RESTCollectionExporters: HoppExporterDefintion< export const RESTCollectionExporters: HoppExporterDefintion<
Collection<HoppRESTRequest> HoppCollection<HoppRESTRequest>
>[] = [ >[] = [
{ {
name: "Hoppscotch REST Collection JSON", name: "Hoppscotch REST Collection JSON",

View File

@@ -3,13 +3,14 @@ import * as TE from "fp-ts/TaskEither"
import * as TO from "fp-ts/TaskOption" import * as TO from "fp-ts/TaskOption"
import * as O from "fp-ts/Option" import * as O from "fp-ts/Option"
import axios from "axios" import axios from "axios"
import { HoppRESTRequest } from "@hoppscotch/data" import { HoppRESTRequest, HoppCollection } from "@hoppscotch/data"
import { step } from "../steps" import { step } from "../steps"
import { defineImporter, IMPORTER_INVALID_FILE_FORMAT } from "." import { defineImporter, IMPORTER_INVALID_FILE_FORMAT } from "."
import { Collection } from "~/newstore/collections"
// TODO: Add validation to output // TODO: Add validation to output
const fetchGist = (url: string): TO.TaskOption<Collection<HoppRESTRequest>> => const fetchGist = (
url: string
): TO.TaskOption<HoppCollection<HoppRESTRequest>> =>
pipe( pipe(
TO.tryCatch(() => TO.tryCatch(() =>
axios.get(`https://api.github.com/gists/${url.split("/").pop()}`, { axios.get(`https://api.github.com/gists/${url.split("/").pop()}`, {

View File

@@ -1,9 +1,9 @@
import { pipe } from "fp-ts/function" import { pipe } from "fp-ts/function"
import * as TE from "fp-ts/TaskEither" import * as TE from "fp-ts/TaskEither"
import * as E from "fp-ts/Either" import * as E from "fp-ts/Either"
import { translateToNewRESTCollection } from "@hoppscotch/data"
import { step } from "../steps" import { step } from "../steps"
import { defineImporter, IMPORTER_INVALID_FILE_FORMAT } from "." import { defineImporter, IMPORTER_INVALID_FILE_FORMAT } from "."
import { translateToNewRESTCollection } from "~/newstore/collections"
export default defineImporter({ export default defineImporter({
name: "import.from_json", name: "import.from_json",

View File

@@ -8,6 +8,8 @@ import {
HoppRESTRequest, HoppRESTRequest,
knownContentTypes, knownContentTypes,
makeRESTRequest, makeRESTRequest,
HoppCollection,
makeCollection,
} from "@hoppscotch/data" } from "@hoppscotch/data"
import * as A from "fp-ts/Array" import * as A from "fp-ts/Array"
import * as S from "fp-ts/string" import * as S from "fp-ts/string"
@@ -15,7 +17,6 @@ import * as TO from "fp-ts/TaskOption"
import * as TE from "fp-ts/TaskEither" import * as TE from "fp-ts/TaskEither"
import { step } from "../steps" import { step } from "../steps"
import { defineImporter, IMPORTER_INVALID_FILE_FORMAT } from "." import { defineImporter, IMPORTER_INVALID_FILE_FORMAT } from "."
import { Collection, makeCollection } from "~/newstore/collections"
// TODO: Insomnia allows custom prefixes for Bearer token auth, Hoppscotch doesn't. We just ignore the prefix for now // TODO: Insomnia allows custom prefixes for Bearer token auth, Hoppscotch doesn't. We just ignore the prefix for now
@@ -194,7 +195,7 @@ const getHoppRequest = (req: InsomniaRequestResource): HoppRESTRequest =>
const getHoppFolder = ( const getHoppFolder = (
folderRes: InsomniaFolderResource, folderRes: InsomniaFolderResource,
resources: InsomniaResource[] resources: InsomniaResource[]
): Collection<HoppRESTRequest> => ): HoppCollection<HoppRESTRequest> =>
makeCollection({ makeCollection({
name: folderRes.name ?? "", name: folderRes.name ?? "",
folders: getFoldersIn(folderRes, resources).map((f) => folders: getFoldersIn(folderRes, resources).map((f) =>

View File

@@ -15,6 +15,8 @@ import {
HoppRESTRequest, HoppRESTRequest,
knownContentTypes, knownContentTypes,
makeRESTRequest, makeRESTRequest,
HoppCollection,
makeCollection,
} from "@hoppscotch/data" } from "@hoppscotch/data"
import { pipe, flow } from "fp-ts/function" import { pipe, flow } from "fp-ts/function"
import * as A from "fp-ts/Array" import * as A from "fp-ts/Array"
@@ -24,7 +26,6 @@ import * as TE from "fp-ts/TaskEither"
import * as RA from "fp-ts/ReadonlyArray" import * as RA from "fp-ts/ReadonlyArray"
import { step } from "../steps" import { step } from "../steps"
import { defineImporter, IMPORTER_INVALID_FILE_FORMAT } from "." import { defineImporter, IMPORTER_INVALID_FILE_FORMAT } from "."
import { Collection, makeCollection } from "~/newstore/collections"
const OPENAPI_DEREF_ERROR = "openapi/deref_error" as const const OPENAPI_DEREF_ERROR = "openapi/deref_error" as const
@@ -558,7 +559,7 @@ const convertPathToHoppReqs = (
const convertOpenApiDocToHopp = ( const convertOpenApiDocToHopp = (
doc: OpenAPI.Document doc: OpenAPI.Document
): TE.TaskEither<never, Collection<HoppRESTRequest>[]> => { ): TE.TaskEither<never, HoppCollection<HoppRESTRequest>[]> => {
const name = doc.info.title const name = doc.info.title
const paths = Object.entries(doc.paths ?? {}) const paths = Object.entries(doc.paths ?? {})

View File

@@ -14,6 +14,8 @@ import {
HoppRESTReqBody, HoppRESTReqBody,
HoppRESTRequest, HoppRESTRequest,
makeRESTRequest, makeRESTRequest,
HoppCollection,
makeCollection,
} from "@hoppscotch/data" } from "@hoppscotch/data"
import { pipe, flow } from "fp-ts/function" import { pipe, flow } from "fp-ts/function"
import * as S from "fp-ts/string" import * as S from "fp-ts/string"
@@ -22,7 +24,6 @@ import * as O from "fp-ts/Option"
import * as TE from "fp-ts/TaskEither" import * as TE from "fp-ts/TaskEither"
import { step } from "../steps" import { step } from "../steps"
import { defineImporter, IMPORTER_INVALID_FILE_FORMAT } from "." import { defineImporter, IMPORTER_INVALID_FILE_FORMAT } from "."
import { Collection, makeCollection } from "~/newstore/collections"
const safeParseJSON = (jsonStr: string) => O.tryCatch(() => JSON.parse(jsonStr)) const safeParseJSON = (jsonStr: string) => O.tryCatch(() => JSON.parse(jsonStr))
@@ -226,7 +227,7 @@ const getHoppRequest = (item: Item): HoppRESTRequest => {
}) })
} }
const getHoppFolder = (ig: ItemGroup<Item>): Collection<HoppRESTRequest> => const getHoppFolder = (ig: ItemGroup<Item>): HoppCollection<HoppRESTRequest> =>
makeCollection({ makeCollection({
name: ig.name, name: ig.name,
folders: pipe( folders: pipe(

View File

@@ -1,22 +1,13 @@
import { pluck } from "rxjs/operators" import { pluck } from "rxjs/operators"
import { import {
HoppGQLRequest, HoppGQLRequest,
translateToGQLRequest,
HoppRESTRequest, HoppRESTRequest,
translateToNewRequest, HoppCollection,
makeCollection,
} from "@hoppscotch/data" } from "@hoppscotch/data"
import DispatchingStore, { defineDispatchers } from "./DispatchingStore" import DispatchingStore, { defineDispatchers } from "./DispatchingStore"
import { getRESTSaveContext, setRESTSaveContext } from "./RESTSession" import { getRESTSaveContext, setRESTSaveContext } from "./RESTSession"
export interface Collection<T extends HoppRESTRequest | HoppGQLRequest> {
v: number
name: string
folders: Collection<T>[]
requests: T[]
id?: string // For Firestore ID
}
const defaultRESTCollectionState = { const defaultRESTCollectionState = {
state: [ state: [
makeCollection<HoppRESTRequest>({ makeCollection<HoppRESTRequest>({
@@ -37,62 +28,11 @@ const defaultGraphqlCollectionState = {
], ],
} }
export function makeCollection<T extends HoppRESTRequest | HoppGQLRequest>(
x: Omit<Collection<T>, "v">
): Collection<T> {
return {
v: 1,
...x,
}
}
export function translateToNewRESTCollection(
x: any
): Collection<HoppRESTRequest> {
if (x.v && x.v === 1) return x
// Legacy
const name = x.name ?? "Untitled"
const folders = (x.folders ?? []).map(translateToNewRESTCollection)
const requests = (x.requests ?? []).map(translateToNewRequest)
const obj = makeCollection<HoppRESTRequest>({
name,
folders,
requests,
})
if (x.id) obj.id = x.id
return obj
}
export function translateToNewGQLCollection(
x: any
): Collection<HoppGQLRequest> {
if (x.v && x.v === 1) return x
// Legacy
const name = x.name ?? "Untitled"
const folders = (x.folders ?? []).map(translateToNewGQLCollection)
const requests = (x.requests ?? []).map(translateToGQLRequest)
const obj = makeCollection<HoppGQLRequest>({
name,
folders,
requests,
})
if (x.id) obj.id = x.id
return obj
}
type RESTCollectionStoreType = typeof defaultRESTCollectionState type RESTCollectionStoreType = typeof defaultRESTCollectionState
type GraphqlCollectionStoreType = typeof defaultGraphqlCollectionState type GraphqlCollectionStoreType = typeof defaultGraphqlCollectionState
function navigateToFolderWithIndexPath( function navigateToFolderWithIndexPath(
collections: Collection<HoppRESTRequest | HoppGQLRequest>[], collections: HoppCollection<HoppRESTRequest | HoppGQLRequest>[],
indexPaths: number[] indexPaths: number[]
) { ) {
if (indexPaths.length === 0) return null if (indexPaths.length === 0) return null
@@ -108,7 +48,7 @@ function navigateToFolderWithIndexPath(
const restCollectionDispatchers = defineDispatchers({ const restCollectionDispatchers = defineDispatchers({
setCollections( setCollections(
_: RESTCollectionStoreType, _: RESTCollectionStoreType,
{ entries }: { entries: Collection<HoppRESTRequest>[] } { entries }: { entries: HoppCollection<HoppRESTRequest>[] }
) { ) {
return { return {
state: entries, state: entries,
@@ -117,7 +57,7 @@ const restCollectionDispatchers = defineDispatchers({
appendCollections( appendCollections(
{ state }: RESTCollectionStoreType, { state }: RESTCollectionStoreType,
{ entries }: { entries: Collection<HoppRESTRequest>[] } { entries }: { entries: HoppCollection<HoppRESTRequest>[] }
) { ) {
return { return {
state: [...state, ...entries], state: [...state, ...entries],
@@ -126,7 +66,7 @@ const restCollectionDispatchers = defineDispatchers({
addCollection( addCollection(
{ state }: RESTCollectionStoreType, { state }: RESTCollectionStoreType,
{ collection }: { collection: Collection<any> } { collection }: { collection: HoppCollection<any> }
) { ) {
return { return {
state: [...state, collection], state: [...state, collection],
@@ -149,7 +89,7 @@ const restCollectionDispatchers = defineDispatchers({
{ {
collectionIndex, collectionIndex,
collection, collection,
}: { collectionIndex: number; collection: Collection<any> } }: { collectionIndex: number; collection: HoppCollection<any> }
) { ) {
return { return {
state: state.map((col, index) => state: state.map((col, index) =>
@@ -162,7 +102,7 @@ const restCollectionDispatchers = defineDispatchers({
{ state }: RESTCollectionStoreType, { state }: RESTCollectionStoreType,
{ name, path }: { name: string; path: string } { name, path }: { name: string; path: string }
) { ) {
const newFolder: Collection<HoppRESTRequest> = makeCollection({ const newFolder: HoppCollection<HoppRESTRequest> = makeCollection({
name, name,
folders: [], folders: [],
requests: [], requests: [],
@@ -374,7 +314,7 @@ const restCollectionDispatchers = defineDispatchers({
const gqlCollectionDispatchers = defineDispatchers({ const gqlCollectionDispatchers = defineDispatchers({
setCollections( setCollections(
_: GraphqlCollectionStoreType, _: GraphqlCollectionStoreType,
{ entries }: { entries: Collection<any>[] } { entries }: { entries: HoppCollection<any>[] }
) { ) {
return { return {
state: entries, state: entries,
@@ -383,7 +323,7 @@ const gqlCollectionDispatchers = defineDispatchers({
appendCollections( appendCollections(
{ state }: GraphqlCollectionStoreType, { state }: GraphqlCollectionStoreType,
{ entries }: { entries: Collection<any>[] } { entries }: { entries: HoppCollection<any>[] }
) { ) {
return { return {
state: [...state, ...entries], state: [...state, ...entries],
@@ -392,7 +332,7 @@ const gqlCollectionDispatchers = defineDispatchers({
addCollection( addCollection(
{ state }: GraphqlCollectionStoreType, { state }: GraphqlCollectionStoreType,
{ collection }: { collection: Collection<any> } { collection }: { collection: HoppCollection<any> }
) { ) {
return { return {
state: [...state, collection], state: [...state, collection],
@@ -415,7 +355,7 @@ const gqlCollectionDispatchers = defineDispatchers({
{ {
collectionIndex, collectionIndex,
collection, collection,
}: { collectionIndex: number; collection: Collection<any> } }: { collectionIndex: number; collection: HoppCollection<any> }
) { ) {
return { return {
state: state.map((col, index) => state: state.map((col, index) =>
@@ -428,7 +368,7 @@ const gqlCollectionDispatchers = defineDispatchers({
{ state }: GraphqlCollectionStoreType, { state }: GraphqlCollectionStoreType,
{ name, path }: { name: string; path: string } { name, path }: { name: string; path: string }
) { ) {
const newFolder: Collection<HoppGQLRequest> = makeCollection({ const newFolder: HoppCollection<HoppGQLRequest> = makeCollection({
name, name,
folders: [], folders: [],
requests: [], requests: [],
@@ -650,7 +590,7 @@ export const graphqlCollectionStore = new DispatchingStore(
gqlCollectionDispatchers gqlCollectionDispatchers
) )
export function setRESTCollections(entries: Collection<HoppRESTRequest>[]) { export function setRESTCollections(entries: HoppCollection<HoppRESTRequest>[]) {
restCollectionStore.dispatch({ restCollectionStore.dispatch({
dispatcher: "setCollections", dispatcher: "setCollections",
payload: { payload: {
@@ -667,7 +607,9 @@ export const graphqlCollections$ = graphqlCollectionStore.subject$.pipe(
pluck("state") pluck("state")
) )
export function appendRESTCollections(entries: Collection<HoppRESTRequest>[]) { export function appendRESTCollections(
entries: HoppCollection<HoppRESTRequest>[]
) {
restCollectionStore.dispatch({ restCollectionStore.dispatch({
dispatcher: "appendCollections", dispatcher: "appendCollections",
payload: { payload: {
@@ -676,7 +618,7 @@ export function appendRESTCollections(entries: Collection<HoppRESTRequest>[]) {
}) })
} }
export function addRESTCollection(collection: Collection<HoppRESTRequest>) { export function addRESTCollection(collection: HoppCollection<HoppRESTRequest>) {
restCollectionStore.dispatch({ restCollectionStore.dispatch({
dispatcher: "addCollection", dispatcher: "addCollection",
payload: { payload: {
@@ -700,7 +642,7 @@ export function getRESTCollection(collectionIndex: number) {
export function editRESTCollection( export function editRESTCollection(
collectionIndex: number, collectionIndex: number,
collection: Collection<HoppRESTRequest> collection: HoppCollection<HoppRESTRequest>
) { ) {
restCollectionStore.dispatch({ restCollectionStore.dispatch({
dispatcher: "editCollection", dispatcher: "editCollection",
@@ -723,7 +665,7 @@ export function addRESTFolder(name: string, path: string) {
export function editRESTFolder( export function editRESTFolder(
path: string, path: string,
folder: Collection<HoppRESTRequest> folder: HoppCollection<HoppRESTRequest>
) { ) {
restCollectionStore.dispatch({ restCollectionStore.dispatch({
dispatcher: "editFolder", dispatcher: "editFolder",
@@ -809,7 +751,9 @@ export function moveRESTRequest(
}) })
} }
export function setGraphqlCollections(entries: Collection<HoppGQLRequest>[]) { export function setGraphqlCollections(
entries: HoppCollection<HoppGQLRequest>[]
) {
graphqlCollectionStore.dispatch({ graphqlCollectionStore.dispatch({
dispatcher: "setCollections", dispatcher: "setCollections",
payload: { payload: {
@@ -819,7 +763,7 @@ export function setGraphqlCollections(entries: Collection<HoppGQLRequest>[]) {
} }
export function appendGraphqlCollections( export function appendGraphqlCollections(
entries: Collection<HoppGQLRequest>[] entries: HoppCollection<HoppGQLRequest>[]
) { ) {
graphqlCollectionStore.dispatch({ graphqlCollectionStore.dispatch({
dispatcher: "appendCollections", dispatcher: "appendCollections",
@@ -829,7 +773,9 @@ export function appendGraphqlCollections(
}) })
} }
export function addGraphqlCollection(collection: Collection<HoppGQLRequest>) { export function addGraphqlCollection(
collection: HoppCollection<HoppGQLRequest>
) {
graphqlCollectionStore.dispatch({ graphqlCollectionStore.dispatch({
dispatcher: "addCollection", dispatcher: "addCollection",
payload: { payload: {
@@ -849,7 +795,7 @@ export function removeGraphqlCollection(collectionIndex: number) {
export function editGraphqlCollection( export function editGraphqlCollection(
collectionIndex: number, collectionIndex: number,
collection: Collection<HoppGQLRequest> collection: HoppCollection<HoppGQLRequest>
) { ) {
graphqlCollectionStore.dispatch({ graphqlCollectionStore.dispatch({
dispatcher: "editCollection", dispatcher: "editCollection",
@@ -872,7 +818,7 @@ export function addGraphqlFolder(name: string, path: string) {
export function editGraphqlFolder( export function editGraphqlFolder(
path: string, path: string,
folder: Collection<HoppGQLRequest> folder: HoppCollection<HoppGQLRequest>
) { ) {
graphqlCollectionStore.dispatch({ graphqlCollectionStore.dispatch({
dispatcher: "editFolder", dispatcher: "editFolder",

View File

@@ -8,6 +8,8 @@ import { pipe } from "fp-ts/function"
import { import {
safelyExtractRESTRequest, safelyExtractRESTRequest,
translateToNewRequest, translateToNewRequest,
translateToNewRESTCollection,
translateToNewGQLCollection,
} from "@hoppscotch/data" } from "@hoppscotch/data"
import { cloneDeep } from "lodash" import { cloneDeep } from "lodash"
import { import {
@@ -31,8 +33,6 @@ import {
graphqlCollectionStore, graphqlCollectionStore,
setGraphqlCollections, setGraphqlCollections,
setRESTCollections, setRESTCollections,
translateToNewRESTCollection,
translateToNewGQLCollection,
} from "./collections" } from "./collections"
import { import {
replaceEnvironments, replaceEnvironments,

View File

@@ -57,7 +57,7 @@
"@codemirror/tooltip": "^0.19.12", "@codemirror/tooltip": "^0.19.12",
"@codemirror/view": "^0.19.39", "@codemirror/view": "^0.19.39",
"@hoppscotch/codemirror-lang-graphql": "workspace:^0.1.0", "@hoppscotch/codemirror-lang-graphql": "workspace:^0.1.0",
"@hoppscotch/data": "workspace:^0.2.0", "@hoppscotch/data": "workspace:^0.3.0",
"@hoppscotch/js-sandbox": "workspace:^1.0.0", "@hoppscotch/js-sandbox": "workspace:^1.0.0",
"@nuxtjs/axios": "^5.13.6", "@nuxtjs/axios": "^5.13.6",
"@nuxtjs/composition-api": "^0.31.0", "@nuxtjs/composition-api": "^0.31.0",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@hoppscotch/data", "name": "@hoppscotch/data",
"version": "0.2.0", "version": "0.3.0",
"description": "Data Types, Validations and Migrations for Hoppscotch Public Data Structures", "description": "Data Types, Validations and Migrations for Hoppscotch Public Data Structures",
"main": "dist/index.js", "main": "dist/index.js",
"module": "true", "module": "true",

View File

@@ -0,0 +1,85 @@
import { HoppGQLRequest, translateToGQLRequest } from "../graphql";
import { HoppRESTRequest, translateToNewRequest } from "../rest";
const CURRENT_COLL_SCHEMA_VER = 1
type SupportedReqTypes =
| HoppRESTRequest
| HoppGQLRequest
export type HoppCollection<T extends SupportedReqTypes> = {
v: number
name: string
folders: HoppCollection<T>[]
requests: T[]
id?: string // For Firestore ID data
}
/**
* Generates a Collection object. This ignores the version number object
* so it can be incremented independently without updating it everywhere
* @param x The Collection Data
* @returns The final collection
*/
export function makeCollection<T extends SupportedReqTypes>(
x: Omit<HoppCollection<T>, "v">
): HoppCollection<T> {
return {
v: CURRENT_COLL_SCHEMA_VER,
...x
}
}
/**
* Translates an old collection to a new collection
* @param x The collection object to load
* @returns The proper new collection format
*/
export function translateToNewRESTCollection(
x: any
): HoppCollection<HoppRESTRequest> {
if (x.v && x.v === 1) return x
// Legacy
const name = x.name ?? "Untitled"
const folders = (x.folders ?? []).map(translateToNewRESTCollection)
const requests = (x.requests ?? []).map(translateToNewRequest)
const obj = makeCollection<HoppRESTRequest>({
name,
folders,
requests,
})
if (x.id) obj.id = x.id
return obj
}
/**
* Translates an old collection to a new collection
* @param x The collection object to load
* @returns The proper new collection format
*/
export function translateToNewGQLCollection(
x: any
): HoppCollection<HoppGQLRequest> {
if (x.v && x.v === 1) return x
// Legacy
const name = x.name ?? "Untitled"
const folders = (x.folders ?? []).map(translateToNewGQLCollection)
const requests = (x.requests ?? []).map(translateToGQLRequest)
const obj = makeCollection<HoppGQLRequest>({
name,
folders,
requests,
})
if (x.id) obj.id = x.id
return obj
}

View File

@@ -1,2 +1,3 @@
export * from "./rest" export * from "./rest"
export * from "./graphql" export * from "./graphql"
export * from "./collection"

20
pnpm-lock.yaml generated
View File

@@ -76,7 +76,7 @@ importers:
'@graphql-codegen/urql-introspection': ^2.1.1 '@graphql-codegen/urql-introspection': ^2.1.1
'@graphql-typed-document-node/core': ^3.1.1 '@graphql-typed-document-node/core': ^3.1.1
'@hoppscotch/codemirror-lang-graphql': workspace:^0.1.0 '@hoppscotch/codemirror-lang-graphql': workspace:^0.1.0
'@hoppscotch/data': workspace:^0.2.0 '@hoppscotch/data': workspace:^0.3.0
'@hoppscotch/js-sandbox': workspace:^1.0.0 '@hoppscotch/js-sandbox': workspace:^1.0.0
'@nuxt/types': ^2.15.8 '@nuxt/types': ^2.15.8
'@nuxt/typescript-build': ^2.1.0 '@nuxt/typescript-build': ^2.1.0
@@ -3764,14 +3764,14 @@ packages:
ufo: 0.7.9 ufo: 0.7.9
dev: false dev: false
/@nuxt/kit-edge/3.0.0-27373739.0ed2d4a: /@nuxt/kit-edge/3.0.0-27376999.6abf75d:
resolution: {integrity: sha512-xQUBq0nOD8gzJ/j6rvuWYGbjyp/+FShXirVbzP4rChX6UE5dMw+0oRBcmQ8ypA1hmpuXhDZHlw1noU0QHg2R9Q==} resolution: {integrity: sha512-9VdJR9s9TXHd+lRRZnZRV+5GwkWKYomIS5NONMVgBDFjxotvqkVsCbpHvUja2I0NlcAxKnFePgqeDC20CBrgHQ==}
engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0} engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0}
dependencies: dependencies:
'@nuxt/schema': /@nuxt/schema-edge/3.0.0-27373739.0ed2d4a '@nuxt/schema': /@nuxt/schema-edge/3.0.0-27376999.6abf75d
consola: 2.15.3 consola: 2.15.3
defu: 5.0.1 defu: 5.0.1
dotenv: 14.1.0 dotenv: 14.2.0
globby: 12.2.0 globby: 12.2.0
hash-sum: 2.0.0 hash-sum: 2.0.0
jiti: 1.12.9 jiti: 1.12.9
@@ -3806,8 +3806,8 @@ packages:
node-fetch: 2.6.6 node-fetch: 2.6.6
dev: false dev: false
/@nuxt/schema-edge/3.0.0-27373739.0ed2d4a: /@nuxt/schema-edge/3.0.0-27376999.6abf75d:
resolution: {integrity: sha512-eMID8ninnb8BwN9b+YpvPbO8tEOrBrvy+2n8wbQe10JhVvf5lLZ+zpGIvlMQbLoFuEEsd444i4m7S5svSr5dTQ==} resolution: {integrity: sha512-BdoTPuXoHT3aqQL37g/SPk1jOFO4pHbEClsj/5X6cLKwktTcqSbMkwZJF0tTyhvAwiOSFdlTvI34juPhvLNzPw==}
engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0} engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0}
dependencies: dependencies:
create-require: 1.1.1 create-require: 1.1.1
@@ -8374,8 +8374,8 @@ packages:
engines: {node: '>=10'} engines: {node: '>=10'}
dev: true dev: true
/dotenv/14.1.0: /dotenv/14.2.0:
resolution: {integrity: sha512-h8V+Yfa8m0YSjf3Rgbno51cxWldb4PEixIJVL55VmW7uAfeLQKiaPrEUiBps+ARK9MeqjJgTf269OMmu6lOODQ==} resolution: {integrity: sha512-05POuPJyPpO6jqzTNweQFfAyMSD4qa4lvsMOWyTRTdpHKy6nnnN+IYWaXF+lHivhBH/ufDKlR4IWCAN3oPnHuw==}
engines: {node: '>=12'} engines: {node: '>=12'}
dev: true dev: true
@@ -13547,7 +13547,7 @@ packages:
/nuxt-windicss/2.2.2: /nuxt-windicss/2.2.2:
resolution: {integrity: sha512-4tvzk9d2TUFxloty187D+wmO8ZNAvpSmRJ5HQO3/AvZdMMhAl4gomXR9fCgFKQe7Fxcj9nIKNInOx8TWowjiqA==} resolution: {integrity: sha512-4tvzk9d2TUFxloty187D+wmO8ZNAvpSmRJ5HQO3/AvZdMMhAl4gomXR9fCgFKQe7Fxcj9nIKNInOx8TWowjiqA==}
dependencies: dependencies:
'@nuxt/kit': /@nuxt/kit-edge/3.0.0-27373739.0ed2d4a '@nuxt/kit': /@nuxt/kit-edge/3.0.0-27376999.6abf75d
'@windicss/plugin-utils': 1.6.1 '@windicss/plugin-utils': 1.6.1
consola: 2.15.3 consola: 2.15.3
defu: 5.0.0 defu: 5.0.0