Compare commits
5 Commits
hotfix/req
...
hotfix/ful
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51e3cf0a6a | ||
|
|
21b1f385e6 | ||
|
|
c0aca81004 | ||
|
|
88bbd1a861 | ||
|
|
befbead59f |
@@ -112,7 +112,7 @@ services:
|
|||||||
build:
|
build:
|
||||||
dockerfile: packages/hoppscotch-backend/Dockerfile
|
dockerfile: packages/hoppscotch-backend/Dockerfile
|
||||||
context: .
|
context: .
|
||||||
target: dev
|
target: prod
|
||||||
env_file:
|
env_file:
|
||||||
- ./.env
|
- ./.env
|
||||||
restart: always
|
restart: always
|
||||||
@@ -122,7 +122,7 @@ services:
|
|||||||
- PORT=3000
|
- PORT=3000
|
||||||
volumes:
|
volumes:
|
||||||
# Uncomment the line below when modifying code. Only applicable when using the "dev" target.
|
# Uncomment the line below when modifying code. Only applicable when using the "dev" target.
|
||||||
- ./packages/hoppscotch-backend/:/usr/src/app
|
# - ./packages/hoppscotch-backend/:/usr/src/app
|
||||||
- /usr/src/app/node_modules/
|
- /usr/src/app/node_modules/
|
||||||
depends_on:
|
depends_on:
|
||||||
hoppscotch-db:
|
hoppscotch-db:
|
||||||
|
|||||||
@@ -1125,7 +1125,7 @@ export class TeamCollectionService {
|
|||||||
id: searchResults[i].id,
|
id: searchResults[i].id,
|
||||||
path: !fetchedParentTree
|
path: !fetchedParentTree
|
||||||
? []
|
? []
|
||||||
: ([fetchedParentTree.right] as CollectionSearchNode[]),
|
: (fetchedParentTree.right as CollectionSearchNode[]),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1151,8 +1151,8 @@ export class TeamCollectionService {
|
|||||||
select id,title,'collection' AS type
|
select id,title,'collection' AS type
|
||||||
from "TeamCollection"
|
from "TeamCollection"
|
||||||
where "TeamCollection"."teamID"=${teamID}
|
where "TeamCollection"."teamID"=${teamID}
|
||||||
and titlesearch @@ to_tsquery(${searchQuery})
|
and titlesearch @@ plainto_tsquery(${searchQuery})
|
||||||
order by ts_rank(titlesearch,to_tsquery(${searchQuery}))
|
order by ts_rank(titlesearch,plainto_tsquery(${searchQuery}))
|
||||||
limit ${take}
|
limit ${take}
|
||||||
OFFSET ${skip === 0 ? 0 : (skip - 1) * take};
|
OFFSET ${skip === 0 ? 0 : (skip - 1) * take};
|
||||||
`;
|
`;
|
||||||
@@ -1183,8 +1183,8 @@ export class TeamCollectionService {
|
|||||||
select id,title,request->>'method' as method,'request' AS type
|
select id,title,request->>'method' as method,'request' AS type
|
||||||
from "TeamRequest"
|
from "TeamRequest"
|
||||||
where "TeamRequest"."teamID"=${teamID}
|
where "TeamRequest"."teamID"=${teamID}
|
||||||
and titlesearch @@ to_tsquery(${searchQuery})
|
and titlesearch @@ plainto_tsquery(${searchQuery})
|
||||||
order by ts_rank(titlesearch,to_tsquery(${searchQuery}))
|
order by ts_rank(titlesearch,plainto_tsquery(${searchQuery}))
|
||||||
limit ${take}
|
limit ${take}
|
||||||
OFFSET ${skip === 0 ? 0 : (skip - 1) * take};
|
OFFSET ${skip === 0 ? 0 : (skip - 1) * take};
|
||||||
`;
|
`;
|
||||||
@@ -1250,45 +1250,53 @@ export class TeamCollectionService {
|
|||||||
* @returns The parent tree of the parent collections
|
* @returns The parent tree of the parent collections
|
||||||
*/
|
*/
|
||||||
private generateParentTree(parentCollections: ParentTreeQueryReturnType[]) {
|
private generateParentTree(parentCollections: ParentTreeQueryReturnType[]) {
|
||||||
function findChildren(id) {
|
function findChildren(id: string): CollectionSearchNode[] {
|
||||||
const collection = parentCollections.filter((item) => item.id === id)[0];
|
const collection = parentCollections.filter((item) => item.id === id)[0];
|
||||||
if (collection.parentID == null) {
|
if (collection.parentID == null) {
|
||||||
return {
|
return <CollectionSearchNode[]>[
|
||||||
id: collection.id,
|
{
|
||||||
title: collection.title,
|
id: collection.id,
|
||||||
type: 'collection',
|
title: collection.title,
|
||||||
path: [],
|
type: 'collection' as const,
|
||||||
};
|
path: [],
|
||||||
|
},
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = {
|
const res = <CollectionSearchNode[]>[
|
||||||
id: collection.id,
|
{
|
||||||
title: collection.title,
|
id: collection.id,
|
||||||
type: 'collection',
|
title: collection.title,
|
||||||
path: findChildren(collection.parentID),
|
type: 'collection' as const,
|
||||||
};
|
path: findChildren(collection.parentID),
|
||||||
|
},
|
||||||
|
];
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parentCollections.length > 0) {
|
if (parentCollections.length > 0) {
|
||||||
if (parentCollections[0].parentID == null) {
|
if (parentCollections[0].parentID == null) {
|
||||||
return {
|
return <CollectionSearchNode[]>[
|
||||||
|
{
|
||||||
|
id: parentCollections[0].id,
|
||||||
|
title: parentCollections[0].title,
|
||||||
|
type: 'collection',
|
||||||
|
path: [],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return <CollectionSearchNode[]>[
|
||||||
|
{
|
||||||
id: parentCollections[0].id,
|
id: parentCollections[0].id,
|
||||||
title: parentCollections[0].title,
|
title: parentCollections[0].title,
|
||||||
type: 'collection',
|
type: 'collection',
|
||||||
path: [],
|
path: findChildren(parentCollections[0].parentID),
|
||||||
};
|
},
|
||||||
}
|
];
|
||||||
|
|
||||||
return {
|
|
||||||
id: parentCollections[0].id,
|
|
||||||
title: parentCollections[0].title,
|
|
||||||
type: 'collection',
|
|
||||||
path: findChildren(parentCollections[0].parentID),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return <CollectionSearchNode[]>[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -4,12 +4,11 @@ import * as O from "fp-ts/Option"
|
|||||||
import * as RA from "fp-ts/ReadonlyArray"
|
import * as RA from "fp-ts/ReadonlyArray"
|
||||||
import * as A from "fp-ts/Array"
|
import * as A from "fp-ts/Array"
|
||||||
import { translateToNewRESTCollection, HoppCollection } from "@hoppscotch/data"
|
import { translateToNewRESTCollection, HoppCollection } from "@hoppscotch/data"
|
||||||
|
import { isPlainObject as _isPlainObject } from "lodash-es"
|
||||||
|
|
||||||
import { IMPORTER_INVALID_FILE_FORMAT } from "."
|
import { IMPORTER_INVALID_FILE_FORMAT } from "."
|
||||||
import { safeParseJSON } from "~/helpers/functional/json"
|
import { safeParseJSON } from "~/helpers/functional/json"
|
||||||
import { translateToNewGQLCollection } from "@hoppscotch/data"
|
import { translateToNewGQLCollection } from "@hoppscotch/data"
|
||||||
import { entityReference } from "verzod"
|
|
||||||
import { z } from "zod"
|
|
||||||
|
|
||||||
export const hoppRESTImporter = (content: string[]) =>
|
export const hoppRESTImporter = (content: string[]) =>
|
||||||
pipe(
|
pipe(
|
||||||
@@ -27,14 +26,26 @@ export const hoppRESTImporter = (content: string[]) =>
|
|||||||
TE.fromOption(() => IMPORTER_INVALID_FILE_FORMAT)
|
TE.fromOption(() => IMPORTER_INVALID_FILE_FORMAT)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks if a value is a plain object
|
||||||
|
*/
|
||||||
|
const isPlainObject = (value: any): value is object => _isPlainObject(value)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks if a collection matches the schema for a hoppscotch collection.
|
||||||
|
* here 2 is the latest version of the schema.
|
||||||
|
*/
|
||||||
|
const isValidCollection = (collection: unknown): collection is HoppCollection =>
|
||||||
|
isPlainObject(collection) && "v" in collection && collection.v === 2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* checks if a collection is a valid hoppscotch collection.
|
* checks if a collection is a valid hoppscotch collection.
|
||||||
* else translate it into one.
|
* else translate it into one.
|
||||||
*/
|
*/
|
||||||
const validateCollection = (collection: unknown) => {
|
const validateCollection = (collection: unknown) => {
|
||||||
const result = entityReference(HoppCollection).safeParse(collection)
|
if (isValidCollection(collection)) {
|
||||||
if (result.success) return O.some(result.data)
|
return O.some(collection)
|
||||||
|
}
|
||||||
return O.some(translateToNewRESTCollection(collection))
|
return O.some(translateToNewRESTCollection(collection))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,9 +75,8 @@ export const hoppGQLImporter = (content: string) =>
|
|||||||
* @returns the collection if it is valid, else a translated version of the collection
|
* @returns the collection if it is valid, else a translated version of the collection
|
||||||
*/
|
*/
|
||||||
export const validateGQLCollection = (collection: unknown) => {
|
export const validateGQLCollection = (collection: unknown) => {
|
||||||
const result = z.array(entityReference(HoppCollection)).safeParse(collection)
|
if (isValidCollection(collection)) {
|
||||||
|
return O.some(collection)
|
||||||
if (result.success) return O.some(result.data)
|
}
|
||||||
|
|
||||||
return O.some(translateToNewGQLCollection(collection))
|
return O.some(translateToNewGQLCollection(collection))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ export function makeCollection(x: Omit<HoppCollection, "v">): HoppCollection {
|
|||||||
* @returns The proper new collection format
|
* @returns The proper new collection format
|
||||||
*/
|
*/
|
||||||
export function translateToNewRESTCollection(x: any): HoppCollection {
|
export function translateToNewRESTCollection(x: any): HoppCollection {
|
||||||
|
if (x.v && x.v === CollectionSchemaVersion) return x
|
||||||
|
|
||||||
// Legacy
|
// Legacy
|
||||||
const name = x.name ?? "Untitled"
|
const name = x.name ?? "Untitled"
|
||||||
const folders = (x.folders ?? []).map(translateToNewRESTCollection)
|
const folders = (x.folders ?? []).map(translateToNewRESTCollection)
|
||||||
@@ -79,6 +81,8 @@ export function translateToNewRESTCollection(x: any): HoppCollection {
|
|||||||
* @returns The proper new collection format
|
* @returns The proper new collection format
|
||||||
*/
|
*/
|
||||||
export function translateToNewGQLCollection(x: any): HoppCollection {
|
export function translateToNewGQLCollection(x: any): HoppCollection {
|
||||||
|
if (x.v && x.v === CollectionSchemaVersion) return x
|
||||||
|
|
||||||
// Legacy
|
// Legacy
|
||||||
const name = x.name ?? "Untitled"
|
const name = x.name ?? "Untitled"
|
||||||
const folders = (x.folders ?? []).map(translateToNewGQLCollection)
|
const folders = (x.folders ?? []).map(translateToNewGQLCollection)
|
||||||
|
|||||||
@@ -18,8 +18,22 @@ export const HoppRESTRequestVariables = z.array(
|
|||||||
|
|
||||||
export type HoppRESTRequestVariables = z.infer<typeof HoppRESTRequestVariables>
|
export type HoppRESTRequestVariables = z.infer<typeof HoppRESTRequestVariables>
|
||||||
|
|
||||||
const V2_SCHEMA = V1_SCHEMA.extend({
|
const V2_SCHEMA = z.object({
|
||||||
v: z.literal("2"),
|
v: z.literal("2"),
|
||||||
|
id: z.optional(z.string()), // Firebase Firestore ID
|
||||||
|
|
||||||
|
name: z.string(),
|
||||||
|
method: z.string(),
|
||||||
|
endpoint: z.string(),
|
||||||
|
params: HoppRESTParams,
|
||||||
|
headers: HoppRESTHeaders,
|
||||||
|
preRequestScript: z.string().catch(""),
|
||||||
|
testScript: z.string().catch(""),
|
||||||
|
|
||||||
|
auth: HoppRESTAuth,
|
||||||
|
|
||||||
|
body: HoppRESTReqBody,
|
||||||
|
|
||||||
requestVariables: HoppRESTRequestVariables,
|
requestVariables: HoppRESTRequestVariables,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -112,15 +112,10 @@ function exportedCollectionToHoppCollection(
|
|||||||
folders: restCollection.folders.map((folder) =>
|
folders: restCollection.folders.map((folder) =>
|
||||||
exportedCollectionToHoppCollection(folder, collectionType)
|
exportedCollectionToHoppCollection(folder, collectionType)
|
||||||
),
|
),
|
||||||
requests: restCollection.requests.map((request) => {
|
requests: restCollection.requests.map(
|
||||||
const requestParsedResult = HoppRESTRequest.safeParse(request)
|
({
|
||||||
if (requestParsedResult.type === "ok") {
|
|
||||||
return requestParsedResult.value
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
|
||||||
v,
|
|
||||||
id,
|
id,
|
||||||
|
v,
|
||||||
auth,
|
auth,
|
||||||
body,
|
body,
|
||||||
endpoint,
|
endpoint,
|
||||||
@@ -130,23 +125,20 @@ function exportedCollectionToHoppCollection(
|
|||||||
params,
|
params,
|
||||||
preRequestScript,
|
preRequestScript,
|
||||||
testScript,
|
testScript,
|
||||||
requestVariables,
|
}) => ({
|
||||||
} = request
|
|
||||||
return {
|
|
||||||
v,
|
|
||||||
id,
|
id,
|
||||||
name,
|
v,
|
||||||
endpoint,
|
|
||||||
method,
|
|
||||||
params,
|
|
||||||
requestVariables: requestVariables,
|
|
||||||
auth,
|
auth,
|
||||||
headers,
|
|
||||||
body,
|
body,
|
||||||
|
endpoint,
|
||||||
|
headers,
|
||||||
|
method,
|
||||||
|
name,
|
||||||
|
params,
|
||||||
preRequestScript,
|
preRequestScript,
|
||||||
testScript,
|
testScript,
|
||||||
}
|
})
|
||||||
}),
|
),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const gqlCollection = collection as ExportedUserCollectionGQL
|
const gqlCollection = collection as ExportedUserCollectionGQL
|
||||||
|
|||||||
@@ -120,15 +120,10 @@ function exportedCollectionToHoppCollection(
|
|||||||
folders: restCollection.folders.map((folder) =>
|
folders: restCollection.folders.map((folder) =>
|
||||||
exportedCollectionToHoppCollection(folder, collectionType)
|
exportedCollectionToHoppCollection(folder, collectionType)
|
||||||
),
|
),
|
||||||
requests: restCollection.requests.map((request) => {
|
requests: restCollection.requests.map(
|
||||||
const requestParsedResult = HoppRESTRequest.safeParse(request)
|
({
|
||||||
if (requestParsedResult.type === "ok") {
|
|
||||||
return requestParsedResult.value
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
|
||||||
v,
|
|
||||||
id,
|
id,
|
||||||
|
v,
|
||||||
auth,
|
auth,
|
||||||
body,
|
body,
|
||||||
endpoint,
|
endpoint,
|
||||||
@@ -139,22 +134,21 @@ function exportedCollectionToHoppCollection(
|
|||||||
preRequestScript,
|
preRequestScript,
|
||||||
testScript,
|
testScript,
|
||||||
requestVariables,
|
requestVariables,
|
||||||
} = request
|
}) => ({
|
||||||
return {
|
|
||||||
v,
|
|
||||||
id,
|
id,
|
||||||
name,
|
v,
|
||||||
endpoint,
|
|
||||||
method,
|
|
||||||
params,
|
|
||||||
requestVariables: requestVariables,
|
|
||||||
auth,
|
auth,
|
||||||
headers,
|
|
||||||
body,
|
body,
|
||||||
|
endpoint,
|
||||||
|
headers,
|
||||||
|
method,
|
||||||
|
name,
|
||||||
|
params,
|
||||||
preRequestScript,
|
preRequestScript,
|
||||||
testScript,
|
testScript,
|
||||||
}
|
requestVariables,
|
||||||
}),
|
})
|
||||||
|
),
|
||||||
auth: data.auth,
|
auth: data.auth,
|
||||||
headers: data.headers,
|
headers: data.headers,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user