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.PG_CONNECTION]: Knex<any>
|
||||
[ContainerRegistrationKeys.REMOTE_QUERY]: RemoteQueryFunction
|
||||
[ContainerRegistrationKeys.QUERY]: RemoteQueryFunction
|
||||
[ContainerRegistrationKeys.LOGGER]: Logger
|
||||
}
|
||||
}
|
||||
@@ -420,53 +421,24 @@ async function MedusaApp_({
|
||||
customRemoteFetchData: remoteFetchData,
|
||||
})
|
||||
|
||||
/**
|
||||
* Query wrapper to provide specific API's and pre processing around remoteQuery.query
|
||||
* @param queryConfig
|
||||
* @param options
|
||||
*/
|
||||
async function query<const TEntry extends string>(
|
||||
queryConfig: RemoteQueryObjectConfig<TEntry>,
|
||||
const query: RemoteQueryFunction = async (
|
||||
queryOptions:
|
||||
| RemoteQueryObjectConfig<any>
|
||||
| RemoteQueryObjectFromStringResult<any>
|
||||
| RemoteJoinerQuery,
|
||||
options?: RemoteJoinerOptions
|
||||
): Promise<any>
|
||||
|
||||
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)) {
|
||||
) => {
|
||||
if (!isObject(queryOptions)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Invalid query, expected object and received something else."
|
||||
)
|
||||
}
|
||||
|
||||
let normalizedQuery: any = query
|
||||
let normalizedQuery: any = queryOptions
|
||||
|
||||
if ("__value" in query) {
|
||||
normalizedQuery = query.__value
|
||||
if ("__value" in queryOptions) {
|
||||
normalizedQuery = queryOptions.__value
|
||||
} else if (
|
||||
"entryPoint" in normalizedQuery ||
|
||||
"service" in normalizedQuery
|
||||
@@ -478,20 +450,39 @@ async function MedusaApp_({
|
||||
|
||||
return await remoteQuery.query(normalizedQuery, undefined, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Query wrapper to provide specific GraphQL like API around remoteQuery.query
|
||||
* @param query
|
||||
* @param variables
|
||||
* @param options
|
||||
*/
|
||||
query.gql = async function (
|
||||
query: string,
|
||||
variables?: Record<string, unknown>,
|
||||
options?: RemoteJoinerOptions
|
||||
) {
|
||||
query.gql = async function (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 ({
|
||||
modulesNames,
|
||||
action = "run",
|
||||
|
||||
36
packages/core/types/src/modules-sdk/__tests__/query.spec.ts
Normal file
36
packages/core/types/src/modules-sdk/__tests__/query.spec.ts
Normal file
@@ -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 { RemoteQueryEntryPoints } from "./remote-query-entry-points"
|
||||
import {
|
||||
RemoteQueryObjectConfig,
|
||||
RemoteQueryObjectFromStringResult,
|
||||
@@ -12,6 +14,29 @@ export type RemoteQueryFunctionReturnPagination = {
|
||||
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> =
|
||||
TEntry extends keyof RemoteQueryEntryPoints
|
||||
? Prettify<Omit<RemoteQueryEntryPoints[TEntry], ExcludedProps>>
|
||||
@@ -69,6 +94,13 @@ export type RemoteQueryFunction = {
|
||||
* @param options
|
||||
*/
|
||||
(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
|
||||
* @param query
|
||||
|
||||
@@ -4,6 +4,7 @@ export const ContainerRegistrationKeys = {
|
||||
CONFIG_MODULE: "configModule",
|
||||
LOGGER: "logger",
|
||||
REMOTE_QUERY: "remoteQuery",
|
||||
QUERY: "query",
|
||||
REMOTE_LINK: "remoteLink",
|
||||
FEATURE_FLAG_ROUTER: "featureFlagRouter",
|
||||
} as const
|
||||
|
||||
Reference in New Issue
Block a user