From a01e7e4ffef3c89db0478f40fb1cd9f620b711f4 Mon Sep 17 00:00:00 2001 From: Adrien de Peretti Date: Wed, 11 Sep 2024 15:08:46 +0200 Subject: [PATCH] chore: Register Query in container (#9103) * chore(framework): Register the query * chore(framework): Register the query --- packages/core/modules-sdk/src/medusa-app.ts | 6 +- .../modules-sdk/src/remote-query/query.ts | 117 +++++++++++------- .../types/src/modules-sdk/remote-query.ts | 46 +++++++ .../framework/src/medusa-app-loader.ts | 12 +- 4 files changed, 130 insertions(+), 51 deletions(-) diff --git a/packages/core/modules-sdk/src/medusa-app.ts b/packages/core/modules-sdk/src/medusa-app.ts index 9da67b7783..089693a419 100644 --- a/packages/core/modules-sdk/src/medusa-app.ts +++ b/packages/core/modules-sdk/src/medusa-app.ts @@ -353,9 +353,11 @@ async function MedusaApp_({ ) if (loaderOnly) { - async function query(...args: Parameters) { + async function query(...args: any[]) { throw new Error("Querying not allowed in loaderOnly mode") } + query.graph = query + query.gql = query return { onApplicationShutdown, @@ -363,7 +365,7 @@ async function MedusaApp_({ onApplicationStart, modules: allModules, link: undefined, - query: query as RemoteQueryFunction, + query: query as unknown as RemoteQueryFunction, runMigrations: async () => { throw new Error("Migrations not allowed in loaderOnly mode") }, diff --git a/packages/core/modules-sdk/src/remote-query/query.ts b/packages/core/modules-sdk/src/remote-query/query.ts index 4188c677f4..e9cfb90e60 100644 --- a/packages/core/modules-sdk/src/remote-query/query.ts +++ b/packages/core/modules-sdk/src/remote-query/query.ts @@ -14,52 +14,60 @@ import { remoteQueryObjectFromString, } from "@medusajs/utils" -function unwrapQueryConfig( - config: - | RemoteQueryObjectConfig - | RemoteQueryObjectFromStringResult - | RemoteJoinerQuery -): object { - let normalizedQuery: any = config - - if ("__value" in config) { - normalizedQuery = config.__value - } else if ("entryPoint" in normalizedQuery || "service" in normalizedQuery) { - normalizedQuery = remoteQueryObjectFromString( - normalizedQuery as Parameters[0] - ).__value - } - - return normalizedQuery -} - -function unwrapRemoteQueryResponse( - response: - | any[] - | { rows: any[]; metadata: RemoteQueryFunctionReturnPagination } -): GraphResultSet { - if (Array.isArray(response)) { - return { data: response, metadata: undefined } - } - - return { - data: response.rows, - metadata: response.metadata, - } -} - /** - * Wrap the remote query into a dedicated and more user friendly API than the low level API - * @param remoteQuery + * API wrapper around the remoteQuery */ -export function createQuery(remoteQuery: RemoteQuery): RemoteQueryFunction { - const query: RemoteQueryFunction = async ( +export class Query { + #remoteQuery: RemoteQuery + + constructor(remoteQuery: RemoteQuery) { + this.#remoteQuery = remoteQuery + } + + #unwrapQueryConfig( + config: + | RemoteQueryObjectConfig + | RemoteQueryObjectFromStringResult + | RemoteJoinerQuery + ): object { + let normalizedQuery: any = config + + if ("__value" in config) { + normalizedQuery = config.__value + } else if ( + "entryPoint" in normalizedQuery || + "service" in normalizedQuery + ) { + normalizedQuery = remoteQueryObjectFromString( + normalizedQuery as Parameters[0] + ).__value + } + + return normalizedQuery + } + + #unwrapRemoteQueryResponse( + response: + | any[] + | { rows: any[]; metadata: RemoteQueryFunctionReturnPagination } + ): GraphResultSet { + if (Array.isArray(response)) { + return { data: response, metadata: undefined } + } + + return { + data: response.rows, + metadata: response.metadata, + } + } + + async query( queryOptions: | RemoteQueryObjectConfig | RemoteQueryObjectFromStringResult | RemoteJoinerQuery, options?: RemoteJoinerOptions - ) => { + ) { if (!isObject(queryOptions)) { throw new MedusaError( MedusaError.Types.INVALID_DATA, @@ -67,8 +75,8 @@ export function createQuery(remoteQuery: RemoteQuery): RemoteQueryFunction { ) } - const config = unwrapQueryConfig(queryOptions) - return await remoteQuery.query(config, undefined, options) + const config = this.#unwrapQueryConfig(queryOptions) + return await this.#remoteQuery.query(config, undefined, options) } /** @@ -77,27 +85,42 @@ export function createQuery(remoteQuery: RemoteQuery): RemoteQueryFunction { * @param variables * @param options */ - query.gql = async function (query, variables?, options?) { - return await remoteQuery.query(query, variables, options) + async gql(query, variables?, options?) { + return await this.#remoteQuery.query(query, variables, options) } /** * Graph function uses the remoteQuery under the hood and * returns a result set */ - query.graph = async function ( + async graph( queryOptions: RemoteQueryObjectConfig, options?: RemoteJoinerOptions ): Promise> { const normalizedQuery = remoteQueryObjectFromString(queryOptions).__value - const response = await remoteQuery.query( + const response = await this.#remoteQuery.query( normalizedQuery, undefined, 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 } diff --git a/packages/core/types/src/modules-sdk/remote-query.ts b/packages/core/types/src/modules-sdk/remote-query.ts index a2047d5226..13baa4e1ac 100644 --- a/packages/core/types/src/modules-sdk/remote-query.ts +++ b/packages/core/types/src/modules-sdk/remote-query.ts @@ -113,3 +113,49 @@ export type RemoteQueryFunction = { options?: RemoteJoinerOptions ) => Promise } + +export interface Query { + /** + * Query wrapper to provide specific API's and pre processing around remoteQuery.query + * @param queryConfig + * @param options + */ + query( + queryConfig: RemoteQueryObjectConfig, + options?: RemoteJoinerOptions + ): Promise + + /** + * Query wrapper to provide specific API's and pre processing around remoteQuery.query + * @param queryConfig + * @param options + */ + query>( + queryConfig: TConfig, + options?: RemoteJoinerOptions + ): Promise + /** + * Query wrapper to provide specific API's and pre processing around remoteQuery.query + * @param query + * @param options + */ + query(query: RemoteJoinerQuery, options?: RemoteJoinerOptions): Promise + + /** + * 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, + options?: RemoteJoinerOptions + ) => Promise +} diff --git a/packages/framework/framework/src/medusa-app-loader.ts b/packages/framework/framework/src/medusa-app-loader.ts index 53f0c8b528..b4b3565b83 100644 --- a/packages/framework/framework/src/medusa-app-loader.ts +++ b/packages/framework/framework/src/medusa-app-loader.ts @@ -232,6 +232,10 @@ export class MedusaAppLoader { ContainerRegistrationKeys.REMOTE_QUERY, asValue(undefined) ) + this.#container.register( + ContainerRegistrationKeys.QUERY, + asValue(undefined) + ) this.#container.register( ContainerRegistrationKeys.REMOTE_LINK, asValue(undefined) @@ -252,14 +256,18 @@ export class MedusaAppLoader { return medusaApp } - container.register( + this.#container.register( ContainerRegistrationKeys.REMOTE_LINK, asValue(medusaApp.link) ) - container.register( + this.#container.register( ContainerRegistrationKeys.REMOTE_QUERY, asValue(medusaApp.query) ) + this.#container.register( + ContainerRegistrationKeys.QUERY, + asValue(medusaApp.query) + ) for (const moduleService of Object.values(medusaApp.modules)) { const loadedModule = moduleService as LoadedModule