mirror of
https://github.com/vercel/commerce.git
synced 2025-05-14 21:47:51 +00:00
feat(poc): fix type errors in transform, add simple sitemap
This commit is contained in:
parent
9c89c36008
commit
1cdb5d3343
@ -1,4 +1,4 @@
|
||||
import { getCollections, getPages, getProducts } from 'lib/shopify';
|
||||
import { getProductSeoUrls } from 'lib/shopware';
|
||||
import { MetadataRoute } from 'next';
|
||||
|
||||
const baseUrl = process.env.NEXT_PUBLIC_VERCEL_URL
|
||||
@ -11,29 +11,16 @@ export default async function sitemap(): Promise<Promise<Promise<MetadataRoute.S
|
||||
lastModified: new Date().toISOString()
|
||||
}));
|
||||
|
||||
const collectionsPromise = getCollections().then((collections) =>
|
||||
collections.map((collection) => ({
|
||||
url: `${baseUrl}${collection.path}`,
|
||||
lastModified: collection.updatedAt
|
||||
}))
|
||||
);
|
||||
|
||||
const productsPromise = getProducts({}).then((products) =>
|
||||
// @ToDo: Get categories and get cms pages
|
||||
const productsPromise = getProductSeoUrls().then((products) =>
|
||||
products.map((product) => ({
|
||||
url: `${baseUrl}/product/${product.handle}`,
|
||||
url: `${baseUrl}/product/${product.path}`,
|
||||
lastModified: product.updatedAt
|
||||
}))
|
||||
);
|
||||
|
||||
const pagesPromise = getPages().then((pages) =>
|
||||
pages.map((page) => ({
|
||||
url: `${baseUrl}/${page.handle}`,
|
||||
lastModified: page.updatedAt
|
||||
}))
|
||||
);
|
||||
|
||||
const fetchedRoutes = (
|
||||
await Promise.all([collectionsPromise, productsPromise, pagesPromise])
|
||||
await Promise.all([productsPromise])
|
||||
).flat();
|
||||
|
||||
return [...routesMap, ...fetchedRoutes];
|
||||
|
@ -1,17 +1,73 @@
|
||||
import { operations, operationPaths, components } from '@shopware/api-client/api-types';
|
||||
|
||||
type schemas = components['schemas'];
|
||||
type operationsWithoutOriginal = Omit<
|
||||
operations,
|
||||
'readProduct' | 'searchPage' | 'readProductListing'
|
||||
| 'readCategory'
|
||||
| 'readCategoryList'
|
||||
| 'readNavigation'
|
||||
| 'readProduct'
|
||||
| 'readProductCrossSellings'
|
||||
| 'readProductListing'
|
||||
| 'searchPage'
|
||||
>;
|
||||
export type extendedPaths = 'readProduct post /product' | operationPaths;
|
||||
export type extendedPaths =
|
||||
| 'readCategory post /category/{navigationId}?slots'
|
||||
| 'readCategoryList post /category'
|
||||
| 'readNavigation post /navigation/{activeId}/{rootId} sw-include-seo-urls'
|
||||
| 'readProduct post /product'
|
||||
| 'readProductCrossSellings post /product/{productId}/cross-selling'
|
||||
| 'readProductListing post /product-listing/{categoryId}'
|
||||
| 'searchPage post /search'
|
||||
| operationPaths;
|
||||
export type extendedOperations = operationsWithoutOriginal & {
|
||||
readCategory: extendedReadCategory;
|
||||
readCategoryList: extendedReadCategoryList;
|
||||
readNavigation: extendedReadNavigation;
|
||||
readProduct: extendedReadProduct;
|
||||
searchPage: extendedSearchPage;
|
||||
readProductCrossSellings: extendedReadProductCrossSellings;
|
||||
readProductListing: extendedReadProductListing;
|
||||
searchPage: extendedSearchPage;
|
||||
};
|
||||
|
||||
export type ExtendedCriteria = Omit<components['schemas']['Criteria'], 'filter'> & {
|
||||
export type ExtendedCmsBlock = Omit<schemas['CmsBlock'], 'slots'> & {
|
||||
slots?: schemas['CmsSlot'][];
|
||||
};
|
||||
export type ExtendedCmsSection = Omit<schemas['CmsSection'], 'blocks'> & {
|
||||
blocks?: ExtendedCmsBlock[];
|
||||
};
|
||||
export type ExtendedCmsPage = Omit<schemas['CmsPage'], 'sections'> & {
|
||||
sections?: ExtendedCmsSection[];
|
||||
};
|
||||
|
||||
export type ExtendedProduct = Omit<
|
||||
schemas['Product'],
|
||||
'children' | 'seoUrls' | 'options' | 'media'
|
||||
> & {
|
||||
children?: ExtendedProduct[];
|
||||
seoUrls?: schemas['SeoUrl'][];
|
||||
options?: schemas['PropertyGroupOption'][];
|
||||
media?: schemas['ProductMedia'][];
|
||||
};
|
||||
|
||||
export type ExtendedProductListingResult = Omit<schemas['ProductListingResult'], 'elements'> & {
|
||||
elements?: ExtendedProduct[];
|
||||
};
|
||||
|
||||
export type ExtendedCrossSellingElementCollection = Omit<
|
||||
schemas['CrossSellingElementCollection'],
|
||||
'products'
|
||||
> & {
|
||||
products?: ExtendedProduct[];
|
||||
};
|
||||
|
||||
export type ExtendedCategory = Omit<schemas['Category'], 'children' | 'seoUrls' | 'cmsPage'> & {
|
||||
children?: ExtendedCategory[];
|
||||
seoUrls?: schemas['SeoUrl'][];
|
||||
cmsPage?: ExtendedCmsPage;
|
||||
};
|
||||
|
||||
export type ExtendedCriteria = Omit<schemas['Criteria'], 'filter'> & {
|
||||
filter?: {
|
||||
field: string;
|
||||
type: string;
|
||||
@ -30,8 +86,25 @@ type extendedReadProduct = {
|
||||
200: {
|
||||
content: {
|
||||
'application/json': {
|
||||
elements?: components['schemas']['Product'][];
|
||||
} & components['schemas']['EntitySearchResult'];
|
||||
elements?: ExtendedProduct[];
|
||||
} & schemas['EntitySearchResult'];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
type extendedReadProductCrossSellings = {
|
||||
parameters: {
|
||||
path: {
|
||||
/** Product ID */
|
||||
productId: string;
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** Found cross sellings */
|
||||
200: {
|
||||
content: {
|
||||
'application/json': ExtendedCrossSellingElementCollection
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -106,14 +179,93 @@ type extendedSearchPage = {
|
||||
/** Using the search parameter, the server performs a text search on all records based on their data model and weighting as defined in the entity definition using the SearchRanking flag. */
|
||||
search: string;
|
||||
} & ExtendedProductCriteria &
|
||||
components['schemas']['ProductListingFlags'];
|
||||
schemas['ProductListingFlags'];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** Returns a product listing containing all products and additional fields to display a listing. */
|
||||
200: {
|
||||
content: {
|
||||
'application/json': components['schemas']['ProductListingResult'];
|
||||
'application/json': ExtendedProductListingResult;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
type extendedReadNavigation = {
|
||||
parameters: {
|
||||
header?: {
|
||||
/** Instructs Shopware to try and resolve SEO URLs for the given navigation item */
|
||||
'sw-include-seo-urls'?: boolean;
|
||||
};
|
||||
path: {
|
||||
/** Identifier of the active category in the navigation tree (if not used, just set to the same as rootId). */
|
||||
activeId: string;
|
||||
/** Identifier of the root category for your desired navigation tree. You can use it to fetch sub-trees of your navigation tree. */
|
||||
rootId: string;
|
||||
};
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
'application/json': ExtendedCriteria & {
|
||||
/** Return the categories as a tree or as a flat list. */
|
||||
buildTree?: unknown;
|
||||
/** Determines the depth of fetched navigation levels. */
|
||||
depth?: unknown;
|
||||
};
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** All available navigations */
|
||||
200: {
|
||||
content: {
|
||||
'application/json': ExtendedCategory[];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
type extendedReadCategory = {
|
||||
parameters: {
|
||||
query?: {
|
||||
/** Resolves only the given slot identifiers. The identifiers have to be seperated by a '|' character */
|
||||
slots?: string;
|
||||
};
|
||||
path: {
|
||||
/** Identifier of the category to be fetched */
|
||||
navigationId: string;
|
||||
};
|
||||
};
|
||||
requestBody?: {
|
||||
content: {
|
||||
'application/json': ExtendedCriteria &
|
||||
Omit<schemas['ProductListingCriteria'], 'filter'> &
|
||||
ExtendedCriteria;
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** The loaded category with cms page */
|
||||
200: {
|
||||
content: {
|
||||
'application/json': ExtendedCategory;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
type extendedReadCategoryList = {
|
||||
requestBody?: {
|
||||
content: {
|
||||
'application/json': ExtendedCriteria;
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** Entity search result containing categories. */
|
||||
200: {
|
||||
content: {
|
||||
'application/json': {
|
||||
elements?: ExtendedCategory[];
|
||||
} & components['schemas']['EntitySearchResult'];
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -128,14 +280,14 @@ type extendedReadProductListing = {
|
||||
};
|
||||
requestBody?: {
|
||||
content: {
|
||||
'application/json': ExtendedProductCriteria & components['schemas']['ProductListingFlags'];
|
||||
'application/json': ExtendedProductCriteria & schemas['ProductListingFlags'];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** Returns a product listing containing all products and additional fields to display a listing. */
|
||||
200: {
|
||||
content: {
|
||||
'application/json': components['schemas']['ProductListingResult'];
|
||||
'application/json': ExtendedProductListingResult;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,10 +1,17 @@
|
||||
import { createAPIClient, RequestReturnType } from '@shopware/api-client';
|
||||
import { operations } from '@shopware/api-client/api-types';
|
||||
import { extendedPaths, extendedOperations } from './api-extended';
|
||||
import {
|
||||
ApiSchemas,
|
||||
ExtendedCategory,
|
||||
ExtendedCriteria,
|
||||
ExtendedCrossSellingElementCollection,
|
||||
ExtendedProductListingResult,
|
||||
extendedOperations,
|
||||
extendedPaths
|
||||
} from './api-extended';
|
||||
import {
|
||||
CategoryListingResultSW,
|
||||
ProductListingCriteria,
|
||||
RouteNames,
|
||||
SeoURLResultSW,
|
||||
StoreNavigationTypeSW
|
||||
} from './types';
|
||||
@ -27,7 +34,7 @@ export type ApiReturnType<OPERATION_NAME extends keyof operations> = RequestRetu
|
||||
export async function requestNavigation(
|
||||
type: StoreNavigationTypeSW,
|
||||
depth: number
|
||||
): Promise<ApiSchemas['NavigationRouteResponse']> {
|
||||
): Promise<ExtendedCategory[]> {
|
||||
return await apiInstance.invoke(
|
||||
'readNavigation post /navigation/{activeId}/{rootId} sw-include-seo-urls',
|
||||
{
|
||||
@ -41,7 +48,7 @@ export async function requestNavigation(
|
||||
export async function requestCategory(
|
||||
categoryId: string,
|
||||
criteria?: Partial<ProductListingCriteria>
|
||||
): Promise<ApiSchemas['Category']> {
|
||||
): Promise<ExtendedCategory> {
|
||||
return await apiInstance.invoke('readCategory post /category/{navigationId}?slots', {
|
||||
navigationId: categoryId,
|
||||
criteria
|
||||
@ -49,21 +56,21 @@ export async function requestCategory(
|
||||
}
|
||||
|
||||
export async function requestCategoryList(
|
||||
criteria: Partial<ApiSchemas['Criteria']>
|
||||
criteria: Partial<ExtendedCriteria>
|
||||
): Promise<CategoryListingResultSW> {
|
||||
return await apiInstance.invoke('readCategoryList post /category', criteria);
|
||||
}
|
||||
|
||||
export async function requestProductsCollection(
|
||||
criteria: Partial<ProductListingCriteria>
|
||||
): Promise<ApiSchemas['ProductListingResult']> {
|
||||
): Promise<ExtendedProductListingResult> {
|
||||
return await apiInstance.invoke('readProduct post /product', criteria);
|
||||
}
|
||||
|
||||
export async function requestCategoryProductsCollection(
|
||||
categoryId: string,
|
||||
criteria: Partial<ProductListingCriteria>
|
||||
): Promise<ApiSchemas['ProductListingResult']> {
|
||||
): Promise<ExtendedProductListingResult> {
|
||||
return await apiInstance.invoke('readProductListing post /product-listing/{categoryId}', {
|
||||
...criteria,
|
||||
categoryId: categoryId
|
||||
@ -72,17 +79,35 @@ export async function requestCategoryProductsCollection(
|
||||
|
||||
export async function requestSearchCollectionProducts(
|
||||
criteria?: Partial<ProductListingCriteria>
|
||||
): Promise<ApiSchemas['ProductListingResult']> {
|
||||
): Promise<ExtendedProductListingResult> {
|
||||
return await apiInstance.invoke('searchPage post /search', {
|
||||
search: encodeURIComponent(criteria?.query || ''),
|
||||
...criteria
|
||||
});
|
||||
}
|
||||
|
||||
export async function requestSeoUrl(handle: string): Promise<SeoURLResultSW> {
|
||||
export async function requestSeoUrls(routeName: RouteNames, page: number = 1, limit: number = 100) {
|
||||
return await apiInstance.invoke('readSeoUrl post /seo-url', {
|
||||
page: 1,
|
||||
limit: 1,
|
||||
page: page,
|
||||
limit: limit,
|
||||
filter: [
|
||||
{
|
||||
type: 'equals',
|
||||
field: 'routeName',
|
||||
value: routeName
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
export async function requestSeoUrl(
|
||||
handle: string,
|
||||
page: number = 1,
|
||||
limit: number = 1
|
||||
): Promise<SeoURLResultSW> {
|
||||
return await apiInstance.invoke('readSeoUrl post /seo-url', {
|
||||
page: page,
|
||||
limit: limit,
|
||||
filter: [
|
||||
{
|
||||
type: 'multi',
|
||||
@ -108,7 +133,7 @@ export async function requestSeoUrl(handle: string): Promise<SeoURLResultSW> {
|
||||
export async function requestCrossSell(
|
||||
productId: string,
|
||||
criteria?: Partial<ProductListingCriteria>
|
||||
): Promise<ApiSchemas['CrossSellingElementCollection']> {
|
||||
): Promise<ExtendedCrossSellingElementCollection> {
|
||||
return await apiInstance.invoke(
|
||||
'readProductCrossSellings post /product/{productId}/cross-selling',
|
||||
{
|
||||
|
@ -24,7 +24,8 @@ import {
|
||||
requestNavigation,
|
||||
requestProductsCollection,
|
||||
requestSearchCollectionProducts,
|
||||
requestSeoUrl
|
||||
requestSeoUrl,
|
||||
requestSeoUrls
|
||||
} from './api';
|
||||
import {
|
||||
transformCollection,
|
||||
@ -35,6 +36,7 @@ import {
|
||||
transformProducts,
|
||||
transformStaticCollection
|
||||
} from './transform';
|
||||
import { ExtendedCategory, ExtendedProduct, ExtendedProductListingResult } from './api-extended';
|
||||
|
||||
export async function getMenu(params?: {
|
||||
type?: StoreNavigationTypeSW;
|
||||
@ -66,11 +68,9 @@ export async function getFirstSeoUrlElement(
|
||||
}
|
||||
}
|
||||
|
||||
export async function getFirstProduct(
|
||||
productId: string
|
||||
): Promise<ApiSchemas['Product'] | undefined> {
|
||||
export async function getFirstProduct(productId: string): Promise<ExtendedProduct | undefined> {
|
||||
const productCriteria = getDefaultProductCriteria(productId);
|
||||
const res: ApiSchemas['ProductListingResult'] = await requestProductsCollection(productCriteria);
|
||||
const res: ExtendedProductListingResult = await requestProductsCollection(productCriteria);
|
||||
if (res.elements && res.elements.length > 0 && res.elements[0]) {
|
||||
return res.elements[0];
|
||||
}
|
||||
@ -142,7 +142,7 @@ export async function getCollectionProducts(params?: {
|
||||
export async function getCategory(
|
||||
seoUrl: ApiSchemas['SeoUrl'],
|
||||
cms: boolean = false
|
||||
): Promise<ApiSchemas['Category']> {
|
||||
): Promise<ExtendedCategory> {
|
||||
const criteria = cms ? getDefaultCategoryWithCmsCriteria() : getDefaultCategoryCriteria();
|
||||
const resCategory = await requestCategory(seoUrl.foreignKey, criteria);
|
||||
|
||||
@ -165,8 +165,21 @@ export async function getCollection(handle: string | []) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function getProductSeoUrls() {
|
||||
const productSeoUrls: { path: string; updatedAt: string }[] = [];
|
||||
const res = await requestSeoUrls('frontend.detail.page');
|
||||
|
||||
if (res.elements && res.elements.length > 0) {
|
||||
res.elements.map((item) =>
|
||||
productSeoUrls.push({ path: item.seoPathInfo, updatedAt: item.updatedAt ?? item.createdAt })
|
||||
);
|
||||
}
|
||||
|
||||
return productSeoUrls;
|
||||
}
|
||||
|
||||
export async function getProduct(handle: string | []): Promise<Product | undefined> {
|
||||
let productSW: ApiSchemas['Product'] | undefined;
|
||||
let productSW: ExtendedProduct | undefined;
|
||||
let productId: string | undefined;
|
||||
const productHandle = transformHandle(handle);
|
||||
|
||||
@ -189,11 +202,12 @@ export async function getProduct(handle: string | []): Promise<Product | undefin
|
||||
}
|
||||
|
||||
export async function getProductRecommendations(productId: string): Promise<Product[]> {
|
||||
let products: ApiSchemas['ProductListingResult'] = {};
|
||||
let products: ExtendedProductListingResult = {};
|
||||
|
||||
const res = await requestCrossSell(productId, getDefaultCrossSellingCriteria());
|
||||
// @ToDo: Make this more dynamic to merge multiple Cross-Sellings, at the moment we only get the first one
|
||||
if (res && res[0] && res[0].products) {
|
||||
// @ts-ignore (@ToDo: fix this wrong type ...)
|
||||
products.elements = res[0].products;
|
||||
}
|
||||
|
||||
|
@ -8,9 +8,15 @@ import {
|
||||
ProductOption,
|
||||
ProductVariant
|
||||
} from './types';
|
||||
import {
|
||||
ExtendedCategory,
|
||||
ExtendedCmsPage,
|
||||
ExtendedProduct,
|
||||
ExtendedProductListingResult
|
||||
} from './api-extended';
|
||||
import { ListItem } from 'components/layout/search/filter';
|
||||
|
||||
export function transformMenu(res: ApiSchemas['NavigationRouteResponse'], type: string) {
|
||||
export function transformMenu(res: ExtendedCategory[], type: string) {
|
||||
let menu: Menu[] = [];
|
||||
|
||||
res.map((item) => menu.push(transformMenuItem(item, type)));
|
||||
@ -18,7 +24,7 @@ export function transformMenu(res: ApiSchemas['NavigationRouteResponse'], type:
|
||||
return menu;
|
||||
}
|
||||
|
||||
function transformMenuItem(item: ApiSchemas['Category'], type: string): Menu {
|
||||
function transformMenuItem(item: ExtendedCategory, type: string): Menu {
|
||||
// @ToDo: currently only footer-navigation is used for cms pages, this need to be more dynamic (shoud depending on the item)
|
||||
return {
|
||||
id: item.id ?? '',
|
||||
@ -36,11 +42,11 @@ function transformMenuItem(item: ApiSchemas['Category'], type: string): Menu {
|
||||
|
||||
export function transformPage(
|
||||
seoUrlElement: ApiSchemas['SeoUrl'],
|
||||
category: ApiSchemas['Category']
|
||||
category: ExtendedCategory
|
||||
): Page {
|
||||
let plainHtmlContent;
|
||||
if (category.cmsPage) {
|
||||
const cmsPage: ApiSchemas['CmsPage'] = category.cmsPage;
|
||||
const cmsPage: ExtendedCmsPage = category.cmsPage;
|
||||
plainHtmlContent = transformToPlainHtmlContent(cmsPage);
|
||||
}
|
||||
|
||||
@ -62,7 +68,7 @@ export function transformPage(
|
||||
};
|
||||
}
|
||||
|
||||
export function transformToPlainHtmlContent(cmsPage: ApiSchemas['CmsPage']): string {
|
||||
export function transformToPlainHtmlContent(cmsPage: ExtendedCmsPage): string {
|
||||
let plainHtmlContent = '';
|
||||
|
||||
cmsPage.sections?.map((section) => {
|
||||
@ -84,7 +90,7 @@ export function transformToPlainHtmlContent(cmsPage: ApiSchemas['CmsPage']): str
|
||||
|
||||
export function transformCollection(
|
||||
seoUrlElement: ApiSchemas['SeoUrl'],
|
||||
resCategory: ApiSchemas['Category']
|
||||
resCategory: ExtendedCategory
|
||||
) {
|
||||
return {
|
||||
handle: seoUrlElement.seoPathInfo,
|
||||
@ -137,7 +143,7 @@ export function transformStaticCollectionToList(collection: Collection[]): ListI
|
||||
return listItem;
|
||||
}
|
||||
|
||||
export function transformProducts(res: ApiSchemas['ProductListingResult']): Product[] {
|
||||
export function transformProducts(res: ExtendedProductListingResult): Product[] {
|
||||
let products: Product[] = [];
|
||||
|
||||
if (res.elements && res.elements.length > 0) {
|
||||
@ -147,7 +153,7 @@ export function transformProducts(res: ApiSchemas['ProductListingResult']): Prod
|
||||
return products;
|
||||
}
|
||||
|
||||
export function transformProduct(item: ApiSchemas['Product']): Product {
|
||||
export function transformProduct(item: ExtendedProduct): Product {
|
||||
const productOptions = transformOptions(item);
|
||||
const productVariants = transformVariants(item);
|
||||
|
||||
@ -202,7 +208,7 @@ export function transformProduct(item: ApiSchemas['Product']): Product {
|
||||
};
|
||||
}
|
||||
|
||||
function transformOptions(parent: ApiSchemas['Product']): ProductOption[] {
|
||||
function transformOptions(parent: ExtendedProduct): ProductOption[] {
|
||||
// we only transform options for parents with children, ignore child products with options
|
||||
let productOptions: ProductOption[] = [];
|
||||
if (parent.children && parent.parentId === null && parent.children.length > 0) {
|
||||
@ -231,7 +237,7 @@ function transformOptions(parent: ApiSchemas['Product']): ProductOption[] {
|
||||
return productOptions;
|
||||
}
|
||||
|
||||
function transformVariants(parent: ApiSchemas['Product']): ProductVariant[] {
|
||||
function transformVariants(parent: ExtendedProduct): ProductVariant[] {
|
||||
let productVariants: ProductVariant[] = [];
|
||||
if (parent.children && parent.parentId === null && parent.children.length > 0) {
|
||||
parent.children.map((child) => {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { components } from '@shopware/api-client/api-types';
|
||||
import { ExtendedCriteria } from './api-extended';
|
||||
import { ExtendedCriteria, ExtendedCategory, ExtendedCmsPage } from './api-extended';
|
||||
|
||||
/** Shopware Types */
|
||||
|
||||
@ -10,10 +10,11 @@ export type ProductListingCriteria = {
|
||||
query: string;
|
||||
} & Omit<ApiSchemas['ProductListingCriteria'], 'filter'> &
|
||||
ExtendedCriteria;
|
||||
export type RouteNames = 'frontend.navigation.page' | 'frontend.detail.page' | 'frontend.account.customer-group-registration.page' | 'frontend.landing.page'
|
||||
|
||||
/** Return Types */
|
||||
export type CategoryListingResultSW = {
|
||||
elements?: ApiSchemas['Category'][];
|
||||
elements?: ExtendedCategory[];
|
||||
} & ApiSchemas['EntitySearchResult'];
|
||||
export type SeoURLResultSW = {
|
||||
elements?: ApiSchemas['SeoUrl'][];
|
||||
@ -33,7 +34,7 @@ export type Page = {
|
||||
updatedAt: string;
|
||||
routeName?: string;
|
||||
foreignKey?: string;
|
||||
originalCmsPage?: ApiSchemas['CmsPage'];
|
||||
originalCmsPage?: ExtendedCmsPage;
|
||||
};
|
||||
|
||||
export type ProductOption = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user