feature: introduce types for query.graph method (#9031)
This commit is contained in:
@@ -54,6 +54,7 @@ declare module "@medusajs/types" {
|
|||||||
[ContainerRegistrationKeys.CONFIG_MODULE]: ConfigModule
|
[ContainerRegistrationKeys.CONFIG_MODULE]: ConfigModule
|
||||||
[ContainerRegistrationKeys.PG_CONNECTION]: Knex<any>
|
[ContainerRegistrationKeys.PG_CONNECTION]: Knex<any>
|
||||||
[ContainerRegistrationKeys.REMOTE_QUERY]: RemoteQueryFunction
|
[ContainerRegistrationKeys.REMOTE_QUERY]: RemoteQueryFunction
|
||||||
|
[ContainerRegistrationKeys.QUERY]: RemoteQueryFunction
|
||||||
[ContainerRegistrationKeys.LOGGER]: Logger
|
[ContainerRegistrationKeys.LOGGER]: Logger
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -420,53 +421,24 @@ async function MedusaApp_({
|
|||||||
customRemoteFetchData: remoteFetchData,
|
customRemoteFetchData: remoteFetchData,
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
const query: RemoteQueryFunction = async (
|
||||||
* Query wrapper to provide specific API's and pre processing around remoteQuery.query
|
queryOptions:
|
||||||
* @param queryConfig
|
| RemoteQueryObjectConfig<any>
|
||||||
* @param options
|
| RemoteQueryObjectFromStringResult<any>
|
||||||
*/
|
| RemoteJoinerQuery,
|
||||||
async function query<const TEntry extends string>(
|
|
||||||
queryConfig: RemoteQueryObjectConfig<TEntry>,
|
|
||||||
options?: RemoteJoinerOptions
|
options?: RemoteJoinerOptions
|
||||||
): Promise<any>
|
) => {
|
||||||
|
if (!isObject(queryOptions)) {
|
||||||
async function query<
|
|
||||||
const TConfig extends RemoteQueryObjectFromStringResult<any>
|
|
||||||
>(queryConfig: TConfig, options?: RemoteJoinerOptions): Promise<any>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query wrapper to provide specific API's and pre processing around remoteQuery.query
|
|
||||||
* @param query
|
|
||||||
* @param options
|
|
||||||
*/
|
|
||||||
async function query(
|
|
||||||
query: RemoteJoinerQuery,
|
|
||||||
options?: RemoteJoinerOptions
|
|
||||||
): Promise<any>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query wrapper to provide specific API's and pre processing around remoteQuery.query
|
|
||||||
* @param query
|
|
||||||
* @param options
|
|
||||||
*/
|
|
||||||
async function query<const TEntry extends string>(
|
|
||||||
query:
|
|
||||||
| RemoteJoinerQuery
|
|
||||||
| RemoteQueryObjectConfig<TEntry>
|
|
||||||
| RemoteQueryObjectFromStringResult<any>,
|
|
||||||
options?: RemoteJoinerOptions
|
|
||||||
) {
|
|
||||||
if (!isObject(query)) {
|
|
||||||
throw new MedusaError(
|
throw new MedusaError(
|
||||||
MedusaError.Types.INVALID_DATA,
|
MedusaError.Types.INVALID_DATA,
|
||||||
"Invalid query, expected object and received something else."
|
"Invalid query, expected object and received something else."
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let normalizedQuery: any = query
|
let normalizedQuery: any = queryOptions
|
||||||
|
|
||||||
if ("__value" in query) {
|
if ("__value" in queryOptions) {
|
||||||
normalizedQuery = query.__value
|
normalizedQuery = queryOptions.__value
|
||||||
} else if (
|
} else if (
|
||||||
"entryPoint" in normalizedQuery ||
|
"entryPoint" in normalizedQuery ||
|
||||||
"service" in normalizedQuery
|
"service" in normalizedQuery
|
||||||
@@ -478,20 +450,39 @@ async function MedusaApp_({
|
|||||||
|
|
||||||
return await remoteQuery.query(normalizedQuery, undefined, options)
|
return await remoteQuery.query(normalizedQuery, undefined, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query wrapper to provide specific GraphQL like API around remoteQuery.query
|
* Query wrapper to provide specific GraphQL like API around remoteQuery.query
|
||||||
* @param query
|
* @param query
|
||||||
* @param variables
|
* @param variables
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
query.gql = async function (
|
query.gql = async function (query, variables?, options?) {
|
||||||
query: string,
|
|
||||||
variables?: Record<string, unknown>,
|
|
||||||
options?: RemoteJoinerOptions
|
|
||||||
) {
|
|
||||||
return await remoteQuery.query(query, variables, options)
|
return await remoteQuery.query(query, variables, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Graph function uses the remoteQuery under the hood and
|
||||||
|
* returns a result set
|
||||||
|
*/
|
||||||
|
query.graph = async function (queryOptions, options) {
|
||||||
|
const normalizedQuery = remoteQueryObjectFromString(queryOptions).__value
|
||||||
|
const response = await remoteQuery.query(
|
||||||
|
normalizedQuery,
|
||||||
|
undefined,
|
||||||
|
options
|
||||||
|
)
|
||||||
|
|
||||||
|
if (Array.isArray(response)) {
|
||||||
|
return { data: response, metadata: undefined }
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: response.rows,
|
||||||
|
metadata: response.metadata,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const applyMigration = async ({
|
const applyMigration = async ({
|
||||||
modulesNames,
|
modulesNames,
|
||||||
action = "run",
|
action = "run",
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { expectTypeOf } from "expect-type"
|
||||||
|
import { FixtureEntryPoints } from "../__fixtures__/remote-query"
|
||||||
|
import {
|
||||||
|
QueryGraphFunction,
|
||||||
|
RemoteQueryFunctionReturnPagination,
|
||||||
|
} from "../remote-query"
|
||||||
|
|
||||||
|
describe("Query", () => {
|
||||||
|
describe("Infer via queryConfig", () => {
|
||||||
|
it("should infer return type of a known entry", async () => {
|
||||||
|
const graph = (() => {}) as unknown as QueryGraphFunction
|
||||||
|
const result = await graph({
|
||||||
|
entryPoint: "product",
|
||||||
|
fields: ["handle", "id"],
|
||||||
|
})
|
||||||
|
|
||||||
|
expectTypeOf(result).toEqualTypeOf<{
|
||||||
|
data: FixtureEntryPoints["product"][]
|
||||||
|
metadata?: RemoteQueryFunctionReturnPagination
|
||||||
|
}>()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should infer as any for an known entry", async () => {
|
||||||
|
const graph = (() => {}) as unknown as QueryGraphFunction
|
||||||
|
const result = await graph({
|
||||||
|
entryPoint: "foo",
|
||||||
|
fields: ["handle", "id"],
|
||||||
|
})
|
||||||
|
|
||||||
|
expectTypeOf(result).toEqualTypeOf<{
|
||||||
|
data: any[]
|
||||||
|
metadata?: RemoteQueryFunctionReturnPagination
|
||||||
|
}>()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
|
import { Prettify } from "../common"
|
||||||
import { RemoteJoinerOptions, RemoteJoinerQuery } from "../joiner"
|
import { RemoteJoinerOptions, RemoteJoinerQuery } from "../joiner"
|
||||||
|
import { RemoteQueryEntryPoints } from "./remote-query-entry-points"
|
||||||
import {
|
import {
|
||||||
RemoteQueryObjectConfig,
|
RemoteQueryObjectConfig,
|
||||||
RemoteQueryObjectFromStringResult,
|
RemoteQueryObjectFromStringResult,
|
||||||
@@ -12,6 +14,29 @@ export type RemoteQueryFunctionReturnPagination = {
|
|||||||
count: number
|
count: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The GraphResultSet presents a typed output for the
|
||||||
|
* result returned by the underlying remote query
|
||||||
|
*/
|
||||||
|
export type GraphResultSet<TEntry extends string> = {
|
||||||
|
data: TEntry extends keyof RemoteQueryEntryPoints
|
||||||
|
? RemoteQueryEntryPoints[TEntry][]
|
||||||
|
: any[]
|
||||||
|
metadata?: RemoteQueryFunctionReturnPagination
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QueryGraphFunction is a wrapper on top of remoteQuery
|
||||||
|
* that simplifies the input it accepts and returns
|
||||||
|
* a normalized/consistent output.
|
||||||
|
*/
|
||||||
|
export type QueryGraphFunction = {
|
||||||
|
<const TEntry extends string>(
|
||||||
|
queryConfig: RemoteQueryObjectConfig<TEntry>,
|
||||||
|
options?: RemoteJoinerOptions
|
||||||
|
): Promise<Prettify<GraphResultSet<TEntry>>>
|
||||||
|
}
|
||||||
|
|
||||||
/*export type RemoteQueryReturnedData<TEntry extends string> =
|
/*export type RemoteQueryReturnedData<TEntry extends string> =
|
||||||
TEntry extends keyof RemoteQueryEntryPoints
|
TEntry extends keyof RemoteQueryEntryPoints
|
||||||
? Prettify<Omit<RemoteQueryEntryPoints[TEntry], ExcludedProps>>
|
? Prettify<Omit<RemoteQueryEntryPoints[TEntry], ExcludedProps>>
|
||||||
@@ -69,6 +94,13 @@ export type RemoteQueryFunction = {
|
|||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
(query: RemoteJoinerQuery, options?: RemoteJoinerOptions): Promise<any>
|
(query: RemoteJoinerQuery, options?: RemoteJoinerOptions): Promise<any>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Graph function uses the remoteQuery under the hood and
|
||||||
|
* returns a result set
|
||||||
|
*/
|
||||||
|
graph: QueryGraphFunction
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query wrapper to provide specific GraphQL like API around remoteQuery.query
|
* Query wrapper to provide specific GraphQL like API around remoteQuery.query
|
||||||
* @param query
|
* @param query
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ export const ContainerRegistrationKeys = {
|
|||||||
CONFIG_MODULE: "configModule",
|
CONFIG_MODULE: "configModule",
|
||||||
LOGGER: "logger",
|
LOGGER: "logger",
|
||||||
REMOTE_QUERY: "remoteQuery",
|
REMOTE_QUERY: "remoteQuery",
|
||||||
|
QUERY: "query",
|
||||||
REMOTE_LINK: "remoteLink",
|
REMOTE_LINK: "remoteLink",
|
||||||
FEATURE_FLAG_ROUTER: "featureFlagRouter",
|
FEATURE_FLAG_ROUTER: "featureFlagRouter",
|
||||||
} as const
|
} as const
|
||||||
|
|||||||
Reference in New Issue
Block a user