feat(modules-sdk): remote query retrieve (#6849)
What: Remote Joiner options to check if keys exist on entry points or relations
This commit is contained in:
1 parent
cbb5e6bd99
commit
1c6ba4468e
10 files changed
+356
-34
No files matched your search
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/modules-sdk": patch
|
||||||
|
"@medusajs/orchestration": patch
|
||||||
|
"@medusajs/types": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Remote Joiner options to check if keys exist on entrypoints or relations
|
||||||
@@ -0,0 +1,205 @@
|
|||||||
|
import { ModuleRegistrationName, Modules } from "@medusajs/modules-sdk"
|
||||||
|
import { IPaymentModuleService, IRegionModuleService } from "@medusajs/types"
|
||||||
|
import { ContainerRegistrationKeys } from "@medusajs/utils"
|
||||||
|
import { medusaIntegrationTestRunner } from "medusa-test-utils"
|
||||||
|
import { createAdminUser } from "../../..//helpers/create-admin-user"
|
||||||
|
import { adminHeaders } from "../../../helpers/create-admin-user"
|
||||||
|
|
||||||
|
jest.setTimeout(50000)
|
||||||
|
|
||||||
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
|
||||||
|
medusaIntegrationTestRunner({
|
||||||
|
env,
|
||||||
|
testSuite: ({ dbConnection, getContainer, api }) => {
|
||||||
|
describe("Remote Query", () => {
|
||||||
|
let appContainer
|
||||||
|
let regionModule: IRegionModuleService
|
||||||
|
let paymentModule: IPaymentModuleService
|
||||||
|
let remoteQuery
|
||||||
|
let remoteLink
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
appContainer = getContainer()
|
||||||
|
regionModule = appContainer.resolve(ModuleRegistrationName.REGION)
|
||||||
|
paymentModule = appContainer.resolve(ModuleRegistrationName.PAYMENT)
|
||||||
|
remoteQuery = appContainer.resolve(
|
||||||
|
ContainerRegistrationKeys.REMOTE_QUERY
|
||||||
|
)
|
||||||
|
remoteLink = appContainer.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await createAdminUser(dbConnection, adminHeaders, appContainer)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should fail to retrieve a single non-existing id", async () => {
|
||||||
|
const region = await regionModule.create({
|
||||||
|
name: "Test Region",
|
||||||
|
currency_code: "usd",
|
||||||
|
countries: ["us"],
|
||||||
|
})
|
||||||
|
|
||||||
|
const getRegion = await remoteQuery({
|
||||||
|
region: {
|
||||||
|
fields: ["id", "currency_code"],
|
||||||
|
__args: {
|
||||||
|
id: region.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(getRegion).toEqual([
|
||||||
|
{
|
||||||
|
id: region.id,
|
||||||
|
currency_code: "usd",
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const getNonExistingRegion = remoteQuery(
|
||||||
|
{
|
||||||
|
region: {
|
||||||
|
fields: ["id", "currency_code"],
|
||||||
|
__args: {
|
||||||
|
id: "region_123",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
{ throwIfKeyNotFound: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(getNonExistingRegion).rejects.toThrow(
|
||||||
|
"region id not found: region_123"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should fail if a expected relation is not found", async () => {
|
||||||
|
const region = await regionModule.create({
|
||||||
|
name: "Test Region",
|
||||||
|
currency_code: "usd",
|
||||||
|
countries: ["us"],
|
||||||
|
})
|
||||||
|
|
||||||
|
const regionWithPayment = await regionModule.create({
|
||||||
|
name: "Test W/ Payment",
|
||||||
|
currency_code: "brl",
|
||||||
|
countries: ["br"],
|
||||||
|
})
|
||||||
|
|
||||||
|
const regionNoLink = await regionModule.create({
|
||||||
|
name: "No link",
|
||||||
|
currency_code: "eur",
|
||||||
|
countries: ["dk"],
|
||||||
|
})
|
||||||
|
|
||||||
|
await remoteLink.create([
|
||||||
|
{
|
||||||
|
[Modules.REGION]: {
|
||||||
|
region_id: region.id,
|
||||||
|
},
|
||||||
|
[Modules.PAYMENT]: {
|
||||||
|
payment_provider_id: "pp_system_default_non_existent",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[Modules.REGION]: {
|
||||||
|
region_id: regionWithPayment.id,
|
||||||
|
},
|
||||||
|
[Modules.PAYMENT]: {
|
||||||
|
payment_provider_id: "pp_system_default", // default payment provider auto created
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
// Validate all relations, including the link
|
||||||
|
expect(
|
||||||
|
remoteQuery(
|
||||||
|
{
|
||||||
|
region: {
|
||||||
|
fields: ["id"],
|
||||||
|
__args: {
|
||||||
|
id: regionNoLink.id,
|
||||||
|
},
|
||||||
|
payment_providers: {
|
||||||
|
fields: ["id"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
throwIfRelationNotFound: true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
).rejects.toThrow(
|
||||||
|
`regionRegionPaymentPaymentProviderLink region_id not found: ${regionNoLink.id}`
|
||||||
|
)
|
||||||
|
|
||||||
|
// Only validate the relations with Payment. It doesn't fail because the link didn't return any data
|
||||||
|
expect(
|
||||||
|
remoteQuery(
|
||||||
|
{
|
||||||
|
region: {
|
||||||
|
fields: ["id"],
|
||||||
|
__args: {
|
||||||
|
id: regionNoLink.id,
|
||||||
|
},
|
||||||
|
payment_providers: {
|
||||||
|
fields: ["id"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
throwIfRelationNotFound: [Modules.PAYMENT],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
).resolves.toHaveLength(1)
|
||||||
|
|
||||||
|
// The link exists, but the payment doesn't
|
||||||
|
expect(
|
||||||
|
remoteQuery(
|
||||||
|
{
|
||||||
|
region: {
|
||||||
|
fields: ["id"],
|
||||||
|
__args: {
|
||||||
|
id: region.id,
|
||||||
|
},
|
||||||
|
payment_providers: {
|
||||||
|
fields: ["id"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
throwIfRelationNotFound: [Modules.PAYMENT],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
).rejects.toThrow(
|
||||||
|
"payment id not found: pp_system_default_non_existent"
|
||||||
|
)
|
||||||
|
|
||||||
|
// everything is fine
|
||||||
|
expect(
|
||||||
|
remoteQuery(
|
||||||
|
{
|
||||||
|
region: {
|
||||||
|
fields: ["id"],
|
||||||
|
__args: {
|
||||||
|
id: regionWithPayment.id,
|
||||||
|
},
|
||||||
|
payment_providers: {
|
||||||
|
fields: ["id"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
throwIfRelationNotFound: [Modules.PAYMENT],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
).resolves.toHaveLength(1)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
ModuleExports,
|
ModuleExports,
|
||||||
ModuleJoinerConfig,
|
ModuleJoinerConfig,
|
||||||
ModuleServiceInitializeOptions,
|
ModuleServiceInitializeOptions,
|
||||||
|
RemoteJoinerOptions,
|
||||||
RemoteJoinerQuery,
|
RemoteJoinerQuery,
|
||||||
RemoteQueryFunction,
|
RemoteQueryFunction,
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
@@ -241,7 +242,8 @@ async function MedusaApp_({
|
|||||||
link: RemoteLink | undefined
|
link: RemoteLink | undefined
|
||||||
query: (
|
query: (
|
||||||
query: string | RemoteJoinerQuery | object,
|
query: string | RemoteJoinerQuery | object,
|
||||||
variables?: Record<string, unknown>
|
variables?: Record<string, unknown>,
|
||||||
|
options?: RemoteJoinerOptions
|
||||||
) => Promise<any>
|
) => Promise<any>
|
||||||
entitiesMap?: Record<string, any>
|
entitiesMap?: Record<string, any>
|
||||||
notFound?: Record<string, Record<string, string>>
|
notFound?: Record<string, Record<string, string>>
|
||||||
@@ -345,9 +347,10 @@ async function MedusaApp_({
|
|||||||
|
|
||||||
const query = async (
|
const query = async (
|
||||||
query: string | RemoteJoinerQuery | object,
|
query: string | RemoteJoinerQuery | object,
|
||||||
variables?: Record<string, unknown>
|
variables?: Record<string, unknown>,
|
||||||
|
options?: RemoteJoinerOptions
|
||||||
) => {
|
) => {
|
||||||
return await remoteQuery.query(query, variables)
|
return await remoteQuery.query(query, variables, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
const runMigrations: RunMigrationFn = async (
|
const runMigrations: RunMigrationFn = async (
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import {
|
|||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
import { isString, toPascalCase } from "@medusajs/utils"
|
import { isString, toPascalCase } from "@medusajs/utils"
|
||||||
|
|
||||||
|
import { RemoteJoinerOptions } from "@medusajs/types"
|
||||||
import { MedusaModule } from "./medusa-module"
|
import { MedusaModule } from "./medusa-module"
|
||||||
|
|
||||||
export class RemoteQuery {
|
export class RemoteQuery {
|
||||||
@@ -230,7 +231,8 @@ export class RemoteQuery {
|
|||||||
|
|
||||||
public async query(
|
public async query(
|
||||||
query: string | RemoteJoinerQuery | object,
|
query: string | RemoteJoinerQuery | object,
|
||||||
variables?: Record<string, unknown>
|
variables?: Record<string, unknown>,
|
||||||
|
options?: RemoteJoinerOptions
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
let finalQuery: RemoteJoinerQuery = query as RemoteJoinerQuery
|
let finalQuery: RemoteJoinerQuery = query as RemoteJoinerQuery
|
||||||
|
|
||||||
@@ -240,6 +242,6 @@ export class RemoteQuery {
|
|||||||
finalQuery = toRemoteJoinerQuery(query, variables)
|
finalQuery = toRemoteJoinerQuery(query, variables)
|
||||||
}
|
}
|
||||||
|
|
||||||
return await this.remoteJoiner.query(finalQuery)
|
return await this.remoteJoiner.query(finalQuery, options)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,6 +129,11 @@ export const mockServiceList = (serviceName) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mock filtering on service order
|
||||||
|
if (serviceName === "orderService" && data.options?.id) {
|
||||||
|
resultset = resultset.filter((item) => data.options.id.includes(item.id))
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data: resultset,
|
data: resultset,
|
||||||
path: serviceName === "productService" ? "rows" : undefined,
|
path: serviceName === "productService" ? "rows" : undefined,
|
||||||
|
|||||||
@@ -241,12 +241,7 @@ describe("RemoteJoiner", () => {
|
|||||||
fields: ["name"],
|
fields: ["name"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
args: [
|
args: [],
|
||||||
{
|
|
||||||
name: "id",
|
|
||||||
value: "3",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await joiner.query(query)
|
const data = await joiner.query(query)
|
||||||
@@ -802,4 +797,34 @@ describe("RemoteJoiner", () => {
|
|||||||
`Service with alias "user" was not found.`
|
`Service with alias "user" was not found.`
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("Should throw when any key of the entrypoint isn't found", async () => {
|
||||||
|
const query = RemoteJoiner.parseQuery(`
|
||||||
|
query {
|
||||||
|
order (id: 201) {
|
||||||
|
id
|
||||||
|
number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
const data = await joiner.query(query, {
|
||||||
|
throwIfKeyNotFound: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(data.length).toEqual(1)
|
||||||
|
|
||||||
|
const queryNotFound = RemoteJoiner.parseQuery(`
|
||||||
|
query {
|
||||||
|
order (id: "ord_1234556") {
|
||||||
|
id
|
||||||
|
number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
const dataNotFound = joiner.query(queryNotFound, {
|
||||||
|
throwIfKeyNotFound: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(dataNotFound).rejects.toThrowError("order id not found: ord_1234556")
|
||||||
|
})
|
||||||
})
|
})
|
||||||
@@ -569,19 +569,13 @@ describe("RemoteJoiner", () => {
|
|||||||
fields: ["name"],
|
fields: ["name"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
args: [
|
|
||||||
{
|
|
||||||
name: "id",
|
|
||||||
value: "3",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await joiner.query(query)
|
await joiner.query(query)
|
||||||
|
|
||||||
expect(serviceMock.orderService).toHaveBeenCalledTimes(1)
|
expect(serviceMock.orderService).toHaveBeenCalledTimes(1)
|
||||||
expect(serviceMock.orderService).toHaveBeenCalledWith({
|
expect(serviceMock.orderService).toHaveBeenCalledWith({
|
||||||
args: [],
|
args: undefined,
|
||||||
fields: ["number", "date", "products", "user_id"],
|
fields: ["number", "date", "products", "user_id"],
|
||||||
expands: {
|
expands: {
|
||||||
products: {
|
products: {
|
||||||
@@ -589,7 +583,7 @@ describe("RemoteJoiner", () => {
|
|||||||
fields: ["product_id"],
|
fields: ["product_id"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
options: { id: ["3"] },
|
options: { id: undefined },
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(serviceMock.userService).toHaveBeenCalledTimes(1)
|
expect(serviceMock.userService).toHaveBeenCalledTimes(1)
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import {
|
|||||||
RemoteNestedExpands,
|
RemoteNestedExpands,
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
|
|
||||||
import { deduplicate, isDefined, isString } from "@medusajs/utils"
|
import { RemoteJoinerOptions } from "@medusajs/types"
|
||||||
|
import { MedusaError, deduplicate, isDefined, isString } from "@medusajs/utils"
|
||||||
import GraphQLParser from "./graphql-ast"
|
import GraphQLParser from "./graphql-ast"
|
||||||
|
|
||||||
const BASE_PATH = "_root"
|
const BASE_PATH = "_root"
|
||||||
@@ -331,7 +332,8 @@ export class RemoteJoiner {
|
|||||||
expand: RemoteExpandProperty,
|
expand: RemoteExpandProperty,
|
||||||
pkField: string,
|
pkField: string,
|
||||||
ids?: (unknown | unknown[])[],
|
ids?: (unknown | unknown[])[],
|
||||||
relationship?: any
|
relationship?: any,
|
||||||
|
options?: RemoteJoinerOptions
|
||||||
): Promise<{
|
): Promise<{
|
||||||
data: unknown[] | { [path: string]: unknown }
|
data: unknown[] | { [path: string]: unknown }
|
||||||
path?: string
|
path?: string
|
||||||
@@ -372,6 +374,15 @@ export class RemoteJoiner {
|
|||||||
|
|
||||||
resData = Array.isArray(resData) ? resData : [resData]
|
resData = Array.isArray(resData) ? resData : [resData]
|
||||||
|
|
||||||
|
this.checkIfKeysExist(
|
||||||
|
uniqueIds,
|
||||||
|
resData,
|
||||||
|
expand,
|
||||||
|
pkField,
|
||||||
|
relationship,
|
||||||
|
options
|
||||||
|
)
|
||||||
|
|
||||||
const filteredDataArray = resData.map((data: any) =>
|
const filteredDataArray = resData.map((data: any) =>
|
||||||
RemoteJoiner.filterFields(data, expand.fields, expand.expands)
|
RemoteJoiner.filterFields(data, expand.fields, expand.expands)
|
||||||
)
|
)
|
||||||
@@ -385,6 +396,47 @@ export class RemoteJoiner {
|
|||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private checkIfKeysExist(
|
||||||
|
uniqueIds: unknown[] | undefined,
|
||||||
|
resData: any[],
|
||||||
|
expand: RemoteExpandProperty,
|
||||||
|
pkField: string,
|
||||||
|
relationship?: any,
|
||||||
|
options?: RemoteJoinerOptions
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
isDefined(uniqueIds) &&
|
||||||
|
((options?.throwIfKeyNotFound && !isDefined(relationship)) ||
|
||||||
|
(options?.throwIfRelationNotFound && isDefined(relationship)))
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDefined(relationship)) {
|
||||||
|
if (
|
||||||
|
Array.isArray(options?.throwIfRelationNotFound) &&
|
||||||
|
!options?.throwIfRelationNotFound.includes(relationship.serviceName)
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const notFound = new Set(uniqueIds)
|
||||||
|
resData.forEach((data) => {
|
||||||
|
notFound.delete(data[pkField])
|
||||||
|
})
|
||||||
|
|
||||||
|
if (notFound.size > 0) {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.NOT_FOUND,
|
||||||
|
`${expand.serviceConfig.serviceName} ${pkField} not found: ` +
|
||||||
|
Array.from(notFound).join(", ")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private handleFieldAliases(
|
private handleFieldAliases(
|
||||||
items: any[],
|
items: any[],
|
||||||
parsedExpands: Map<string, RemoteExpandProperty>,
|
parsedExpands: Map<string, RemoteExpandProperty>,
|
||||||
@@ -466,7 +518,8 @@ export class RemoteJoiner {
|
|||||||
private async handleExpands(
|
private async handleExpands(
|
||||||
items: any[],
|
items: any[],
|
||||||
parsedExpands: Map<string, RemoteExpandProperty>,
|
parsedExpands: Map<string, RemoteExpandProperty>,
|
||||||
implodeMapping: InternalImplodeMapping[] = []
|
implodeMapping: InternalImplodeMapping[] = [],
|
||||||
|
options?: RemoteJoinerOptions
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!parsedExpands) {
|
if (!parsedExpands) {
|
||||||
return
|
return
|
||||||
@@ -488,7 +541,12 @@ export class RemoteJoiner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nestedItems.length > 0) {
|
if (nestedItems.length > 0) {
|
||||||
await this.expandProperty(nestedItems, expand.parentConfig!, expand)
|
await this.expandProperty(
|
||||||
|
nestedItems,
|
||||||
|
expand.parentConfig!,
|
||||||
|
expand,
|
||||||
|
options
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,7 +556,8 @@ export class RemoteJoiner {
|
|||||||
private async expandProperty(
|
private async expandProperty(
|
||||||
items: any[],
|
items: any[],
|
||||||
parentServiceConfig: JoinerServiceConfig,
|
parentServiceConfig: JoinerServiceConfig,
|
||||||
expand?: RemoteExpandProperty
|
expand?: RemoteExpandProperty,
|
||||||
|
options?: RemoteJoinerOptions
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!expand) {
|
if (!expand) {
|
||||||
return
|
return
|
||||||
@@ -509,14 +568,20 @@ export class RemoteJoiner {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (relationship) {
|
if (relationship) {
|
||||||
await this.expandRelationshipProperty(items, expand, relationship)
|
await this.expandRelationshipProperty(
|
||||||
|
items,
|
||||||
|
expand,
|
||||||
|
relationship,
|
||||||
|
options
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async expandRelationshipProperty(
|
private async expandRelationshipProperty(
|
||||||
items: any[],
|
items: any[],
|
||||||
expand: RemoteExpandProperty,
|
expand: RemoteExpandProperty,
|
||||||
relationship: JoinerRelationship
|
relationship: JoinerRelationship,
|
||||||
|
options?: RemoteJoinerOptions
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const field = relationship.inverse
|
const field = relationship.inverse
|
||||||
? relationship.primaryKey
|
? relationship.primaryKey
|
||||||
@@ -552,7 +617,8 @@ export class RemoteJoiner {
|
|||||||
expand,
|
expand,
|
||||||
field,
|
field,
|
||||||
idsToFetch,
|
idsToFetch,
|
||||||
relationship
|
relationship,
|
||||||
|
options
|
||||||
)
|
)
|
||||||
|
|
||||||
const joinFields = relationship.inverse
|
const joinFields = relationship.inverse
|
||||||
@@ -602,14 +668,16 @@ export class RemoteJoiner {
|
|||||||
query: RemoteJoinerQuery,
|
query: RemoteJoinerQuery,
|
||||||
serviceConfig: JoinerServiceConfig,
|
serviceConfig: JoinerServiceConfig,
|
||||||
expands: RemoteJoinerQuery["expands"],
|
expands: RemoteJoinerQuery["expands"],
|
||||||
implodeMapping: InternalImplodeMapping[]
|
implodeMapping: InternalImplodeMapping[],
|
||||||
|
options?: RemoteJoinerOptions
|
||||||
): Map<string, RemoteExpandProperty> {
|
): Map<string, RemoteExpandProperty> {
|
||||||
const parsedExpands = this.parseProperties(
|
const parsedExpands = this.parseProperties(
|
||||||
initialService,
|
initialService,
|
||||||
query,
|
query,
|
||||||
serviceConfig,
|
serviceConfig,
|
||||||
expands,
|
expands,
|
||||||
implodeMapping
|
implodeMapping,
|
||||||
|
options
|
||||||
)
|
)
|
||||||
|
|
||||||
const groupedExpands = this.groupExpands(parsedExpands)
|
const groupedExpands = this.groupExpands(parsedExpands)
|
||||||
@@ -622,7 +690,8 @@ export class RemoteJoiner {
|
|||||||
query: RemoteJoinerQuery,
|
query: RemoteJoinerQuery,
|
||||||
serviceConfig: JoinerServiceConfig,
|
serviceConfig: JoinerServiceConfig,
|
||||||
expands: RemoteJoinerQuery["expands"],
|
expands: RemoteJoinerQuery["expands"],
|
||||||
implodeMapping: InternalImplodeMapping[]
|
implodeMapping: InternalImplodeMapping[],
|
||||||
|
options?: RemoteJoinerOptions
|
||||||
): Map<string, RemoteExpandProperty> {
|
): Map<string, RemoteExpandProperty> {
|
||||||
const aliasRealPathMap = new Map<string, string[]>()
|
const aliasRealPathMap = new Map<string, string[]>()
|
||||||
const parsedExpands = new Map<string, any>()
|
const parsedExpands = new Map<string, any>()
|
||||||
@@ -913,7 +982,10 @@ export class RemoteJoiner {
|
|||||||
return mergedExpands
|
return mergedExpands
|
||||||
}
|
}
|
||||||
|
|
||||||
async query(queryObj: RemoteJoinerQuery): Promise<any> {
|
async query(
|
||||||
|
queryObj: RemoteJoinerQuery,
|
||||||
|
options?: RemoteJoinerOptions
|
||||||
|
): Promise<any> {
|
||||||
const serviceConfig = this.getServiceConfig(
|
const serviceConfig = this.getServiceConfig(
|
||||||
queryObj.service,
|
queryObj.service,
|
||||||
queryObj.alias
|
queryObj.alias
|
||||||
@@ -960,7 +1032,8 @@ export class RemoteJoiner {
|
|||||||
root,
|
root,
|
||||||
pkName,
|
pkName,
|
||||||
primaryKeyArg?.value,
|
primaryKeyArg?.value,
|
||||||
undefined
|
undefined,
|
||||||
|
options
|
||||||
)
|
)
|
||||||
|
|
||||||
const data = response.path ? response.data[response.path!] : response.data
|
const data = response.path ? response.data[response.path!] : response.data
|
||||||
@@ -968,7 +1041,8 @@ export class RemoteJoiner {
|
|||||||
await this.handleExpands(
|
await this.handleExpands(
|
||||||
Array.isArray(data) ? data : [data],
|
Array.isArray(data) ? data : [data],
|
||||||
parsedExpands,
|
parsedExpands,
|
||||||
implodeMapping
|
implodeMapping,
|
||||||
|
options
|
||||||
)
|
)
|
||||||
|
|
||||||
return response.data
|
return response.data
|
||||||
|
|||||||
@@ -83,6 +83,11 @@ export interface RemoteJoinerQuery {
|
|||||||
directives?: { [field: string]: JoinerDirective[] }
|
directives?: { [field: string]: JoinerDirective[] }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface RemoteJoinerOptions {
|
||||||
|
throwIfKeyNotFound?: boolean
|
||||||
|
throwIfRelationNotFound?: boolean | string[]
|
||||||
|
}
|
||||||
|
|
||||||
export interface RemoteNestedExpands {
|
export interface RemoteNestedExpands {
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
fields: string[]
|
fields: string[]
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
JoinerRelationship,
|
JoinerRelationship,
|
||||||
JoinerServiceConfig,
|
JoinerServiceConfig,
|
||||||
|
RemoteJoinerOptions,
|
||||||
RemoteJoinerQuery,
|
RemoteJoinerQuery,
|
||||||
} from "../joiner"
|
} from "../joiner"
|
||||||
|
|
||||||
@@ -278,7 +279,8 @@ export type ModuleBootstrapDeclaration =
|
|||||||
|
|
||||||
export type RemoteQueryFunction = (
|
export type RemoteQueryFunction = (
|
||||||
query: string | RemoteJoinerQuery | object,
|
query: string | RemoteJoinerQuery | object,
|
||||||
variables?: Record<string, unknown>
|
variables?: Record<string, unknown>,
|
||||||
|
options?: RemoteJoinerOptions
|
||||||
) => Promise<any> | null
|
) => Promise<any> | null
|
||||||
|
|
||||||
export interface IModuleService {
|
export interface IModuleService {
|
||||||
|
|||||||
Reference in new issue
Block a user