Added basis setup and type generation for the products queries

This commit is contained in:
royderks 2021-04-16 16:28:52 +02:00 committed by Zaiste
parent ffe5a1c20e
commit b5e21a54b3
No known key found for this signature in database
GPG Key ID: 15DF7EBC7F2FFE35
25 changed files with 32173 additions and 14243 deletions

27
codegen.bigcommerce.json Normal file
View File

@ -0,0 +1,27 @@
{
"schema": {
"https://buybutton.store/graphql": {
"headers": {
"Authorization": "Bearer xzy"
}
}
},
"documents": [
{
"./framework/bigcommerce/api/**/*.ts": {
"noRequire": true
}
}
],
"generates": {
"./framework/bigcommerce/schema.d.ts": {
"plugins": ["typescript", "typescript-operations"]
},
"./framework/bigcommerce/schema.graphql": {
"plugins": ["schema-ast"]
}
},
"hooks": {
"afterAllFileWrite": ["prettier --write"]
}
}

View File

@ -1,23 +1,29 @@
{
"schema": {
"https://buybutton.store/graphql": {
"headers": {
"Authorization": "Bearer xzy"
}
}
"https://master.staging.saleor.cloud/graphql/": {}
},
"documents": [
{
"./framework/bigcommerce/api/**/*.ts": {
"./framework/saleor/utils/queries/get-all-products-query.ts": {
"noRequire": true
}
},
{
"./framework/saleor/utils/queries/get-all-products-paths-query.ts": {
"noRequire": true
}
},
{
"./framework/saleor/utils/queries/get-products.ts": {
"noRequire": true
}
}
],
"generates": {
"./framework/bigcommerce/schema.d.ts": {
"./framework/saleor/schema.d.ts": {
"plugins": ["typescript", "typescript-operations"]
},
"./framework/bigcommerce/schema.graphql": {
"./framework/saleor/schema.graphql": {
"plugins": ["schema-ast"]
}
},

View File

@ -1,5 +1,6 @@
{
"features": {
"wishlist": true
"wishlist": false,
"customCheckout": false
}
}

View File

@ -23,7 +23,7 @@ const getAllPages = async (options?: {
config: SaleorConfig
preview?: boolean
}): Promise<ReturnType> => {
let { config, variables = { first: 250 } } = options ?? {}
let { config, variables = { first: 100 } } = options ?? {}
config = getConfig(config)
const { locale } = config
const { data } = await config.fetch(getAllPagesQuery, { variables })

View File

@ -7,17 +7,17 @@ const getAllCollections = async (options?: {
config: SaleorConfig
preview?: boolean
}) => {
let { config, variables = { first: 250 } } = options ?? {}
let { config, variables = { first: 100 } } = options ?? {}
config = getConfig(config)
const { data } = await config.fetch(getAllCollectionsQuery, { variables })
const edges = data.collections?.edges ?? []
const categories = edges.map(
({ node: { id: entityId, title: name, handle } }: CollectionEdge) => ({
({ node: { id: entityId, name, slug } }: CollectionEdge) => ({
entityId,
name,
path: `/${handle}`,
path: `/${slug}`,
})
)

View File

@ -21,7 +21,7 @@ const getAllProductPaths = async (options?: {
config?: SaleorConfig
preview?: boolean
}): Promise<ReturnType> => {
let { config, variables = { first: 250 } } = options ?? {}
let { config, variables = { first: 100 } } = options ?? {}
config = getConfig(config)
const products = await fetchAllProducts({

View File

@ -1,6 +1,6 @@
import { GraphQLFetcherResult } from '@commerce/api'
import { getConfig, SaleorConfig } from '../api'
import { ProductEdge } from '../schema'
import { Product as SaleorProduct } from '../schema'
import { getAllProductsQuery } from '../utils/queries'
import { normalizeProduct } from '../utils/normalize'
import { Product } from '@commerce/types'
@ -19,7 +19,7 @@ const getAllProducts = async (options: {
config?: SaleorConfig
preview?: boolean
}): Promise<ReturnType> => {
let { config, variables = { first: 250 } } = options ?? {}
let { config, variables = { first: 100 } } = options ?? {}
config = getConfig(config)
const { data }: GraphQLFetcherResult = await config.fetch(
@ -28,7 +28,7 @@ const getAllProducts = async (options: {
)
const products =
data.products?.edges?.map(({ node: p }: ProductEdge) =>
data.products?.edges?.map(({ node: p }: SaleorProduct) =>
normalizeProduct(p)
) ?? []

View File

@ -22,7 +22,7 @@ const getProduct = async (options: {
variables,
})
const { productByHandle: product } = data
const { product } = data
return {
product: product ? normalizeProduct(product) : null,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -11,16 +11,16 @@ export type Category = {
const getCategories = async (config: SaleorConfig): Promise<Category[]> => {
const { data } = await config.fetch(getSiteCollectionsQuery, {
variables: {
first: 250,
first: 100,
},
})
return (
data.collections?.edges?.map(
({ node: { id: entityId, title: name, handle } }: CollectionEdge) => ({
({ node: { id: entityId, name, slug } }: CollectionEdge) => ({
entityId,
name,
path: `/${handle}`,
path: `/${slug}`,
})
) ?? []
)

View File

@ -14,27 +14,30 @@ export type BrandEdge = {
export type Brands = BrandEdge[]
// TODO: Find a way to get vendors from meta
const getVendors = async (config: SaleorConfig): Promise<BrandEdge[]> => {
const vendors = await fetchAllProducts({
config,
query: getAllProductVendors,
variables: {
first: 250,
},
})
// const vendors = await fetchAllProducts({
// config,
// query: getAllProductVendors,
// variables: {
// first: 100,
// },
// })
let vendorsStrings = vendors.map(({ node: { vendor } }) => vendor)
// let vendorsStrings = vendors.map(({ node: { vendor } }) => vendor)
return [...new Set(vendorsStrings)].map((v) => {
const id = v.replace(/\s+/g, '-').toLowerCase()
return {
node: {
entityId: id,
name: v,
path: `brands/${id}`,
},
}
})
// return [...new Set(vendorsStrings)].map((v) => {
// const id = v.replace(/\s+/g, '-').toLowerCase()
// return {
// node: {
// entityId: id,
// name: v,
// path: `brands/${id}`,
// },
// }
// })
return []
}
export default getVendors

View File

@ -1,16 +1,17 @@
import { checkoutDetailsFragment } from '../queries/get-checkout-query'
const checkoutCreateMutation = /* GraphQL */ `
mutation {
mutation createCheckout {
checkoutCreate(input: {}) {
checkoutUserErrors {
code
field
message
}
checkout {
${checkoutDetailsFragment}
}
# Breaks GraphQL Codegen
# checkout {
# ${checkoutDetailsFragment}
# }
}
}
`

View File

@ -1,16 +1,16 @@
import { checkoutDetailsFragment } from '../queries/get-checkout-query'
const checkoutLineItemAddMutation = /* GraphQL */ `
mutation($checkoutId: ID!, $lineItems: [CheckoutLineItemInput!]!) {
mutation checkoutLineItemAdd($checkoutId: ID!, $lineItems: [CheckoutLineItemInput!]!) {
checkoutLineItemsAdd(checkoutId: $checkoutId, lineItems: $lineItems) {
checkoutUserErrors {
code
field
message
}
checkout {
${checkoutDetailsFragment}
}
# checkout {
# ${checkoutDetailsFragment}
# }
}
}
`

View File

@ -1,7 +1,7 @@
import { checkoutDetailsFragment } from '../queries/get-checkout-query'
const checkoutLineItemRemoveMutation = /* GraphQL */ `
mutation($checkoutId: ID!, $lineItemIds: [ID!]!) {
mutation checkoutLineItemRemove($checkoutId: ID!, $lineItemIds: [ID!]!) {
checkoutLineItemsRemove(
checkoutId: $checkoutId
lineItemIds: $lineItemIds
@ -11,9 +11,9 @@ const checkoutLineItemRemoveMutation = /* GraphQL */ `
field
message
}
checkout {
${checkoutDetailsFragment}
}
# checkout {
# ${checkoutDetailsFragment}
# }
}
}
`

View File

@ -1,16 +1,16 @@
import { checkoutDetailsFragment } from '../queries/get-checkout-query'
const checkoutLineItemUpdateMutation = /* GraphQL */ `
mutation($checkoutId: ID!, $lineItems: [CheckoutLineItemUpdateInput!]!) {
mutation checkoutLineItemUpdate($checkoutId: ID!, $lineItems: [CheckoutLineItemUpdateInput!]!) {
checkoutLineItemsUpdate(checkoutId: $checkoutId, lineItems: $lineItems) {
checkoutUserErrors {
code
field
message
}
checkout {
${checkoutDetailsFragment}
}
# checkout {
# ${checkoutDetailsFragment}
# }
}
}
`

View File

@ -9,67 +9,68 @@ import {
ProductVariantConnection,
MoneyV2,
ProductOption,
Money,
} from '../schema'
import type { Cart, LineItem } from '../types'
const money = ({ amount, currencyCode }: MoneyV2) => {
const money = ({ amount, currency }: Money) => {
return {
value: +amount,
currencyCode,
currencyCode: currency || 'USD',
}
}
const normalizeProductOption = ({
id,
name: displayName,
values,
}: ProductOption) => {
return {
const normalizeProductOptions = (options: ProductOption[]) => {
return options?.map(({ id, name: displayName, values }) => ({
__typename: 'MultipleChoiceOption',
id,
displayName,
values: values.map((value) => {
let output: any = {
label: value,
}
if (displayName.match(/colou?r/gi)) {
output = {
...output,
hexColors: [value],
}
}
return output
}),
}
// values: values.map((value) => {
// let output: any = {
// label: value,
// }
// if (displayName.match(/colou?r/gi)) {
// output = {
// ...output,
// hexColors: [value],
// }
// }
// return output
// })
values: [],
}))
}
const normalizeProductImages = ({ edges }: ImageConnection) =>
edges?.map(({ node: { originalSrc: url, ...rest } }) => ({
const normalizeProductImages = (images: any) =>
images.map(({ node: { originalSrc: url, ...rest } }) => ({
url,
...rest,
}))
const normalizeProductVariants = ({ edges }: ProductVariantConnection) => {
return edges?.map(
({
node: { id, selectedOptions, sku, title, priceV2, compareAtPriceV2 },
}) => {
const normalizeProductVariants = (variants: any) => {
return variants?.map(
({ id, selectedOptions, sku, name, priceV2, pricing }) => {
const price = money(pricing?.price?.net)?.value
console.log({ price })
return {
id,
name: title,
name,
sku: sku ?? id,
price: +priceV2.amount,
listPrice: +compareAtPriceV2?.amount,
price,
listPrice: price,
requiresShipping: true,
options: selectedOptions.map(({ name, value }: SelectedOption) => {
const options = normalizeProductOption({
id,
name,
values: [value],
})
return options
}),
// options: selectedOptions.map(({ name, value }: SelectedOption) => {
// const options = normalizeProductOption({
// id,
// name,
// values: [value],
// })
// return options
// }),
options: [],
}
}
)
@ -78,28 +79,27 @@ const normalizeProductVariants = ({ edges }: ProductVariantConnection) => {
export function normalizeProduct(productNode: SaleorProduct): Product {
const {
id,
title: name,
vendor,
images,
name,
media,
variants,
description,
handle,
priceRange,
options,
slug,
pricing,
// options,
...rest
} = productNode
const product = {
id,
name,
vendor,
vendor: '',
description,
path: `/${handle}`,
slug: handle?.replace(/^\/+|\/+$/g, ''),
price: money(priceRange?.minVariantPrice),
images: normalizeProductImages(images),
path: `/${slug}`,
slug: slug?.replace(/^\/+|\/+$/g, ''),
price: money(pricing?.priceRange?.start?.net) || 0,
images: media,
variants: variants ? normalizeProductVariants(variants) : [],
options: options ? options.map((o) => normalizeProductOption(o)) : [],
options: variants ? normalizeProductOptions(variants) : [],
...rest,
}

View File

@ -1,11 +1,11 @@
const getSiteCollectionsQuery = /* GraphQL */ `
query getSiteCollections($first: Int!) {
collections(first: $first) {
query getSiteCollections($first: Int!, $channel: String = "default-channel") {
collections(first: $first, channel: $channel) {
edges {
node {
id
title
handle
name
slug
}
}
}

View File

@ -1,11 +1,11 @@
export const getAllPagesQuery = /* GraphQL */ `
query getAllPages($first: Int = 250) {
query getAllPages($first: Int = 100) {
pages(first: $first) {
edges {
node {
id
title
handle
slug
}
}
}

View File

@ -1,13 +1,17 @@
const getAllProductsPathsQuery = /* GraphQL */ `
query getAllProductPaths($first: Int = 250, $cursor: String) {
products(first: $first, after: $cursor) {
query getAllProductPaths(
$first: Int = 100
$cursor: String
$channel: String = "default-channel"
) {
products(first: $first, after: $cursor, channel: $channel) {
pageInfo {
hasNextPage
hasPreviousPage
}
edges {
node {
handle
slug
}
cursor
}

View File

@ -1,57 +1,42 @@
export const productConnection = `
pageInfo {
hasNextPage
hasPreviousPage
}
edges {
node {
id
title
vendor
handle
description
priceRange {
minVariantPrice {
amount
currencyCode
}
export const productConnection = /* GraphQL */ `
fragment productConnnection on ProductCountableConnection {
pageInfo {
hasNextPage
hasPreviousPage
}
images(first: 1) {
pageInfo {
hasNextPage
hasPreviousPage
}
edges {
node {
originalSrc
altText
width
height
edges {
node {
id
name
description
slug
pricing {
priceRange {
start {
net {
amount
}
}
}
}
media {
url
alt
}
}
}
}
}`
export const productsFragment = `
products(
first: $first
sortKey: $sortKey
reverse: $reverse
query: $query
) {
${productConnection}
}
`
const getAllProductsQuery = /* GraphQL */ `
query getAllProducts(
$first: Int = 250
$query: String = ""
$sortKey: ProductSortKeys = RELEVANCE
$reverse: Boolean = false
$first: Int = 100
$channel: String = "default-channel"
) {
${productsFragment}
products(first: $first, channel: $channel) {
...productConnnection
}
}
${productConnection}
`
export default getAllProductsQuery

View File

@ -1,66 +1,34 @@
const getProductQuery = /* GraphQL */ `
query getProductBySlug($slug: String!) {
productByHandle(handle: $slug) {
query getProductBySlug($slug: String!, $channel: String = "default-channel") {
product(slug: $slug, channel: $channel) {
id
handle
title
productType
vendor
slug
name
description
descriptionHtml
options {
pricing {
priceRange {
start {
net {
amount
}
}
}
}
variants {
id
name
values
}
priceRange {
maxVariantPrice {
amount
currencyCode
}
minVariantPrice {
amount
currencyCode
}
}
variants(first: 250) {
pageInfo {
hasNextPage
hasPreviousPage
}
edges {
node {
id
title
sku
selectedOptions {
name
value
}
priceV2 {
pricing {
price {
net {
amount
currencyCode
}
compareAtPriceV2 {
amount
currencyCode
currency
}
}
}
}
images(first: 250) {
pageInfo {
hasNextPage
hasPreviousPage
}
edges {
node {
originalSrc
altText
width
height
}
}
images {
url
alt
}
}
}

View File

@ -7,6 +7,7 @@ const {
const provider = commerce.provider || getProviderName()
const isBC = provider === 'bigcommerce'
const isShopify = provider === 'shopify'
const isSaleor = provider === 'saleor'
const isSwell = provider === 'swell'
const isVendure = provider === 'vendure'
@ -16,6 +17,9 @@ module.exports = withCommerceConfig({
locales: ['en-US', 'es'],
defaultLocale: 'en-US',
},
images: {
domains: [process.env.COMMERCE_IMAGE_HOST],
},
rewrites() {
return [
(isBC || isShopify || isSwell || isVendure) && {

View File

@ -22,8 +22,8 @@
"@components/*": ["components/*"],
"@commerce": ["framework/commerce"],
"@commerce/*": ["framework/commerce/*"],
"@framework": ["framework/shopify"],
"@framework/*": ["framework/shopify/*"]
"@framework": ["framework/saleor"],
"@framework/*": ["framework/saleor/*"]
}
},
"include": ["next-env.d.ts", "**/*.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"],

View File

@ -5517,11 +5517,6 @@ quick-lru@^4.0.1:
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f"
integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==
quick-lru@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
version "2.1.0"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"