@faststore/api 1.2.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/CHANGELOG.md +333 -0
  2. package/README.md +115 -0
  3. package/dist/__generated__/schema.d.ts +281 -0
  4. package/dist/api.cjs.development.js +2226 -0
  5. package/dist/api.cjs.development.js.map +1 -0
  6. package/dist/api.cjs.production.min.js +2 -0
  7. package/dist/api.cjs.production.min.js.map +1 -0
  8. package/dist/api.esm.js +2217 -0
  9. package/dist/api.esm.js.map +1 -0
  10. package/dist/index.d.ts +136 -0
  11. package/dist/index.js +8 -0
  12. package/dist/platforms/vtex/clients/commerce/index.d.ts +29 -0
  13. package/dist/platforms/vtex/clients/commerce/types/Brand.d.ts +8 -0
  14. package/dist/platforms/vtex/clients/commerce/types/CategoryTree.d.ts +9 -0
  15. package/dist/platforms/vtex/clients/commerce/types/OrderForm.d.ts +347 -0
  16. package/dist/platforms/vtex/clients/commerce/types/Simulation.d.ts +154 -0
  17. package/dist/platforms/vtex/clients/fetch.d.ts +1 -0
  18. package/dist/platforms/vtex/clients/index.d.ts +32 -0
  19. package/dist/platforms/vtex/clients/search/index.d.ts +22 -0
  20. package/dist/platforms/vtex/clients/search/types/AttributeSearchResult.d.ts +56 -0
  21. package/dist/platforms/vtex/clients/search/types/ProductSearchResult.d.ts +199 -0
  22. package/dist/platforms/vtex/index.d.ts +144 -0
  23. package/dist/platforms/vtex/loaders/index.d.ts +7 -0
  24. package/dist/platforms/vtex/loaders/simulation.d.ts +5 -0
  25. package/dist/platforms/vtex/loaders/sku.d.ts +6 -0
  26. package/dist/platforms/vtex/resolvers/aggregateOffer.d.ts +7 -0
  27. package/dist/platforms/vtex/resolvers/aggregateRating.d.ts +2 -0
  28. package/dist/platforms/vtex/resolvers/collection.d.ts +8 -0
  29. package/dist/platforms/vtex/resolvers/facet.d.ts +5 -0
  30. package/dist/platforms/vtex/resolvers/facetValue.d.ts +5 -0
  31. package/dist/platforms/vtex/resolvers/mutation.d.ts +58 -0
  32. package/dist/platforms/vtex/resolvers/offer.d.ts +11 -0
  33. package/dist/platforms/vtex/resolvers/organization.d.ts +2 -0
  34. package/dist/platforms/vtex/resolvers/product.d.ts +5 -0
  35. package/dist/platforms/vtex/resolvers/productGroup.d.ts +3 -0
  36. package/dist/platforms/vtex/resolvers/query.d.ts +51 -0
  37. package/dist/platforms/vtex/resolvers/review.d.ts +2 -0
  38. package/dist/platforms/vtex/resolvers/searchResult.d.ts +5 -0
  39. package/dist/platforms/vtex/resolvers/seo.d.ts +7 -0
  40. package/dist/platforms/vtex/resolvers/validateCart.d.ts +71 -0
  41. package/dist/platforms/vtex/utils/enhanceSku.d.ts +5 -0
  42. package/dist/platforms/vtex/utils/facets.d.ts +12 -0
  43. package/dist/platforms/vtex/utils/slugify.d.ts +1 -0
  44. package/dist/platforms/vtex/utils/sort.d.ts +10 -0
  45. package/dist/typeDefs/index.d.ts +1 -0
  46. package/package.json +44 -0
  47. package/src/__generated__/schema.ts +324 -0
  48. package/src/index.ts +33 -0
  49. package/src/platforms/vtex/clients/commerce/index.ts +100 -0
  50. package/src/platforms/vtex/clients/commerce/types/Brand.ts +8 -0
  51. package/src/platforms/vtex/clients/commerce/types/CategoryTree.ts +9 -0
  52. package/src/platforms/vtex/clients/commerce/types/OrderForm.ts +371 -0
  53. package/src/platforms/vtex/clients/commerce/types/Simulation.ts +170 -0
  54. package/src/platforms/vtex/clients/fetch.ts +13 -0
  55. package/src/platforms/vtex/clients/index.ts +15 -0
  56. package/src/platforms/vtex/clients/search/index.ts +83 -0
  57. package/src/platforms/vtex/clients/search/types/AttributeSearchResult.ts +61 -0
  58. package/src/platforms/vtex/clients/search/types/ProductSearchResult.ts +223 -0
  59. package/src/platforms/vtex/index.ts +62 -0
  60. package/src/platforms/vtex/loaders/index.ts +16 -0
  61. package/src/platforms/vtex/loaders/simulation.ts +42 -0
  62. package/src/platforms/vtex/loaders/sku.ts +61 -0
  63. package/src/platforms/vtex/resolvers/aggregateOffer.ts +20 -0
  64. package/src/platforms/vtex/resolvers/aggregateRating.ts +7 -0
  65. package/src/platforms/vtex/resolvers/collection.ts +43 -0
  66. package/src/platforms/vtex/resolvers/facet.ts +11 -0
  67. package/src/platforms/vtex/resolvers/facetValue.ts +11 -0
  68. package/src/platforms/vtex/resolvers/mutation.ts +5 -0
  69. package/src/platforms/vtex/resolvers/offer.ts +26 -0
  70. package/src/platforms/vtex/resolvers/organization.ts +5 -0
  71. package/src/platforms/vtex/resolvers/product.ts +75 -0
  72. package/src/platforms/vtex/resolvers/productGroup.ts +9 -0
  73. package/src/platforms/vtex/resolvers/query.ts +115 -0
  74. package/src/platforms/vtex/resolvers/review.ts +11 -0
  75. package/src/platforms/vtex/resolvers/searchResult.ts +46 -0
  76. package/src/platforms/vtex/resolvers/seo.ts +10 -0
  77. package/src/platforms/vtex/resolvers/validateCart.ts +166 -0
  78. package/src/platforms/vtex/utils/enhanceSku.ts +8 -0
  79. package/src/platforms/vtex/utils/facets.ts +31 -0
  80. package/src/platforms/vtex/utils/slugify.ts +4 -0
  81. package/src/platforms/vtex/utils/sort.ts +10 -0
  82. package/src/typeDefs/aggregateOffer.graphql +10 -0
  83. package/src/typeDefs/aggregateRating.graphql +4 -0
  84. package/src/typeDefs/author.graphql +3 -0
  85. package/src/typeDefs/brand.graphql +3 -0
  86. package/src/typeDefs/breadcrumb.graphql +10 -0
  87. package/src/typeDefs/cart.graphql +13 -0
  88. package/src/typeDefs/collection.graphql +26 -0
  89. package/src/typeDefs/facet.graphql +14 -0
  90. package/src/typeDefs/image.graphql +9 -0
  91. package/src/typeDefs/index.ts +47 -0
  92. package/src/typeDefs/mutation.graphql +4 -0
  93. package/src/typeDefs/offer.graphql +21 -0
  94. package/src/typeDefs/order.graphql +9 -0
  95. package/src/typeDefs/organization.graphql +7 -0
  96. package/src/typeDefs/pageInfo.graphql +8 -0
  97. package/src/typeDefs/product.graphql +25 -0
  98. package/src/typeDefs/productGroup.graphql +5 -0
  99. package/src/typeDefs/query.graphql +64 -0
  100. package/src/typeDefs/review.graphql +9 -0
  101. package/src/typeDefs/seo.graphql +6 -0
  102. package/src/typeDefs/status.graphql +5 -0
  103. package/src/typings/schema.d.ts +7 -0
@@ -0,0 +1,115 @@
1
+ import { enhanceSku } from '../utils/enhanceSku'
2
+ import { transformSelectedFacet } from '../utils/facets'
3
+ import { SORT_MAP } from '../utils/sort'
4
+ import type {
5
+ QueryProductArgs,
6
+ QueryAllCollectionsArgs,
7
+ QueryAllProductsArgs,
8
+ QuerySearchArgs,
9
+ } from '../../../__generated__/schema'
10
+ import type { CategoryTree } from '../clients/commerce/types/CategoryTree'
11
+ import type { Context } from '../index'
12
+
13
+ export const Query = {
14
+ product: async (_: unknown, { locator }: QueryProductArgs, ctx: Context) => {
15
+ const {
16
+ loaders: { skuLoader },
17
+ } = ctx
18
+
19
+ return skuLoader.load(locator.map(transformSelectedFacet))
20
+ },
21
+ search: async (
22
+ _: unknown,
23
+ { first, after: maybeAfter, sort, term, selectedFacets }: QuerySearchArgs
24
+ ) => {
25
+ const after = maybeAfter ? Number(maybeAfter) : 0
26
+ const searchArgs = {
27
+ page: Math.ceil(after / first),
28
+ count: first,
29
+ query: term,
30
+ sort: SORT_MAP[sort ?? 'score_desc'],
31
+ selectedFacets: selectedFacets?.map(transformSelectedFacet) ?? [],
32
+ }
33
+
34
+ return searchArgs
35
+ },
36
+ allProducts: async (
37
+ _: unknown,
38
+ { first, after: maybeAfter }: QueryAllProductsArgs,
39
+ ctx: Context
40
+ ) => {
41
+ const {
42
+ clients: { search },
43
+ } = ctx
44
+
45
+ const after = maybeAfter ? Number(maybeAfter) : 0
46
+ const products = await search.products({
47
+ page: Math.ceil(after / first),
48
+ count: first,
49
+ })
50
+
51
+ const skus = products.products
52
+ .map((product) => product.skus.map((sku) => enhanceSku(sku, product)))
53
+ .flat()
54
+ .filter((sku) => sku.sellers.length > 0)
55
+
56
+ return {
57
+ pageInfo: {
58
+ hasNextPage: products.pagination.after.length > 0,
59
+ hasPreviousPage: products.pagination.before.length > 0,
60
+ startCursor: '0',
61
+ endCursor: products.total.toString(),
62
+ totalCount: products.total,
63
+ },
64
+ edges: skus.map((sku, index) => ({
65
+ node: sku,
66
+ cursor: (after + index).toString(),
67
+ })),
68
+ }
69
+ },
70
+ allCollections: async (
71
+ _: unknown,
72
+ __: QueryAllCollectionsArgs,
73
+ ctx: Context
74
+ ) => {
75
+ const {
76
+ clients: { commerce },
77
+ } = ctx
78
+
79
+ const [brands, tree] = await Promise.all([
80
+ commerce.catalog.brand.list(),
81
+ commerce.catalog.category.tree(),
82
+ ])
83
+
84
+ const categories: Array<CategoryTree & { level: number }> = []
85
+ const dfs = (node: CategoryTree, level: number) => {
86
+ categories.push({ ...node, level })
87
+
88
+ for (const child of node.children) {
89
+ dfs(child, level + 1)
90
+ }
91
+ }
92
+
93
+ for (const node of tree) {
94
+ dfs(node, 0)
95
+ }
96
+
97
+ const collections = [
98
+ ...brands.map((x) => ({ ...x, type: 'brand' })),
99
+ ...categories,
100
+ ]
101
+
102
+ return {
103
+ pageInfo: {
104
+ hasNextPage: false,
105
+ hasPreviousPage: false,
106
+ startCursor: '0',
107
+ endCursor: '0',
108
+ },
109
+ edges: collections.map((node, index) => ({
110
+ node,
111
+ cursor: index.toString(),
112
+ })),
113
+ }
114
+ },
115
+ }
@@ -0,0 +1,11 @@
1
+ import type { Resolver } from '..'
2
+
3
+ export const StoreReview: Record<string, Resolver> = {
4
+ reviewRating: () => ({
5
+ ratingValue: 5,
6
+ bestRating: 5,
7
+ }),
8
+ author: () => ({
9
+ name: '',
10
+ }),
11
+ }
@@ -0,0 +1,46 @@
1
+ import { enhanceSku } from '../utils/enhanceSku'
2
+ import type { Resolver } from '..'
3
+ import type { SearchArgs } from '../clients/search'
4
+
5
+ type Root = Omit<SearchArgs, 'type'>
6
+
7
+ export const StoreSearchResult: Record<string, Resolver<Root>> = {
8
+ products: async (searchArgs, _, ctx) => {
9
+ const {
10
+ clients: { search },
11
+ } = ctx
12
+
13
+ const products = await search.products(searchArgs)
14
+
15
+ const skus = products.products
16
+ .map((product) => {
17
+ const maybeSku = product.skus.find((x) => x.sellers.length > 0)
18
+
19
+ return maybeSku && enhanceSku(maybeSku, product)
20
+ })
21
+ .filter((sku) => !!sku)
22
+
23
+ return {
24
+ pageInfo: {
25
+ hasNextPage: products.pagination.after.length > 0,
26
+ hasPreviousPage: products.pagination.before.length > 0,
27
+ startCursor: '0',
28
+ endCursor: products.total.toString(),
29
+ totalCount: products.total,
30
+ },
31
+ edges: skus.map((sku, index) => ({
32
+ node: sku,
33
+ cursor: index.toString(),
34
+ })),
35
+ }
36
+ },
37
+ facets: async (searchArgs, _, ctx) => {
38
+ const {
39
+ clients: { search: is },
40
+ } = ctx
41
+
42
+ const facets = await is.facets(searchArgs)
43
+
44
+ return facets.attributes
45
+ },
46
+ }
@@ -0,0 +1,10 @@
1
+ import type { Resolver } from '..'
2
+
3
+ type Root = { title?: string; description?: string }
4
+
5
+ export const StoreSeo: Record<string, Resolver<Root>> = {
6
+ title: ({ title }) => title ?? '',
7
+ description: ({ description }) => description ?? '',
8
+ titleTemplate: () => '',
9
+ canonical: () => '',
10
+ }
@@ -0,0 +1,166 @@
1
+ import deepEquals from 'fast-deep-equal'
2
+
3
+ import type { IStoreCart, IStoreOffer } from '../../../__generated__/schema'
4
+ import type {
5
+ OrderForm,
6
+ OrderFormItem,
7
+ OrderFormInputItem,
8
+ } from '../clients/commerce/types/OrderForm'
9
+ import type { Context } from '..'
10
+
11
+ type Indexed<T> = T & { index?: number }
12
+
13
+ const getId = (item: IStoreOffer) =>
14
+ [item.itemOffered.sku, item.seller.identifier, item.price].join('::')
15
+
16
+ const orderFormItemToOffer = (
17
+ item: OrderFormItem,
18
+ index?: number
19
+ ): Indexed<IStoreOffer> => ({
20
+ listPrice: item.listPrice / 100,
21
+ price: item.sellingPrice / 100,
22
+ quantity: item.quantity,
23
+ seller: { identifier: item.seller },
24
+ itemOffered: {
25
+ sku: item.id,
26
+ image: [],
27
+ name: item.name,
28
+ },
29
+ index,
30
+ })
31
+
32
+ const offerToOrderItemInput = (
33
+ offer: Indexed<IStoreOffer>
34
+ ): OrderFormInputItem => ({
35
+ quantity: offer.quantity,
36
+ seller: offer.seller.identifier,
37
+ id: offer.itemOffered.sku,
38
+ index: offer.index,
39
+ })
40
+
41
+ const groupById = (offers: IStoreOffer[]): Map<string, IStoreOffer> =>
42
+ offers.reduce((acc, item) => {
43
+ const id = getId(item)
44
+
45
+ acc.set(id, acc.get(id) ?? item)
46
+
47
+ return acc
48
+ }, new Map<string, IStoreOffer>())
49
+
50
+ const equals = (of1: OrderForm, of2: OrderForm) => {
51
+ const pick = ({ orderFormId, messages, items, salesChannel }: OrderForm) => ({
52
+ orderFormId,
53
+ messages,
54
+ salesChannel,
55
+ items: items.map(
56
+ ({ uniqueId, quantity, seller, sellingPrice, availability }) => ({
57
+ uniqueId,
58
+ quantity,
59
+ seller,
60
+ sellingPrice,
61
+ availability,
62
+ })
63
+ ),
64
+ })
65
+
66
+ return deepEquals(pick(of1), pick(of2))
67
+ }
68
+
69
+ /**
70
+ * This resolver implements the optimistic cart behavior. The main idea in here
71
+ * is that we receive a cart from the UI (as query params) and we validate it with
72
+ * the commerce platform. If the cart is valid, we return null, if the cart is
73
+ * invalid according to the commerce platform, we return the new cart the UI should use
74
+ * instead
75
+ *
76
+ * The algoritm is something like:
77
+ * 1. Fetch orderForm from VTEX
78
+ * 2. Compute delta changes between the orderForm and the UI's cart
79
+ * 3. Update the orderForm in VTEX platform accordingly
80
+ * 4. If any chages were made, send to the UI the new cart. Null otherwise
81
+ */
82
+ export const validateCart = async (
83
+ _: unknown,
84
+ {
85
+ cart: {
86
+ order: { orderNumber, acceptedOffer },
87
+ },
88
+ }: { cart: IStoreCart },
89
+ ctx: Context
90
+ ) => {
91
+ const {
92
+ clients: { commerce },
93
+ loaders: { skuLoader },
94
+ } = ctx
95
+
96
+ // Step1: Get OrderForm from VTEX Commerce
97
+ const orderForm = await commerce.checkout.orderForm({
98
+ id: orderNumber,
99
+ })
100
+
101
+ // Step2: Process items from both browser and checkout so they have the same shape
102
+ const browserItemsById = groupById(acceptedOffer)
103
+ const originItemsById = groupById(orderForm.items.map(orderFormItemToOffer))
104
+ const browserItems = Array.from(browserItemsById.values()) // items on the user's browser
105
+ const originItems = Array.from(originItemsById.values()) // items on the VTEX platform backend
106
+
107
+ // Step3: Compute delta changes
108
+ const { itemsToAdd, itemsToUpdate } = browserItems.reduce(
109
+ (acc, item) => {
110
+ const maybeOriginItem = originItemsById.get(getId(item))
111
+
112
+ if (!maybeOriginItem) {
113
+ acc.itemsToAdd.push(item)
114
+ } else {
115
+ acc.itemsToUpdate.push({
116
+ ...maybeOriginItem,
117
+ quantity: item.quantity,
118
+ })
119
+ }
120
+
121
+ return acc
122
+ },
123
+ {
124
+ itemsToAdd: [] as IStoreOffer[],
125
+ itemsToUpdate: [] as IStoreOffer[],
126
+ }
127
+ )
128
+
129
+ const itemsToDelete = originItems
130
+ .filter((item) => !browserItemsById.has(getId(item)))
131
+ .map((item) => ({ ...item, quantity: 0 }))
132
+
133
+ const changes = [...itemsToAdd, ...itemsToUpdate, ...itemsToDelete].map(
134
+ offerToOrderItemInput
135
+ )
136
+
137
+ if (changes.length === 0) {
138
+ return null
139
+ }
140
+
141
+ // Step4: Apply delta changes to order form
142
+ const updatedOrderForm = await commerce.checkout.updateOrderFormItems({
143
+ id: orderForm.orderFormId,
144
+ orderItems: changes,
145
+ })
146
+
147
+ // Step5: If no changes detected before/after updating orderForm, the order is validated
148
+ if (equals(orderForm, updatedOrderForm)) {
149
+ return null
150
+ }
151
+
152
+ // Step6: There were changes, convert orderForm to StoreOrder
153
+ return {
154
+ order: {
155
+ orderNumber: updatedOrderForm.orderFormId,
156
+ acceptedOffer: updatedOrderForm.items.map((item) => ({
157
+ ...item,
158
+ product: skuLoader.load([{ key: 'id', value: item.id }]), // TODO: add channel
159
+ })),
160
+ },
161
+ messages: updatedOrderForm.messages.map(({ text, status }) => ({
162
+ text,
163
+ status: status.toUpperCase(),
164
+ })),
165
+ }
166
+ }
@@ -0,0 +1,8 @@
1
+ import type { Product, Sku } from '../clients/search/types/ProductSearchResult'
2
+
3
+ export type EnhancedSku = Sku & { isVariantOf: Product }
4
+
5
+ export const enhanceSku = (sku: Sku, product: Product): EnhancedSku => ({
6
+ ...sku,
7
+ isVariantOf: product,
8
+ })
@@ -0,0 +1,31 @@
1
+ export interface SelectedFacet {
2
+ key: string
3
+ value: string
4
+ }
5
+
6
+ const getIdFromSlug = (slug: string) => {
7
+ const id = slug.split('-').pop()
8
+
9
+ if (id == null) {
10
+ throw new Error('Error while extracting sku id from product slug')
11
+ }
12
+
13
+ return id
14
+ }
15
+
16
+ /**
17
+ * Transform facets from the store to VTEX platform facets.
18
+ * For instance, the channel in Store becames trade-policy in VTEX's realm
19
+ * */
20
+ export const transformSelectedFacet = ({ key, value }: SelectedFacet) => {
21
+ switch (key) {
22
+ case 'channel':
23
+ return { key: 'trade-policy', value }
24
+
25
+ case 'slug':
26
+ return { key: 'id', value: getIdFromSlug(value) }
27
+
28
+ default:
29
+ return { key, value }
30
+ }
31
+ }
@@ -0,0 +1,4 @@
1
+ import rawSlugify from 'slugify'
2
+
3
+ export const slugify = (path: string) =>
4
+ rawSlugify(path, { replacement: '-', lower: true })
@@ -0,0 +1,10 @@
1
+ export const SORT_MAP = {
2
+ price_desc: 'price:desc',
3
+ price_asc: 'price:asc',
4
+ orders_desc: 'orders:desc',
5
+ name_desc: 'name:desc',
6
+ name_asc: 'name:asc',
7
+ release_desc: 'release:desc',
8
+ discount_desc: 'discount:desc',
9
+ score_desc: '',
10
+ } as const
@@ -0,0 +1,10 @@
1
+ type StoreAggregateOffer {
2
+ # Highest spot price amongst all sellers
3
+ highPrice: Float!
4
+ # Lowest spot price amongst all sellers
5
+ lowPrice: Float!
6
+ # Number of sellers selling this sku
7
+ offerCount: Int!
8
+ priceCurrency: String!
9
+ offers: [StoreOffer!]!
10
+ }
@@ -0,0 +1,4 @@
1
+ type StoreAggregateRating {
2
+ ratingValue: Float!
3
+ reviewCount: Int!
4
+ }
@@ -0,0 +1,3 @@
1
+ type StoreAuthor {
2
+ name: String!
3
+ }
@@ -0,0 +1,3 @@
1
+ type StoreBrand {
2
+ name: String!
3
+ }
@@ -0,0 +1,10 @@
1
+ type StoreListItem {
2
+ item: String!
3
+ name: String!
4
+ position: Int!
5
+ }
6
+
7
+ type StoreBreadcrumbList {
8
+ itemListElement: [StoreListItem!]!
9
+ numberOfItems: Int!
10
+ }
@@ -0,0 +1,13 @@
1
+ type StoreCartMessage {
2
+ text: String!
3
+ status: StoreStatus!
4
+ }
5
+
6
+ type StoreCart {
7
+ order: StoreOrder!
8
+ messages: [StoreCartMessage!]!
9
+ }
10
+
11
+ input IStoreCart {
12
+ order: IStoreOrder!
13
+ }
@@ -0,0 +1,26 @@
1
+ enum StoreCollectionType {
2
+ Department
3
+ Category
4
+ Brand
5
+ Cluster
6
+ }
7
+
8
+ type StoreCollectionFacet {
9
+ key: String!
10
+ value: String!
11
+ }
12
+
13
+ type StoreCollectionMeta {
14
+ selectedFacets: [StoreCollectionFacet!]!
15
+ }
16
+
17
+ type StoreCollection {
18
+ # Meta tag data
19
+ seo: StoreSeo!
20
+ # location for structured data
21
+ breadcrumbList: StoreBreadcrumbList!
22
+ meta: StoreCollectionMeta!
23
+ id: ID!
24
+ slug: String!
25
+ type: StoreCollectionType!
26
+ }
@@ -0,0 +1,14 @@
1
+ type StoreFacet {
2
+ key: String!
3
+ label: String!
4
+ values: [StoreFacetValue!]!
5
+ type: StoreFacetType!
6
+ }
7
+
8
+ type StoreFacetValue {
9
+ value: String!
10
+ label: String!
11
+ selected: Boolean!
12
+ # Number of items with this facet
13
+ quantity: Int!
14
+ }
@@ -0,0 +1,9 @@
1
+ type StoreImage {
2
+ url: String!
3
+ alternateName: String!
4
+ }
5
+
6
+ input IStoreImage {
7
+ url: String!
8
+ alternateName: String!
9
+ }
@@ -0,0 +1,47 @@
1
+ import { print } from 'graphql'
2
+
3
+ import AggregateOffer from './aggregateOffer.graphql'
4
+ import AggregateRating from './aggregateRating.graphql'
5
+ import Author from './author.graphql'
6
+ import Brand from './brand.graphql'
7
+ import Breadcrumb from './breadcrumb.graphql'
8
+ import Collection from './collection.graphql'
9
+ import Facet from './facet.graphql'
10
+ import Image from './image.graphql'
11
+ import Mutation from './mutation.graphql'
12
+ import Offer from './offer.graphql'
13
+ import Order from './order.graphql'
14
+ import Organization from './organization.graphql'
15
+ import PageInfo from './pageInfo.graphql'
16
+ import Product from './product.graphql'
17
+ import ProductGroup from './productGroup.graphql'
18
+ import Query from './query.graphql'
19
+ import Review from './review.graphql'
20
+ import Seo from './seo.graphql'
21
+ import Cart from './cart.graphql'
22
+ import Status from './status.graphql'
23
+
24
+ export const typeDefs = [
25
+ Query,
26
+ Mutation,
27
+ Brand,
28
+ Breadcrumb,
29
+ Collection,
30
+ Facet,
31
+ Image,
32
+ PageInfo,
33
+ Product,
34
+ Seo,
35
+ Offer,
36
+ AggregateRating,
37
+ Review,
38
+ Author,
39
+ ProductGroup,
40
+ Organization,
41
+ AggregateOffer,
42
+ Order,
43
+ Cart,
44
+ Status,
45
+ ]
46
+ .map(print)
47
+ .join('\n')
@@ -0,0 +1,4 @@
1
+ type Mutation {
2
+ # Returns the order if anything changed with the order. Null if the order is valid
3
+ validateCart(cart: IStoreCart!): StoreCart
4
+ }
@@ -0,0 +1,21 @@
1
+ type StoreOffer {
2
+ listPrice: Float!
3
+ sellingPrice: Float!
4
+ priceCurrency: String!
5
+ # Also known as spotPrice
6
+ price: Float!
7
+ priceValidUntil: String!
8
+ itemCondition: String!
9
+ availability: String!
10
+ seller: StoreOrganization!
11
+ itemOffered: StoreProduct!
12
+ quantity: Int!
13
+ }
14
+
15
+ input IStoreOffer {
16
+ price: Float!
17
+ listPrice: Float!
18
+ seller: IStoreOrganization!
19
+ itemOffered: IStoreProduct!
20
+ quantity: Int!
21
+ }
@@ -0,0 +1,9 @@
1
+ type StoreOrder {
2
+ orderNumber: String!
3
+ acceptedOffer: [StoreOffer!]!
4
+ }
5
+
6
+ input IStoreOrder {
7
+ orderNumber: String!
8
+ acceptedOffer: [IStoreOffer!]!
9
+ }
@@ -0,0 +1,7 @@
1
+ type StoreOrganization {
2
+ identifier: String!
3
+ }
4
+
5
+ input IStoreOrganization {
6
+ identifier: String!
7
+ }
@@ -0,0 +1,8 @@
1
+ type StorePageInfo {
2
+ hasNextPage: Boolean!
3
+ hasPreviousPage: Boolean!
4
+ startCursor: String!
5
+ endCursor: String!
6
+ # Total number of items(products/collections), not pages
7
+ totalCount: Int!
8
+ }
@@ -0,0 +1,25 @@
1
+ type StoreProduct {
2
+ # Meta tag data
3
+ seo: StoreSeo!
4
+ # Location for structured data
5
+ breadcrumbList: StoreBreadcrumbList!
6
+ # Where to retrieve this entity
7
+ slug: String!
8
+ name: String!
9
+ productID: String!
10
+ brand: StoreBrand!
11
+ description: String!
12
+ image: [StoreImage!]!
13
+ offers: StoreAggregateOffer!
14
+ sku: String!
15
+ gtin: String!
16
+ review: [StoreReview!]!
17
+ aggregateRating: StoreAggregateRating!
18
+ isVariantOf: StoreProductGroup!
19
+ }
20
+
21
+ input IStoreProduct {
22
+ sku: String!
23
+ name: String!
24
+ image: [IStoreImage!]!
25
+ }
@@ -0,0 +1,5 @@
1
+ type StoreProductGroup {
2
+ hasVariant: [StoreProduct!]!
3
+ productGroupID: String!
4
+ name: String!
5
+ }