chore: Register Query in container (#9103)

* chore(framework): Register the query

* chore(framework): Register the query
This commit is contained in:
Adrien de Peretti
2024-09-11 15:08:46 +02:00
committed by GitHub
parent a729fb3fbb
commit a01e7e4ffe
4 changed files with 130 additions and 51 deletions
+4 -2
View File
@@ -353,9 +353,11 @@ async function MedusaApp_({
) )
if (loaderOnly) { if (loaderOnly) {
async function query(...args: Parameters<RemoteQueryFunction>) { async function query(...args: any[]) {
throw new Error("Querying not allowed in loaderOnly mode") throw new Error("Querying not allowed in loaderOnly mode")
} }
query.graph = query
query.gql = query
return { return {
onApplicationShutdown, onApplicationShutdown,
@@ -363,7 +365,7 @@ async function MedusaApp_({
onApplicationStart, onApplicationStart,
modules: allModules, modules: allModules,
link: undefined, link: undefined,
query: query as RemoteQueryFunction, query: query as unknown as RemoteQueryFunction,
runMigrations: async () => { runMigrations: async () => {
throw new Error("Migrations not allowed in loaderOnly mode") throw new Error("Migrations not allowed in loaderOnly mode")
}, },
@@ -14,30 +14,43 @@ import {
remoteQueryObjectFromString, remoteQueryObjectFromString,
} from "@medusajs/utils" } from "@medusajs/utils"
function unwrapQueryConfig( /**
* API wrapper around the remoteQuery
*/
export class Query {
#remoteQuery: RemoteQuery
constructor(remoteQuery: RemoteQuery) {
this.#remoteQuery = remoteQuery
}
#unwrapQueryConfig(
config: config:
| RemoteQueryObjectConfig<any> | RemoteQueryObjectConfig<any>
| RemoteQueryObjectFromStringResult<any> | RemoteQueryObjectFromStringResult<any>
| RemoteJoinerQuery | RemoteJoinerQuery
): object { ): object {
let normalizedQuery: any = config let normalizedQuery: any = config
if ("__value" in config) { if ("__value" in config) {
normalizedQuery = config.__value normalizedQuery = config.__value
} else if ("entryPoint" in normalizedQuery || "service" in normalizedQuery) { } else if (
"entryPoint" in normalizedQuery ||
"service" in normalizedQuery
) {
normalizedQuery = remoteQueryObjectFromString( normalizedQuery = remoteQueryObjectFromString(
normalizedQuery as Parameters<typeof remoteQueryObjectFromString>[0] normalizedQuery as Parameters<typeof remoteQueryObjectFromString>[0]
).__value ).__value
} }
return normalizedQuery return normalizedQuery
} }
function unwrapRemoteQueryResponse( #unwrapRemoteQueryResponse(
response: response:
| any[] | any[]
| { rows: any[]; metadata: RemoteQueryFunctionReturnPagination } | { rows: any[]; metadata: RemoteQueryFunctionReturnPagination }
): GraphResultSet<any> { ): GraphResultSet<any> {
if (Array.isArray(response)) { if (Array.isArray(response)) {
return { data: response, metadata: undefined } return { data: response, metadata: undefined }
} }
@@ -46,20 +59,15 @@ function unwrapRemoteQueryResponse(
data: response.rows, data: response.rows,
metadata: response.metadata, metadata: response.metadata,
} }
} }
/** async query(
* Wrap the remote query into a dedicated and more user friendly API than the low level API
* @param remoteQuery
*/
export function createQuery(remoteQuery: RemoteQuery): RemoteQueryFunction {
const query: RemoteQueryFunction = async (
queryOptions: queryOptions:
| RemoteQueryObjectConfig<any> | RemoteQueryObjectConfig<any>
| RemoteQueryObjectFromStringResult<any> | RemoteQueryObjectFromStringResult<any>
| RemoteJoinerQuery, | RemoteJoinerQuery,
options?: RemoteJoinerOptions options?: RemoteJoinerOptions
) => { ) {
if (!isObject(queryOptions)) { if (!isObject(queryOptions)) {
throw new MedusaError( throw new MedusaError(
MedusaError.Types.INVALID_DATA, MedusaError.Types.INVALID_DATA,
@@ -67,8 +75,8 @@ export function createQuery(remoteQuery: RemoteQuery): RemoteQueryFunction {
) )
} }
const config = unwrapQueryConfig(queryOptions) const config = this.#unwrapQueryConfig(queryOptions)
return await remoteQuery.query(config, undefined, options) return await this.#remoteQuery.query(config, undefined, options)
} }
/** /**
@@ -77,27 +85,42 @@ export function createQuery(remoteQuery: RemoteQuery): RemoteQueryFunction {
* @param variables * @param variables
* @param options * @param options
*/ */
query.gql = async function (query, variables?, options?) { async gql(query, variables?, options?) {
return await remoteQuery.query(query, variables, options) return await this.#remoteQuery.query(query, variables, options)
} }
/** /**
* Graph function uses the remoteQuery under the hood and * Graph function uses the remoteQuery under the hood and
* returns a result set * returns a result set
*/ */
query.graph = async function <const TEntry extends string>( async graph<const TEntry extends string>(
queryOptions: RemoteQueryObjectConfig<TEntry>, queryOptions: RemoteQueryObjectConfig<TEntry>,
options?: RemoteJoinerOptions options?: RemoteJoinerOptions
): Promise<GraphResultSet<TEntry>> { ): Promise<GraphResultSet<TEntry>> {
const normalizedQuery = remoteQueryObjectFromString(queryOptions).__value const normalizedQuery = remoteQueryObjectFromString(queryOptions).__value
const response = await remoteQuery.query( const response = await this.#remoteQuery.query(
normalizedQuery, normalizedQuery,
undefined, undefined,
options options
) )
return unwrapRemoteQueryResponse(response) return this.#unwrapRemoteQueryResponse(response)
}
}
/**
* API wrapper around the remoteQuery with backward compatibility support
* @param remoteQuery
*/
export function createQuery(remoteQuery: RemoteQuery): RemoteQueryFunction {
const query = new Query(remoteQuery)
function backwardCompatibleQuery(...args: any[]) {
return query.query.apply(query, args)
} }
return query backwardCompatibleQuery.graph = query.graph
backwardCompatibleQuery.gql = query.gql
return backwardCompatibleQuery
} }
@@ -113,3 +113,49 @@ export type RemoteQueryFunction = {
options?: RemoteJoinerOptions options?: RemoteJoinerOptions
) => Promise<any> ) => Promise<any>
} }
export interface Query {
/**
* Query wrapper to provide specific API's and pre processing around remoteQuery.query
* @param queryConfig
* @param options
*/
query<const TEntry extends string>(
queryConfig: RemoteQueryObjectConfig<TEntry>,
options?: RemoteJoinerOptions
): Promise<any>
/**
* Query wrapper to provide specific API's and pre processing around remoteQuery.query
* @param queryConfig
* @param options
*/
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
*/
query(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
* @param variables
* @param options
*/
gql: (
query: string,
variables?: Record<string, unknown>,
options?: RemoteJoinerOptions
) => Promise<any>
}
@@ -232,6 +232,10 @@ export class MedusaAppLoader {
ContainerRegistrationKeys.REMOTE_QUERY, ContainerRegistrationKeys.REMOTE_QUERY,
asValue(undefined) asValue(undefined)
) )
this.#container.register(
ContainerRegistrationKeys.QUERY,
asValue(undefined)
)
this.#container.register( this.#container.register(
ContainerRegistrationKeys.REMOTE_LINK, ContainerRegistrationKeys.REMOTE_LINK,
asValue(undefined) asValue(undefined)
@@ -252,14 +256,18 @@ export class MedusaAppLoader {
return medusaApp return medusaApp
} }
container.register( this.#container.register(
ContainerRegistrationKeys.REMOTE_LINK, ContainerRegistrationKeys.REMOTE_LINK,
asValue(medusaApp.link) asValue(medusaApp.link)
) )
container.register( this.#container.register(
ContainerRegistrationKeys.REMOTE_QUERY, ContainerRegistrationKeys.REMOTE_QUERY,
asValue(medusaApp.query) asValue(medusaApp.query)
) )
this.#container.register(
ContainerRegistrationKeys.QUERY,
asValue(medusaApp.query)
)
for (const moduleService of Object.values(medusaApp.modules)) { for (const moduleService of Object.values(medusaApp.modules)) {
const loadedModule = moduleService as LoadedModule const loadedModule = moduleService as LoadedModule