feat: Application types generation from project GQL schema's (#8995)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { IPricingModuleService } from "@medusajs/types"
|
||||
import { MedusaError, ModuleRegistrationName } from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
export interface GetVariantPriceSetsStepInput {
|
||||
variantIds: string[]
|
||||
@@ -24,21 +24,13 @@ export const getVariantPriceSetsStep = createStep(
|
||||
|
||||
const remoteQuery = container.resolve("remoteQuery")
|
||||
|
||||
const variantPriceSets = await remoteQuery(
|
||||
{
|
||||
variant: {
|
||||
fields: ["id"],
|
||||
price_set: {
|
||||
fields: ["id"],
|
||||
},
|
||||
},
|
||||
const variantPriceSets = await remoteQuery({
|
||||
entryPoint: "variant",
|
||||
fields: ["id", "price_set.id"],
|
||||
variables: {
|
||||
id: data.variantIds,
|
||||
},
|
||||
{
|
||||
variant: {
|
||||
id: data.variantIds,
|
||||
},
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
const notFound: string[] = []
|
||||
const priceSetIds: string[] = []
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import { CartWorkflowDTO } from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
Modules,
|
||||
isObject,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { ContainerRegistrationKeys, isObject, Modules } from "@medusajs/utils"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
export interface RetrieveCartWithLinksStepInput {
|
||||
cart_or_cart_id: string | CartWorkflowDTO
|
||||
@@ -29,12 +24,17 @@ export const retrieveCartWithLinksStep = createStep(
|
||||
const remoteQuery = container.resolve(
|
||||
ContainerRegistrationKeys.REMOTE_QUERY
|
||||
)
|
||||
const query = remoteQueryObjectFromString({
|
||||
const query = {
|
||||
entryPoint: Modules.CART,
|
||||
fields,
|
||||
})
|
||||
variables: {
|
||||
cart: {
|
||||
id,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const [cart] = await remoteQuery(query, { cart: { id } })
|
||||
const [cart] = await remoteQuery(query)
|
||||
|
||||
return new StepResponse(cart)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
Modules,
|
||||
PromotionActions,
|
||||
} from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
export interface UpdateCartPromotionStepInput {
|
||||
id: string
|
||||
@@ -33,9 +33,10 @@ export const updateCartPromotionsStep = createStep(
|
||||
)
|
||||
|
||||
const existingCartPromotionLinks = await remoteQuery({
|
||||
cart_promotion: {
|
||||
__args: { cart_id: [id] },
|
||||
fields: ["cart_id", "promotion_id"],
|
||||
entryPoint: "cart_promotion",
|
||||
fields: ["cart_id", "promotion_id"],
|
||||
variables: {
|
||||
cart_id: [id],
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
/**
|
||||
* The remote query's details.
|
||||
@@ -164,7 +164,7 @@ export const useRemoteQueryStep = createStep(
|
||||
: undefined,
|
||||
}
|
||||
|
||||
const entities = await query(queryObject, undefined, config)
|
||||
const entities = await query(queryObjectConfig, config)
|
||||
const result = list ? entities : entities[0]
|
||||
|
||||
return new StepResponse(result)
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
LINKS,
|
||||
Modules,
|
||||
promiseAll,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
export type SetShippingOptionsPriceSetsStepInput = {
|
||||
@@ -28,16 +27,14 @@ async function getCurrentShippingOptionPriceSetsLinks(
|
||||
shippingOptionIds: string[],
|
||||
{ remoteQuery }: { remoteQuery: RemoteQueryFunction }
|
||||
): Promise<LinkItems> {
|
||||
const query = remoteQueryObjectFromString({
|
||||
const shippingOptionPriceSetLinks = (await remoteQuery({
|
||||
service: LINKS.ShippingOptionPriceSet,
|
||||
variables: {
|
||||
filters: { shipping_option_id: shippingOptionIds },
|
||||
take: null,
|
||||
},
|
||||
fields: ["shipping_option_id", "price_set_id"],
|
||||
})
|
||||
|
||||
const shippingOptionPriceSetLinks = (await remoteQuery(query)) as {
|
||||
} as any)) as {
|
||||
shipping_option_id: string
|
||||
price_set_id: string
|
||||
}[]
|
||||
|
||||
@@ -10,12 +10,11 @@ import {
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
isDefined,
|
||||
LINKS,
|
||||
ModuleRegistrationName,
|
||||
isDefined,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
interface PriceRegionId {
|
||||
region_id: string
|
||||
@@ -33,16 +32,14 @@ async function getCurrentShippingOptionPrices(
|
||||
): Promise<
|
||||
{ shipping_option_id: string; price_set_id: string; prices: PriceDTO[] }[]
|
||||
> {
|
||||
const query = remoteQueryObjectFromString({
|
||||
const shippingOptionPrices = (await remoteQuery({
|
||||
service: LINKS.ShippingOptionPriceSet,
|
||||
variables: {
|
||||
filters: { shipping_option_id: shippingOptionIds },
|
||||
take: null,
|
||||
},
|
||||
fields: ["shipping_option_id", "price_set_id", "price_set.prices.*"],
|
||||
})
|
||||
|
||||
const shippingOptionPrices = (await remoteQuery(query)) as {
|
||||
} as any)) as {
|
||||
shipping_option_id: string
|
||||
price_set_id: string
|
||||
price_set: PriceSetDTO
|
||||
|
||||
@@ -3,9 +3,8 @@ import {
|
||||
ContainerRegistrationKeys,
|
||||
MedusaError,
|
||||
ModuleRegistrationName,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
export type FulfillmentProviderValidationWorkflowInput = {
|
||||
id?: string
|
||||
@@ -21,7 +20,10 @@ export const validateFulfillmentProvidersStepId =
|
||||
*/
|
||||
export const validateFulfillmentProvidersStep = createStep(
|
||||
validateFulfillmentProvidersStepId,
|
||||
async (input: FulfillmentProviderValidationWorkflowInput[], { container }) => {
|
||||
async (
|
||||
input: FulfillmentProviderValidationWorkflowInput[],
|
||||
{ container }
|
||||
) => {
|
||||
const dataToValidate: {
|
||||
service_zone_id: string
|
||||
provider_id: string
|
||||
@@ -83,7 +85,7 @@ export const validateFulfillmentProvidersStep = createStep(
|
||||
)
|
||||
}
|
||||
|
||||
const serviceZoneQuery = remoteQueryObjectFromString({
|
||||
const serviceZones = await remoteQuery({
|
||||
entryPoint: "service_zone",
|
||||
fields: ["id", "fulfillment_set.locations.fulfillment_providers.id"],
|
||||
variables: {
|
||||
@@ -91,8 +93,6 @@ export const validateFulfillmentProvidersStep = createStep(
|
||||
},
|
||||
})
|
||||
|
||||
const serviceZones = await remoteQuery(serviceZoneQuery)
|
||||
|
||||
const serviceZonesMap = new Map<
|
||||
string,
|
||||
ServiceZoneDTO & {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import {
|
||||
arrayDifference,
|
||||
ContainerRegistrationKeys,
|
||||
MedusaError,
|
||||
arrayDifference,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
@@ -17,13 +16,11 @@ export const validateInventoryItems = createStep(
|
||||
ContainerRegistrationKeys.REMOTE_QUERY
|
||||
)
|
||||
|
||||
const query = remoteQueryObjectFromString({
|
||||
const items = await remoteQuery({
|
||||
entryPoint: "inventory_item",
|
||||
variables: { id },
|
||||
fields: ["id"],
|
||||
})
|
||||
|
||||
const items = await remoteQuery(query)
|
||||
const diff = arrayDifference(
|
||||
id,
|
||||
items.map(({ id }) => id)
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import {
|
||||
arrayDifference,
|
||||
ContainerRegistrationKeys,
|
||||
MedusaError,
|
||||
arrayDifference,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
import { InventoryTypes } from "@medusajs/types"
|
||||
@@ -19,7 +18,7 @@ export const validateInventoryLocationsStep = createStep(
|
||||
ContainerRegistrationKeys.REMOTE_QUERY
|
||||
)
|
||||
|
||||
const locationQuery = remoteQueryObjectFromString({
|
||||
const stockLocations = await remoteQuery({
|
||||
entryPoint: "stock_location",
|
||||
variables: {
|
||||
id: data.map((d) => d.location_id),
|
||||
@@ -27,8 +26,6 @@ export const validateInventoryLocationsStep = createStep(
|
||||
fields: ["id"],
|
||||
})
|
||||
|
||||
const stockLocations = await remoteQuery(locationQuery)
|
||||
|
||||
const diff = arrayDifference(
|
||||
data.map((d) => d.location_id),
|
||||
stockLocations.map((l) => l.id)
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
MedusaError,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { ContainerRegistrationKeys, MedusaError } from "@medusajs/utils"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
export const validateVariantPriceLinksStepId = "validate-variant-price-links"
|
||||
/**
|
||||
@@ -28,13 +24,11 @@ export const validateVariantPriceLinksStep = createStep(
|
||||
.filter(Boolean)
|
||||
.flat(1)
|
||||
|
||||
const variantPricingLinkQuery = remoteQueryObjectFromString({
|
||||
const links = await remoteQuery({
|
||||
entryPoint: "product_variant_price_set",
|
||||
fields: ["variant_id", "price_set_id"],
|
||||
variables: { variant_id: variantIds, take: null },
|
||||
})
|
||||
|
||||
const links = await remoteQuery(variantPricingLinkQuery)
|
||||
const variantPriceSetMap: Record<string, string> = {}
|
||||
|
||||
for (const link of links) {
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { FilterableProductProps, RemoteQueryFunction } from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { ContainerRegistrationKeys } from "@medusajs/utils"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
export type GetAllProductsStepInput = {
|
||||
@@ -27,7 +24,7 @@ export const getAllProductsStep = createStep(
|
||||
|
||||
// We intentionally fetch the products serially here to avoid putting too much load on the DB
|
||||
while (true) {
|
||||
const remoteQueryObject = remoteQueryObjectFromString({
|
||||
const { rows: products } = await remoteQuery({
|
||||
entryPoint: "product",
|
||||
variables: {
|
||||
filters: data.filter,
|
||||
@@ -36,8 +33,6 @@ export const getAllProductsStep = createStep(
|
||||
},
|
||||
fields: data.select,
|
||||
})
|
||||
|
||||
const { rows: products } = await remoteQuery(remoteQueryObject)
|
||||
allProducts.push(...products)
|
||||
|
||||
if (products.length < pageSize) {
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import { RemoteLink } from "@medusajs/modules-sdk"
|
||||
import { IPaymentModuleService, RemoteQueryFunction } from "@medusajs/types"
|
||||
import {
|
||||
arrayDifference,
|
||||
ContainerRegistrationKeys,
|
||||
LINKS,
|
||||
MedusaError,
|
||||
ModuleRegistrationName,
|
||||
Modules,
|
||||
arrayDifference,
|
||||
promiseAll,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
import { createStep, StepResponse } from "@medusajs/workflows-sdk"
|
||||
|
||||
export interface SetRegionsPaymentProvidersStepInput {
|
||||
input: {
|
||||
@@ -64,16 +63,14 @@ async function getCurrentRegionPaymentProvidersLinks(
|
||||
[Modules.PAYMENT]: { payment_provider_id: string }
|
||||
}[]
|
||||
> {
|
||||
const query = remoteQueryObjectFromString({
|
||||
const regionProviderLinks = (await remoteQuery({
|
||||
service: LINKS.RegionPaymentProvider,
|
||||
variables: {
|
||||
filters: { region_id: regionIds },
|
||||
take: null,
|
||||
},
|
||||
fields: ["region_id", "payment_provider_id"],
|
||||
})
|
||||
|
||||
const regionProviderLinks = (await remoteQuery(query)) as {
|
||||
} as any)) as {
|
||||
region_id: string
|
||||
payment_provider_id: string
|
||||
}[]
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
"typescript": "^5.1.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@graphql-codegen/cli": "^5.0.2",
|
||||
"@graphql-codegen/typescript": "^4.0.9",
|
||||
"@graphql-tools/merge": "^9.0.0",
|
||||
"@graphql-tools/schema": "^10.0.0",
|
||||
"@medusajs/orchestration": "^0.5.7",
|
||||
|
||||
@@ -5,3 +5,4 @@ export * from "./medusa-module"
|
||||
export * from "./remote-link"
|
||||
export * from "./remote-query"
|
||||
export * from "./types"
|
||||
export { gqlSchemaToTypes } from "./utils"
|
||||
|
||||
@@ -17,20 +17,24 @@ import {
|
||||
RemoteJoinerOptions,
|
||||
RemoteJoinerQuery,
|
||||
RemoteQueryFunction,
|
||||
RemoteQueryObjectConfig,
|
||||
RemoteQueryObjectFromStringResult,
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
createMedusaContainer,
|
||||
isObject,
|
||||
isString,
|
||||
MedusaError,
|
||||
ModuleRegistrationName,
|
||||
Modules,
|
||||
ModulesSdkUtils,
|
||||
createMedusaContainer,
|
||||
isObject,
|
||||
isString,
|
||||
promiseAll,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import type { Knex } from "@mikro-orm/knex"
|
||||
import { asValue } from "awilix"
|
||||
import { GraphQLSchema } from "graphql/type"
|
||||
import { MODULE_PACKAGE_NAMES } from "./definitions"
|
||||
import {
|
||||
MedusaModule,
|
||||
@@ -227,6 +231,7 @@ export type MedusaAppOutput = {
|
||||
link: RemoteLink | undefined
|
||||
query: RemoteQueryFunction
|
||||
entitiesMap?: Record<string, any>
|
||||
gqlSchema?: GraphQLSchema
|
||||
notFound?: Record<string, Record<string, string>>
|
||||
runMigrations: RunMigrationFn
|
||||
revertMigrations: RevertMigrationFn
|
||||
@@ -352,15 +357,17 @@ async function MedusaApp_({
|
||||
)
|
||||
|
||||
if (loaderOnly) {
|
||||
async function query(...args: Parameters<RemoteQueryFunction>) {
|
||||
throw new Error("Querying not allowed in loaderOnly mode")
|
||||
}
|
||||
|
||||
return {
|
||||
onApplicationShutdown,
|
||||
onApplicationPrepareShutdown,
|
||||
onApplicationStart,
|
||||
modules: allModules,
|
||||
link: undefined,
|
||||
query: async () => {
|
||||
throw new Error("Querying not allowed in loaderOnly mode")
|
||||
},
|
||||
query: query as RemoteQueryFunction,
|
||||
runMigrations: async () => {
|
||||
throw new Error("Migrations not allowed in loaderOnly mode")
|
||||
},
|
||||
@@ -413,11 +420,75 @@ async function MedusaApp_({
|
||||
customRemoteFetchData: remoteFetchData,
|
||||
})
|
||||
|
||||
const query = async (
|
||||
query: string | RemoteJoinerQuery | object,
|
||||
/**
|
||||
* Query wrapper to provide specific API's and pre processing around remoteQuery.query
|
||||
* @param queryConfig
|
||||
* @param options
|
||||
*/
|
||||
async function query<const TEntry extends string>(
|
||||
queryConfig: RemoteQueryObjectConfig<TEntry>,
|
||||
options?: RemoteJoinerOptions
|
||||
): Promise<any>
|
||||
|
||||
async function query<
|
||||
const TConfig extends RemoteQueryObjectFromStringResult<any>
|
||||
>(queryConfig: TConfig, options?: RemoteJoinerOptions): Promise<any>
|
||||
|
||||
/**
|
||||
* Query wrapper to provide specific API's and pre processing around remoteQuery.query
|
||||
* @param query
|
||||
* @param options
|
||||
*/
|
||||
async function query(
|
||||
query: RemoteJoinerQuery,
|
||||
options?: RemoteJoinerOptions
|
||||
): Promise<any>
|
||||
|
||||
/**
|
||||
* Query wrapper to provide specific API's and pre processing around remoteQuery.query
|
||||
* @param query
|
||||
* @param options
|
||||
*/
|
||||
async function query<const TEntry extends string>(
|
||||
query:
|
||||
| RemoteJoinerQuery
|
||||
| RemoteQueryObjectConfig<TEntry>
|
||||
| RemoteQueryObjectFromStringResult<any>,
|
||||
options?: RemoteJoinerOptions
|
||||
) {
|
||||
if (!isObject(query)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Invalid query, expected object and received something else."
|
||||
)
|
||||
}
|
||||
|
||||
let normalizedQuery: any = query
|
||||
|
||||
if ("__value" in query) {
|
||||
normalizedQuery = query.__value
|
||||
} else if (
|
||||
"entryPoint" in normalizedQuery ||
|
||||
"service" in normalizedQuery
|
||||
) {
|
||||
normalizedQuery = remoteQueryObjectFromString(
|
||||
normalizedQuery as Parameters<typeof remoteQueryObjectFromString>[0]
|
||||
).__value
|
||||
}
|
||||
|
||||
return await remoteQuery.query(normalizedQuery, undefined, options)
|
||||
}
|
||||
/**
|
||||
* Query wrapper to provide specific GraphQL like API around remoteQuery.query
|
||||
* @param query
|
||||
* @param variables
|
||||
* @param options
|
||||
*/
|
||||
query.gql = async function (
|
||||
query: string,
|
||||
variables?: Record<string, unknown>,
|
||||
options?: RemoteJoinerOptions
|
||||
) => {
|
||||
) {
|
||||
return await remoteQuery.query(query, variables, options)
|
||||
}
|
||||
|
||||
@@ -524,6 +595,7 @@ async function MedusaApp_({
|
||||
link: remoteLink,
|
||||
query,
|
||||
entitiesMap: schema.getTypeMap(),
|
||||
gqlSchema: schema,
|
||||
notFound,
|
||||
runMigrations,
|
||||
revertMigrations,
|
||||
|
||||
@@ -145,7 +145,7 @@ export class RemoteQuery {
|
||||
return {
|
||||
skip: options.skip,
|
||||
take: options.take,
|
||||
cursor: options.cursor,
|
||||
// cursor: options.cursor, not yet supported
|
||||
// TODO: next cursor
|
||||
count,
|
||||
}
|
||||
|
||||
@@ -7,3 +7,5 @@ export enum MODULE_RESOURCE_TYPE {
|
||||
SHARED = "shared",
|
||||
ISOLATED = "isolated",
|
||||
}
|
||||
|
||||
export { GraphQLSchema } from "graphql"
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
import { MedusaModule } from "../medusa-module"
|
||||
import { FileSystem } from "@medusajs/utils"
|
||||
import { GraphQLSchema } from "graphql/type"
|
||||
import { parse, printSchema } from "graphql"
|
||||
import { codegen } from "@graphql-codegen/core"
|
||||
import * as typescriptPlugin from "@graphql-codegen/typescript"
|
||||
|
||||
function buildEntryPointsTypeMap(
|
||||
schema: string
|
||||
): { entryPoint: string; entityType: any }[] {
|
||||
// build map entry point to there type to be merged and used by the remote query
|
||||
|
||||
const joinerConfigs = MedusaModule.getAllJoinerConfigs()
|
||||
return joinerConfigs
|
||||
.flatMap((config) => {
|
||||
const aliases = Array.isArray(config.alias)
|
||||
? config.alias
|
||||
: config.alias
|
||||
? [config.alias]
|
||||
: []
|
||||
|
||||
return aliases.flatMap((alias) => {
|
||||
const names = Array.isArray(alias.name) ? alias.name : [alias.name]
|
||||
const entity = alias.args?.["entity"]
|
||||
return names.map((aliasItem) => {
|
||||
return {
|
||||
entryPoint: aliasItem,
|
||||
entityType: entity
|
||||
? schema.includes(`export type ${entity} `)
|
||||
? alias.args?.["entity"]
|
||||
: "any"
|
||||
: "any",
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
.filter(Boolean)
|
||||
}
|
||||
|
||||
async function generateTypes({
|
||||
outputDir,
|
||||
config,
|
||||
}: {
|
||||
outputDir: string
|
||||
config: Parameters<typeof codegen>[0]
|
||||
}) {
|
||||
const fileSystem = new FileSystem(outputDir)
|
||||
|
||||
let output = await codegen(config)
|
||||
const entryPoints = buildEntryPointsTypeMap(output)
|
||||
|
||||
const remoteQueryEntryPoints = `
|
||||
declare module '@medusajs/types' {
|
||||
interface RemoteQueryEntryPoints {
|
||||
${entryPoints
|
||||
.map((entry) => ` ${entry.entryPoint}: ${entry.entityType}`)
|
||||
.join("\n")}
|
||||
}
|
||||
}`
|
||||
|
||||
output += remoteQueryEntryPoints
|
||||
|
||||
await fileSystem.create("remote-query-types.d.ts", output)
|
||||
await fileSystem.create(
|
||||
"index.d.ts",
|
||||
"export * as RemoteQueryTypes from './remote-query-types'"
|
||||
)
|
||||
}
|
||||
|
||||
export async function gqlSchemaToTypes({
|
||||
schema,
|
||||
outputDir,
|
||||
}: {
|
||||
schema: GraphQLSchema
|
||||
outputDir: string
|
||||
}) {
|
||||
const config = {
|
||||
documents: [],
|
||||
config: {
|
||||
scalars: {
|
||||
DateTime: { output: "Date | string" },
|
||||
JSON: { output: "Record<any, unknown>" },
|
||||
},
|
||||
},
|
||||
filename: "",
|
||||
schema: parse(printSchema(schema as any)),
|
||||
plugins: [
|
||||
// Each plugin should be an object
|
||||
{
|
||||
typescript: {}, // Here you can pass configuration to the plugin
|
||||
},
|
||||
],
|
||||
pluginMap: {
|
||||
typescript: typescriptPlugin,
|
||||
},
|
||||
}
|
||||
|
||||
await generateTypes({ outputDir, config })
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from "./clean-graphql-schema"
|
||||
export * from "./graphql-schema-to-fields"
|
||||
export * from "./gql-schema-to-types"
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
module.exports = {
|
||||
moduleNameMapper: {},
|
||||
transform: {
|
||||
"^.+\\.[jt]s$": [
|
||||
"@swc/jest",
|
||||
{
|
||||
jsc: {
|
||||
parser: { syntax: "typescript", decorators: true },
|
||||
transform: { decoratorMetadata: true },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
testEnvironment: `node`,
|
||||
moduleFileExtensions: [`js`, `ts`],
|
||||
modulePathIgnorePatterns: ["dist/"],
|
||||
}
|
||||
@@ -24,6 +24,7 @@
|
||||
"awilix": "^8.0.1",
|
||||
"bignumber.js": "^9.1.2",
|
||||
"cross-env": "^5.2.1",
|
||||
"expect-type": "^0.20.0",
|
||||
"ioredis": "^5.4.1",
|
||||
"rimraf": "^5.0.1",
|
||||
"typescript": "^5.1.6",
|
||||
@@ -31,7 +32,7 @@
|
||||
"winston": "^3.8.2"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rimraf dist && tsc --build",
|
||||
"build": "rimraf dist && tsc -p tsconfig.spec.json --noEmit && tsc -p tsconfig.build.json",
|
||||
"watch": "tsc --build --watch",
|
||||
"test": "exit 0"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
// TODO: The intent is to manage fields picking from a object, not to act upon at the moment and just keeping it here for reference.
|
||||
|
||||
import { Prettify } from "./common"
|
||||
|
||||
type Split<S extends string, D extends string> = string extends S
|
||||
? string[]
|
||||
: S extends ""
|
||||
? []
|
||||
: S extends `${infer T}${D}${infer U}`
|
||||
? [T, ...Split<U, D>]
|
||||
: [S]
|
||||
|
||||
type NestedPickHelper<T, Path extends string[]> = Path extends [
|
||||
infer First,
|
||||
...infer Rest
|
||||
]
|
||||
? First extends keyof T
|
||||
? Rest extends string[]
|
||||
? Rest["length"] extends 0
|
||||
? T[First]
|
||||
: T[First] extends Array<infer Item>
|
||||
? {
|
||||
[K in keyof Item as Rest[0] extends "*"
|
||||
? K
|
||||
: K extends Rest[number]
|
||||
? K
|
||||
: never]: Item[K] extends object
|
||||
? NestedPickHelper<Item[K], Rest>
|
||||
: Item[K] extends Array<infer Item>
|
||||
? NestedPickHelper<Item, Rest>
|
||||
: Rest[0] extends "*"
|
||||
? Item[K]
|
||||
: K extends Rest[number]
|
||||
? Item[K]
|
||||
: never
|
||||
}[]
|
||||
: T[First] extends object
|
||||
? {
|
||||
[K in keyof T[First] as Rest[0] extends "*"
|
||||
? K
|
||||
: K extends Rest[number]
|
||||
? K
|
||||
: never]: T[First][K] extends object
|
||||
? NestedPickHelper<T[First], Rest>
|
||||
: T[First][K] extends Array<infer Item>
|
||||
? NestedPickHelper<Item, Rest>
|
||||
: Rest[0] extends "*"
|
||||
? T[First][K]
|
||||
: K extends Rest[number]
|
||||
? T[First][K]
|
||||
: never
|
||||
}
|
||||
: First extends "*"
|
||||
? {
|
||||
[K in keyof T]: T[K]
|
||||
}
|
||||
: {
|
||||
[K in keyof T[First] as K extends Rest[number]
|
||||
? K
|
||||
: never]: NestedPickHelper<T[First], Rest>
|
||||
}
|
||||
: never
|
||||
: First extends `${infer ArrayKey}[${infer Index}]`
|
||||
? ArrayKey extends keyof T
|
||||
? T[ArrayKey] extends (infer U)[]
|
||||
? NestedPickHelper<U, Rest & string[]>
|
||||
: never
|
||||
: never
|
||||
: First extends "*"
|
||||
? T
|
||||
: never
|
||||
: T
|
||||
|
||||
type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (
|
||||
x: infer I
|
||||
) => void
|
||||
? I
|
||||
: never
|
||||
|
||||
export type NestedPickFirstIteration<T, Props extends string[]> = {
|
||||
[P in Props[number] as Split<P, ".">[0] & string]: NestedPickHelper<
|
||||
T,
|
||||
Split<P, ".">
|
||||
>
|
||||
}
|
||||
|
||||
type NestedPick<T, Props extends string[]> = {
|
||||
[K in keyof NestedPickFirstIteration<T, Props>]: Prettify<
|
||||
NestedPickFirstIteration<T, Props>[K] extends Array<infer V>
|
||||
? UnionToIntersection<V>[]
|
||||
: UnionToIntersection<NestedPickFirstIteration<T, Props>[K]>
|
||||
>
|
||||
}
|
||||
|
||||
type Obj = {
|
||||
id: string
|
||||
title: string
|
||||
variant: {
|
||||
id: string
|
||||
description: string
|
||||
}
|
||||
options: { id: string; value: string }[]
|
||||
extra: {
|
||||
detail: {
|
||||
name: string
|
||||
info: {
|
||||
data: string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Test = NestedPick<
|
||||
Obj,
|
||||
[
|
||||
"id",
|
||||
"variant.description",
|
||||
"variant.id",
|
||||
"options.id",
|
||||
"options.value",
|
||||
"extra.detail.info.data"
|
||||
]
|
||||
>
|
||||
|
||||
const test: Test = {
|
||||
id: "test",
|
||||
variant: {
|
||||
description: "test",
|
||||
id: "test",
|
||||
},
|
||||
options: [
|
||||
{
|
||||
id: "test",
|
||||
value: "test",
|
||||
},
|
||||
],
|
||||
extra: {
|
||||
detail: {
|
||||
info: {
|
||||
data: "test",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,458 @@
|
||||
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: { output: "Date | string" }
|
||||
output: { output: "Date | string" }
|
||||
}
|
||||
JSON: {
|
||||
input: { output: "Record<any, unknown>" }
|
||||
output: { output: "Record<any, 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>
|
||||
}
|
||||
|
||||
export type ProductVariant = {
|
||||
__typename?: "ProductVariant"
|
||||
id: Scalars["ID"]["output"]
|
||||
handle: Scalars["String"]["output"]
|
||||
title: 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 "../remote-query-entry-points" {
|
||||
export interface RemoteQueryEntryPoints extends FixtureEntryPoints {}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
import { ObjectToRemoteQueryFields } from "../object-to-remote-query-fields"
|
||||
import { expectTypeOf } from "expect-type"
|
||||
|
||||
describe("ObjectToRemoteQueryFields", () => {
|
||||
it("should return all the nested paths properties from an object", () => {
|
||||
type Object = {
|
||||
id: string
|
||||
title: string
|
||||
description: string
|
||||
date: Date
|
||||
variants: {
|
||||
id: string
|
||||
sku: string
|
||||
title: string
|
||||
}[]
|
||||
sales_channel: {
|
||||
id: string
|
||||
name: string
|
||||
value: string
|
||||
}
|
||||
metadata: Record<string, unknown>
|
||||
}
|
||||
|
||||
type Paths = ObjectToRemoteQueryFields<Object>
|
||||
|
||||
expectTypeOf<Paths>().toEqualTypeOf<
|
||||
| "*"
|
||||
| "date"
|
||||
| "metadata"
|
||||
| "id"
|
||||
| "title"
|
||||
| "description"
|
||||
| "variants.*"
|
||||
| "variants.id"
|
||||
| "variants.sku"
|
||||
| "variants.title"
|
||||
| "sales_channel.*"
|
||||
| "sales_channel.id"
|
||||
| "sales_channel.name"
|
||||
| "sales_channel.value"
|
||||
>()
|
||||
})
|
||||
|
||||
it("should return all the nested paths properties from an object with nullable and undefined", () => {
|
||||
type Maybe<T> = T | null
|
||||
|
||||
type Object = {
|
||||
id: string
|
||||
title: string
|
||||
description: string
|
||||
date: Date
|
||||
variants: Maybe<
|
||||
Maybe<{
|
||||
id: string
|
||||
sku: string
|
||||
title: string
|
||||
}>[]
|
||||
>
|
||||
sales_channel?: Maybe<{
|
||||
id: string
|
||||
name: string
|
||||
value: string
|
||||
}>
|
||||
metadata: Record<string, unknown>
|
||||
}
|
||||
|
||||
type Paths = ObjectToRemoteQueryFields<Object>
|
||||
|
||||
expectTypeOf<Paths>().toEqualTypeOf<
|
||||
| "*"
|
||||
| "id"
|
||||
| "metadata"
|
||||
| "date"
|
||||
| "title"
|
||||
| "description"
|
||||
| "variants.*"
|
||||
| "variants.id"
|
||||
| "variants.sku"
|
||||
| "variants.title"
|
||||
| "sales_channel.*"
|
||||
| "sales_channel.id"
|
||||
| "sales_channel.name"
|
||||
| "sales_channel.value"
|
||||
>()
|
||||
})
|
||||
|
||||
it("should fail return all the nested paths properties from an object with nullable and undefined", () => {
|
||||
type Maybe<T> = T | null
|
||||
|
||||
type Object = {
|
||||
id: string
|
||||
title: string
|
||||
description: string
|
||||
date: Date
|
||||
variants: Maybe<
|
||||
Maybe<{
|
||||
id: string
|
||||
sku: string
|
||||
title: string
|
||||
}>[]
|
||||
>
|
||||
sales_channel?: Maybe<{
|
||||
id: string
|
||||
name: string
|
||||
value: string
|
||||
}>
|
||||
metadata: Record<string, unknown>
|
||||
}
|
||||
|
||||
type Paths = ObjectToRemoteQueryFields<Object>
|
||||
|
||||
expectTypeOf<Paths>().toEqualTypeOf<
|
||||
// @ts-expect-error
|
||||
| "foo"
|
||||
| "*"
|
||||
| "date"
|
||||
| "metadata"
|
||||
| "id"
|
||||
| "title"
|
||||
| "description"
|
||||
| "variants.*"
|
||||
| "variants.id"
|
||||
| "variants.sku"
|
||||
| "variants.title"
|
||||
| "sales_channel.*"
|
||||
| "sales_channel.id"
|
||||
| "sales_channel.name"
|
||||
| "sales_channel.value"
|
||||
>()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,56 @@
|
||||
import { expectTypeOf } from "expect-type"
|
||||
import { RemoteQueryEntryPoints } from "../remote-query-entry-points"
|
||||
import { FixtureEntryPoints } from "../__fixtures__/remote-query"
|
||||
import { RemoteQueryObjectConfig } from "../remote-query-object-from-string"
|
||||
|
||||
describe("RemoteQuery", () => {
|
||||
describe("RemoteQueryEntryPoints", () => {
|
||||
it("should include declaration merging types with the defined entry points", () => {
|
||||
expectTypeOf<RemoteQueryEntryPoints>().toMatchTypeOf<FixtureEntryPoints>()
|
||||
})
|
||||
})
|
||||
|
||||
describe("RemoteQueryObjectConfig", () => {
|
||||
it("should return the correct type for fields when using a string entry point", () => {
|
||||
type Result = RemoteQueryObjectConfig<"simple_product">["fields"]
|
||||
expectTypeOf<Result>().toEqualTypeOf<
|
||||
(
|
||||
| "*"
|
||||
| "id"
|
||||
| "handle"
|
||||
| "title"
|
||||
| "variants.id"
|
||||
| "variants.*"
|
||||
| "sales_channels.id"
|
||||
| "sales_channels.*"
|
||||
| "sales_channels.name"
|
||||
| "sales_channels_link.*"
|
||||
| "sales_channels_link.product_id"
|
||||
| "sales_channels_link.sales_channel_id"
|
||||
)[]
|
||||
>()
|
||||
})
|
||||
|
||||
it("should fail return the correct type for fields when using a string entry point", () => {
|
||||
type Result = RemoteQueryObjectConfig<"simple_product">["fields"]
|
||||
expectTypeOf<Result>().toEqualTypeOf<
|
||||
// @ts-expect-error
|
||||
(
|
||||
| "*"
|
||||
| "foo"
|
||||
| "id"
|
||||
| "handle"
|
||||
| "title"
|
||||
| "variants.id"
|
||||
| "variants.*"
|
||||
| "sales_channels.id"
|
||||
| "sales_channels.*"
|
||||
| "sales_channels.name"
|
||||
| "sales_channels_link.*"
|
||||
| "sales_channels_link.product_id"
|
||||
| "sales_channels_link.sales_channel_id"
|
||||
)[]
|
||||
>()
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,19 +1,22 @@
|
||||
import {
|
||||
JoinerRelationship,
|
||||
JoinerServiceConfig,
|
||||
RemoteJoinerOptions,
|
||||
RemoteJoinerQuery,
|
||||
} from "../joiner"
|
||||
import { JoinerRelationship, JoinerServiceConfig } from "../joiner"
|
||||
|
||||
import { MedusaContainer } from "../common"
|
||||
import { RepositoryService } from "../dal"
|
||||
import { Logger } from "../logger"
|
||||
import {
|
||||
RemoteQueryObjectConfig,
|
||||
RemoteQueryObjectFromStringResult,
|
||||
} from "./remote-query-object-from-string"
|
||||
|
||||
export { RemoteQueryObjectConfig, RemoteQueryObjectFromStringResult }
|
||||
|
||||
export type Constructor<T> = new (...args: any[]) => T | (new () => T)
|
||||
|
||||
export * from "../common/medusa-container"
|
||||
export * from "./medusa-internal-service"
|
||||
export * from "./module-provider"
|
||||
export * from "./remote-query"
|
||||
export * from "./remote-query-entry-points"
|
||||
|
||||
export type LogLevel =
|
||||
| "query"
|
||||
@@ -292,12 +295,6 @@ export type ModuleBootstrapDeclaration =
|
||||
// | ModuleServiceInitializeOptions
|
||||
// | ModuleServiceInitializeCustomDataLayerOptions
|
||||
|
||||
export type RemoteQueryFunction = (
|
||||
query: string | RemoteJoinerQuery | object,
|
||||
variables?: Record<string, unknown>,
|
||||
options?: RemoteJoinerOptions
|
||||
) => Promise<any> | null
|
||||
|
||||
export interface IModuleService {
|
||||
/**
|
||||
* @ignore
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
type Marker = [never, 0, 1, 2, 3, 4]
|
||||
|
||||
type ExcludedProps = ["__typename"]
|
||||
type SpecialNonRelationProps = ["metadata"]
|
||||
type RawBigNumberPrefix = "raw_"
|
||||
|
||||
type ExpandStarSelector<
|
||||
T extends object,
|
||||
Depth extends number,
|
||||
Exclusion extends string[]
|
||||
> = ObjectToRemoteQueryFields<T & { "*": "*" }, Depth, Exclusion>
|
||||
|
||||
type TypeOnly<T> = Required<Exclude<T, null | undefined>>
|
||||
|
||||
/**
|
||||
* Output an array of strings representing the path to each leaf node in an object
|
||||
*/
|
||||
export type ObjectToRemoteQueryFields<
|
||||
MaybeT,
|
||||
Depth extends number = 2,
|
||||
Exclusion extends string[] = [],
|
||||
T = TypeOnly<MaybeT> & { "*": "*" }
|
||||
> = Depth extends never
|
||||
? never
|
||||
: T extends object
|
||||
? {
|
||||
[K in keyof T]: K extends // handle big number
|
||||
`${RawBigNumberPrefix}${string}`
|
||||
? Exclude<K, symbol>
|
||||
: // handle metadata
|
||||
K extends SpecialNonRelationProps[number]
|
||||
? Exclude<K, symbol>
|
||||
: // Special props that should be excluded
|
||||
K extends ExcludedProps[number]
|
||||
? never
|
||||
: // Prevent recursive reference to itself
|
||||
K extends Exclusion[number]
|
||||
? never
|
||||
: TypeOnly<T[K]> extends Array<infer R>
|
||||
? TypeOnly<R> extends Date
|
||||
? Exclude<K, symbol>
|
||||
: TypeOnly<R> extends object
|
||||
? `${Exclude<K, symbol>}.${ExpandStarSelector<
|
||||
TypeOnly<R>,
|
||||
Marker[Depth],
|
||||
[K & string, ...Exclusion]
|
||||
>}`
|
||||
: never
|
||||
: TypeOnly<T[K]> extends Date
|
||||
? Exclude<K, symbol>
|
||||
: TypeOnly<T[K]> extends object
|
||||
? `${Exclude<K, symbol>}.${ExpandStarSelector<
|
||||
TypeOnly<T[K]>,
|
||||
Marker[Depth],
|
||||
[K & string, ...Exclusion]
|
||||
>}`
|
||||
: Exclude<K, symbol>
|
||||
}[keyof T]
|
||||
: never
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Bucket filled with map of entry point -> types that are autogenerated by the CLI
|
||||
*/
|
||||
export interface RemoteQueryEntryPoints {}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { RemoteQueryEntryPoints } from "./remote-query-entry-points"
|
||||
import { ObjectToRemoteQueryFields } from "./object-to-remote-query-fields"
|
||||
|
||||
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
|
||||
entryPoint: TEntry | keyof RemoteQueryEntryPoints
|
||||
variables?: any
|
||||
fields: ObjectToRemoteQueryFields<
|
||||
RemoteQueryEntryPoints[TEntry & keyof RemoteQueryEntryPoints]
|
||||
> extends never
|
||||
? string[]
|
||||
: ObjectToRemoteQueryFields<
|
||||
RemoteQueryEntryPoints[TEntry & keyof RemoteQueryEntryPoints]
|
||||
>[]
|
||||
}
|
||||
|
||||
export type RemoteQueryObjectFromStringResult<
|
||||
TConfig extends RemoteQueryObjectConfig<any>
|
||||
> = {
|
||||
__TConfig: TConfig
|
||||
__value: object
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
import { RemoteJoinerOptions, RemoteJoinerQuery } from "../joiner"
|
||||
import {
|
||||
RemoteQueryObjectConfig,
|
||||
RemoteQueryObjectFromStringResult,
|
||||
} from "./remote-query-object-from-string"
|
||||
|
||||
/*type ExcludedProps = "__typename"*/
|
||||
|
||||
export type RemoteQueryFunctionReturnPagination = {
|
||||
skip: number
|
||||
take: number
|
||||
count: number
|
||||
}
|
||||
|
||||
/*export type RemoteQueryReturnedData<TEntry extends string> =
|
||||
TEntry extends keyof RemoteQueryEntryPoints
|
||||
? Prettify<Omit<RemoteQueryEntryPoints[TEntry], ExcludedProps>>
|
||||
: any*/
|
||||
|
||||
/*export type NarrowRemoteFunctionReturnType<
|
||||
TConfig extends RemoteQueryObjectConfig<any>
|
||||
> = TConfig extends RemoteQueryObjectConfig<infer TEntry>
|
||||
? TConfig extends { variables: infer Variables }
|
||||
? Variables extends { skip: number }
|
||||
? {
|
||||
rows: RemoteQueryReturnedData<TEntry>[]
|
||||
metadata: RemoteQueryFunctionReturnPagination
|
||||
}
|
||||
: Variables extends { skip?: number | undefined } | { skip?: number }
|
||||
? // TODO: the real type is the one in parenthsis but we put any for now as the current API is broken and need fixin in a separate iteration (RemoteQueryReturnedData<TEntry>[] | {rows: RemoteQueryReturnedData<TEntry>[] metadata: RemoteQueryFunctionReturnPagination })
|
||||
any
|
||||
: RemoteQueryReturnedData<TEntry>[]
|
||||
: RemoteQueryReturnedData<TEntry>[]
|
||||
: never*/
|
||||
|
||||
/*export type RemoteQueryFunctionReturnType<
|
||||
TConfig extends
|
||||
| RemoteQueryObjectConfig<any>
|
||||
| RemoteQueryObjectFromStringResult<any>
|
||||
> = TConfig extends RemoteQueryObjectFromStringResult<any>
|
||||
? NarrowRemoteFunctionReturnType<TConfig['__value']>
|
||||
: TConfig extends RemoteQueryObjectConfig<any>
|
||||
? NarrowRemoteFunctionReturnType<TConfig>
|
||||
: never*/
|
||||
|
||||
export type RemoteQueryFunction = {
|
||||
/**
|
||||
* Query wrapper to provide specific API's and pre processing around remoteQuery.query
|
||||
* @param queryConfig
|
||||
* @param options
|
||||
*/
|
||||
<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
|
||||
*/
|
||||
<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: RemoteJoinerQuery, options?: RemoteJoinerOptions): Promise<any>
|
||||
/**
|
||||
* 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>
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"include": ["src"],
|
||||
"exclude": [
|
||||
"dist",
|
||||
"src/**/__tests__",
|
||||
"src/**/__mocks__",
|
||||
"src/**/__fixtures__",
|
||||
"node_modules"
|
||||
],
|
||||
}
|
||||
@@ -21,8 +21,6 @@
|
||||
"include": ["src"],
|
||||
"exclude": [
|
||||
"dist",
|
||||
"./src/**/__tests__",
|
||||
"./src/**/__mocks__",
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"include": ["src", "integration-tests"],
|
||||
"exclude": ["node_modules", "dist"],
|
||||
"compilerOptions": {
|
||||
"sourceMap": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import { deepMerge } from "../deep-merge"
|
||||
|
||||
describe("Deep merge ", function () {
|
||||
it("should merge 2 objects", () => {
|
||||
const a = {
|
||||
x: 1,
|
||||
y: {
|
||||
z: 3,
|
||||
w: 4,
|
||||
a: {
|
||||
b: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
const aCopy = JSON.parse(JSON.stringify(a))
|
||||
|
||||
const b = {
|
||||
y: {
|
||||
w: 5,
|
||||
q: 6,
|
||||
a: {
|
||||
c: 14,
|
||||
},
|
||||
},
|
||||
z: 2,
|
||||
}
|
||||
const bCopy = JSON.parse(JSON.stringify(b))
|
||||
|
||||
const merged = deepMerge(a, b)
|
||||
expect(merged).toEqual({
|
||||
x: 1,
|
||||
y: {
|
||||
z: 3,
|
||||
w: 5,
|
||||
a: {
|
||||
b: 1,
|
||||
c: 14,
|
||||
},
|
||||
q: 6,
|
||||
},
|
||||
z: 2,
|
||||
})
|
||||
expect(a).toEqual(aCopy)
|
||||
expect(b).toEqual(bCopy)
|
||||
})
|
||||
})
|
||||
@@ -45,7 +45,7 @@ describe("remoteQueryObjectFromString", function () {
|
||||
fields,
|
||||
})
|
||||
|
||||
expect(output).toEqual({
|
||||
expect(output.__value).toEqual({
|
||||
product: {
|
||||
__args: {
|
||||
q: "name",
|
||||
@@ -101,9 +101,9 @@ describe("remoteQueryObjectFromString", function () {
|
||||
service: "product",
|
||||
variables: {},
|
||||
fields,
|
||||
})
|
||||
} as any)
|
||||
|
||||
expect(output).toEqual({
|
||||
expect(output.__value).toEqual({
|
||||
product: {
|
||||
__args: {},
|
||||
fields: [
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { isObject } from "./is-object"
|
||||
|
||||
export function deepMerge(target: any, source: any) {
|
||||
const recursive = (a, b) => {
|
||||
if (!isObject(a)) {
|
||||
return b
|
||||
}
|
||||
if (!isObject(b)) {
|
||||
return a
|
||||
}
|
||||
|
||||
Object.keys(b).forEach((key) => {
|
||||
if (isObject(b[key])) {
|
||||
a[key] ??= {}
|
||||
a[key] = deepMerge(a[key], b[key])
|
||||
} else {
|
||||
a[key] = b[key]
|
||||
}
|
||||
})
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
const copy = { ...target }
|
||||
return recursive(copy, source)
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { MapToConfig } from "./map-object-to"
|
||||
|
||||
export function generateLinkableKeysMap(
|
||||
linkableKeys: Record<string, string>
|
||||
): MapToConfig {
|
||||
const entityLinkableKeysMap: MapToConfig = {}
|
||||
|
||||
Object.entries(linkableKeys).forEach(([key, value]) => {
|
||||
entityLinkableKeysMap[value] ??= []
|
||||
entityLinkableKeysMap[value].push({
|
||||
mapTo: key,
|
||||
valueFrom: key.split("_").pop()!,
|
||||
})
|
||||
})
|
||||
|
||||
return entityLinkableKeysMap
|
||||
}
|
||||
@@ -12,10 +12,12 @@ export * from "./deduplicate"
|
||||
export * from "./deep-copy"
|
||||
export * from "./deep-equal-obj"
|
||||
export * from "./deep-flat-map"
|
||||
export * from "./deep-merge"
|
||||
export * from "./define-config"
|
||||
export * from "./env-editor"
|
||||
export * from "./errors"
|
||||
export * from "./file-system"
|
||||
export * from "./generate-entity-id"
|
||||
export * from "./generate-linkable-keys-map"
|
||||
export * from "./get-caller-file-path"
|
||||
export * from "./get-config-file"
|
||||
export * from "./get-duplicates"
|
||||
@@ -26,7 +28,6 @@ export * from "./get-set-difference"
|
||||
export * from "./graceful-shutdown-server"
|
||||
export * from "./group-by"
|
||||
export * from "./handle-postgres-database-error"
|
||||
export * from "./is-truthy"
|
||||
export * from "./is-big-number"
|
||||
export * from "./is-boolean"
|
||||
export * from "./is-date"
|
||||
@@ -35,10 +36,12 @@ export * from "./is-email"
|
||||
export * from "./is-object"
|
||||
export * from "./is-present"
|
||||
export * from "./is-string"
|
||||
export * from "./is-truthy"
|
||||
export * from "./load-env"
|
||||
export * from "./lower-case-first"
|
||||
export * from "./map-object-to"
|
||||
export * from "./medusa-container"
|
||||
export * from "./normalize-import-path-with-source"
|
||||
export * from "./object-from-string-path"
|
||||
export * from "./object-to-string-path"
|
||||
export * from "./optional-numeric-serializer"
|
||||
@@ -68,6 +71,3 @@ export * from "./trim-zeros"
|
||||
export * from "./upper-case-first"
|
||||
export * from "./validate-handle"
|
||||
export * from "./wrap-handler"
|
||||
export * from "./define-config"
|
||||
export * from "./env-editor"
|
||||
export * from "./normalize-import-path-with-source"
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import {
|
||||
RemoteQueryObjectConfig,
|
||||
RemoteQueryObjectFromStringResult,
|
||||
} from "@medusajs/types"
|
||||
import { isObject } from "./is-object"
|
||||
|
||||
/**
|
||||
@@ -83,20 +87,18 @@ import { isObject } from "./is-object"
|
||||
* // },
|
||||
* // }
|
||||
*/
|
||||
export function remoteQueryObjectFromString(
|
||||
config:
|
||||
| {
|
||||
entryPoint: string
|
||||
variables?: any
|
||||
fields: string[]
|
||||
}
|
||||
| {
|
||||
service: string
|
||||
variables?: any
|
||||
fields: string[]
|
||||
}
|
||||
): object {
|
||||
const { entryPoint, service, variables, fields } = {
|
||||
export function remoteQueryObjectFromString<
|
||||
const TEntry extends string,
|
||||
const TConfig extends RemoteQueryObjectConfig<TEntry>
|
||||
>(
|
||||
config: TConfig | RemoteQueryObjectConfig<TEntry>
|
||||
): RemoteQueryObjectFromStringResult<TConfig> {
|
||||
const {
|
||||
entryPoint,
|
||||
service,
|
||||
variables = {},
|
||||
fields = [],
|
||||
} = {
|
||||
...config,
|
||||
entryPoint: "entryPoint" in config ? config.entryPoint : undefined,
|
||||
service: "service" in config ? config.service : undefined,
|
||||
@@ -114,12 +116,13 @@ export function remoteQueryObjectFromString(
|
||||
const usedVariables = new Set()
|
||||
|
||||
for (const field of fields) {
|
||||
if (!field.includes(".")) {
|
||||
const fieldAsString = field as string
|
||||
if (!fieldAsString.includes(".")) {
|
||||
remoteJoinerConfig[entryKey]["fields"].push(field)
|
||||
continue
|
||||
}
|
||||
|
||||
const fieldSegments = field.split(".")
|
||||
const fieldSegments = fieldAsString.split(".")
|
||||
const fieldProperty = fieldSegments.pop()
|
||||
|
||||
let combinedPath = ""
|
||||
@@ -151,5 +154,7 @@ export function remoteQueryObjectFromString(
|
||||
|
||||
remoteJoinerConfig[entryKey]["__args"] = topLevelArgs ?? {}
|
||||
|
||||
return remoteJoinerConfig
|
||||
return {
|
||||
__value: remoteJoinerConfig,
|
||||
} as RemoteQueryObjectFromStringResult<TConfig>
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ export function defineJoinerConfig(
|
||||
alias?: JoinerServiceConfigAlias[]
|
||||
schema?: string
|
||||
models?: DmlEntity<any, any>[] | { name: string }[]
|
||||
linkableKeys?: Record<string, string>
|
||||
linkableKeys?: ModuleJoinerConfig["linkableKeys"]
|
||||
primaryKeys?: string[]
|
||||
} = {}
|
||||
): Omit<
|
||||
@@ -151,18 +151,19 @@ export function defineJoinerConfig(
|
||||
schema = toGraphQLSchema([...modelDefinitions.values()])
|
||||
}
|
||||
|
||||
if (!linkableKeys) {
|
||||
const linkableKeysFromDml = buildLinkableKeysFromDmlObjects([
|
||||
...modelDefinitions.values(),
|
||||
])
|
||||
const linkableKeysFromMikroOrm = buildLinkableKeysFromMikroOrmObjects([
|
||||
...mikroOrmObjects.values(),
|
||||
])
|
||||
linkableKeys = {
|
||||
...linkableKeysFromDml,
|
||||
...linkableKeysFromMikroOrm,
|
||||
}
|
||||
const linkableKeysFromDml = buildLinkableKeysFromDmlObjects([
|
||||
...modelDefinitions.values(),
|
||||
])
|
||||
const linkableKeysFromMikroOrm = buildLinkableKeysFromMikroOrmObjects([
|
||||
...mikroOrmObjects.values(),
|
||||
])
|
||||
|
||||
const mergedLinkableKeys = {
|
||||
...linkableKeysFromDml,
|
||||
...linkableKeysFromMikroOrm,
|
||||
...linkableKeys,
|
||||
}
|
||||
linkableKeys = mergedLinkableKeys
|
||||
|
||||
if (!primaryKeys && modelDefinitions.size) {
|
||||
const linkConfig = buildLinkConfigFromModelObjects(
|
||||
@@ -370,6 +371,7 @@ export function buildLinkConfigFromModelObjects<
|
||||
const linkableKeyName =
|
||||
parsedProperty.dataType.options?.linkable ??
|
||||
`${camelToSnakeCase(model.name).toLowerCase()}_${property}`
|
||||
|
||||
modelLinkConfig[property] = {
|
||||
linkable: linkableKeyName,
|
||||
primaryKey: property,
|
||||
@@ -397,21 +399,24 @@ export function buildLinkConfigFromLinkableKeys<
|
||||
|
||||
for (const [linkable, modelName] of Object.entries(linkableKeys)) {
|
||||
const kebabCasedModelName = camelToSnakeCase(toCamelCase(modelName))
|
||||
|
||||
const inferredReferenceProperty = linkable.replace(
|
||||
`${kebabCasedModelName}_`,
|
||||
""
|
||||
)
|
||||
|
||||
const keyName = lowerCaseFirst(modelName)
|
||||
const config = {
|
||||
linkable: linkable,
|
||||
primaryKey: inferredReferenceProperty,
|
||||
serviceName,
|
||||
field: lowerCaseFirst(modelName),
|
||||
field: keyName,
|
||||
}
|
||||
linkConfig[lowerCaseFirst(modelName)] = {
|
||||
[inferredReferenceProperty]: config,
|
||||
|
||||
linkConfig[keyName] ??= {
|
||||
toJSON: () => config,
|
||||
}
|
||||
linkConfig[keyName][inferredReferenceProperty] = config
|
||||
}
|
||||
|
||||
return linkConfig as Record<string, any>
|
||||
@@ -432,6 +437,5 @@ export function buildModelsNameToLinkableKeysMap(
|
||||
valueFrom: key.split("_").pop()!,
|
||||
})
|
||||
})
|
||||
|
||||
return entityLinkableKeysMap
|
||||
}
|
||||
|
||||
@@ -35,12 +35,12 @@ export function Module<
|
||||
} {
|
||||
const modelObjects = service[MedusaServiceModelObjectsSymbol] ?? {}
|
||||
|
||||
const defaultJoinerConfig = defineJoinerConfig(serviceName, {
|
||||
models: Object.keys(modelObjects).length
|
||||
? Object.values(modelObjects)
|
||||
: undefined,
|
||||
})
|
||||
service.prototype.__joinerConfig ??= () => defaultJoinerConfig
|
||||
service.prototype.__joinerConfig ??= () =>
|
||||
defineJoinerConfig(serviceName, {
|
||||
models: Object.keys(modelObjects).length
|
||||
? Object.values(modelObjects)
|
||||
: undefined,
|
||||
})
|
||||
|
||||
let linkable = {} as Linkable
|
||||
|
||||
|
||||
Reference in New Issue
Block a user