fix(gatsby-source-medusa): Unsupported exports warning and schema (#1463)

**What**

- Moves `sourceUpdatedNodes` and `sourceAllNodes` to a separate file, to prevent warning of unsupported exports. See #1455.
- Adds warnings if `GET /store/products`, `GET /store/regions`, and `GET /store/collections` return empty arrays. This should help new users more easily figure out why their storefronts does not work as expected.
- Adds schema to plugin, so that node types for products, regions and collections are always created. This will prevent errors such as `allMedusaRegions query failed` from happening in the storefront, as the query will be valid as the type exists, even if it returns nothing. This should make the gatsby plugin/starter easier to use. This error is an reoccurring issue in our discord, when new users try to run the Gatsby starter without seeding the storefront beforehand. 

Resolves #1455 

Co-authored-by: Sebastian Rindom <7554214+srindom@users.noreply.github.com>
This commit is contained in:
Kasper Fabricius Kristensen
2022-07-13 14:42:06 +02:00
committed by GitHub
parent a1a5848827
commit cbdc5b7774
4 changed files with 201 additions and 78 deletions

View File

@@ -0,0 +1,5 @@
---
"gatsby-source-medusa": patch
---
Moves sourceUpdatedNodes and sourceAllNodes to a separate file, to prevent warning of unsupported exports.

View File

@@ -18,7 +18,7 @@ function medusaRequest(
}
export const createClient = (options: MedusaPluginOptions): any => {
const { storeUrl, authToken } = options as any
const { storeUrl, apiKey } = options
/**
* @param {string} _date used fetch products updated since the specified date
@@ -41,6 +41,12 @@ export const createClient = (options: MedusaPluginOptions): any => {
})
} while (products.length < count)
if (!products.length && !_date) {
console.warn(
"[gatsby-source-medusa]: 📣 No products were retrieved. If this is a new store, please ensure that you have at least one published product in your store. You can create a product by using the Medusa admin dashboard."
)
}
return products
}
@@ -58,6 +64,13 @@ export const createClient = (options: MedusaPluginOptions): any => {
const regions = await medusaRequest(storeUrl, path).then(({ data }) => {
return data.regions
})
if (!regions.length && !_date) {
console.warn(
"[gatsby-source-medusa]: 📣 No regions were retrieved. If this is a new store, please ensure that you have configured at least one region in the Medusa admin dashboard."
)
}
return regions
}
@@ -68,14 +81,14 @@ export const createClient = (options: MedusaPluginOptions): any => {
*/
async function orders(_date?: string): Promise<any[]> {
const orders = await medusaRequest(storeUrl, `/admin/orders`, {
Authorization: `Bearer ${authToken}`,
Authorization: `Bearer ${apiKey}`,
})
.then(({ data }) => {
return data.orders
})
.catch((error) => {
console.warn(`
The following error status was produced while attempting to fetch orders: ${error}. \n
📣 The following error status was produced while attempting to fetch orders: ${error}. \n
Make sure that the auth token you provided is valid.
`)
return []
@@ -104,6 +117,12 @@ export const createClient = (options: MedusaPluginOptions): any => {
})
} while (collections.length < count)
if (!collections.length && !_date) {
console.warn(
"[gatsby-source-medusa]: 📣 No collections were retrieved. You can create collections using the Medusa admin dasbboard."
)
}
return collections
}

View File

@@ -11,8 +11,7 @@ import {
createRemoteFileNode,
CreateRemoteFileNodeArgs,
} from "gatsby-source-filesystem"
import { makeSourceFromOperation } from "./make-source-from-operation"
import { createOperations } from "./operations"
import { sourceAllNodes, sourceUpdatedNodes } from "./source-nodes"
export function pluginOptionsSchema({ Joi }: PluginOptionsSchemaArgs): any {
return Joi.object({
@@ -21,77 +20,6 @@ export function pluginOptionsSchema({ Joi }: PluginOptionsSchemaArgs): any {
})
}
async function sourceAllNodes(
gatsbyApi: SourceNodesArgs,
pluginOptions: MedusaPluginOptions
): Promise<void> {
const {
createProductsOperation,
createRegionsOperation,
createOrdersOperation,
createCollectionsOperation,
} = createOperations(pluginOptions)
const operations = [
createProductsOperation,
createRegionsOperation,
createCollectionsOperation,
]
// if auth token is provided then source orders
if (pluginOptions.apiKey) {
operations.push(createOrdersOperation)
}
const sourceFromOperation = makeSourceFromOperation(gatsbyApi)
for (const op of operations) {
await sourceFromOperation(op)
}
}
const medusaNodeTypes = [
"MedusaRegions",
"MedusaProducts",
"MedusaOrders",
"MedusaCollections",
]
async function sourceUpdatedNodes(
gatsbyApi: SourceNodesArgs,
pluginOptions: MedusaPluginOptions,
lastBuildTime: string
): Promise<void> {
const {
incrementalProductsOperation,
incrementalRegionsOperation,
incrementalOrdersOperation,
incrementalCollectionsOperation,
} = createOperations(pluginOptions)
for (const nodeType of medusaNodeTypes) {
gatsbyApi
.getNodesByType(nodeType)
.forEach((node) => gatsbyApi.actions.touchNode(node))
}
const operations = [
incrementalProductsOperation(lastBuildTime),
incrementalRegionsOperation(lastBuildTime),
incrementalCollectionsOperation(lastBuildTime),
]
if (pluginOptions.apiKey) {
operations.push(incrementalOrdersOperation(lastBuildTime))
}
const sourceFromOperation = makeSourceFromOperation(gatsbyApi)
for (const op of operations) {
await sourceFromOperation(op)
}
}
export async function onPostBuild({ cache }: { cache: any }): Promise<void> {
await cache.set("timestamp", Date.now())
}
@@ -145,13 +73,110 @@ export async function createSchemaCustomization({
schema: any
}): Promise<void> {
createTypes(`
type MedusaProducts implements Node {
type MedusaProducts implements Node {
id: ID!
title: String!
subtitle: String
description: String
handle: String!
is_giftcard: Boolean!
status: String!
thumbnail: File @link(from: "fields.localThumbnail")
options: [MedusaProductOptions]!
variants: [MedusaProductVariants]!
collection: MedusaCollections @link(from: "collection_id")
collection_id: String
profile_id: String!
discountable: Boolean!
published_at: Date!
created_at: Date!
updated_at: Date!
weight: Int
length: Int
width: Int
}
type MedusaImages implements Node {
id: ID!
url: String!
created_at: Date!
updated_at: Date!
image: File @link(from: "fields.localImage")
}
type MedusaCollections implements Node {
id: ID!
handle: String!
title: String!
created_at: Date!
updated_at: Date!
}
type MedusaProductOptions @dontInfer {
id: ID!
title: String!
product_id: String!
values: [MedusaProductOptionValues]!
created_at: Date!
updated_at: Date!
}
type MedusaProductOptionValues @dontInfer {
id: ID!
value: String!
created_at: Date!
updated_at: Date!
option_id: String!
variant_id: String!
}
type MedusaProductVariants @dontInfer {
id: ID!
title: String!
product_id: String!
prices: [MedusaMoneyAmounts]!
sku: String
barcode: String
upc: String
variant_rank: Int
inventory_quantity: Int!
allow_backorder: Boolean!
manage_inventory: Boolean!
hs_code: String
origin_country: String
mid_code: String
material: String
weight: Int
length: Int
height: Int
width: Int
options: [MedusaProductOptionValues]!
created_at: Date!
updated_at: Date!
}
type MedusaMoneyAmounts @dontInfer {
id: ID!
amount: Int!
currency_code: String!
created_at: Date!
updated_at: Date!
variant_id: String!
}
type MedusaRegions implements Node {
id: ID!
name: String!
currency_code: String!
tax_rate: Int!
tax_code: String
automatic_taxes: Boolean!
created_at: Date!
updated_at: Date!
countries: [MedusaCountries]!
}
type MedusaCountries implements Node {
id: ID!
name: String!
iso_2: String!
iso_3: String!
num_code: Int!
display_name: String!
region_id: String!
}
`)
}

View File

@@ -0,0 +1,74 @@
import { SourceNodesArgs } from "gatsby"
import { makeSourceFromOperation } from "./make-source-from-operation"
import { createOperations } from "./operations"
const medusaNodeTypes = [
"MedusaRegions",
"MedusaProducts",
"MedusaOrders",
"MedusaCollections",
]
export async function sourceAllNodes(
gatsbyApi: SourceNodesArgs,
pluginOptions: MedusaPluginOptions
): Promise<void> {
const {
createProductsOperation,
createRegionsOperation,
createOrdersOperation,
createCollectionsOperation,
} = createOperations(pluginOptions)
const operations = [
createProductsOperation,
createRegionsOperation,
createCollectionsOperation,
]
// if auth token is provided then source orders
if (pluginOptions.apiKey) {
operations.push(createOrdersOperation)
}
const sourceFromOperation = makeSourceFromOperation(gatsbyApi)
for (const op of operations) {
await sourceFromOperation(op)
}
}
export async function sourceUpdatedNodes(
gatsbyApi: SourceNodesArgs,
pluginOptions: MedusaPluginOptions,
lastBuildTime: string
): Promise<void> {
const {
incrementalProductsOperation,
incrementalRegionsOperation,
incrementalOrdersOperation,
incrementalCollectionsOperation,
} = createOperations(pluginOptions)
for (const nodeType of medusaNodeTypes) {
gatsbyApi
.getNodesByType(nodeType)
.forEach((node) => gatsbyApi.actions.touchNode(node))
}
const operations = [
incrementalProductsOperation(lastBuildTime),
incrementalRegionsOperation(lastBuildTime),
incrementalCollectionsOperation(lastBuildTime),
]
if (pluginOptions.apiKey) {
operations.push(incrementalOrdersOperation(lastBuildTime))
}
const sourceFromOperation = makeSourceFromOperation(gatsbyApi)
for (const op of operations) {
await sourceFromOperation(op)
}
}