chore: query graph api (#9125)
CLOSES: FRMW-2704 **What** Re-structure the Query graph API as well as introduce dynamic typing from schemas on the filters and better handling of relation treatment for fields/filters inference Co-authored-by: Adrien de Peretti <25098370+adrien2p@users.noreply.github.com>
This commit is contained in:
1 parent
3e97a64b21
commit
8829f89402
21 files changed
+2164
-52
No files matched your search
@@ -48,7 +48,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.QUERY]: Omit<RemoteQueryFunction, symbol>
|
||||||
[ContainerRegistrationKeys.LOGGER]: Logger
|
[ContainerRegistrationKeys.LOGGER]: Logger
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -520,7 +520,7 @@ async function MedusaApp_({
|
|||||||
onApplicationStart,
|
onApplicationStart,
|
||||||
modules: allModules,
|
modules: allModules,
|
||||||
link: remoteLink,
|
link: remoteLink,
|
||||||
query: createQuery(remoteQuery),
|
query: createQuery(remoteQuery) as any, // TODO: rm any once we remove the old RemoteQueryFunction and rely on the Query object instead,
|
||||||
entitiesMap: schema.getTypeMap(),
|
entitiesMap: schema.getTypeMap(),
|
||||||
gqlSchema: schema,
|
gqlSchema: schema,
|
||||||
notFound,
|
notFound,
|
||||||
|
|||||||
@@ -0,0 +1,454 @@
|
|||||||
|
export type Maybe<T> = T | null
|
||||||
|
export type InputMaybe<T> = Maybe<T>
|
||||||
|
export type Exact<T extends { [key: string]: unknown }> = {
|
||||||
|
[K in keyof T]: T[K]
|
||||||
|
}
|
||||||
|
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & {
|
||||||
|
[SubKey in K]?: Maybe<T[SubKey]>
|
||||||
|
}
|
||||||
|
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & {
|
||||||
|
[SubKey in K]: Maybe<T[SubKey]>
|
||||||
|
}
|
||||||
|
export type MakeEmpty<
|
||||||
|
T extends { [key: string]: unknown },
|
||||||
|
K extends keyof T
|
||||||
|
> = { [_ in K]?: never }
|
||||||
|
export type Incremental<T> =
|
||||||
|
| T
|
||||||
|
| {
|
||||||
|
[P in keyof T]?: P extends " $fragmentName" | "__typename" ? T[P] : never
|
||||||
|
}
|
||||||
|
|
||||||
|
/** All built-in and custom scalars, mapped to their actual values */
|
||||||
|
export type Scalars = {
|
||||||
|
ID: { input: string; output: string }
|
||||||
|
String: { input: string; output: string }
|
||||||
|
Boolean: { input: boolean; output: boolean }
|
||||||
|
Int: { input: number; output: number }
|
||||||
|
Float: { input: number; output: number }
|
||||||
|
DateTime: { input: Date | string; output: Date | string }
|
||||||
|
JSON: { input: Record<string, unknown>; output: Record<string, unknown> }
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SimpleProduct = {
|
||||||
|
id: Scalars["ID"]["output"]
|
||||||
|
handle: string
|
||||||
|
title?: Scalars["String"]["output"]
|
||||||
|
variants?: Maybe<Array<Maybe<Pick<ProductVariant, "id">>>>
|
||||||
|
sales_channels_link?: Array<
|
||||||
|
Pick<LinkProductSalesChannel, "product_id" | "sales_channel_id">
|
||||||
|
>
|
||||||
|
sales_channels?: Array<Pick<SalesChannel, "id" | "name">>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Product = {
|
||||||
|
__typename?: "Product"
|
||||||
|
id: Scalars["ID"]["output"]
|
||||||
|
handle: Scalars["String"]["output"]
|
||||||
|
title: Scalars["String"]["output"]
|
||||||
|
description?: Scalars["String"]["output"]
|
||||||
|
variants?: Array<ProductVariant>
|
||||||
|
sales_channels_link?: Array<LinkProductSalesChannel>
|
||||||
|
sales_channels?: Array<SalesChannel>
|
||||||
|
metadata?: Maybe<Scalars["JSON"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ProductVariant = {
|
||||||
|
__typename?: "ProductVariant"
|
||||||
|
id: Scalars["ID"]["output"]
|
||||||
|
handle: Scalars["String"]["output"]
|
||||||
|
title: Scalars["String"]["output"]
|
||||||
|
sku: Scalars["String"]["output"]
|
||||||
|
product?: Maybe<Product>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ProductCategory = {
|
||||||
|
__typename?: "ProductCategory"
|
||||||
|
id: Scalars["ID"]["output"]
|
||||||
|
handle: Scalars["String"]["output"]
|
||||||
|
title?: Maybe<Scalars["String"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SalesChannel = {
|
||||||
|
__typename?: "SalesChannel"
|
||||||
|
id: Scalars["ID"]["output"]
|
||||||
|
name?: Maybe<Scalars["String"]["output"]>
|
||||||
|
description?: Maybe<Scalars["String"]["output"]>
|
||||||
|
created_at?: Maybe<Scalars["DateTime"]["output"]>
|
||||||
|
updated_at?: Maybe<Scalars["DateTime"]["output"]>
|
||||||
|
products_link?: Maybe<Array<Maybe<LinkProductSalesChannel>>>
|
||||||
|
api_keys_link?: Maybe<Array<Maybe<LinkPublishableApiKeySalesChannel>>>
|
||||||
|
locations_link?: Maybe<Array<Maybe<LinkSalesChannelStockLocation>>>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkCartPaymentCollection = {
|
||||||
|
__typename?: "LinkCartPaymentCollection"
|
||||||
|
cart_id: Scalars["String"]["output"]
|
||||||
|
payment_collection_id: Scalars["String"]["output"]
|
||||||
|
createdAt: Scalars["String"]["output"]
|
||||||
|
updatedAt: Scalars["String"]["output"]
|
||||||
|
deletedAt?: Maybe<Scalars["String"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkCartPromotion = {
|
||||||
|
__typename?: "LinkCartPromotion"
|
||||||
|
cart_id: Scalars["String"]["output"]
|
||||||
|
promotion_id: Scalars["String"]["output"]
|
||||||
|
createdAt: Scalars["String"]["output"]
|
||||||
|
updatedAt: Scalars["String"]["output"]
|
||||||
|
deletedAt?: Maybe<Scalars["String"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkLocationFulfillmentProvider = {
|
||||||
|
__typename?: "LinkLocationFulfillmentProvider"
|
||||||
|
stock_location_id: Scalars["String"]["output"]
|
||||||
|
fulfillment_provider_id: Scalars["String"]["output"]
|
||||||
|
createdAt: Scalars["String"]["output"]
|
||||||
|
updatedAt: Scalars["String"]["output"]
|
||||||
|
deletedAt?: Maybe<Scalars["String"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkLocationFulfillmentSet = {
|
||||||
|
__typename?: "LinkLocationFulfillmentSet"
|
||||||
|
stock_location_id: Scalars["String"]["output"]
|
||||||
|
fulfillment_set_id: Scalars["String"]["output"]
|
||||||
|
createdAt: Scalars["String"]["output"]
|
||||||
|
updatedAt: Scalars["String"]["output"]
|
||||||
|
deletedAt?: Maybe<Scalars["String"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkOrderCart = {
|
||||||
|
__typename?: "LinkOrderCart"
|
||||||
|
order_id: Scalars["String"]["output"]
|
||||||
|
cart_id: Scalars["String"]["output"]
|
||||||
|
createdAt: Scalars["String"]["output"]
|
||||||
|
updatedAt: Scalars["String"]["output"]
|
||||||
|
deletedAt?: Maybe<Scalars["String"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkOrderFulfillment = {
|
||||||
|
__typename?: "LinkOrderFulfillment"
|
||||||
|
order_id: Scalars["String"]["output"]
|
||||||
|
fulfillment_id: Scalars["String"]["output"]
|
||||||
|
createdAt: Scalars["String"]["output"]
|
||||||
|
updatedAt: Scalars["String"]["output"]
|
||||||
|
deletedAt?: Maybe<Scalars["String"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkOrderPaymentCollection = {
|
||||||
|
__typename?: "LinkOrderPaymentCollection"
|
||||||
|
order_id: Scalars["String"]["output"]
|
||||||
|
payment_collection_id: Scalars["String"]["output"]
|
||||||
|
createdAt: Scalars["String"]["output"]
|
||||||
|
updatedAt: Scalars["String"]["output"]
|
||||||
|
deletedAt?: Maybe<Scalars["String"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkOrderPromotion = {
|
||||||
|
__typename?: "LinkOrderPromotion"
|
||||||
|
order_id: Scalars["String"]["output"]
|
||||||
|
promotion_id: Scalars["String"]["output"]
|
||||||
|
createdAt: Scalars["String"]["output"]
|
||||||
|
updatedAt: Scalars["String"]["output"]
|
||||||
|
deletedAt?: Maybe<Scalars["String"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkReturnFulfillment = {
|
||||||
|
__typename?: "LinkReturnFulfillment"
|
||||||
|
return_id: Scalars["String"]["output"]
|
||||||
|
fulfillment_id: Scalars["String"]["output"]
|
||||||
|
createdAt: Scalars["String"]["output"]
|
||||||
|
updatedAt: Scalars["String"]["output"]
|
||||||
|
deletedAt?: Maybe<Scalars["String"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkProductSalesChannel = {
|
||||||
|
__typename?: "LinkProductSalesChannel"
|
||||||
|
product_id: Scalars["String"]["output"]
|
||||||
|
sales_channel_id: Scalars["String"]["output"]
|
||||||
|
product?: Maybe<Product>
|
||||||
|
sales_channel?: Maybe<SalesChannel>
|
||||||
|
createdAt: Scalars["String"]["output"]
|
||||||
|
updatedAt: Scalars["String"]["output"]
|
||||||
|
deletedAt?: Maybe<Scalars["String"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkProductVariantInventoryItem = {
|
||||||
|
__typename?: "LinkProductVariantInventoryItem"
|
||||||
|
variant_id: Scalars["String"]["output"]
|
||||||
|
inventory_item_id: Scalars["String"]["output"]
|
||||||
|
required_quantity: Scalars["Int"]["output"]
|
||||||
|
variant?: Maybe<Product>
|
||||||
|
createdAt: Scalars["String"]["output"]
|
||||||
|
updatedAt: Scalars["String"]["output"]
|
||||||
|
deletedAt?: Maybe<Scalars["String"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkProductVariantPriceSet = {
|
||||||
|
__typename?: "LinkProductVariantPriceSet"
|
||||||
|
variant_id: Scalars["String"]["output"]
|
||||||
|
price_set_id: Scalars["String"]["output"]
|
||||||
|
variant?: Maybe<Product>
|
||||||
|
createdAt: Scalars["String"]["output"]
|
||||||
|
updatedAt: Scalars["String"]["output"]
|
||||||
|
deletedAt?: Maybe<Scalars["String"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkPublishableApiKeySalesChannel = {
|
||||||
|
__typename?: "LinkPublishableApiKeySalesChannel"
|
||||||
|
publishable_key_id: Scalars["String"]["output"]
|
||||||
|
sales_channel_id: Scalars["String"]["output"]
|
||||||
|
sales_channel?: Maybe<SalesChannel>
|
||||||
|
createdAt: Scalars["String"]["output"]
|
||||||
|
updatedAt: Scalars["String"]["output"]
|
||||||
|
deletedAt?: Maybe<Scalars["String"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkRegionPaymentProvider = {
|
||||||
|
__typename?: "LinkRegionPaymentProvider"
|
||||||
|
region_id: Scalars["String"]["output"]
|
||||||
|
payment_provider_id: Scalars["String"]["output"]
|
||||||
|
createdAt: Scalars["String"]["output"]
|
||||||
|
updatedAt: Scalars["String"]["output"]
|
||||||
|
deletedAt?: Maybe<Scalars["String"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkSalesChannelStockLocation = {
|
||||||
|
__typename?: "LinkSalesChannelStockLocation"
|
||||||
|
sales_channel_id: Scalars["String"]["output"]
|
||||||
|
stock_location_id: Scalars["String"]["output"]
|
||||||
|
sales_channel?: Maybe<SalesChannel>
|
||||||
|
createdAt: Scalars["String"]["output"]
|
||||||
|
updatedAt: Scalars["String"]["output"]
|
||||||
|
deletedAt?: Maybe<Scalars["String"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkShippingOptionPriceSet = {
|
||||||
|
__typename?: "LinkShippingOptionPriceSet"
|
||||||
|
shipping_option_id: Scalars["String"]["output"]
|
||||||
|
price_set_id: Scalars["String"]["output"]
|
||||||
|
createdAt: Scalars["String"]["output"]
|
||||||
|
updatedAt: Scalars["String"]["output"]
|
||||||
|
deletedAt?: Maybe<Scalars["String"]["output"]>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FixtureEntryPoints {
|
||||||
|
file: any
|
||||||
|
files: any
|
||||||
|
workflow_execution: any
|
||||||
|
workflow_executions: any
|
||||||
|
inventory_items: any
|
||||||
|
inventory_item: any
|
||||||
|
inventory: any
|
||||||
|
reservation: any
|
||||||
|
reservations: any
|
||||||
|
reservation_item: any
|
||||||
|
reservation_items: any
|
||||||
|
inventory_level: any
|
||||||
|
inventory_levels: any
|
||||||
|
stock_location_address: any
|
||||||
|
stock_location_addresses: any
|
||||||
|
stock_location: any
|
||||||
|
stock_locations: any
|
||||||
|
price_set: any
|
||||||
|
price_sets: any
|
||||||
|
price_list: any
|
||||||
|
price_lists: any
|
||||||
|
price: any
|
||||||
|
prices: any
|
||||||
|
price_preference: any
|
||||||
|
price_preferences: any
|
||||||
|
product_variant: ProductVariant
|
||||||
|
product_variants: ProductVariant
|
||||||
|
variant: ProductVariant
|
||||||
|
variants: ProductVariant
|
||||||
|
product: Product
|
||||||
|
products: Product
|
||||||
|
simple_product: SimpleProduct
|
||||||
|
product_option: any
|
||||||
|
product_options: any
|
||||||
|
product_type: any
|
||||||
|
product_types: any
|
||||||
|
product_image: any
|
||||||
|
product_images: any
|
||||||
|
product_tag: any
|
||||||
|
product_tags: any
|
||||||
|
product_collection: any
|
||||||
|
product_collections: any
|
||||||
|
product_category: ProductCategory
|
||||||
|
product_categories: ProductCategory
|
||||||
|
sales_channel: SalesChannel
|
||||||
|
sales_channels: SalesChannel
|
||||||
|
customer_address: any
|
||||||
|
customer_addresses: any
|
||||||
|
customer_group_customer: any
|
||||||
|
customer_group_customers: any
|
||||||
|
customer_group: any
|
||||||
|
customer_groups: any
|
||||||
|
customer: any
|
||||||
|
customers: any
|
||||||
|
cart: any
|
||||||
|
carts: any
|
||||||
|
address: any
|
||||||
|
addresses: any
|
||||||
|
line_item: any
|
||||||
|
line_items: any
|
||||||
|
line_item_adjustment: any
|
||||||
|
line_item_adjustments: any
|
||||||
|
line_item_tax_line: any
|
||||||
|
line_item_tax_lines: any
|
||||||
|
shipping_method: any
|
||||||
|
shipping_methods: any
|
||||||
|
shipping_method_adjustment: any
|
||||||
|
shipping_method_adjustments: any
|
||||||
|
shipping_method_tax_line: any
|
||||||
|
shipping_method_tax_lines: any
|
||||||
|
promotion: any
|
||||||
|
promotions: any
|
||||||
|
campaign: any
|
||||||
|
campaigns: any
|
||||||
|
promotion_rule: any
|
||||||
|
promotion_rules: any
|
||||||
|
api_key: any
|
||||||
|
api_keys: any
|
||||||
|
tax_rate: any
|
||||||
|
tax_rates: any
|
||||||
|
tax_region: any
|
||||||
|
tax_regions: any
|
||||||
|
tax_rate_rule: any
|
||||||
|
tax_rate_rules: any
|
||||||
|
tax_provider: any
|
||||||
|
tax_providers: any
|
||||||
|
store: any
|
||||||
|
stores: any
|
||||||
|
store_currency: any
|
||||||
|
store_currencies: any
|
||||||
|
user: any
|
||||||
|
users: any
|
||||||
|
invite: any
|
||||||
|
invites: any
|
||||||
|
auth_identity: any
|
||||||
|
auth_identities: any
|
||||||
|
order: any
|
||||||
|
orders: any
|
||||||
|
order_address: any
|
||||||
|
order_addresses: any
|
||||||
|
order_line_item: any
|
||||||
|
order_line_items: any
|
||||||
|
order_line_item_adjustment: any
|
||||||
|
order_line_item_adjustments: any
|
||||||
|
order_line_item_tax_line: any
|
||||||
|
order_line_item_tax_lines: any
|
||||||
|
order_shipping_method: any
|
||||||
|
order_shipping_methods: any
|
||||||
|
order_shipping_method_adjustment: any
|
||||||
|
order_shipping_method_adjustments: any
|
||||||
|
order_shipping_method_tax_line: any
|
||||||
|
order_shipping_method_tax_lines: any
|
||||||
|
order_transaction: any
|
||||||
|
order_transactions: any
|
||||||
|
order_change: any
|
||||||
|
order_changes: any
|
||||||
|
order_change_action: any
|
||||||
|
order_change_actions: any
|
||||||
|
order_item: any
|
||||||
|
order_items: any
|
||||||
|
order_summary: any
|
||||||
|
order_summaries: any
|
||||||
|
order_shipping: any
|
||||||
|
order_shippings: any
|
||||||
|
return_reason: any
|
||||||
|
return_reasons: any
|
||||||
|
return: any
|
||||||
|
returns: any
|
||||||
|
return_item: any
|
||||||
|
return_items: any
|
||||||
|
order_claim: any
|
||||||
|
order_claims: any
|
||||||
|
order_claim_item: any
|
||||||
|
order_claim_items: any
|
||||||
|
order_claim_item_image: any
|
||||||
|
order_claim_item_images: any
|
||||||
|
order_exchange: any
|
||||||
|
order_exchanges: any
|
||||||
|
order_exchange_item: any
|
||||||
|
order_exchange_items: any
|
||||||
|
payment: any
|
||||||
|
payments: any
|
||||||
|
payment_collection: any
|
||||||
|
payment_collections: any
|
||||||
|
payment_provider: any
|
||||||
|
payment_providers: any
|
||||||
|
payment_session: any
|
||||||
|
payment_sessions: any
|
||||||
|
refund_reason: any
|
||||||
|
refund_reasons: any
|
||||||
|
fulfillment_address: any
|
||||||
|
fulfillment_addresses: any
|
||||||
|
fulfillment_item: any
|
||||||
|
fulfillment_items: any
|
||||||
|
fulfillment_label: any
|
||||||
|
fulfillment_labels: any
|
||||||
|
fulfillment_provider: any
|
||||||
|
fulfillment_providers: any
|
||||||
|
fulfillment_set: any
|
||||||
|
fulfillment_sets: any
|
||||||
|
fulfillment: any
|
||||||
|
fulfillments: any
|
||||||
|
geo_zone: any
|
||||||
|
geo_zones: any
|
||||||
|
service_zone: any
|
||||||
|
service_zones: any
|
||||||
|
shipping_option_rule: any
|
||||||
|
shipping_option_rules: any
|
||||||
|
shipping_option_type: any
|
||||||
|
shipping_option_types: any
|
||||||
|
shipping_option: any
|
||||||
|
shipping_options: any
|
||||||
|
shipping_profile: any
|
||||||
|
shipping_profiles: any
|
||||||
|
notification: any
|
||||||
|
notifications: any
|
||||||
|
region: any
|
||||||
|
regions: any
|
||||||
|
country: any
|
||||||
|
countries: any
|
||||||
|
currency: any
|
||||||
|
currencies: any
|
||||||
|
cart_payment_collection: LinkCartPaymentCollection
|
||||||
|
cart_payment_collections: LinkCartPaymentCollection
|
||||||
|
cart_promotion: LinkCartPromotion
|
||||||
|
cart_promotions: LinkCartPromotion
|
||||||
|
location_fulfillment_provider: LinkLocationFulfillmentProvider
|
||||||
|
location_fulfillment_providers: LinkLocationFulfillmentProvider
|
||||||
|
location_fulfillment_set: LinkLocationFulfillmentSet
|
||||||
|
location_fulfillment_sets: LinkLocationFulfillmentSet
|
||||||
|
order_cart: LinkOrderCart
|
||||||
|
order_carts: LinkOrderCart
|
||||||
|
order_fulfillment: LinkOrderFulfillment
|
||||||
|
order_fulfillments: LinkOrderFulfillment
|
||||||
|
order_payment_collection: LinkOrderPaymentCollection
|
||||||
|
order_payment_collections: LinkOrderPaymentCollection
|
||||||
|
order_promotion: LinkOrderPromotion
|
||||||
|
order_promotions: LinkOrderPromotion
|
||||||
|
return_fulfillment: LinkReturnFulfillment
|
||||||
|
return_fulfillments: LinkReturnFulfillment
|
||||||
|
product_sales_channel: LinkProductSalesChannel
|
||||||
|
product_sales_channels: LinkProductSalesChannel
|
||||||
|
product_variant_inventory_item: LinkProductVariantInventoryItem
|
||||||
|
product_variant_inventory_items: LinkProductVariantInventoryItem
|
||||||
|
product_variant_price_set: LinkProductVariantPriceSet
|
||||||
|
product_variant_price_sets: LinkProductVariantPriceSet
|
||||||
|
publishable_api_key_sales_channel: LinkPublishableApiKeySalesChannel
|
||||||
|
publishable_api_key_sales_channels: LinkPublishableApiKeySalesChannel
|
||||||
|
region_payment_provider: LinkRegionPaymentProvider
|
||||||
|
region_payment_providers: LinkRegionPaymentProvider
|
||||||
|
sales_channel_location: LinkSalesChannelStockLocation
|
||||||
|
sales_channel_locations: LinkSalesChannelStockLocation
|
||||||
|
shipping_option_price_set: LinkShippingOptionPriceSet
|
||||||
|
shipping_option_price_sets: LinkShippingOptionPriceSet
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "@medusajs/types" {
|
||||||
|
export interface RemoteQueryEntryPoints extends FixtureEntryPoints {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
import { QueryContext, QueryFilter } from "@medusajs/utils"
|
||||||
|
import "../__fixtures__/remote-query-type"
|
||||||
|
import { toRemoteQuery } from "../to-remote-query"
|
||||||
|
|
||||||
|
describe("toRemoteQuery", () => {
|
||||||
|
it("should transform a query with top level filtering", () => {
|
||||||
|
const format = toRemoteQuery({
|
||||||
|
entity: "product",
|
||||||
|
fields: ["id", "handle", "description"],
|
||||||
|
filters: QueryFilter<"product">({
|
||||||
|
handle: {
|
||||||
|
$ilike: "abc%",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(format).toEqual({
|
||||||
|
product: {
|
||||||
|
__fields: ["id", "handle", "description"],
|
||||||
|
__args: {
|
||||||
|
filters: {
|
||||||
|
handle: {
|
||||||
|
$ilike: "abc%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should transform a query with pagination", () => {
|
||||||
|
const format = toRemoteQuery({
|
||||||
|
entity: "product",
|
||||||
|
fields: ["id", "handle", "description"],
|
||||||
|
pagination: {
|
||||||
|
skip: 5,
|
||||||
|
take: 10,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(format).toEqual({
|
||||||
|
product: {
|
||||||
|
__fields: ["id", "handle", "description"],
|
||||||
|
__args: {
|
||||||
|
skip: 5,
|
||||||
|
take: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should transform a query with top level filtering and pagination", () => {
|
||||||
|
const format = toRemoteQuery({
|
||||||
|
entity: "product",
|
||||||
|
fields: ["id", "handle", "description"],
|
||||||
|
pagination: {
|
||||||
|
skip: 5,
|
||||||
|
take: 10,
|
||||||
|
},
|
||||||
|
filters: QueryFilter<"product">({
|
||||||
|
handle: {
|
||||||
|
$ilike: "abc%",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(format).toEqual({
|
||||||
|
product: {
|
||||||
|
__fields: ["id", "handle", "description"],
|
||||||
|
__args: {
|
||||||
|
skip: 5,
|
||||||
|
take: 10,
|
||||||
|
filters: {
|
||||||
|
handle: {
|
||||||
|
$ilike: "abc%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should transform a query with filters and context into remote query input [1]", () => {
|
||||||
|
const format = toRemoteQuery({
|
||||||
|
entity: "product",
|
||||||
|
fields: [
|
||||||
|
"id",
|
||||||
|
"description",
|
||||||
|
"variants.title",
|
||||||
|
"variants.calculated_price",
|
||||||
|
"variants.options.*",
|
||||||
|
],
|
||||||
|
filters: {
|
||||||
|
variants: QueryFilter<"variants">({
|
||||||
|
sku: {
|
||||||
|
$ilike: "abc%",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
context: {
|
||||||
|
variants: {
|
||||||
|
calculated_price: QueryContext({
|
||||||
|
region_id: "reg_123",
|
||||||
|
currency_code: "usd",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(format).toEqual({
|
||||||
|
product: {
|
||||||
|
__fields: ["id", "description"],
|
||||||
|
variants: {
|
||||||
|
__args: {
|
||||||
|
filters: {
|
||||||
|
sku: {
|
||||||
|
$ilike: "abc%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
calculated_price: {
|
||||||
|
__args: {
|
||||||
|
context: {
|
||||||
|
region_id: "reg_123",
|
||||||
|
currency_code: "usd",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
__fields: ["title", "calculated_price"],
|
||||||
|
options: {
|
||||||
|
__fields: ["*"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should transform a query with filters and context into remote query input [2]", () => {
|
||||||
|
const langContext = QueryContext({
|
||||||
|
context: {
|
||||||
|
lang: "pt-br",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const format = toRemoteQuery({
|
||||||
|
entity: "product",
|
||||||
|
fields: [
|
||||||
|
"id",
|
||||||
|
"title",
|
||||||
|
"description",
|
||||||
|
"product_translation.*",
|
||||||
|
"categories.*",
|
||||||
|
"categories.category_translation.*",
|
||||||
|
"variants.*",
|
||||||
|
"variants.variant_translation.*",
|
||||||
|
],
|
||||||
|
filters: QueryFilter<"product">({
|
||||||
|
id: "prod_01J742X0QPFW3R2ZFRTRC34FS8",
|
||||||
|
}),
|
||||||
|
context: {
|
||||||
|
product_translation: langContext,
|
||||||
|
categories: {
|
||||||
|
category_translation: langContext,
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
variant_translation: langContext,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(format).toEqual({
|
||||||
|
product: {
|
||||||
|
__fields: ["id", "title", "description"],
|
||||||
|
__args: {
|
||||||
|
filters: {
|
||||||
|
id: "prod_01J742X0QPFW3R2ZFRTRC34FS8",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
product_translation: {
|
||||||
|
__args: {
|
||||||
|
context: {
|
||||||
|
context: {
|
||||||
|
lang: "pt-br",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
__fields: ["*"],
|
||||||
|
},
|
||||||
|
categories: {
|
||||||
|
category_translation: {
|
||||||
|
__args: {
|
||||||
|
context: {
|
||||||
|
context: {
|
||||||
|
lang: "pt-br",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
__fields: ["*"],
|
||||||
|
},
|
||||||
|
__fields: ["*"],
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
variant_translation: {
|
||||||
|
__args: {
|
||||||
|
context: {
|
||||||
|
context: {
|
||||||
|
lang: "pt-br",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
__fields: ["*"],
|
||||||
|
},
|
||||||
|
__fields: ["*"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import { RemoteQuery } from "./remote-query"
|
|
||||||
import {
|
import {
|
||||||
GraphResultSet,
|
GraphResultSet,
|
||||||
RemoteJoinerOptions,
|
RemoteJoinerOptions,
|
||||||
RemoteJoinerQuery,
|
RemoteJoinerQuery,
|
||||||
RemoteQueryFunction,
|
RemoteQueryFunction,
|
||||||
RemoteQueryFunctionReturnPagination,
|
RemoteQueryFunctionReturnPagination,
|
||||||
|
RemoteQueryInput,
|
||||||
RemoteQueryObjectConfig,
|
RemoteQueryObjectConfig,
|
||||||
RemoteQueryObjectFromStringResult,
|
RemoteQueryObjectFromStringResult,
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
@@ -13,6 +13,8 @@ import {
|
|||||||
MedusaError,
|
MedusaError,
|
||||||
remoteQueryObjectFromString,
|
remoteQueryObjectFromString,
|
||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
|
import { RemoteQuery } from "./remote-query"
|
||||||
|
import { toRemoteQuery } from "./to-remote-query"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API wrapper around the remoteQuery
|
* API wrapper around the remoteQuery
|
||||||
@@ -25,7 +27,7 @@ export class Query {
|
|||||||
*/
|
*/
|
||||||
static traceGraphQuery?: (
|
static traceGraphQuery?: (
|
||||||
queryFn: () => Promise<any>,
|
queryFn: () => Promise<any>,
|
||||||
queryOptions: RemoteQueryObjectConfig<any>
|
queryOptions: RemoteQueryInput<any>
|
||||||
) => Promise<any>
|
) => Promise<any>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,14 +60,16 @@ export class Query {
|
|||||||
|
|
||||||
#unwrapQueryConfig(
|
#unwrapQueryConfig(
|
||||||
config:
|
config:
|
||||||
| RemoteQueryObjectConfig<any>
|
|
||||||
| RemoteQueryObjectFromStringResult<any>
|
| RemoteQueryObjectFromStringResult<any>
|
||||||
|
| RemoteQueryObjectConfig<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 ("entity" in normalizedQuery) {
|
||||||
|
normalizedQuery = toRemoteQuery(normalizedQuery)
|
||||||
} else if (
|
} else if (
|
||||||
"entryPoint" in normalizedQuery ||
|
"entryPoint" in normalizedQuery ||
|
||||||
"service" in normalizedQuery
|
"service" in normalizedQuery
|
||||||
@@ -95,6 +99,7 @@ export class Query {
|
|||||||
|
|
||||||
async query(
|
async query(
|
||||||
queryOptions:
|
queryOptions:
|
||||||
|
| RemoteQueryInput<any>
|
||||||
| RemoteQueryObjectConfig<any>
|
| RemoteQueryObjectConfig<any>
|
||||||
| RemoteQueryObjectFromStringResult<any>
|
| RemoteQueryObjectFromStringResult<any>
|
||||||
| RemoteJoinerQuery,
|
| RemoteJoinerQuery,
|
||||||
@@ -110,7 +115,7 @@ export class Query {
|
|||||||
const config = this.#unwrapQueryConfig(queryOptions)
|
const config = this.#unwrapQueryConfig(queryOptions)
|
||||||
if (Query.traceRemoteQuery) {
|
if (Query.traceRemoteQuery) {
|
||||||
return await Query.traceRemoteQuery(
|
return await Query.traceRemoteQuery(
|
||||||
async () => this.#remoteQuery.query(config, undefined, options),
|
async () => await this.#remoteQuery.query(config, undefined, options),
|
||||||
queryOptions
|
queryOptions
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -133,10 +138,10 @@ export class Query {
|
|||||||
* returns a result set
|
* returns a result set
|
||||||
*/
|
*/
|
||||||
async graph<const TEntry extends string>(
|
async graph<const TEntry extends string>(
|
||||||
queryOptions: RemoteQueryObjectConfig<TEntry>,
|
queryOptions: RemoteQueryInput<TEntry>,
|
||||||
options?: RemoteJoinerOptions
|
options?: RemoteJoinerOptions
|
||||||
): Promise<GraphResultSet<TEntry>> {
|
): Promise<GraphResultSet<TEntry>> {
|
||||||
const normalizedQuery = remoteQueryObjectFromString(queryOptions).__value
|
const normalizedQuery = toRemoteQuery<TEntry>(queryOptions)
|
||||||
let response:
|
let response:
|
||||||
| any[]
|
| any[]
|
||||||
| { rows: any[]; metadata: RemoteQueryFunctionReturnPagination }
|
| { rows: any[]; metadata: RemoteQueryFunctionReturnPagination }
|
||||||
@@ -148,8 +153,8 @@ export class Query {
|
|||||||
if (Query.traceGraphQuery) {
|
if (Query.traceGraphQuery) {
|
||||||
response = await Query.traceGraphQuery(
|
response = await Query.traceGraphQuery(
|
||||||
async () =>
|
async () =>
|
||||||
this.#remoteQuery.query(normalizedQuery, undefined, options),
|
await this.#remoteQuery.query(normalizedQuery, undefined, options),
|
||||||
queryOptions
|
queryOptions as RemoteQueryInput<any>
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
response = await this.#remoteQuery.query(
|
response = await this.#remoteQuery.query(
|
||||||
@@ -167,7 +172,7 @@ export class Query {
|
|||||||
* API wrapper around the remoteQuery with backward compatibility support
|
* API wrapper around the remoteQuery with backward compatibility support
|
||||||
* @param remoteQuery
|
* @param remoteQuery
|
||||||
*/
|
*/
|
||||||
export function createQuery(remoteQuery: RemoteQuery): RemoteQueryFunction {
|
export function createQuery(remoteQuery: RemoteQuery) {
|
||||||
const query = new Query(remoteQuery)
|
const query = new Query(remoteQuery)
|
||||||
|
|
||||||
function backwardCompatibleQuery(...args: any[]) {
|
function backwardCompatibleQuery(...args: any[]) {
|
||||||
@@ -177,5 +182,5 @@ export function createQuery(remoteQuery: RemoteQuery): RemoteQueryFunction {
|
|||||||
backwardCompatibleQuery.graph = query.graph.bind(query)
|
backwardCompatibleQuery.graph = query.graph.bind(query)
|
||||||
backwardCompatibleQuery.gql = query.gql.bind(query)
|
backwardCompatibleQuery.gql = query.gql.bind(query)
|
||||||
|
|
||||||
return backwardCompatibleQuery
|
return backwardCompatibleQuery as Omit<RemoteQueryFunction, symbol>
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
import {
|
||||||
|
RemoteQueryEntryPoints,
|
||||||
|
RemoteQueryFilters,
|
||||||
|
RemoteQueryGraph,
|
||||||
|
RemoteQueryObjectConfig,
|
||||||
|
} from "@medusajs/types"
|
||||||
|
import { QueryContext, QueryFilter, isObject } from "@medusajs/utils"
|
||||||
|
|
||||||
|
const FIELDS = "__fields"
|
||||||
|
const ARGUMENTS = "__args"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert a specific API configuration to a remote query object
|
||||||
|
*
|
||||||
|
* @param config
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const remoteQueryObject = toRemoteQuery({
|
||||||
|
* entity: "product",
|
||||||
|
* fields,
|
||||||
|
* filters: { variants: QueryFilter({ sku: "abc" }) },
|
||||||
|
* context: {
|
||||||
|
* variants: { calculated_price: QueryContext({ region_id: "reg_123" }) }
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* console.log(remoteQueryObject);
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function toRemoteQuery<const TEntity extends string>(config: {
|
||||||
|
entity: TEntity | keyof RemoteQueryEntryPoints
|
||||||
|
fields: RemoteQueryObjectConfig<TEntity>["fields"]
|
||||||
|
filters?: RemoteQueryFilters<TEntity>
|
||||||
|
pagination?: {
|
||||||
|
skip?: number
|
||||||
|
take?: number
|
||||||
|
}
|
||||||
|
context?: Record<string, any>
|
||||||
|
}): RemoteQueryGraph<TEntity> {
|
||||||
|
const { entity, fields = [], filters = {}, context = {} } = config
|
||||||
|
|
||||||
|
const joinerQuery: Record<string, any> = {
|
||||||
|
[entity]: {
|
||||||
|
__fields: [],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
function processNestedObjects(
|
||||||
|
target: any,
|
||||||
|
source: Record<string, any>,
|
||||||
|
topLevel = true
|
||||||
|
) {
|
||||||
|
for (const key in source) {
|
||||||
|
const src = topLevel ? source : source[key]
|
||||||
|
|
||||||
|
if (!isObject(src)) {
|
||||||
|
target[key] = src
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QueryContext.isQueryContext(src) || QueryFilter.isQueryFilter(src)) {
|
||||||
|
const normalizedFilters = { ...src } as any
|
||||||
|
delete normalizedFilters.__type
|
||||||
|
|
||||||
|
const prop = QueryFilter.isQueryFilter(src) ? "filters" : "context"
|
||||||
|
|
||||||
|
if (topLevel) {
|
||||||
|
target[ARGUMENTS] ??= {}
|
||||||
|
target[ARGUMENTS][prop] = normalizedFilters
|
||||||
|
} else {
|
||||||
|
target[key] ??= {}
|
||||||
|
target[key][ARGUMENTS] ??= {}
|
||||||
|
target[key][ARGUMENTS][prop] = normalizedFilters
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!topLevel) {
|
||||||
|
target[key] ??= {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextTarget = topLevel ? target : target[key]
|
||||||
|
processNestedObjects(nextTarget, src, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process filters and context recursively
|
||||||
|
processNestedObjects(joinerQuery[entity], filters)
|
||||||
|
processNestedObjects(joinerQuery[entity], context)
|
||||||
|
|
||||||
|
for (const field of fields) {
|
||||||
|
const fieldAsString = field as string
|
||||||
|
if (!fieldAsString.includes(".")) {
|
||||||
|
joinerQuery[entity][FIELDS].push(field)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const fieldSegments = fieldAsString.split(".")
|
||||||
|
const fieldProperty = fieldSegments.pop()
|
||||||
|
|
||||||
|
let combinedPath = ""
|
||||||
|
const deepConfigRef = fieldSegments.reduce((acc, curr) => {
|
||||||
|
combinedPath = combinedPath ? combinedPath + "." + curr : curr
|
||||||
|
acc[curr] ??= {}
|
||||||
|
return acc[curr]
|
||||||
|
}, joinerQuery[entity])
|
||||||
|
|
||||||
|
deepConfigRef[FIELDS] ??= []
|
||||||
|
deepConfigRef[FIELDS].push(fieldProperty)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.pagination) {
|
||||||
|
joinerQuery[entity][ARGUMENTS] ??= {}
|
||||||
|
joinerQuery[entity][ARGUMENTS] = {
|
||||||
|
...joinerQuery[entity][ARGUMENTS],
|
||||||
|
...config.pagination,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return joinerQuery as RemoteQueryGraph<TEntity>
|
||||||
|
}
|
||||||
@@ -78,8 +78,11 @@ export async function gqlSchemaToTypes({
|
|||||||
documents: [],
|
documents: [],
|
||||||
config: {
|
config: {
|
||||||
scalars: {
|
scalars: {
|
||||||
DateTime: { output: "Date | string" },
|
DateTime: { input: "Date | string", output: "Date | string" },
|
||||||
JSON: { output: "Record<any, unknown>" },
|
JSON: {
|
||||||
|
input: "Record<string, unknown>",
|
||||||
|
output: "Record<string, unknown>",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
filename: "",
|
filename: "",
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export function toRemoteJoinerQuery(
|
|||||||
|
|
||||||
const canExpand =
|
const canExpand =
|
||||||
typeof value === "object" &&
|
typeof value === "object" &&
|
||||||
!["fields", "__args", "__directives"].includes(key)
|
!["fields", "__fields", "__args", "__directives"].includes(key) // TODO: deprecate "fields"
|
||||||
|
|
||||||
if (!canExpand) {
|
if (!canExpand) {
|
||||||
continue
|
continue
|
||||||
@@ -65,8 +65,8 @@ export function toRemoteJoinerQuery(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value.fields) {
|
if (value.__fields || value.fields) {
|
||||||
reference.fields = value.fields
|
reference.fields = value.__fields ?? value.fields
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEntryPoint) {
|
if (isEntryPoint) {
|
||||||
|
|||||||
@@ -26,25 +26,23 @@ export type Scalars = {
|
|||||||
Boolean: { input: boolean; output: boolean }
|
Boolean: { input: boolean; output: boolean }
|
||||||
Int: { input: number; output: number }
|
Int: { input: number; output: number }
|
||||||
Float: { input: number; output: number }
|
Float: { input: number; output: number }
|
||||||
DateTime: {
|
DateTime: { input: Date | string; output: Date | string }
|
||||||
input: { output: "Date | string" }
|
JSON: { input: Record<string, unknown>; output: Record<string, unknown> }
|
||||||
output: { output: "Date | string" }
|
|
||||||
}
|
|
||||||
JSON: {
|
|
||||||
input: { output: "Record<any, unknown>" }
|
|
||||||
output: { output: "Record<any, unknown>" }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SimpleProduct = {
|
export type SimpleProduct = {
|
||||||
|
__typename?: "SimpleProduct"
|
||||||
id: Scalars["ID"]["output"]
|
id: Scalars["ID"]["output"]
|
||||||
handle: string
|
handle: string
|
||||||
title?: Scalars["String"]["output"]
|
title?: Scalars["String"]["output"]
|
||||||
variants?: Maybe<Array<Maybe<Pick<ProductVariant, "id">>>>
|
variants?: Maybe<Array<Maybe<Pick<ProductVariant, "id" | "__typename">>>>
|
||||||
sales_channels_link?: Array<
|
sales_channels_link?: Array<
|
||||||
Pick<LinkProductSalesChannel, "product_id" | "sales_channel_id">
|
Pick<
|
||||||
|
LinkProductSalesChannel,
|
||||||
|
"product_id" | "sales_channel_id" | "__typename"
|
||||||
|
>
|
||||||
>
|
>
|
||||||
sales_channels?: Array<Pick<SalesChannel, "id" | "name">>
|
sales_channels?: Array<Pick<SalesChannel, "id" | "name" | "__typename">>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Product = {
|
export type Product = {
|
||||||
|
|||||||
@@ -9,11 +9,13 @@ describe("ObjectToRemoteQueryFields", () => {
|
|||||||
description: string
|
description: string
|
||||||
date: Date
|
date: Date
|
||||||
variants: {
|
variants: {
|
||||||
|
__typename: string
|
||||||
id: string
|
id: string
|
||||||
sku: string
|
sku: string
|
||||||
title: string
|
title: string
|
||||||
}[]
|
}[]
|
||||||
sales_channel: {
|
sales_channel: {
|
||||||
|
__typename: string
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
value: string
|
value: string
|
||||||
@@ -51,12 +53,14 @@ describe("ObjectToRemoteQueryFields", () => {
|
|||||||
date: Date
|
date: Date
|
||||||
variants: Maybe<
|
variants: Maybe<
|
||||||
Maybe<{
|
Maybe<{
|
||||||
|
__typename: string
|
||||||
id: string
|
id: string
|
||||||
sku: string
|
sku: string
|
||||||
title: string
|
title: string
|
||||||
}>[]
|
}>[]
|
||||||
>
|
>
|
||||||
sales_channel?: Maybe<{
|
sales_channel?: Maybe<{
|
||||||
|
__typename: string
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
value: string
|
value: string
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ describe("Query", () => {
|
|||||||
it("should infer return type of a known entry", async () => {
|
it("should infer return type of a known entry", async () => {
|
||||||
const graph = (() => {}) as unknown as QueryGraphFunction
|
const graph = (() => {}) as unknown as QueryGraphFunction
|
||||||
const result = await graph({
|
const result = await graph({
|
||||||
entryPoint: "product",
|
entity: "product",
|
||||||
fields: ["handle", "id"],
|
fields: ["handle", "id"],
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ describe("Query", () => {
|
|||||||
it("should infer as any for an known entry", async () => {
|
it("should infer as any for an known entry", async () => {
|
||||||
const graph = (() => {}) as unknown as QueryGraphFunction
|
const graph = (() => {}) as unknown as QueryGraphFunction
|
||||||
const result = await graph({
|
const result = await graph({
|
||||||
entryPoint: "foo",
|
entity: "foo",
|
||||||
fields: ["handle", "id"],
|
fields: ["handle", "id"],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,18 @@ import { MedusaContainer } from "../common"
|
|||||||
import { RepositoryService } from "../dal"
|
import { RepositoryService } from "../dal"
|
||||||
import { Logger } from "../logger"
|
import { Logger } from "../logger"
|
||||||
import {
|
import {
|
||||||
|
RemoteQueryGraph,
|
||||||
|
RemoteQueryInput,
|
||||||
RemoteQueryObjectConfig,
|
RemoteQueryObjectConfig,
|
||||||
RemoteQueryObjectFromStringResult,
|
RemoteQueryObjectFromStringResult,
|
||||||
} from "./remote-query-object-from-string"
|
} from "./remote-query-object-from-string"
|
||||||
|
|
||||||
export { RemoteQueryObjectConfig, RemoteQueryObjectFromStringResult }
|
export {
|
||||||
|
RemoteQueryGraph,
|
||||||
|
RemoteQueryInput,
|
||||||
|
RemoteQueryObjectConfig,
|
||||||
|
RemoteQueryObjectFromStringResult,
|
||||||
|
}
|
||||||
|
|
||||||
export type Constructor<T> = new (...args: any[]) => T | (new () => T)
|
export type Constructor<T> = new (...args: any[]) => T | (new () => T)
|
||||||
|
|
||||||
@@ -17,6 +24,8 @@ export * from "./medusa-internal-service"
|
|||||||
export * from "./module-provider"
|
export * from "./module-provider"
|
||||||
export * from "./remote-query"
|
export * from "./remote-query"
|
||||||
export * from "./remote-query-entry-points"
|
export * from "./remote-query-entry-points"
|
||||||
|
export * from "./to-remote-query"
|
||||||
|
export * from "./query-filter"
|
||||||
|
|
||||||
export type LogLevel =
|
export type LogLevel =
|
||||||
| "query"
|
| "query"
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
type Marker = [never, 0, 1, 2, 3, 4]
|
type Marker = [never, 0, 1, 2, 3, 4]
|
||||||
|
|
||||||
type ExcludedProps = ["__typename"]
|
type ExcludedProps = "__typename"
|
||||||
type SpecialNonRelationProps = ["metadata"]
|
|
||||||
type RawBigNumberPrefix = "raw_"
|
type RawBigNumberPrefix = "raw_"
|
||||||
|
|
||||||
type ExpandStarSelector<
|
type ExpandStarSelector<
|
||||||
@@ -26,12 +25,9 @@ export type ObjectToRemoteQueryFields<
|
|||||||
? {
|
? {
|
||||||
[K in keyof T]: K extends // handle big number
|
[K in keyof T]: K extends // handle big number
|
||||||
`${RawBigNumberPrefix}${string}`
|
`${RawBigNumberPrefix}${string}`
|
||||||
? Exclude<K, symbol>
|
|
||||||
: // handle metadata
|
|
||||||
K extends SpecialNonRelationProps[number]
|
|
||||||
? Exclude<K, symbol>
|
? Exclude<K, symbol>
|
||||||
: // Special props that should be excluded
|
: // Special props that should be excluded
|
||||||
K extends ExcludedProps[number]
|
K extends ExcludedProps
|
||||||
? never
|
? never
|
||||||
: // Prevent recursive reference to itself
|
: // Prevent recursive reference to itself
|
||||||
K extends Exclusion[number]
|
K extends Exclusion[number]
|
||||||
@@ -39,21 +35,25 @@ export type ObjectToRemoteQueryFields<
|
|||||||
: TypeOnly<T[K]> extends Array<infer R>
|
: TypeOnly<T[K]> extends Array<infer R>
|
||||||
? TypeOnly<R> extends Date
|
? TypeOnly<R> extends Date
|
||||||
? Exclude<K, symbol>
|
? Exclude<K, symbol>
|
||||||
: TypeOnly<R> extends object
|
: TypeOnly<R> extends { __typename: any }
|
||||||
? `${Exclude<K, symbol>}.${ExpandStarSelector<
|
? `${Exclude<K, symbol>}.${ExpandStarSelector<
|
||||||
TypeOnly<R>,
|
TypeOnly<R>,
|
||||||
Marker[Depth],
|
Marker[Depth],
|
||||||
[K & string, ...Exclusion]
|
[K & string, ...Exclusion]
|
||||||
>}`
|
>}`
|
||||||
|
: TypeOnly<R> extends object
|
||||||
|
? Exclude<K, symbol>
|
||||||
: never
|
: never
|
||||||
: TypeOnly<T[K]> extends Date
|
: TypeOnly<T[K]> extends Date
|
||||||
? Exclude<K, symbol>
|
? Exclude<K, symbol>
|
||||||
: TypeOnly<T[K]> extends object
|
: TypeOnly<T[K]> extends { __typename: any }
|
||||||
? `${Exclude<K, symbol>}.${ExpandStarSelector<
|
? `${Exclude<K, symbol>}.${ExpandStarSelector<
|
||||||
TypeOnly<T[K]>,
|
TypeOnly<T[K]>,
|
||||||
Marker[Depth],
|
Marker[Depth],
|
||||||
[K & string, ...Exclusion]
|
[K & string, ...Exclusion]
|
||||||
>}`
|
>}`
|
||||||
|
: T[K] extends object
|
||||||
|
? Exclude<K, symbol>
|
||||||
: Exclude<K, symbol>
|
: Exclude<K, symbol>
|
||||||
}[keyof T]
|
}[keyof T]
|
||||||
: never
|
: never
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { RemoteQueryFilters } from "./to-remote-query"
|
||||||
|
|
||||||
|
export type QueryFilterType = {
|
||||||
|
<TEntry extends string>(
|
||||||
|
query: RemoteQueryFilters<TEntry>
|
||||||
|
): RemoteQueryFilters<TEntry> & { __type: "QueryFilter" }
|
||||||
|
|
||||||
|
isQueryFilter: (obj: any) => boolean
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { RemoteQueryEntryPoints } from "./remote-query-entry-points"
|
|
||||||
import { ObjectToRemoteQueryFields } from "./object-to-remote-query-fields"
|
import { ObjectToRemoteQueryFields } from "./object-to-remote-query-fields"
|
||||||
|
import { RemoteQueryEntryPoints } from "./remote-query-entry-points"
|
||||||
|
import { RemoteQueryFilters } from "./to-remote-query"
|
||||||
|
|
||||||
export type RemoteQueryObjectConfig<TEntry extends string> = {
|
export type RemoteQueryObjectConfig<TEntry extends string> = {
|
||||||
// service: string This property is still supported under the hood but part of the type due to types missmatch towards fields
|
// service: string This property is still supported under the hood but part of the type due to types missmatch towards fields
|
||||||
@@ -20,3 +21,25 @@ export type RemoteQueryObjectFromStringResult<
|
|||||||
__TConfig: TConfig
|
__TConfig: TConfig
|
||||||
__value: object
|
__value: object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type RemoteQueryInput<TEntry extends string> = {
|
||||||
|
// service: string This property is still supported under the hood but part of the type due to types missmatch towards fields
|
||||||
|
entity: TEntry | keyof RemoteQueryEntryPoints
|
||||||
|
fields: ObjectToRemoteQueryFields<
|
||||||
|
RemoteQueryEntryPoints[TEntry & keyof RemoteQueryEntryPoints]
|
||||||
|
> extends never
|
||||||
|
? string[]
|
||||||
|
: ObjectToRemoteQueryFields<
|
||||||
|
RemoteQueryEntryPoints[TEntry & keyof RemoteQueryEntryPoints]
|
||||||
|
>[]
|
||||||
|
pagination?: {
|
||||||
|
skip: number
|
||||||
|
take?: number
|
||||||
|
}
|
||||||
|
filters?: RemoteQueryFilters<TEntry>
|
||||||
|
context?: any
|
||||||
|
}
|
||||||
|
|
||||||
|
export type RemoteQueryGraph<TEntry extends string> = {
|
||||||
|
__TConfig: RemoteQueryObjectConfig<TEntry>
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ import { Prettify } from "../common"
|
|||||||
import { RemoteJoinerOptions, RemoteJoinerQuery } from "../joiner"
|
import { RemoteJoinerOptions, RemoteJoinerQuery } from "../joiner"
|
||||||
import { RemoteQueryEntryPoints } from "./remote-query-entry-points"
|
import { RemoteQueryEntryPoints } from "./remote-query-entry-points"
|
||||||
import {
|
import {
|
||||||
|
RemoteQueryInput,
|
||||||
RemoteQueryObjectConfig,
|
RemoteQueryObjectConfig,
|
||||||
RemoteQueryObjectFromStringResult,
|
RemoteQueryObjectFromStringResult,
|
||||||
} from "./remote-query-object-from-string"
|
} from "./remote-query-object-from-string"
|
||||||
@@ -32,7 +33,7 @@ export type GraphResultSet<TEntry extends string> = {
|
|||||||
*/
|
*/
|
||||||
export type QueryGraphFunction = {
|
export type QueryGraphFunction = {
|
||||||
<const TEntry extends string>(
|
<const TEntry extends string>(
|
||||||
queryConfig: RemoteQueryObjectConfig<TEntry>,
|
queryConfig: RemoteQueryInput<TEntry>,
|
||||||
options?: RemoteJoinerOptions
|
options?: RemoteJoinerOptions
|
||||||
): Promise<Prettify<GraphResultSet<TEntry>>>
|
): Promise<Prettify<GraphResultSet<TEntry>>>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
import { Prettify } from "../common"
|
||||||
|
import { OperatorMap } from "../dal"
|
||||||
|
import { RemoteQueryEntryPoints } from "./remote-query-entry-points"
|
||||||
|
|
||||||
|
type ExcludedProps = "__typename"
|
||||||
|
type Depth = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||||
|
type CleanupObject<T> = Prettify<Omit<Exclude<T, symbol>, ExcludedProps>>
|
||||||
|
type OmitNever<T extends object> = {
|
||||||
|
[K in keyof T as T[K] extends never ? never : K]: T[K]
|
||||||
|
}
|
||||||
|
type TypeOnly<T> = Required<Exclude<T, null | undefined>>
|
||||||
|
|
||||||
|
type ExtractFiltersOperators<
|
||||||
|
MaybeT,
|
||||||
|
Lim extends number = Depth[2],
|
||||||
|
Exclusion extends string[] = [],
|
||||||
|
T = TypeOnly<MaybeT>
|
||||||
|
> = {
|
||||||
|
[Key in keyof T]?: Key extends Exclusion[number]
|
||||||
|
? never
|
||||||
|
: Key extends ExcludedProps
|
||||||
|
? never
|
||||||
|
: T[Key] extends string | number | boolean | Date
|
||||||
|
? T[Key] | OperatorMap<T[Key] | T[Key][]>
|
||||||
|
: T[Key] extends Array<infer R>
|
||||||
|
? TypeOnly<R> extends { __typename: any }
|
||||||
|
? RemoteQueryFilters<
|
||||||
|
Key & string,
|
||||||
|
T,
|
||||||
|
[Key & string, ...Exclusion],
|
||||||
|
Depth[Lim]
|
||||||
|
>
|
||||||
|
: R extends object
|
||||||
|
? CleanupObject<R>
|
||||||
|
: never
|
||||||
|
: T[Key] extends { __typename: any }
|
||||||
|
? RemoteQueryFilters<
|
||||||
|
Key & string,
|
||||||
|
T[Key],
|
||||||
|
[Key & string, ...Exclusion],
|
||||||
|
Depth[Lim]
|
||||||
|
>
|
||||||
|
: T[Key] extends object
|
||||||
|
? CleanupObject<T[Key]>
|
||||||
|
: never
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract all available filters from a remote entry point deeply
|
||||||
|
*/
|
||||||
|
export type RemoteQueryFilters<
|
||||||
|
TEntry extends string,
|
||||||
|
RemoteQueryEntryPointsLevel = RemoteQueryEntryPoints,
|
||||||
|
Exclusion extends string[] = [],
|
||||||
|
Lim extends number = Depth[3]
|
||||||
|
> = Lim extends number
|
||||||
|
? TEntry extends keyof RemoteQueryEntryPointsLevel
|
||||||
|
? TypeOnly<RemoteQueryEntryPointsLevel[TEntry]> extends Array<infer V>
|
||||||
|
? Prettify<
|
||||||
|
OmitNever<ExtractFiltersOperators<V, Lim, [TEntry, ...Exclusion]>>
|
||||||
|
>
|
||||||
|
: Prettify<
|
||||||
|
OmitNever<
|
||||||
|
ExtractFiltersOperators<
|
||||||
|
RemoteQueryEntryPointsLevel[TEntry],
|
||||||
|
Lim,
|
||||||
|
[TEntry, ...Exclusion]
|
||||||
|
>
|
||||||
|
>
|
||||||
|
>
|
||||||
|
: Record<string, any>
|
||||||
|
: never
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -1,6 +1,7 @@
|
|||||||
export * from "./build-query"
|
export * from "./build-query"
|
||||||
export * from "./create-pg-connection"
|
export * from "./create-pg-connection"
|
||||||
export * from "./decorators"
|
export * from "./decorators"
|
||||||
|
export * from "./define-link"
|
||||||
export * from "./definition"
|
export * from "./definition"
|
||||||
export * from "./event-builder-factory"
|
export * from "./event-builder-factory"
|
||||||
export * from "./joiner-config-builder"
|
export * from "./joiner-config-builder"
|
||||||
@@ -14,4 +15,5 @@ export * from "./medusa-service"
|
|||||||
export * from "./migration-scripts"
|
export * from "./migration-scripts"
|
||||||
export * from "./mikro-orm-cli-config-builder"
|
export * from "./mikro-orm-cli-config-builder"
|
||||||
export * from "./module"
|
export * from "./module"
|
||||||
export * from "./define-link"
|
export * from "./query-context"
|
||||||
|
export * from "./query-filter"
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
type QueryContextType = {
|
||||||
|
(query: Record<string, unknown>): Record<string, unknown>
|
||||||
|
isQueryContext: (obj: any) => boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const __type = "QueryContext"
|
||||||
|
|
||||||
|
function QueryContextFn(query: Record<string, unknown>) {
|
||||||
|
return {
|
||||||
|
...query,
|
||||||
|
__type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryContextFn.isQueryContext = (obj: any) => {
|
||||||
|
return obj.__type === __type
|
||||||
|
}
|
||||||
|
|
||||||
|
export const QueryContext: QueryContextType = QueryContextFn
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { RemoteQueryFilters } from "@medusajs/types"
|
||||||
|
|
||||||
|
const __type = "QueryFilter"
|
||||||
|
|
||||||
|
export function QueryFilterFn<TEntry extends string>(
|
||||||
|
query: RemoteQueryFilters<TEntry>
|
||||||
|
): RemoteQueryFilters<TEntry> & { __type: "QueryFilter" } {
|
||||||
|
return {
|
||||||
|
...query,
|
||||||
|
__type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryFilterFn.isQueryFilter = (obj: any) => {
|
||||||
|
return obj.__type === __type
|
||||||
|
}
|
||||||
|
|
||||||
|
export const QueryFilter = QueryFilterFn
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
import { snakeCase } from "lodash"
|
import { Query, RoutesLoader, Tracer } from "@medusajs/framework"
|
||||||
import { NodeSDK } from "@opentelemetry/sdk-node"
|
|
||||||
import { Resource } from "@opentelemetry/resources"
|
|
||||||
import { SpanStatusCode } from "@opentelemetry/api"
|
import { SpanStatusCode } from "@opentelemetry/api"
|
||||||
import { RoutesLoader, Tracer, Query } from "@medusajs/framework"
|
|
||||||
import {
|
|
||||||
type SpanExporter,
|
|
||||||
SimpleSpanProcessor,
|
|
||||||
} from "@opentelemetry/sdk-trace-node"
|
|
||||||
import { PgInstrumentation } from "@opentelemetry/instrumentation-pg"
|
|
||||||
import type { Instrumentation } from "@opentelemetry/instrumentation"
|
import type { Instrumentation } from "@opentelemetry/instrumentation"
|
||||||
|
import { PgInstrumentation } from "@opentelemetry/instrumentation-pg"
|
||||||
|
import { Resource } from "@opentelemetry/resources"
|
||||||
|
import { NodeSDK } from "@opentelemetry/sdk-node"
|
||||||
|
import {
|
||||||
|
SimpleSpanProcessor,
|
||||||
|
type SpanExporter,
|
||||||
|
} from "@opentelemetry/sdk-trace-node"
|
||||||
|
import { snakeCase } from "lodash"
|
||||||
|
|
||||||
import start from "../commands/start"
|
import start from "../commands/start"
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ export function instrumentRemoteQuery() {
|
|||||||
|
|
||||||
Query.instrument.graphQuery(async function (queryFn, queryOptions) {
|
Query.instrument.graphQuery(async function (queryFn, queryOptions) {
|
||||||
return await QueryTracer.trace(
|
return await QueryTracer.trace(
|
||||||
`query.graph: ${queryOptions.entryPoint}`,
|
`query.graph: ${queryOptions.entity}`,
|
||||||
async (span) => {
|
async (span) => {
|
||||||
span.setAttributes({
|
span.setAttributes({
|
||||||
"query.fields": queryOptions.fields,
|
"query.fields": queryOptions.fields,
|
||||||
|
|||||||
Reference in new issue
Block a user