feat: extract shop from mp/shop — initial libreshop/shop
Some checks failed
Build and publish / build (push) Failing after 19s
Some checks failed
Build and publish / build (push) Failing after 19s
Source moved verbatim from mp/shop/ on 2026-04-29; mp was the first concrete adapter consuming the libreshop toolkit. Builds and publishes git.librete.ch/libreshop/shop on every main / v* push via the standard .gitea/workflows/build.yml shared across libreshop components.
This commit is contained in:
147
composables/useShopApi.ts
Normal file
147
composables/useShopApi.ts
Normal file
@@ -0,0 +1,147 @@
|
||||
import type {
|
||||
Product,
|
||||
Order,
|
||||
ProductVariantResponse,
|
||||
PatternVariantsResponse,
|
||||
ProductCover,
|
||||
Legal,
|
||||
DeliveryMethod,
|
||||
PaymentMethod,
|
||||
ApiResponse
|
||||
} from "~/types";
|
||||
|
||||
/**
|
||||
* Shop API composable.
|
||||
* All requests go through dedicated Nuxt server API routes.
|
||||
* The API token is handled server-side and never exposed to clients.
|
||||
*/
|
||||
export function useShopApi() {
|
||||
return {
|
||||
// Products
|
||||
async getProducts(coverId?: string, page = 1, pageSize = 24) {
|
||||
const params = new URLSearchParams();
|
||||
if (coverId) params.append("cover", coverId);
|
||||
params.append("page", page.toString());
|
||||
params.append("pageSize", pageSize.toString());
|
||||
|
||||
return await $fetch<ApiResponse<Product>>(`/api/products?${params}`);
|
||||
},
|
||||
|
||||
async getCheapestProducts(coverId?: string, page = 1, pageSize = 24) {
|
||||
const params = new URLSearchParams();
|
||||
if (coverId) params.append("cover", coverId);
|
||||
params.append("page", page.toString());
|
||||
params.append("pageSize", pageSize.toString());
|
||||
|
||||
return await $fetch<ApiResponse<Product>>(`/api/products/promo?${params}`);
|
||||
},
|
||||
|
||||
async getProductById(id: string) {
|
||||
return await $fetch<Product>(`/api/products/${id}`);
|
||||
},
|
||||
|
||||
async getProductBySlug(slug: string) {
|
||||
return await $fetch<Product | null>(`/api/product/${slug}`);
|
||||
},
|
||||
|
||||
async getProductVariants(id: string): Promise<ProductVariantResponse> {
|
||||
return await $fetch<ProductVariantResponse>(`/api/products/${id}/variants`);
|
||||
},
|
||||
|
||||
async getProductVariantsByProductId(id: number): Promise<ProductVariantResponse> {
|
||||
return await $fetch<ProductVariantResponse>(`/api/products/${id}/variants`);
|
||||
},
|
||||
|
||||
async getPatternVariants(id: string): Promise<PatternVariantsResponse> {
|
||||
return await $fetch<PatternVariantsResponse>(`/api/products/${id}/variants/pattern`);
|
||||
},
|
||||
|
||||
async getPatternVariantsByProductId(id: number): Promise<PatternVariantsResponse> {
|
||||
return await $fetch<PatternVariantsResponse>(`/api/products/${id}/variants/pattern`);
|
||||
},
|
||||
|
||||
// Product metadata
|
||||
async getProductRulings() {
|
||||
return await $fetch<ApiResponse<unknown>>(`/api/product-rulings`);
|
||||
},
|
||||
|
||||
async getProductPatterns() {
|
||||
return await $fetch<ApiResponse<unknown>>(`/api/product-patterns`);
|
||||
},
|
||||
|
||||
async getProductPages() {
|
||||
return await $fetch<ApiResponse<unknown>>(`/api/product-pages`);
|
||||
},
|
||||
|
||||
async getProductCovers() {
|
||||
return await $fetch<ApiResponse<ProductCover>>(`/api/product-covers`);
|
||||
},
|
||||
|
||||
async getProductCoverById(id: string) {
|
||||
return await $fetch<ApiResponse<ProductCover>>(`/api/product-covers/${id}`);
|
||||
},
|
||||
|
||||
// Orders
|
||||
async createOrder(): Promise<Order> {
|
||||
return await $fetch<Order>("/api/orders", { method: "POST" });
|
||||
},
|
||||
|
||||
async getOrder(uuid: string): Promise<Order> {
|
||||
return await $fetch<Order>(`/api/orders/${uuid}`);
|
||||
},
|
||||
|
||||
async updateOrder(uuid: string, data: Partial<Order>): Promise<Order> {
|
||||
return await $fetch<Order>(`/api/orders/${uuid}`, {
|
||||
method: "PUT",
|
||||
body: { data }
|
||||
});
|
||||
},
|
||||
|
||||
async addProductToCart(uuid: string, productId: number, count = 1): Promise<Order> {
|
||||
return await $fetch<Order>(`/api/orders/${uuid}/add-product/${productId}?count=${count}`, {
|
||||
method: "PUT"
|
||||
});
|
||||
},
|
||||
|
||||
async removeProductFromCart(uuid: string, productId: number, count = 1): Promise<Order> {
|
||||
return await $fetch<Order>(`/api/orders/${uuid}/remove-product/${productId}?count=${count}`, {
|
||||
method: "PUT"
|
||||
});
|
||||
},
|
||||
|
||||
async checkoutOrder(uuid: string): Promise<{ id: string }> {
|
||||
const returnUrl = import.meta.client ? window.location.href : "";
|
||||
return await $fetch<{ id: string }>(`/api/orders/${uuid}/checkout?returnUrl=${encodeURIComponent(returnUrl)}`, {
|
||||
method: "POST"
|
||||
});
|
||||
},
|
||||
|
||||
async capturePayment(uuid: string, paypalOrderId: string): Promise<Order> {
|
||||
return await $fetch<Order>(`/api/orders/${uuid}/capture/${paypalOrderId}`, {
|
||||
method: "POST"
|
||||
});
|
||||
},
|
||||
|
||||
// Payment & Delivery
|
||||
async getPaymentMethods() {
|
||||
return await $fetch<ApiResponse<PaymentMethod>>(`/api/payments`);
|
||||
},
|
||||
|
||||
async getDeliveryMethods() {
|
||||
return await $fetch<ApiResponse<DeliveryMethod>>(`/api/deliveries`);
|
||||
},
|
||||
|
||||
// Content
|
||||
async getLegal(): Promise<Legal> {
|
||||
return await $fetch<Legal>(`/api/legal`);
|
||||
},
|
||||
|
||||
async getContent(): Promise<unknown> {
|
||||
return await $fetch<unknown>(`/api/content`);
|
||||
},
|
||||
|
||||
async getWebsites(): Promise<unknown> {
|
||||
return await $fetch<unknown>(`/api/websites`);
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user