mirror of
https://github.com/vercel/commerce.git
synced 2025-05-16 14:36:59 +00:00
Static content done
This commit is contained in:
parent
a8e49ee3f4
commit
8fc54664da
@ -4,11 +4,14 @@ documents: 'lib/**/*.graphql'
|
|||||||
generates:
|
generates:
|
||||||
lib/saleor/generated/:
|
lib/saleor/generated/:
|
||||||
preset: 'client'
|
preset: 'client'
|
||||||
|
presetConfig:
|
||||||
|
fragmentMasking: false
|
||||||
config:
|
config:
|
||||||
defaultScalarType: 'unknown'
|
defaultScalarType: 'unknown'
|
||||||
useTypeImports: true
|
useTypeImports: true
|
||||||
dedupeFragments: true
|
dedupeFragments: true
|
||||||
skipTypename: true
|
skipTypename: true
|
||||||
|
documentMode: 'string'
|
||||||
scalars:
|
scalars:
|
||||||
_Any: 'unknown'
|
_Any: 'unknown'
|
||||||
Date: 'string'
|
Date: 'string'
|
||||||
|
78
lib/saleor/editorjs.ts
Normal file
78
lib/saleor/editorjs.ts
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import { invariant } from './utils';
|
||||||
|
|
||||||
|
type EditorJsHeaderBlock = {
|
||||||
|
type: 'header';
|
||||||
|
data: { text: string; level: 1 | 2 | 3 | 4 | 5 | 6 };
|
||||||
|
};
|
||||||
|
type EditorJsParagraphBlock = { type: 'paragraph'; data: { text: string } };
|
||||||
|
type EditorJsListBlock = {
|
||||||
|
type: 'list';
|
||||||
|
data: { style: 'unordered' | 'ordered'; items: string[] };
|
||||||
|
};
|
||||||
|
|
||||||
|
type EditorJsBlockCommon = { id: string };
|
||||||
|
type EditorJsBlocks = EditorJsHeaderBlock | EditorJsParagraphBlock | EditorJsListBlock;
|
||||||
|
|
||||||
|
type EditorJsBlock = EditorJsBlocks & EditorJsBlockCommon;
|
||||||
|
|
||||||
|
interface EditorJsResponse {
|
||||||
|
blocks: readonly EditorJsBlock[];
|
||||||
|
time: number;
|
||||||
|
version: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseEditorJson = (content: string): EditorJsResponse | null => {
|
||||||
|
try {
|
||||||
|
const data: EditorJsResponse = JSON.parse(content);
|
||||||
|
// manually validate it has more or less proper shape
|
||||||
|
invariant(data && 'blocks' in data, `Invalid shape`);
|
||||||
|
invariant(Array.isArray(data.blocks), `Invalid shape`);
|
||||||
|
invariant(
|
||||||
|
data.blocks.every((item) => 'type' in item && 'data' in item),
|
||||||
|
`Invalid shape`
|
||||||
|
);
|
||||||
|
return data;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const parseEditorJsToHtml = (content: string) => {
|
||||||
|
const data = parseEditorJson(content);
|
||||||
|
if (!data) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const html = data.blocks
|
||||||
|
.map((block) => {
|
||||||
|
switch (block.type) {
|
||||||
|
case 'header':
|
||||||
|
return header(block.data);
|
||||||
|
case 'list':
|
||||||
|
return list(block.data);
|
||||||
|
case 'paragraph':
|
||||||
|
return paragraph(block.data);
|
||||||
|
default:
|
||||||
|
console.warn(`Unknown block type: ${JSON.stringify(block)}`);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.join('');
|
||||||
|
|
||||||
|
return html;
|
||||||
|
};
|
||||||
|
|
||||||
|
function list(data: EditorJsListBlock['data']): string {
|
||||||
|
const el = data.style === 'ordered' ? 'ul' : 'ol';
|
||||||
|
const items = data.items.map((item) => `<li>${item}</li>`).join('');
|
||||||
|
return `<${el}>${items}</${el}>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function paragraph({ text }: EditorJsParagraphBlock['data']): string {
|
||||||
|
return `<p>${text}</p>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function header({ level, text }: EditorJsHeaderBlock['data']): string {
|
||||||
|
return `<h${level}>${text}</h${level}>`;
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import * as types from './graphql';
|
import * as types from './graphql';
|
||||||
import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map of all GraphQL operations in the project.
|
* Map of all GraphQL operations in the project.
|
||||||
@ -15,6 +14,10 @@ import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-
|
|||||||
const documents = {
|
const documents = {
|
||||||
'fragment FeaturedProduct on Product {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n}':
|
'fragment FeaturedProduct on Product {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n}':
|
||||||
types.FeaturedProductFragmentDoc,
|
types.FeaturedProductFragmentDoc,
|
||||||
|
'query GetCategoryBySlug($slug: String!) {\n category(slug: $slug) {\n id\n name\n slug\n description\n seoTitle\n seoDescription\n }\n}':
|
||||||
|
types.GetCategoryBySlugDocument,
|
||||||
|
'query GetCategoryProductsBySlug($slug: String!) {\n category(slug: $slug) {\n products(channel: "default-channel", first: 100) {\n edges {\n node {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n }\n }\n }\n }\n}':
|
||||||
|
types.GetCategoryProductsBySlugDocument,
|
||||||
'query GetCollectionBySlug($slug: String!) {\n collection(channel: "default-channel", slug: $slug) {\n id\n name\n slug\n description\n seoTitle\n seoDescription\n }\n}':
|
'query GetCollectionBySlug($slug: String!) {\n collection(channel: "default-channel", slug: $slug) {\n id\n name\n slug\n description\n seoTitle\n seoDescription\n }\n}':
|
||||||
types.GetCollectionBySlugDocument,
|
types.GetCollectionBySlugDocument,
|
||||||
'query GetCollectionProductsBySlug($slug: String!) {\n collection(channel: "default-channel", slug: $slug) {\n products(first: 100) {\n edges {\n node {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n }\n }\n }\n }\n}':
|
'query GetCollectionProductsBySlug($slug: String!) {\n collection(channel: "default-channel", slug: $slug) {\n products(first: 100) {\n edges {\n node {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n }\n }\n }\n }\n}':
|
||||||
@ -23,11 +26,13 @@ const documents = {
|
|||||||
types.GetCollectionsDocument,
|
types.GetCollectionsDocument,
|
||||||
'query GetFeaturedProducts($first: Int!) {\n products(first: $first, channel: "default-channel") {\n edges {\n node {\n ...FeaturedProduct\n }\n }\n }\n}':
|
'query GetFeaturedProducts($first: Int!) {\n products(first: $first, channel: "default-channel") {\n edges {\n node {\n ...FeaturedProduct\n }\n }\n }\n}':
|
||||||
types.GetFeaturedProductsDocument,
|
types.GetFeaturedProductsDocument,
|
||||||
'query GetMenuBySlug($slug: String!) {\n menu(slug: $slug, channel: "default-channel") {\n id\n slug\n name\n items {\n id\n name\n url\n collection {\n slug\n }\n children {\n id\n collection {\n slug\n }\n }\n }\n }\n}':
|
'fragment MenuItem on MenuItem {\n id\n name\n url\n collection {\n slug\n }\n category {\n slug\n }\n page {\n slug\n }\n}\n\nquery GetMenuBySlug($slug: String!) {\n menu(slug: $slug, channel: "default-channel") {\n id\n slug\n name\n items {\n ...MenuItem\n children {\n ...MenuItem\n children {\n ...MenuItem\n children {\n ...MenuItem\n }\n }\n }\n }\n }\n}':
|
||||||
types.GetMenuBySlugDocument,
|
types.MenuItemFragmentDoc,
|
||||||
'query GetPageBySlug($slug: String!) {\n page(slug: $slug) {\n id\n title\n slug\n content\n seoTitle\n seoDescription\n created\n }\n}':
|
'query GetPageBySlug($slug: String!) {\n page(slug: $slug) {\n id\n title\n slug\n content\n seoTitle\n seoDescription\n created\n }\n}':
|
||||||
types.GetPageBySlugDocument,
|
types.GetPageBySlugDocument,
|
||||||
'query GetProductBySlug($slug: String!) {\n product(slug: $slug) {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n }\n}':
|
'query GetPages {\n pages(first: 10) {\n edges {\n node {\n id\n title\n slug\n content\n seoTitle\n seoDescription\n created\n }\n }\n }\n}':
|
||||||
|
types.GetPagesDocument,
|
||||||
|
'query GetProductBySlug($slug: String!) {\n product(channel: "default-channel", slug: $slug) {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n }\n}':
|
||||||
types.GetProductBySlugDocument,
|
types.GetProductBySlugDocument,
|
||||||
'query SearchProducts($search: String!, $sortBy: ProductOrderField!, $sortDirection: OrderDirection!) {\n products(\n first: 100\n channel: "default-channel"\n sortBy: {field: $sortBy, direction: $sortDirection}\n filter: {search: $search}\n ) {\n edges {\n node {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n }\n }\n }\n}':
|
'query SearchProducts($search: String!, $sortBy: ProductOrderField!, $sortDirection: OrderDirection!) {\n products(\n first: 100\n channel: "default-channel"\n sortBy: {field: $sortBy, direction: $sortDirection}\n filter: {search: $search}\n ) {\n edges {\n node {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n }\n }\n }\n}':
|
||||||
types.SearchProductsDocument,
|
types.SearchProductsDocument,
|
||||||
@ -37,82 +42,83 @@ const documents = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
*
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* const query = graphql(`query GetUser($id: ID!) { user(id: $id) { name } }`);
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* The query argument is unknown!
|
|
||||||
* Please regenerate the types.
|
|
||||||
*/
|
*/
|
||||||
export function graphql(source: string): unknown;
|
export function graphql(
|
||||||
|
source: 'fragment FeaturedProduct on Product {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n}'
|
||||||
|
): typeof import('./graphql').FeaturedProductFragmentDoc;
|
||||||
/**
|
/**
|
||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
*/
|
*/
|
||||||
export function graphql(
|
export function graphql(
|
||||||
source: 'fragment FeaturedProduct on Product {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n}'
|
source: 'query GetCategoryBySlug($slug: String!) {\n category(slug: $slug) {\n id\n name\n slug\n description\n seoTitle\n seoDescription\n }\n}'
|
||||||
): (typeof documents)['fragment FeaturedProduct on Product {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n}'];
|
): typeof import('./graphql').GetCategoryBySlugDocument;
|
||||||
|
/**
|
||||||
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
|
*/
|
||||||
|
export function graphql(
|
||||||
|
source: 'query GetCategoryProductsBySlug($slug: String!) {\n category(slug: $slug) {\n products(channel: "default-channel", first: 100) {\n edges {\n node {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n }\n }\n }\n }\n}'
|
||||||
|
): typeof import('./graphql').GetCategoryProductsBySlugDocument;
|
||||||
/**
|
/**
|
||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
*/
|
*/
|
||||||
export function graphql(
|
export function graphql(
|
||||||
source: 'query GetCollectionBySlug($slug: String!) {\n collection(channel: "default-channel", slug: $slug) {\n id\n name\n slug\n description\n seoTitle\n seoDescription\n }\n}'
|
source: 'query GetCollectionBySlug($slug: String!) {\n collection(channel: "default-channel", slug: $slug) {\n id\n name\n slug\n description\n seoTitle\n seoDescription\n }\n}'
|
||||||
): (typeof documents)['query GetCollectionBySlug($slug: String!) {\n collection(channel: "default-channel", slug: $slug) {\n id\n name\n slug\n description\n seoTitle\n seoDescription\n }\n}'];
|
): typeof import('./graphql').GetCollectionBySlugDocument;
|
||||||
/**
|
/**
|
||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
*/
|
*/
|
||||||
export function graphql(
|
export function graphql(
|
||||||
source: 'query GetCollectionProductsBySlug($slug: String!) {\n collection(channel: "default-channel", slug: $slug) {\n products(first: 100) {\n edges {\n node {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n }\n }\n }\n }\n}'
|
source: 'query GetCollectionProductsBySlug($slug: String!) {\n collection(channel: "default-channel", slug: $slug) {\n products(first: 100) {\n edges {\n node {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n }\n }\n }\n }\n}'
|
||||||
): (typeof documents)['query GetCollectionProductsBySlug($slug: String!) {\n collection(channel: "default-channel", slug: $slug) {\n products(first: 100) {\n edges {\n node {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n }\n }\n }\n }\n}'];
|
): typeof import('./graphql').GetCollectionProductsBySlugDocument;
|
||||||
/**
|
/**
|
||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
*/
|
*/
|
||||||
export function graphql(
|
export function graphql(
|
||||||
source: 'query GetCollections {\n collections(channel: "default-channel", first: 100) {\n edges {\n node {\n id\n name\n slug\n description\n seoTitle\n seoDescription\n }\n }\n }\n}'
|
source: 'query GetCollections {\n collections(channel: "default-channel", first: 100) {\n edges {\n node {\n id\n name\n slug\n description\n seoTitle\n seoDescription\n }\n }\n }\n}'
|
||||||
): (typeof documents)['query GetCollections {\n collections(channel: "default-channel", first: 100) {\n edges {\n node {\n id\n name\n slug\n description\n seoTitle\n seoDescription\n }\n }\n }\n}'];
|
): typeof import('./graphql').GetCollectionsDocument;
|
||||||
/**
|
/**
|
||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
*/
|
*/
|
||||||
export function graphql(
|
export function graphql(
|
||||||
source: 'query GetFeaturedProducts($first: Int!) {\n products(first: $first, channel: "default-channel") {\n edges {\n node {\n ...FeaturedProduct\n }\n }\n }\n}'
|
source: 'query GetFeaturedProducts($first: Int!) {\n products(first: $first, channel: "default-channel") {\n edges {\n node {\n ...FeaturedProduct\n }\n }\n }\n}'
|
||||||
): (typeof documents)['query GetFeaturedProducts($first: Int!) {\n products(first: $first, channel: "default-channel") {\n edges {\n node {\n ...FeaturedProduct\n }\n }\n }\n}'];
|
): typeof import('./graphql').GetFeaturedProductsDocument;
|
||||||
/**
|
/**
|
||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
*/
|
*/
|
||||||
export function graphql(
|
export function graphql(
|
||||||
source: 'query GetMenuBySlug($slug: String!) {\n menu(slug: $slug, channel: "default-channel") {\n id\n slug\n name\n items {\n id\n name\n url\n collection {\n slug\n }\n children {\n id\n collection {\n slug\n }\n }\n }\n }\n}'
|
source: 'fragment MenuItem on MenuItem {\n id\n name\n url\n collection {\n slug\n }\n category {\n slug\n }\n page {\n slug\n }\n}\n\nquery GetMenuBySlug($slug: String!) {\n menu(slug: $slug, channel: "default-channel") {\n id\n slug\n name\n items {\n ...MenuItem\n children {\n ...MenuItem\n children {\n ...MenuItem\n children {\n ...MenuItem\n }\n }\n }\n }\n }\n}'
|
||||||
): (typeof documents)['query GetMenuBySlug($slug: String!) {\n menu(slug: $slug, channel: "default-channel") {\n id\n slug\n name\n items {\n id\n name\n url\n collection {\n slug\n }\n children {\n id\n collection {\n slug\n }\n }\n }\n }\n}'];
|
): typeof import('./graphql').MenuItemFragmentDoc;
|
||||||
/**
|
/**
|
||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
*/
|
*/
|
||||||
export function graphql(
|
export function graphql(
|
||||||
source: 'query GetPageBySlug($slug: String!) {\n page(slug: $slug) {\n id\n title\n slug\n content\n seoTitle\n seoDescription\n created\n }\n}'
|
source: 'query GetPageBySlug($slug: String!) {\n page(slug: $slug) {\n id\n title\n slug\n content\n seoTitle\n seoDescription\n created\n }\n}'
|
||||||
): (typeof documents)['query GetPageBySlug($slug: String!) {\n page(slug: $slug) {\n id\n title\n slug\n content\n seoTitle\n seoDescription\n created\n }\n}'];
|
): typeof import('./graphql').GetPageBySlugDocument;
|
||||||
/**
|
/**
|
||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
*/
|
*/
|
||||||
export function graphql(
|
export function graphql(
|
||||||
source: 'query GetProductBySlug($slug: String!) {\n product(slug: $slug) {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n }\n}'
|
source: 'query GetPages {\n pages(first: 10) {\n edges {\n node {\n id\n title\n slug\n content\n seoTitle\n seoDescription\n created\n }\n }\n }\n}'
|
||||||
): (typeof documents)['query GetProductBySlug($slug: String!) {\n product(slug: $slug) {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n }\n}'];
|
): typeof import('./graphql').GetPagesDocument;
|
||||||
|
/**
|
||||||
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
|
*/
|
||||||
|
export function graphql(
|
||||||
|
source: 'query GetProductBySlug($slug: String!) {\n product(channel: "default-channel", slug: $slug) {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n }\n}'
|
||||||
|
): typeof import('./graphql').GetProductBySlugDocument;
|
||||||
/**
|
/**
|
||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
*/
|
*/
|
||||||
export function graphql(
|
export function graphql(
|
||||||
source: 'query SearchProducts($search: String!, $sortBy: ProductOrderField!, $sortDirection: OrderDirection!) {\n products(\n first: 100\n channel: "default-channel"\n sortBy: {field: $sortBy, direction: $sortDirection}\n filter: {search: $search}\n ) {\n edges {\n node {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n }\n }\n }\n}'
|
source: 'query SearchProducts($search: String!, $sortBy: ProductOrderField!, $sortDirection: OrderDirection!) {\n products(\n first: 100\n channel: "default-channel"\n sortBy: {field: $sortBy, direction: $sortDirection}\n filter: {search: $search}\n ) {\n edges {\n node {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n }\n }\n }\n}'
|
||||||
): (typeof documents)['query SearchProducts($search: String!, $sortBy: ProductOrderField!, $sortDirection: OrderDirection!) {\n products(\n first: 100\n channel: "default-channel"\n sortBy: {field: $sortBy, direction: $sortDirection}\n filter: {search: $search}\n ) {\n edges {\n node {\n id\n slug\n name\n isAvailableForPurchase\n description\n seoTitle\n seoDescription\n pricing {\n priceRange {\n start {\n gross {\n currency\n amount\n }\n }\n stop {\n gross {\n currency\n amount\n }\n }\n }\n }\n media {\n url(size: 2160)\n type\n alt\n }\n collections {\n name\n }\n updatedAt\n variants {\n id\n name\n pricing {\n price {\n gross {\n currency\n amount\n }\n }\n }\n }\n }\n }\n }\n}'];
|
): typeof import('./graphql').SearchProductsDocument;
|
||||||
/**
|
/**
|
||||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||||
*/
|
*/
|
||||||
export function graphql(
|
export function graphql(
|
||||||
source: 'query GetProducts {\n products(first: 10, channel: "default-channel") {\n edges {\n node {\n name\n }\n }\n }\n}'
|
source: 'query GetProducts {\n products(first: 10, channel: "default-channel") {\n edges {\n node {\n name\n }\n }\n }\n}'
|
||||||
): (typeof documents)['query GetProducts {\n products(first: 10, channel: "default-channel") {\n edges {\n node {\n name\n }\n }\n }\n}'];
|
): typeof import('./graphql').GetProductsDocument;
|
||||||
|
|
||||||
export function graphql(source: string) {
|
export function graphql(source: string) {
|
||||||
return (documents as any)[source] ?? {};
|
return (documents as any)[source] ?? {};
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> =
|
|
||||||
TDocumentNode extends DocumentNode<infer TType, any> ? TType : never;
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,2 +1 @@
|
|||||||
export * from './fragment-masking';
|
|
||||||
export * from './gql';
|
export * from './gql';
|
||||||
|
@ -1,16 +1,20 @@
|
|||||||
import type { TypedDocumentNode } from '@graphql-typed-document-node/core';
|
import { Cart, Collection, Menu, Page, Product } from 'lib/types';
|
||||||
import { print } from 'graphql';
|
import { parseEditorJsToHtml } from './editorjs';
|
||||||
import { Collection, Menu, Page, Product } from 'lib/types';
|
|
||||||
import {
|
import {
|
||||||
|
GetCategoryBySlugDocument,
|
||||||
|
GetCategoryProductsBySlugDocument,
|
||||||
GetCollectionBySlugDocument,
|
GetCollectionBySlugDocument,
|
||||||
GetCollectionProductsBySlugDocument,
|
GetCollectionProductsBySlugDocument,
|
||||||
GetCollectionsDocument,
|
GetCollectionsDocument,
|
||||||
GetMenuBySlugDocument,
|
GetMenuBySlugDocument,
|
||||||
GetPageBySlugDocument,
|
GetPageBySlugDocument,
|
||||||
|
GetPagesDocument,
|
||||||
GetProductBySlugDocument,
|
GetProductBySlugDocument,
|
||||||
|
MenuItemFragment,
|
||||||
OrderDirection,
|
OrderDirection,
|
||||||
ProductOrderField,
|
ProductOrderField,
|
||||||
SearchProductsDocument
|
SearchProductsDocument,
|
||||||
|
TypedDocumentString
|
||||||
} from './generated/graphql';
|
} from './generated/graphql';
|
||||||
import { invariant } from './utils';
|
import { invariant } from './utils';
|
||||||
|
|
||||||
@ -28,7 +32,7 @@ export async function saleorFetch<Result, Variables>({
|
|||||||
headers,
|
headers,
|
||||||
cache = 'force-cache'
|
cache = 'force-cache'
|
||||||
}: {
|
}: {
|
||||||
query: TypedDocumentNode<Result, Variables>;
|
query: TypedDocumentString<Result, Variables>;
|
||||||
variables: Variables;
|
variables: Variables;
|
||||||
headers?: HeadersInit;
|
headers?: HeadersInit;
|
||||||
cache?: RequestCache;
|
cache?: RequestCache;
|
||||||
@ -42,7 +46,7 @@ export async function saleorFetch<Result, Variables>({
|
|||||||
...headers
|
...headers
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
query: print(query),
|
query: query.toString(),
|
||||||
...(variables && { variables })
|
...(variables && { variables })
|
||||||
}),
|
}),
|
||||||
cache,
|
cache,
|
||||||
@ -138,7 +142,9 @@ export async function getProduct(handle: string): Promise<Product | undefined> {
|
|||||||
availableForSale: saleorProduct.product.isAvailableForPurchase || true,
|
availableForSale: saleorProduct.product.isAvailableForPurchase || true,
|
||||||
title: saleorProduct.product.name,
|
title: saleorProduct.product.name,
|
||||||
description: saleorProduct.product.description || '',
|
description: saleorProduct.product.description || '',
|
||||||
descriptionHtml: saleorProduct.product.description || '', // @todo
|
descriptionHtml: saleorProduct.product.description
|
||||||
|
? parseEditorJsToHtml(saleorProduct.product.description)
|
||||||
|
: '',
|
||||||
options: [], // @todo
|
options: [], // @todo
|
||||||
priceRange: {
|
priceRange: {
|
||||||
maxVariantPrice: {
|
maxVariantPrice: {
|
||||||
@ -174,50 +180,78 @@ export async function getProduct(handle: string): Promise<Product | undefined> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCollection(handle: string): Promise<Collection | undefined> {
|
const _getCollection = async (handle: string) =>
|
||||||
const saleorCollection = await saleorFetch({
|
(
|
||||||
query: GetCollectionBySlugDocument,
|
await saleorFetch({
|
||||||
variables: {
|
query: GetCollectionBySlugDocument,
|
||||||
slug: handle
|
variables: {
|
||||||
}
|
slug: handle
|
||||||
});
|
}
|
||||||
|
})
|
||||||
|
).collection;
|
||||||
|
const _getCategory = async (handle: string) =>
|
||||||
|
(
|
||||||
|
await saleorFetch({
|
||||||
|
query: GetCategoryBySlugDocument,
|
||||||
|
variables: {
|
||||||
|
slug: handle
|
||||||
|
}
|
||||||
|
})
|
||||||
|
).category;
|
||||||
|
|
||||||
if (!saleorCollection.collection) {
|
export async function getCollection(handle: string): Promise<Collection | undefined> {
|
||||||
|
const saleorCollection = (await _getCollection(handle)) || (await _getCategory(handle));
|
||||||
|
|
||||||
|
if (!saleorCollection) {
|
||||||
throw new Error(`Collection not found: ${handle}`);
|
throw new Error(`Collection not found: ${handle}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
handle: saleorCollection.collection.slug,
|
handle: saleorCollection.slug,
|
||||||
title: saleorCollection.collection.name,
|
title: saleorCollection.name,
|
||||||
description: saleorCollection.collection.description as string,
|
description: saleorCollection.description as string,
|
||||||
seo: {
|
seo: {
|
||||||
title: saleorCollection.collection.seoTitle || saleorCollection.collection.name,
|
title: saleorCollection.seoTitle || saleorCollection.name,
|
||||||
description: saleorCollection.collection.seoDescription || ''
|
description: saleorCollection.seoDescription || ''
|
||||||
},
|
},
|
||||||
updatedAt: '', // @todo ?
|
updatedAt: '', // @todo ?
|
||||||
path: `/search/${saleorCollection.collection.slug}`
|
path: `/search/${saleorCollection.slug}`
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleToSlug: Record<string, string> = {
|
||||||
|
'hidden-homepage-featured-items': 'featured',
|
||||||
|
'hidden-homepage-carousel': 'all-products'
|
||||||
|
};
|
||||||
|
const _getCollectionProducts = async (handle: string) =>
|
||||||
|
(
|
||||||
|
await saleorFetch({
|
||||||
|
query: GetCollectionProductsBySlugDocument,
|
||||||
|
variables: {
|
||||||
|
slug: handleToSlug[handle] || handle
|
||||||
|
}
|
||||||
|
})
|
||||||
|
).collection;
|
||||||
|
const _getCategoryProducts = async (handle: string) =>
|
||||||
|
(
|
||||||
|
await saleorFetch({
|
||||||
|
query: GetCategoryProductsBySlugDocument,
|
||||||
|
variables: {
|
||||||
|
slug: handleToSlug[handle] || handle
|
||||||
|
}
|
||||||
|
})
|
||||||
|
).category;
|
||||||
|
|
||||||
export async function getCollectionProducts(handle: string): Promise<Product[]> {
|
export async function getCollectionProducts(handle: string): Promise<Product[]> {
|
||||||
const handleToSlug: Record<string, string> = {
|
const saleorCollectionProducts =
|
||||||
'hidden-homepage-featured-items': 'featured',
|
(await _getCollectionProducts(handle)) || (await _getCategoryProducts(handle));
|
||||||
'hidden-homepage-carousel': 'all-products'
|
|
||||||
};
|
|
||||||
|
|
||||||
const saleorCollectionProducts = await saleorFetch({
|
if (!saleorCollectionProducts) {
|
||||||
query: GetCollectionProductsBySlugDocument,
|
|
||||||
variables: {
|
|
||||||
slug: handleToSlug[handle] || handle
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!saleorCollectionProducts.collection) {
|
|
||||||
throw new Error(`Collection not found: ${handle}`);
|
throw new Error(`Collection not found: ${handle}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
saleorCollectionProducts.collection.products?.edges.map((product) => {
|
saleorCollectionProducts.products?.edges.map((product) => {
|
||||||
const images =
|
const images =
|
||||||
product.node.media
|
product.node.media
|
||||||
?.filter((media) => media.type === 'IMAGE')
|
?.filter((media) => media.type === 'IMAGE')
|
||||||
@ -236,7 +270,9 @@ export async function getCollectionProducts(handle: string): Promise<Product[]>
|
|||||||
availableForSale: product.node.isAvailableForPurchase || true,
|
availableForSale: product.node.isAvailableForPurchase || true,
|
||||||
title: product.node.name,
|
title: product.node.name,
|
||||||
description: product.node.description || '',
|
description: product.node.description || '',
|
||||||
descriptionHtml: product.node.description || '', // @todo
|
descriptionHtml: product.node.description
|
||||||
|
? parseEditorJsToHtml(product.node.description)
|
||||||
|
: '',
|
||||||
options: [], // @todo
|
options: [], // @todo
|
||||||
priceRange: {
|
priceRange: {
|
||||||
maxVariantPrice: {
|
maxVariantPrice: {
|
||||||
@ -291,12 +327,47 @@ export async function getMenu(handle: string): Promise<Menu[]> {
|
|||||||
throw new Error(`Menu not found: ${handle}`);
|
throw new Error(`Menu not found: ${handle}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const result = flattenMenuItems(saleorMenu.menu.items);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
saleorMenu.menu.items?.map((item) => {
|
result
|
||||||
return {
|
.filter(
|
||||||
path: item.url || '', // @todo handle manus without url
|
(menu) =>
|
||||||
title: item.name
|
menu.path &&
|
||||||
};
|
// manually removing empty categories
|
||||||
|
// @todo ?
|
||||||
|
menu.path !== '/search/paints' &&
|
||||||
|
menu.path !== '/search/juices' &&
|
||||||
|
menu.path !== '/search/alcohol' &&
|
||||||
|
menu.path !== '/search/homewares' &&
|
||||||
|
menu.path !== '/search/groceries'
|
||||||
|
)
|
||||||
|
// unique by path
|
||||||
|
.filter((item1, idx, arr) => arr.findIndex((item2) => item2.path === item1.path) === idx)
|
||||||
|
.slice(0, 3)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type MenuItemWithChildren = MenuItemFragment & {
|
||||||
|
children?: null | undefined | MenuItemWithChildren[];
|
||||||
|
};
|
||||||
|
function flattenMenuItems(menuItems: null | undefined | MenuItemWithChildren[]): Menu[] {
|
||||||
|
return (
|
||||||
|
menuItems?.flatMap((item) => {
|
||||||
|
const path =
|
||||||
|
item.url ||
|
||||||
|
(item.collection
|
||||||
|
? `/search/${item.collection.slug}`
|
||||||
|
: item.category
|
||||||
|
? `/search/${item.category.slug}`
|
||||||
|
: '');
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
path: path,
|
||||||
|
title: item.name
|
||||||
|
},
|
||||||
|
...flattenMenuItems(item.children)
|
||||||
|
];
|
||||||
}) || []
|
}) || []
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -339,7 +410,9 @@ export async function getProducts({
|
|||||||
availableForSale: product.node.isAvailableForPurchase || true,
|
availableForSale: product.node.isAvailableForPurchase || true,
|
||||||
title: product.node.name,
|
title: product.node.name,
|
||||||
description: product.node.description || '',
|
description: product.node.description || '',
|
||||||
descriptionHtml: product.node.description || '', // @todo
|
descriptionHtml: product.node.description
|
||||||
|
? parseEditorJsToHtml(product.node.description)
|
||||||
|
: '',
|
||||||
options: [], // @todo
|
options: [], // @todo
|
||||||
priceRange: {
|
priceRange: {
|
||||||
maxVariantPrice: {
|
maxVariantPrice: {
|
||||||
@ -376,3 +449,41 @@ export async function getProducts({
|
|||||||
}) || []
|
}) || []
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getPages(): Promise<Page[]> {
|
||||||
|
const saleorPages = await saleorFetch({
|
||||||
|
query: GetPagesDocument,
|
||||||
|
variables: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
saleorPages.pages?.edges.map((page) => {
|
||||||
|
return {
|
||||||
|
id: page.node.id,
|
||||||
|
title: page.node.title,
|
||||||
|
handle: page.node.slug,
|
||||||
|
body: page.node.content || '',
|
||||||
|
bodySummary: page.node.seoDescription || '',
|
||||||
|
seo: {
|
||||||
|
title: page.node.seoTitle || page.node.title,
|
||||||
|
description: page.node.seoDescription || ''
|
||||||
|
},
|
||||||
|
createdAt: page.node.created,
|
||||||
|
updatedAt: page.node.created
|
||||||
|
};
|
||||||
|
}) || []
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getCart(cartId: string): Promise<Cart | null> {
|
||||||
|
// @todo
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
export async function createCart(): Promise<Cart> {
|
||||||
|
// @todo
|
||||||
|
throw new Error(`Not implemented`);
|
||||||
|
}
|
||||||
|
export async function getProductRecommendations(productId: string): Promise<Product[]> {
|
||||||
|
// @todo
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
10
lib/saleor/queries/GetCategoryBySlug.graphql
Normal file
10
lib/saleor/queries/GetCategoryBySlug.graphql
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
query GetCategoryBySlug($slug: String!) {
|
||||||
|
category(slug: $slug) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
slug
|
||||||
|
description
|
||||||
|
seoTitle
|
||||||
|
seoDescription
|
||||||
|
}
|
||||||
|
}
|
54
lib/saleor/queries/GetCategoryProductsBySlug.graphql
Normal file
54
lib/saleor/queries/GetCategoryProductsBySlug.graphql
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
query GetCategoryProductsBySlug($slug: String!) {
|
||||||
|
category(slug: $slug) {
|
||||||
|
products(channel: "default-channel", first: 100) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
slug
|
||||||
|
name
|
||||||
|
isAvailableForPurchase
|
||||||
|
description
|
||||||
|
seoTitle
|
||||||
|
seoDescription
|
||||||
|
pricing {
|
||||||
|
priceRange {
|
||||||
|
start {
|
||||||
|
gross {
|
||||||
|
currency
|
||||||
|
amount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stop {
|
||||||
|
gross {
|
||||||
|
currency
|
||||||
|
amount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
media {
|
||||||
|
url(size: 2160)
|
||||||
|
type
|
||||||
|
alt
|
||||||
|
}
|
||||||
|
collections {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
updatedAt
|
||||||
|
variants {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
pricing {
|
||||||
|
price {
|
||||||
|
gross {
|
||||||
|
currency
|
||||||
|
amount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,19 +1,32 @@
|
|||||||
|
fragment MenuItem on MenuItem {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
url
|
||||||
|
collection {
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
category {
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
page {
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
query GetMenuBySlug($slug: String!) {
|
query GetMenuBySlug($slug: String!) {
|
||||||
menu(slug: $slug, channel: "default-channel") {
|
menu(slug: $slug, channel: "default-channel") {
|
||||||
id
|
id
|
||||||
slug
|
slug
|
||||||
name
|
name
|
||||||
items {
|
items {
|
||||||
id
|
...MenuItem
|
||||||
name
|
|
||||||
url
|
|
||||||
collection {
|
|
||||||
slug
|
|
||||||
}
|
|
||||||
children {
|
children {
|
||||||
id
|
...MenuItem
|
||||||
collection {
|
children {
|
||||||
slug
|
...MenuItem
|
||||||
|
children {
|
||||||
|
...MenuItem
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
lib/saleor/queries/GetPages.graphql
Normal file
15
lib/saleor/queries/GetPages.graphql
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
query GetPages {
|
||||||
|
pages(first: 10) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
slug
|
||||||
|
content
|
||||||
|
seoTitle
|
||||||
|
seoDescription
|
||||||
|
created
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
query GetProductBySlug($slug: String!) {
|
query GetProductBySlug($slug: String!) {
|
||||||
product(slug: $slug) {
|
product(channel: "default-channel", slug: $slug) {
|
||||||
id
|
id
|
||||||
slug
|
slug
|
||||||
name
|
name
|
||||||
|
@ -23,12 +23,10 @@
|
|||||||
"*": "prettier --write --ignore-unknown"
|
"*": "prettier --write --ignore-unknown"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@graphql-typed-document-node/core": "3.2.0",
|
|
||||||
"@headlessui/react": "^1.7.10",
|
"@headlessui/react": "^1.7.10",
|
||||||
"@vercel/og": "^0.1.0",
|
"@vercel/og": "^0.1.0",
|
||||||
"clsx": "^1.2.1",
|
"clsx": "^1.2.1",
|
||||||
"framer-motion": "^8.4.0",
|
"framer-motion": "^8.4.0",
|
||||||
"graphql": "16.6.0",
|
|
||||||
"is-empty-iterable": "^3.0.0",
|
"is-empty-iterable": "^3.0.0",
|
||||||
"next": "13.3.1",
|
"next": "13.3.1",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
|
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@ -1,9 +1,6 @@
|
|||||||
lockfileVersion: '6.0'
|
lockfileVersion: '6.0'
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
'@graphql-typed-document-node/core':
|
|
||||||
specifier: 3.2.0
|
|
||||||
version: registry.npmjs.org/@graphql-typed-document-node/core@3.2.0(graphql@16.6.0)
|
|
||||||
'@headlessui/react':
|
'@headlessui/react':
|
||||||
specifier: ^1.7.10
|
specifier: ^1.7.10
|
||||||
version: 1.7.14(react-dom@18.2.0)(react@18.2.0)
|
version: 1.7.14(react-dom@18.2.0)(react@18.2.0)
|
||||||
@ -16,9 +13,6 @@ dependencies:
|
|||||||
framer-motion:
|
framer-motion:
|
||||||
specifier: ^8.4.0
|
specifier: ^8.4.0
|
||||||
version: 8.5.5(react-dom@18.2.0)(react@18.2.0)
|
version: 8.5.5(react-dom@18.2.0)(react@18.2.0)
|
||||||
graphql:
|
|
||||||
specifier: 16.6.0
|
|
||||||
version: registry.npmjs.org/graphql@16.6.0
|
|
||||||
is-empty-iterable:
|
is-empty-iterable:
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.0.0
|
version: 3.0.0
|
||||||
@ -4923,6 +4917,7 @@ packages:
|
|||||||
graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
|
graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
graphql: registry.npmjs.org/graphql@16.6.0
|
graphql: registry.npmjs.org/graphql@16.6.0
|
||||||
|
dev: true
|
||||||
|
|
||||||
registry.npmjs.org/@jridgewell/gen-mapping@0.3.3:
|
registry.npmjs.org/@jridgewell/gen-mapping@0.3.3:
|
||||||
resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz}
|
resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz}
|
||||||
@ -6080,6 +6075,7 @@ packages:
|
|||||||
name: graphql
|
name: graphql
|
||||||
version: 16.6.0
|
version: 16.6.0
|
||||||
engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0}
|
engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0}
|
||||||
|
dev: true
|
||||||
|
|
||||||
registry.npmjs.org/has-flag@3.0.0:
|
registry.npmjs.org/has-flag@3.0.0:
|
||||||
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz}
|
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user