@commercejs/platform 0.1.0
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.
- package/README.md +156 -0
- package/dist/__tests__/platform.drizzle.test.d.ts +2 -0
- package/dist/__tests__/platform.drizzle.test.d.ts.map +1 -0
- package/dist/__tests__/platform.drizzle.test.js +27 -0
- package/dist/__tests__/platform.drizzle.test.js.map +1 -0
- package/dist/__tests__/platform.prisma.test.d.ts +2 -0
- package/dist/__tests__/platform.prisma.test.d.ts.map +1 -0
- package/dist/__tests__/platform.prisma.test.js +27 -0
- package/dist/__tests__/platform.prisma.test.js.map +1 -0
- package/dist/__tests__/platform.suite.d.ts +8 -0
- package/dist/__tests__/platform.suite.d.ts.map +1 -0
- package/dist/__tests__/platform.suite.js +406 -0
- package/dist/__tests__/platform.suite.js.map +1 -0
- package/dist/adapter.d.ts +20 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +122 -0
- package/dist/adapter.js.map +1 -0
- package/dist/database/drizzle/client.d.ts +13 -0
- package/dist/database/drizzle/client.d.ts.map +1 -0
- package/dist/database/drizzle/client.js +29 -0
- package/dist/database/drizzle/client.js.map +1 -0
- package/dist/database/drizzle/index.d.ts +5 -0
- package/dist/database/drizzle/index.d.ts.map +1 -0
- package/dist/database/drizzle/index.js +7 -0
- package/dist/database/drizzle/index.js.map +1 -0
- package/dist/database/drizzle/migrate.d.ts +9 -0
- package/dist/database/drizzle/migrate.d.ts.map +1 -0
- package/dist/database/drizzle/migrate.js +317 -0
- package/dist/database/drizzle/migrate.js.map +1 -0
- package/dist/database/drizzle/queries/brands.d.ts +26 -0
- package/dist/database/drizzle/queries/brands.d.ts.map +1 -0
- package/dist/database/drizzle/queries/brands.js +19 -0
- package/dist/database/drizzle/queries/brands.js.map +1 -0
- package/dist/database/drizzle/queries/cart.d.ts +61 -0
- package/dist/database/drizzle/queries/cart.d.ts.map +1 -0
- package/dist/database/drizzle/queries/cart.js +57 -0
- package/dist/database/drizzle/queries/cart.js.map +1 -0
- package/dist/database/drizzle/queries/catalog.d.ts +149 -0
- package/dist/database/drizzle/queries/catalog.d.ts.map +1 -0
- package/dist/database/drizzle/queries/catalog.js +88 -0
- package/dist/database/drizzle/queries/catalog.js.map +1 -0
- package/dist/database/drizzle/queries/countries.d.ts +22 -0
- package/dist/database/drizzle/queries/countries.d.ts.map +1 -0
- package/dist/database/drizzle/queries/countries.js +19 -0
- package/dist/database/drizzle/queries/countries.js.map +1 -0
- package/dist/database/drizzle/queries/customers.d.ts +87 -0
- package/dist/database/drizzle/queries/customers.d.ts.map +1 -0
- package/dist/database/drizzle/queries/customers.js +41 -0
- package/dist/database/drizzle/queries/customers.js.map +1 -0
- package/dist/database/drizzle/queries/index.d.ts +12 -0
- package/dist/database/drizzle/queries/index.d.ts.map +1 -0
- package/dist/database/drizzle/queries/index.js +28 -0
- package/dist/database/drizzle/queries/index.js.map +1 -0
- package/dist/database/drizzle/queries/orders.d.ts +74 -0
- package/dist/database/drizzle/queries/orders.d.ts.map +1 -0
- package/dist/database/drizzle/queries/orders.js +39 -0
- package/dist/database/drizzle/queries/orders.js.map +1 -0
- package/dist/database/drizzle/queries/promotions.d.ts +61 -0
- package/dist/database/drizzle/queries/promotions.d.ts.map +1 -0
- package/dist/database/drizzle/queries/promotions.js +39 -0
- package/dist/database/drizzle/queries/promotions.js.map +1 -0
- package/dist/database/drizzle/queries/returns.d.ts +62 -0
- package/dist/database/drizzle/queries/returns.d.ts.map +1 -0
- package/dist/database/drizzle/queries/returns.js +58 -0
- package/dist/database/drizzle/queries/returns.js.map +1 -0
- package/dist/database/drizzle/queries/reviews.d.ts +25 -0
- package/dist/database/drizzle/queries/reviews.d.ts.map +1 -0
- package/dist/database/drizzle/queries/reviews.js +57 -0
- package/dist/database/drizzle/queries/reviews.js.map +1 -0
- package/dist/database/drizzle/queries/store.d.ts +22 -0
- package/dist/database/drizzle/queries/store.d.ts.map +1 -0
- package/dist/database/drizzle/queries/store.js +14 -0
- package/dist/database/drizzle/queries/store.js.map +1 -0
- package/dist/database/drizzle/queries/wishlists.d.ts +31 -0
- package/dist/database/drizzle/queries/wishlists.d.ts.map +1 -0
- package/dist/database/drizzle/queries/wishlists.js +44 -0
- package/dist/database/drizzle/queries/wishlists.js.map +1 -0
- package/dist/database/drizzle/schema/brands.d.ts +196 -0
- package/dist/database/drizzle/schema/brands.d.ts.map +1 -0
- package/dist/database/drizzle/schema/brands.js +17 -0
- package/dist/database/drizzle/schema/brands.js.map +1 -0
- package/dist/database/drizzle/schema/carts.d.ts +294 -0
- package/dist/database/drizzle/schema/carts.d.ts.map +1 -0
- package/dist/database/drizzle/schema/carts.js +28 -0
- package/dist/database/drizzle/schema/carts.js.map +1 -0
- package/dist/database/drizzle/schema/categories.d.ts +215 -0
- package/dist/database/drizzle/schema/categories.d.ts.map +1 -0
- package/dist/database/drizzle/schema/categories.js +18 -0
- package/dist/database/drizzle/schema/categories.js.map +1 -0
- package/dist/database/drizzle/schema/countries.d.ts +158 -0
- package/dist/database/drizzle/schema/countries.d.ts.map +1 -0
- package/dist/database/drizzle/schema/countries.js +15 -0
- package/dist/database/drizzle/schema/countries.js.map +1 -0
- package/dist/database/drizzle/schema/customers.d.ts +469 -0
- package/dist/database/drizzle/schema/customers.d.ts.map +1 -0
- package/dist/database/drizzle/schema/customers.js +33 -0
- package/dist/database/drizzle/schema/customers.js.map +1 -0
- package/dist/database/drizzle/schema/index.d.ts +13 -0
- package/dist/database/drizzle/schema/index.d.ts.map +1 -0
- package/dist/database/drizzle/schema/index.js +16 -0
- package/dist/database/drizzle/schema/index.js.map +1 -0
- package/dist/database/drizzle/schema/orders.d.ts +722 -0
- package/dist/database/drizzle/schema/orders.d.ts.map +1 -0
- package/dist/database/drizzle/schema/orders.js +63 -0
- package/dist/database/drizzle/schema/orders.js.map +1 -0
- package/dist/database/drizzle/schema/products.d.ts +1180 -0
- package/dist/database/drizzle/schema/products.d.ts.map +1 -0
- package/dist/database/drizzle/schema/products.js +99 -0
- package/dist/database/drizzle/schema/products.js.map +1 -0
- package/dist/database/drizzle/schema/promotions.d.ts +474 -0
- package/dist/database/drizzle/schema/promotions.d.ts.map +1 -0
- package/dist/database/drizzle/schema/promotions.js +34 -0
- package/dist/database/drizzle/schema/promotions.js.map +1 -0
- package/dist/database/drizzle/schema/returns.d.ts +467 -0
- package/dist/database/drizzle/schema/returns.d.ts.map +1 -0
- package/dist/database/drizzle/schema/returns.js +34 -0
- package/dist/database/drizzle/schema/returns.js.map +1 -0
- package/dist/database/drizzle/schema/reviews.d.ts +175 -0
- package/dist/database/drizzle/schema/reviews.d.ts.map +1 -0
- package/dist/database/drizzle/schema/reviews.js +17 -0
- package/dist/database/drizzle/schema/reviews.js.map +1 -0
- package/dist/database/drizzle/schema/store.d.ts +350 -0
- package/dist/database/drizzle/schema/store.d.ts.map +1 -0
- package/dist/database/drizzle/schema/store.js +25 -0
- package/dist/database/drizzle/schema/store.js.map +1 -0
- package/dist/database/drizzle/schema/wishlists.d.ts +167 -0
- package/dist/database/drizzle/schema/wishlists.d.ts.map +1 -0
- package/dist/database/drizzle/schema/wishlists.js +19 -0
- package/dist/database/drizzle/schema/wishlists.js.map +1 -0
- package/dist/database/drizzle/seed.d.ts +6 -0
- package/dist/database/drizzle/seed.d.ts.map +1 -0
- package/dist/database/drizzle/seed.js +166 -0
- package/dist/database/drizzle/seed.js.map +1 -0
- package/dist/database/index.d.ts +8 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +12 -0
- package/dist/database/index.js.map +1 -0
- package/dist/database/prisma/client.d.ts +13 -0
- package/dist/database/prisma/client.d.ts.map +1 -0
- package/dist/database/prisma/client.js +25 -0
- package/dist/database/prisma/client.js.map +1 -0
- package/dist/database/prisma/generated/browser.d.ts +135 -0
- package/dist/database/prisma/generated/browser.d.ts.map +1 -0
- package/dist/database/prisma/generated/browser.js +18 -0
- package/dist/database/prisma/generated/browser.js.map +1 -0
- package/dist/database/prisma/generated/client.d.ts +152 -0
- package/dist/database/prisma/generated/client.d.ts.map +1 -0
- package/dist/database/prisma/generated/client.js +33 -0
- package/dist/database/prisma/generated/client.js.map +1 -0
- package/dist/database/prisma/generated/commonInputTypes.d.ts +344 -0
- package/dist/database/prisma/generated/commonInputTypes.d.ts.map +1 -0
- package/dist/database/prisma/generated/commonInputTypes.js +11 -0
- package/dist/database/prisma/generated/commonInputTypes.js.map +1 -0
- package/dist/database/prisma/generated/enums.d.ts +2 -0
- package/dist/database/prisma/generated/enums.d.ts.map +1 -0
- package/dist/database/prisma/generated/enums.js +11 -0
- package/dist/database/prisma/generated/enums.js.map +1 -0
- package/dist/database/prisma/generated/internal/class.d.ts +402 -0
- package/dist/database/prisma/generated/internal/class.d.ts.map +1 -0
- package/dist/database/prisma/generated/internal/class.js +42 -0
- package/dist/database/prisma/generated/internal/class.js.map +1 -0
- package/dist/database/prisma/generated/internal/prismaNamespace.d.ts +2735 -0
- package/dist/database/prisma/generated/internal/prismaNamespace.d.ts.map +1 -0
- package/dist/database/prisma/generated/internal/prismaNamespace.js +415 -0
- package/dist/database/prisma/generated/internal/prismaNamespace.js.map +1 -0
- package/dist/database/prisma/generated/internal/prismaNamespaceBrowser.d.ts +400 -0
- package/dist/database/prisma/generated/internal/prismaNamespaceBrowser.d.ts.map +1 -0
- package/dist/database/prisma/generated/internal/prismaNamespaceBrowser.js +386 -0
- package/dist/database/prisma/generated/internal/prismaNamespaceBrowser.js.map +1 -0
- package/dist/database/prisma/generated/models/Brand.d.ts +1141 -0
- package/dist/database/prisma/generated/models/Brand.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/Brand.js +2 -0
- package/dist/database/prisma/generated/models/Brand.js.map +1 -0
- package/dist/database/prisma/generated/models/Cart.d.ts +1464 -0
- package/dist/database/prisma/generated/models/Cart.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/Cart.js +2 -0
- package/dist/database/prisma/generated/models/Cart.js.map +1 -0
- package/dist/database/prisma/generated/models/CartItem.d.ts +1487 -0
- package/dist/database/prisma/generated/models/CartItem.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/CartItem.js +2 -0
- package/dist/database/prisma/generated/models/CartItem.js.map +1 -0
- package/dist/database/prisma/generated/models/Category.d.ts +1717 -0
- package/dist/database/prisma/generated/models/Category.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/Category.js +2 -0
- package/dist/database/prisma/generated/models/Category.js.map +1 -0
- package/dist/database/prisma/generated/models/Country.d.ts +1076 -0
- package/dist/database/prisma/generated/models/Country.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/Country.js +2 -0
- package/dist/database/prisma/generated/models/Country.js.map +1 -0
- package/dist/database/prisma/generated/models/Coupon.d.ts +1242 -0
- package/dist/database/prisma/generated/models/Coupon.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/Coupon.js +2 -0
- package/dist/database/prisma/generated/models/Coupon.js.map +1 -0
- package/dist/database/prisma/generated/models/Customer.d.ts +1536 -0
- package/dist/database/prisma/generated/models/Customer.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/Customer.js +2 -0
- package/dist/database/prisma/generated/models/Customer.js.map +1 -0
- package/dist/database/prisma/generated/models/CustomerAddress.d.ts +1519 -0
- package/dist/database/prisma/generated/models/CustomerAddress.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/CustomerAddress.js +2 -0
- package/dist/database/prisma/generated/models/CustomerAddress.js.map +1 -0
- package/dist/database/prisma/generated/models/Order.d.ts +2136 -0
- package/dist/database/prisma/generated/models/Order.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/Order.js +2 -0
- package/dist/database/prisma/generated/models/Order.js.map +1 -0
- package/dist/database/prisma/generated/models/OrderHistory.d.ts +1204 -0
- package/dist/database/prisma/generated/models/OrderHistory.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/OrderHistory.js +2 -0
- package/dist/database/prisma/generated/models/OrderHistory.js.map +1 -0
- package/dist/database/prisma/generated/models/OrderItem.d.ts +1464 -0
- package/dist/database/prisma/generated/models/OrderItem.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/OrderItem.js +2 -0
- package/dist/database/prisma/generated/models/OrderItem.js.map +1 -0
- package/dist/database/prisma/generated/models/Product.d.ts +2969 -0
- package/dist/database/prisma/generated/models/Product.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/Product.js +2 -0
- package/dist/database/prisma/generated/models/Product.js.map +1 -0
- package/dist/database/prisma/generated/models/ProductAttribute.d.ts +1239 -0
- package/dist/database/prisma/generated/models/ProductAttribute.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/ProductAttribute.js +2 -0
- package/dist/database/prisma/generated/models/ProductAttribute.js.map +1 -0
- package/dist/database/prisma/generated/models/ProductCategory.d.ts +1154 -0
- package/dist/database/prisma/generated/models/ProductCategory.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/ProductCategory.js +2 -0
- package/dist/database/prisma/generated/models/ProductCategory.js.map +1 -0
- package/dist/database/prisma/generated/models/ProductImage.d.ts +1242 -0
- package/dist/database/prisma/generated/models/ProductImage.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/ProductImage.js +2 -0
- package/dist/database/prisma/generated/models/ProductImage.js.map +1 -0
- package/dist/database/prisma/generated/models/ProductOption.d.ts +1328 -0
- package/dist/database/prisma/generated/models/ProductOption.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/ProductOption.js +2 -0
- package/dist/database/prisma/generated/models/ProductOption.js.map +1 -0
- package/dist/database/prisma/generated/models/ProductOptionValue.d.ts +1207 -0
- package/dist/database/prisma/generated/models/ProductOptionValue.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/ProductOptionValue.js +2 -0
- package/dist/database/prisma/generated/models/ProductOptionValue.js.map +1 -0
- package/dist/database/prisma/generated/models/ProductTag.d.ts +1099 -0
- package/dist/database/prisma/generated/models/ProductTag.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/ProductTag.js +2 -0
- package/dist/database/prisma/generated/models/ProductTag.js.map +1 -0
- package/dist/database/prisma/generated/models/ProductVariant.d.ts +1543 -0
- package/dist/database/prisma/generated/models/ProductVariant.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/ProductVariant.js +2 -0
- package/dist/database/prisma/generated/models/ProductVariant.js.map +1 -0
- package/dist/database/prisma/generated/models/Promotion.d.ts +1658 -0
- package/dist/database/prisma/generated/models/Promotion.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/Promotion.js +2 -0
- package/dist/database/prisma/generated/models/Promotion.js.map +1 -0
- package/dist/database/prisma/generated/models/Return.d.ts +1448 -0
- package/dist/database/prisma/generated/models/Return.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/Return.js +2 -0
- package/dist/database/prisma/generated/models/Return.js.map +1 -0
- package/dist/database/prisma/generated/models/ReturnItem.d.ts +1417 -0
- package/dist/database/prisma/generated/models/ReturnItem.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/ReturnItem.js +2 -0
- package/dist/database/prisma/generated/models/ReturnItem.js.map +1 -0
- package/dist/database/prisma/generated/models/Review.d.ts +1142 -0
- package/dist/database/prisma/generated/models/Review.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/Review.js +2 -0
- package/dist/database/prisma/generated/models/Review.js.map +1 -0
- package/dist/database/prisma/generated/models/StoreInfo.d.ts +1356 -0
- package/dist/database/prisma/generated/models/StoreInfo.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/StoreInfo.js +2 -0
- package/dist/database/prisma/generated/models/StoreInfo.js.map +1 -0
- package/dist/database/prisma/generated/models/Wishlist.d.ts +1090 -0
- package/dist/database/prisma/generated/models/Wishlist.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/Wishlist.js +2 -0
- package/dist/database/prisma/generated/models/Wishlist.js.map +1 -0
- package/dist/database/prisma/generated/models/WishlistItem.d.ts +1169 -0
- package/dist/database/prisma/generated/models/WishlistItem.d.ts.map +1 -0
- package/dist/database/prisma/generated/models/WishlistItem.js +2 -0
- package/dist/database/prisma/generated/models/WishlistItem.js.map +1 -0
- package/dist/database/prisma/generated/models.d.ts +28 -0
- package/dist/database/prisma/generated/models.d.ts.map +1 -0
- package/dist/database/prisma/generated/models.js +2 -0
- package/dist/database/prisma/generated/models.js.map +1 -0
- package/dist/database/prisma/index.d.ts +5 -0
- package/dist/database/prisma/index.d.ts.map +1 -0
- package/dist/database/prisma/index.js +7 -0
- package/dist/database/prisma/index.js.map +1 -0
- package/dist/database/prisma/migrate.d.ts +8 -0
- package/dist/database/prisma/migrate.d.ts.map +1 -0
- package/dist/database/prisma/migrate.js +323 -0
- package/dist/database/prisma/migrate.js.map +1 -0
- package/dist/database/prisma/queries/brands.d.ts +26 -0
- package/dist/database/prisma/queries/brands.d.ts.map +1 -0
- package/dist/database/prisma/queries/brands.js +17 -0
- package/dist/database/prisma/queries/brands.js.map +1 -0
- package/dist/database/prisma/queries/cart.d.ts +61 -0
- package/dist/database/prisma/queries/cart.d.ts.map +1 -0
- package/dist/database/prisma/queries/cart.js +68 -0
- package/dist/database/prisma/queries/cart.js.map +1 -0
- package/dist/database/prisma/queries/catalog.d.ts +149 -0
- package/dist/database/prisma/queries/catalog.d.ts.map +1 -0
- package/dist/database/prisma/queries/catalog.js +94 -0
- package/dist/database/prisma/queries/catalog.js.map +1 -0
- package/dist/database/prisma/queries/countries.d.ts +22 -0
- package/dist/database/prisma/queries/countries.d.ts.map +1 -0
- package/dist/database/prisma/queries/countries.js +17 -0
- package/dist/database/prisma/queries/countries.js.map +1 -0
- package/dist/database/prisma/queries/customers.d.ts +87 -0
- package/dist/database/prisma/queries/customers.d.ts.map +1 -0
- package/dist/database/prisma/queries/customers.js +32 -0
- package/dist/database/prisma/queries/customers.js.map +1 -0
- package/dist/database/prisma/queries/index.d.ts +12 -0
- package/dist/database/prisma/queries/index.d.ts.map +1 -0
- package/dist/database/prisma/queries/index.js +28 -0
- package/dist/database/prisma/queries/index.js.map +1 -0
- package/dist/database/prisma/queries/orders.d.ts +74 -0
- package/dist/database/prisma/queries/orders.d.ts.map +1 -0
- package/dist/database/prisma/queries/orders.js +49 -0
- package/dist/database/prisma/queries/orders.js.map +1 -0
- package/dist/database/prisma/queries/promotions.d.ts +81 -0
- package/dist/database/prisma/queries/promotions.d.ts.map +1 -0
- package/dist/database/prisma/queries/promotions.js +31 -0
- package/dist/database/prisma/queries/promotions.js.map +1 -0
- package/dist/database/prisma/queries/returns.d.ts +102 -0
- package/dist/database/prisma/queries/returns.d.ts.map +1 -0
- package/dist/database/prisma/queries/returns.js +50 -0
- package/dist/database/prisma/queries/returns.js.map +1 -0
- package/dist/database/prisma/queries/reviews.d.ts +25 -0
- package/dist/database/prisma/queries/reviews.d.ts.map +1 -0
- package/dist/database/prisma/queries/reviews.js +50 -0
- package/dist/database/prisma/queries/reviews.js.map +1 -0
- package/dist/database/prisma/queries/store.d.ts +22 -0
- package/dist/database/prisma/queries/store.d.ts.map +1 -0
- package/dist/database/prisma/queries/store.js +31 -0
- package/dist/database/prisma/queries/store.js.map +1 -0
- package/dist/database/prisma/queries/wishlists.d.ts +37 -0
- package/dist/database/prisma/queries/wishlists.d.ts.map +1 -0
- package/dist/database/prisma/queries/wishlists.js +37 -0
- package/dist/database/prisma/queries/wishlists.js.map +1 -0
- package/dist/database/prisma/seed.d.ts +5 -0
- package/dist/database/prisma/seed.d.ts.map +1 -0
- package/dist/database/prisma/seed.js +127 -0
- package/dist/database/prisma/seed.js.map +1 -0
- package/dist/domains/brands.d.ts +5 -0
- package/dist/domains/brands.d.ts.map +1 -0
- package/dist/domains/brands.js +21 -0
- package/dist/domains/brands.js.map +1 -0
- package/dist/domains/cart.d.ts +11 -0
- package/dist/domains/cart.d.ts.map +1 -0
- package/dist/domains/cart.js +110 -0
- package/dist/domains/cart.js.map +1 -0
- package/dist/domains/catalog.d.ts +7 -0
- package/dist/domains/catalog.d.ts.map +1 -0
- package/dist/domains/catalog.js +157 -0
- package/dist/domains/catalog.js.map +1 -0
- package/dist/domains/checkout.d.ts +11 -0
- package/dist/domains/checkout.d.ts.map +1 -0
- package/dist/domains/checkout.js +174 -0
- package/dist/domains/checkout.js.map +1 -0
- package/dist/domains/countries.d.ts +5 -0
- package/dist/domains/countries.d.ts.map +1 -0
- package/dist/domains/countries.js +21 -0
- package/dist/domains/countries.js.map +1 -0
- package/dist/domains/customers.d.ts +17 -0
- package/dist/domains/customers.d.ts.map +1 -0
- package/dist/domains/customers.js +179 -0
- package/dist/domains/customers.js.map +1 -0
- package/dist/domains/helpers.d.ts +14 -0
- package/dist/domains/helpers.d.ts.map +1 -0
- package/dist/domains/helpers.js +46 -0
- package/dist/domains/helpers.js.map +1 -0
- package/dist/domains/not-supported.d.ts +31 -0
- package/dist/domains/not-supported.d.ts.map +1 -0
- package/dist/domains/not-supported.js +43 -0
- package/dist/domains/not-supported.js.map +1 -0
- package/dist/domains/orders.d.ts +12 -0
- package/dist/domains/orders.d.ts.map +1 -0
- package/dist/domains/orders.js +184 -0
- package/dist/domains/orders.js.map +1 -0
- package/dist/domains/promotions.d.ts +6 -0
- package/dist/domains/promotions.d.ts.map +1 -0
- package/dist/domains/promotions.js +56 -0
- package/dist/domains/promotions.js.map +1 -0
- package/dist/domains/returns.d.ts +15 -0
- package/dist/domains/returns.d.ts.map +1 -0
- package/dist/domains/returns.js +83 -0
- package/dist/domains/returns.js.map +1 -0
- package/dist/domains/reviews.d.ts +16 -0
- package/dist/domains/reviews.d.ts.map +1 -0
- package/dist/domains/reviews.js +60 -0
- package/dist/domains/reviews.js.map +1 -0
- package/dist/domains/store.d.ts +5 -0
- package/dist/domains/store.d.ts.map +1 -0
- package/dist/domains/store.js +45 -0
- package/dist/domains/store.js.map +1 -0
- package/dist/domains/wishlist.d.ts +9 -0
- package/dist/domains/wishlist.d.ts.map +1 -0
- package/dist/domains/wishlist.js +76 -0
- package/dist/domains/wishlist.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# @commercejs/platform
|
|
2
|
+
|
|
3
|
+
The built-in CommerceJS commerce engine — a fully functional eCommerce backend powered by SQLite. Zero external APIs, zero configuration, batteries included.
|
|
4
|
+
|
|
5
|
+
## When to Use
|
|
6
|
+
|
|
7
|
+
- **Development and testing** — instant local commerce backend without external services
|
|
8
|
+
- **Prototyping** — build and demo storefronts with real data flows
|
|
9
|
+
- **Embedded commerce** — self-contained eCommerce for desktop apps, edge deployments, or single-tenant setups
|
|
10
|
+
- **Reference implementation** — see how a `CommerceAdapter` is built end-to-end
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pnpm add @commercejs/platform @commercejs/types
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { initDatabase, createPlatformAdapter, seedDrizzle } from '@commercejs/platform'
|
|
22
|
+
|
|
23
|
+
// 1. Initialize the database (auto-creates all tables)
|
|
24
|
+
initDatabase({ driver: 'drizzle' })
|
|
25
|
+
|
|
26
|
+
// 2. Optionally seed with demo data
|
|
27
|
+
seedDrizzle()
|
|
28
|
+
|
|
29
|
+
// 3. Create the adapter
|
|
30
|
+
const adapter = createPlatformAdapter({ currency: 'SAR' })
|
|
31
|
+
|
|
32
|
+
// 4. Use it — same interface as any CommerceAdapter
|
|
33
|
+
const products = await adapter.getProducts({ limit: 10 })
|
|
34
|
+
const cart = await adapter.createCart()
|
|
35
|
+
const brands = await adapter.getBrands()
|
|
36
|
+
const summary = await adapter.getReviewSummary('prod-1')
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### With the orchestration engine
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { createCommerce } from '@commercejs/core'
|
|
43
|
+
import { initDatabase, createPlatformAdapter, seedDrizzle } from '@commercejs/platform'
|
|
44
|
+
|
|
45
|
+
initDatabase({ driver: 'drizzle' })
|
|
46
|
+
seedDrizzle()
|
|
47
|
+
|
|
48
|
+
const commerce = createCommerce({
|
|
49
|
+
adapter: createPlatformAdapter({ currency: 'SAR' }),
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
const products = await commerce.getProducts({ query: 'shirt' })
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Implemented Domains
|
|
56
|
+
|
|
57
|
+
| Domain | Methods | Status |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| **Catalog** | `getProduct`, `getProducts`, `getCategories` | ✅ |
|
|
60
|
+
| **Cart** | `createCart`, `getCart`, `addToCart`, `updateCartItem`, `removeFromCart`, `applyCoupon`, `removeCoupon` | ✅ |
|
|
61
|
+
| **Checkout** | `getShippingMethods`, `setShippingAddress`, `setBillingAddress`, `setShippingMethod`, `getPaymentMethods`, `setPaymentMethod`, `placeOrder` | ✅ |
|
|
62
|
+
| **Orders** | `createOrder`, `getOrder`, `getCustomerOrders`, `getOrderStatuses`, `updateOrderStatus`, `cancelOrder`, `duplicateOrder`, `getOrderHistory` | ✅ |
|
|
63
|
+
| **Customers** | `login`, `register`, `getCustomer`, `updateCustomer`, `logout`, `forgotPassword`, `resetPassword`, `getAddresses`, `addAddress`, `updateAddress`, `deleteAddress` | ✅ |
|
|
64
|
+
| **Store** | `getStoreInfo` | ✅ |
|
|
65
|
+
| **Brands** | `getBrands` | ✅ |
|
|
66
|
+
| **Countries** | `getCountries` | ✅ |
|
|
67
|
+
| **Wishlist** | `getWishlist`, `addToWishlist`, `removeFromWishlist` | ✅ |
|
|
68
|
+
| **Reviews** | `getProductReviews`, `getReviewSummary`, `submitReview` | ✅ |
|
|
69
|
+
| **Promotions** | `getActivePromotions`, `validateCoupon` | ✅ |
|
|
70
|
+
| **Returns** | `createReturn`, `getReturn`, `getReturns`, `getOrderReturns`, `cancelReturn` | ✅ |
|
|
71
|
+
|
|
72
|
+
### Not Yet Implemented
|
|
73
|
+
|
|
74
|
+
These domains throw `NOT_SUPPORTED` errors:
|
|
75
|
+
|
|
76
|
+
`wholesale` · `auctions` · `rentals` · `gift-cards` · `locations`
|
|
77
|
+
|
|
78
|
+
## Database Drivers
|
|
79
|
+
|
|
80
|
+
The platform supports two database drivers, both backed by SQLite:
|
|
81
|
+
|
|
82
|
+
| Driver | ORM | Best For |
|
|
83
|
+
|---|---|---|
|
|
84
|
+
| `drizzle` (default) | Drizzle ORM | Lightweight, zero-codegen, fast startup |
|
|
85
|
+
| `prisma` | Prisma Client | Teams already using Prisma, migration tooling |
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
// Drizzle (default) — synchronous, file-based
|
|
89
|
+
initDatabase({ driver: 'drizzle' })
|
|
90
|
+
|
|
91
|
+
// Prisma — async, requires prisma generate
|
|
92
|
+
await initDatabase({ driver: 'prisma' })
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Both drivers share identical query interfaces and produce identical results — the test suite runs against both.
|
|
96
|
+
|
|
97
|
+
## Seed Data
|
|
98
|
+
|
|
99
|
+
The `seedDrizzle()` and `seedPrisma()` functions populate the database with demo data:
|
|
100
|
+
|
|
101
|
+
| Data | Records |
|
|
102
|
+
|---|---|
|
|
103
|
+
| Store info | 1 (CommerceJS Demo Store, SAR, en/ar) |
|
|
104
|
+
| Categories | 3 (Clothing, Electronics, Accessories) |
|
|
105
|
+
| Products | 3 (T-Shirt, Earbuds, Leather Bag) |
|
|
106
|
+
| Product images | 3 |
|
|
107
|
+
| Product variants | 3 (S/M/L for T-Shirt) |
|
|
108
|
+
| Brands | 3 (CommerceJS Essentials, TechWave, Artisan Leather) |
|
|
109
|
+
| Countries | 6 (SA, AE, KW, BH, OM, QA) |
|
|
110
|
+
| Reviews | 6 (across all 3 products, ratings 3–5) |
|
|
111
|
+
|
|
112
|
+
## Architecture
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
platform/
|
|
116
|
+
├── src/
|
|
117
|
+
│ ├── adapter.ts # createPlatformAdapter() entry point
|
|
118
|
+
│ ├── domains/ # Domain implementations
|
|
119
|
+
│ │ ├── catalog.ts # Products, categories, search
|
|
120
|
+
│ │ ├── cart.ts # Cart CRUD, coupon application
|
|
121
|
+
│ │ ├── checkout.ts # Shipping, payment, order placement
|
|
122
|
+
│ │ ├── orders.ts # Order management and status
|
|
123
|
+
│ │ ├── customers.ts # Auth, profiles, addresses
|
|
124
|
+
│ │ ├── store.ts # Store metadata
|
|
125
|
+
│ │ ├── brands.ts # Brand listing
|
|
126
|
+
│ │ ├── countries.ts # Country listing
|
|
127
|
+
│ │ ├── wishlist.ts # Favorites
|
|
128
|
+
│ │ ├── reviews.ts # Ratings and reviews
|
|
129
|
+
│ │ ├── promotions.ts # Discounts and coupons
|
|
130
|
+
│ │ ├── returns.ts # Return requests
|
|
131
|
+
│ │ └── not-supported.ts # Stub domains (501)
|
|
132
|
+
│ ├── database/
|
|
133
|
+
│ │ ├── drizzle/ # Drizzle ORM driver
|
|
134
|
+
│ │ │ ├── schema/ # Table definitions
|
|
135
|
+
│ │ │ ├── queries/ # Query functions
|
|
136
|
+
│ │ │ ├── migrate.ts # Auto-migration
|
|
137
|
+
│ │ │ └── seed.ts # Demo data
|
|
138
|
+
│ │ └── prisma/ # Prisma driver (mirrors Drizzle)
|
|
139
|
+
│ └── __tests__/ # Test suite (runs against both drivers)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Testing
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
# Run all platform tests
|
|
146
|
+
pnpm vitest run
|
|
147
|
+
|
|
148
|
+
# Watch mode
|
|
149
|
+
pnpm vitest
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The test suite runs 46 tests against each driver (92 total), covering all implemented domains including seed data validation, CRUD operations, pagination, and error handling.
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
[MIT](../../LICENSE)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.drizzle.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/platform.drizzle.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// @commercejs/platform — Drizzle driver tests
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
import { vi } from 'vitest';
|
|
5
|
+
// Mock the barrel to directly use Drizzle queries
|
|
6
|
+
vi.mock('../database/index.js', async () => {
|
|
7
|
+
return await import('../database/drizzle/queries/index.js');
|
|
8
|
+
});
|
|
9
|
+
import { describe } from 'vitest';
|
|
10
|
+
import { initDrizzle } from '../database/drizzle/client.js';
|
|
11
|
+
import { migrateDrizzle } from '../database/drizzle/migrate.js';
|
|
12
|
+
import { seedDrizzle } from '../database/drizzle/seed.js';
|
|
13
|
+
import { platformTestSuite } from './platform.suite.js';
|
|
14
|
+
describe('@commercejs/platform [drizzle]', () => {
|
|
15
|
+
platformTestSuite({
|
|
16
|
+
setup: () => {
|
|
17
|
+
const db = initDrizzle(':memory:');
|
|
18
|
+
migrateDrizzle(db);
|
|
19
|
+
seedDrizzle(db);
|
|
20
|
+
},
|
|
21
|
+
setupEmpty: () => {
|
|
22
|
+
const db = initDrizzle(':memory:');
|
|
23
|
+
migrateDrizzle(db);
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
//# sourceMappingURL=platform.drizzle.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.drizzle.test.js","sourceRoot":"","sources":["../../src/__tests__/platform.drizzle.test.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,8CAA8C;AAC9C,8EAA8E;AAE9E,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE3B,kDAAkD;AAClD,EAAE,CAAC,IAAI,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;IACzC,OAAO,MAAM,MAAM,CAAC,sCAAsC,CAAC,CAAA;AAC7D,CAAC,CAAC,CAAA;AAEF,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAEvD,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,iBAAiB,CAAC;QAChB,KAAK,EAAE,GAAG,EAAE;YACV,MAAM,EAAE,GAAG,WAAW,CAAC,UAAU,CAAC,CAAA;YAClC,cAAc,CAAC,EAAE,CAAC,CAAA;YAClB,WAAW,CAAC,EAAE,CAAC,CAAA;QACjB,CAAC;QACD,UAAU,EAAE,GAAG,EAAE;YACf,MAAM,EAAE,GAAG,WAAW,CAAC,UAAU,CAAC,CAAA;YAClC,cAAc,CAAC,EAAE,CAAC,CAAA;QACpB,CAAC;KACF,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.prisma.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/platform.prisma.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// @commercejs/platform — Prisma driver tests
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
import { vi } from 'vitest';
|
|
5
|
+
// Mock the barrel to directly use Prisma queries
|
|
6
|
+
vi.mock('../database/index.js', async () => {
|
|
7
|
+
return await import('../database/prisma/queries/index.js');
|
|
8
|
+
});
|
|
9
|
+
import { describe } from 'vitest';
|
|
10
|
+
import { initPrisma } from '../database/prisma/client.js';
|
|
11
|
+
import { migratePrisma } from '../database/prisma/migrate.js';
|
|
12
|
+
import { seedPrisma } from '../database/prisma/seed.js';
|
|
13
|
+
import { platformTestSuite } from './platform.suite.js';
|
|
14
|
+
describe('@commercejs/platform [prisma]', () => {
|
|
15
|
+
platformTestSuite({
|
|
16
|
+
setup: async () => {
|
|
17
|
+
initPrisma(':memory:');
|
|
18
|
+
await migratePrisma();
|
|
19
|
+
await seedPrisma();
|
|
20
|
+
},
|
|
21
|
+
setupEmpty: async () => {
|
|
22
|
+
initPrisma(':memory:');
|
|
23
|
+
await migratePrisma();
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
//# sourceMappingURL=platform.prisma.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.prisma.test.js","sourceRoot":"","sources":["../../src/__tests__/platform.prisma.test.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,6CAA6C;AAC7C,8EAA8E;AAE9E,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE3B,iDAAiD;AACjD,EAAE,CAAC,IAAI,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;IACzC,OAAO,MAAM,MAAM,CAAC,qCAAqC,CAAC,CAAA;AAC5D,CAAC,CAAC,CAAA;AAEF,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAEvD,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;IAC7C,iBAAiB,CAAC;QAChB,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,UAAU,CAAC,UAAU,CAAC,CAAA;YACtB,MAAM,aAAa,EAAE,CAAA;YACrB,MAAM,UAAU,EAAE,CAAA;QACpB,CAAC;QACD,UAAU,EAAE,KAAK,IAAI,EAAE;YACrB,UAAU,CAAC,UAAU,CAAC,CAAA;YACtB,MAAM,aAAa,EAAE,CAAA;QACvB,CAAC;KACF,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface SuiteOptions {
|
|
2
|
+
/** Called in beforeEach to init the DB, migrate, and seed */
|
|
3
|
+
setup: () => void | Promise<void>;
|
|
4
|
+
/** Called in beforeEach (without seed) for auto-seed tests */
|
|
5
|
+
setupEmpty: () => void | Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
export declare function platformTestSuite(opts: SuiteOptions): void;
|
|
8
|
+
//# sourceMappingURL=platform.suite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.suite.d.ts","sourceRoot":"","sources":["../../src/__tests__/platform.suite.ts"],"names":[],"mappings":"AA4BA,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,KAAK,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACjC,8DAA8D;IAC9D,UAAU,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACvC;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,QAqcnD"}
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// @commercejs/platform — shared test suite
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// All adapter tests. Each driver test file calls this with its own setup.
|
|
5
|
+
import { it, expect, beforeEach } from 'vitest';
|
|
6
|
+
import { createPlatformAdapter } from '../adapter.js';
|
|
7
|
+
/** Helper: create a full Address with all required fields */
|
|
8
|
+
function fullAddress(overrides = {}) {
|
|
9
|
+
return {
|
|
10
|
+
firstName: 'Ali',
|
|
11
|
+
lastName: 'Ahmed',
|
|
12
|
+
phone: null,
|
|
13
|
+
street: '123 King Fahd Road',
|
|
14
|
+
street2: null,
|
|
15
|
+
city: 'Riyadh',
|
|
16
|
+
state: null,
|
|
17
|
+
country: 'SA',
|
|
18
|
+
postalCode: '12345',
|
|
19
|
+
district: null,
|
|
20
|
+
nationalAddress: null,
|
|
21
|
+
additionalNumber: null,
|
|
22
|
+
...overrides,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function platformTestSuite(opts) {
|
|
26
|
+
let adapter;
|
|
27
|
+
beforeEach(async () => {
|
|
28
|
+
await opts.setup();
|
|
29
|
+
adapter = createPlatformAdapter();
|
|
30
|
+
});
|
|
31
|
+
// ---- Catalog ----
|
|
32
|
+
it('should list seeded products', async () => {
|
|
33
|
+
const result = await adapter.getProducts({ page: 1, perPage: 10 });
|
|
34
|
+
expect(result.products.items.length).toBe(3);
|
|
35
|
+
expect(result.products.total).toBe(3);
|
|
36
|
+
});
|
|
37
|
+
it('should get a product by id', async () => {
|
|
38
|
+
const result = await adapter.getProducts({ page: 1, perPage: 1 });
|
|
39
|
+
const product = await adapter.getProduct({ id: result.products.items[0].id });
|
|
40
|
+
expect(product.name.en).toBeTruthy();
|
|
41
|
+
});
|
|
42
|
+
it('should get a product by slug', async () => {
|
|
43
|
+
const product = await adapter.getProduct({ slug: 'premium-cotton-t-shirt' });
|
|
44
|
+
expect(product.id).toBe('prod-1');
|
|
45
|
+
});
|
|
46
|
+
it('should include product variants', async () => {
|
|
47
|
+
const product = await adapter.getProduct({ id: 'prod-1' });
|
|
48
|
+
expect(product.variants?.length).toBeGreaterThan(0);
|
|
49
|
+
});
|
|
50
|
+
it('should include product images', async () => {
|
|
51
|
+
const product = await adapter.getProduct({ id: 'prod-1' });
|
|
52
|
+
expect(product.gallery?.length).toBeGreaterThan(0);
|
|
53
|
+
});
|
|
54
|
+
it('should search products by query', async () => {
|
|
55
|
+
const result = await adapter.getProducts({ query: 'cotton', page: 1, perPage: 10 });
|
|
56
|
+
expect(result.products.items.length).toBe(1);
|
|
57
|
+
expect(result.products.items[0].slug).toBe('premium-cotton-t-shirt');
|
|
58
|
+
});
|
|
59
|
+
it('should filter by category', async () => {
|
|
60
|
+
const result = await adapter.getProducts({ categoryId: 'cat-clothing', page: 1, perPage: 10 });
|
|
61
|
+
expect(result.products.items.length).toBe(1);
|
|
62
|
+
});
|
|
63
|
+
it('should paginate', async () => {
|
|
64
|
+
const page1 = await adapter.getProducts({ page: 1, perPage: 2 });
|
|
65
|
+
const page2 = await adapter.getProducts({ page: 2, perPage: 2 });
|
|
66
|
+
expect(page1.products.items.length).toBe(2);
|
|
67
|
+
expect(page2.products.items.length).toBe(1);
|
|
68
|
+
});
|
|
69
|
+
it('should sort by price', async () => {
|
|
70
|
+
const result = await adapter.getProducts({ page: 1, perPage: 10, sort: { field: 'price', direction: 'asc' } });
|
|
71
|
+
const prices = result.products.items.map((p) => p.price.amount);
|
|
72
|
+
expect(prices).toEqual([...prices].sort((a, b) => a - b));
|
|
73
|
+
});
|
|
74
|
+
it('should list categories', async () => {
|
|
75
|
+
const categories = await adapter.getCategories({});
|
|
76
|
+
expect(categories.length).toBe(3);
|
|
77
|
+
});
|
|
78
|
+
it('should throw for missing product', async () => {
|
|
79
|
+
await expect(adapter.getProduct({ id: 'does-not-exist' })).rejects.toThrow();
|
|
80
|
+
});
|
|
81
|
+
// ---- Cart ----
|
|
82
|
+
it('should create an empty cart', async () => {
|
|
83
|
+
const cart = await adapter.createCart();
|
|
84
|
+
expect(cart.id).toBeTruthy();
|
|
85
|
+
expect(cart.items).toHaveLength(0);
|
|
86
|
+
expect(cart.totals.subtotal.amount).toBe(0);
|
|
87
|
+
});
|
|
88
|
+
it('should add item to cart', async () => {
|
|
89
|
+
const cart = await adapter.createCart();
|
|
90
|
+
const updatedCart = await adapter.addToCart(cart.id, { productId: 'prod-1', quantity: 2 });
|
|
91
|
+
expect(updatedCart.items).toHaveLength(1);
|
|
92
|
+
expect(updatedCart.items[0].quantity).toBe(2);
|
|
93
|
+
expect(updatedCart.totals.subtotal.amount).toBeGreaterThan(0);
|
|
94
|
+
});
|
|
95
|
+
it('should deduplicate items on add', async () => {
|
|
96
|
+
const cart = await adapter.createCart();
|
|
97
|
+
await adapter.addToCart(cart.id, { productId: 'prod-1', quantity: 1 });
|
|
98
|
+
const updatedCart = await adapter.addToCart(cart.id, { productId: 'prod-1', quantity: 3 });
|
|
99
|
+
expect(updatedCart.items).toHaveLength(1);
|
|
100
|
+
expect(updatedCart.items[0].quantity).toBe(4);
|
|
101
|
+
});
|
|
102
|
+
it('should update cart item quantity', async () => {
|
|
103
|
+
const cart = await adapter.createCart();
|
|
104
|
+
const added = await adapter.addToCart(cart.id, { productId: 'prod-1', quantity: 1 });
|
|
105
|
+
const updatedCart = await adapter.updateCartItem(cart.id, added.items[0].id, 5);
|
|
106
|
+
expect(updatedCart.items[0].quantity).toBe(5);
|
|
107
|
+
});
|
|
108
|
+
it('should remove cart item', async () => {
|
|
109
|
+
const cart = await adapter.createCart();
|
|
110
|
+
const added = await adapter.addToCart(cart.id, { productId: 'prod-1', quantity: 1 });
|
|
111
|
+
const updatedCart = await adapter.removeFromCart(cart.id, added.items[0].id);
|
|
112
|
+
expect(updatedCart.items).toHaveLength(0);
|
|
113
|
+
});
|
|
114
|
+
it('should apply and remove coupon', async () => {
|
|
115
|
+
const cart = await adapter.createCart();
|
|
116
|
+
const withCoupon = await adapter.applyCoupon(cart.id, 'SAVE10');
|
|
117
|
+
expect(withCoupon.couponCode).toBe('SAVE10');
|
|
118
|
+
const noCoupon = await adapter.removeCoupon(cart.id);
|
|
119
|
+
expect(noCoupon.couponCode).toBeNull();
|
|
120
|
+
});
|
|
121
|
+
it('should use variant price when variant is specified', async () => {
|
|
122
|
+
const product = await adapter.getProduct({ id: 'prod-1' });
|
|
123
|
+
const variant = product.variants?.find((v) => v.name?.en === 'Large');
|
|
124
|
+
expect(variant).toBeTruthy();
|
|
125
|
+
const cart = await adapter.createCart();
|
|
126
|
+
const updatedCart = await adapter.addToCart(cart.id, {
|
|
127
|
+
productId: 'prod-1',
|
|
128
|
+
variantId: variant.id,
|
|
129
|
+
quantity: 1,
|
|
130
|
+
});
|
|
131
|
+
expect(updatedCart.items[0].price.amount).toBe(variant.price.amount);
|
|
132
|
+
});
|
|
133
|
+
// ---- Checkout ----
|
|
134
|
+
it('should list shipping methods', async () => {
|
|
135
|
+
const methods = await adapter.getShippingMethods('dummy-cart');
|
|
136
|
+
expect(methods.length).toBeGreaterThan(0);
|
|
137
|
+
});
|
|
138
|
+
it('should list payment methods', async () => {
|
|
139
|
+
const methods = await adapter.getPaymentMethods('dummy-cart');
|
|
140
|
+
expect(methods.length).toBeGreaterThan(0);
|
|
141
|
+
});
|
|
142
|
+
it('should set shipping address', async () => {
|
|
143
|
+
const cart = await adapter.createCart();
|
|
144
|
+
const updatedCart = await adapter.setShippingAddress(cart.id, fullAddress());
|
|
145
|
+
expect(updatedCart.id).toBe(cart.id);
|
|
146
|
+
});
|
|
147
|
+
it('should place an order from cart', async () => {
|
|
148
|
+
const cart = await adapter.createCart();
|
|
149
|
+
await adapter.addToCart(cart.id, { productId: 'prod-2', quantity: 1 });
|
|
150
|
+
await adapter.setShippingAddress(cart.id, fullAddress());
|
|
151
|
+
const order = await adapter.placeOrder(cart.id);
|
|
152
|
+
expect(order.id).toBeTruthy();
|
|
153
|
+
expect(order.orderNumber).toBeTruthy();
|
|
154
|
+
expect(order.status).toBe('pending');
|
|
155
|
+
expect(order.items.length).toBe(1);
|
|
156
|
+
expect(order.totals.total.amount).toBeGreaterThan(0);
|
|
157
|
+
});
|
|
158
|
+
it('should reject placing order with empty cart', async () => {
|
|
159
|
+
const cart = await adapter.createCart();
|
|
160
|
+
await expect(adapter.placeOrder(cart.id)).rejects.toThrow();
|
|
161
|
+
});
|
|
162
|
+
// ---- Orders ----
|
|
163
|
+
it('should create an order directly', async () => {
|
|
164
|
+
const order = await adapter.createOrder({
|
|
165
|
+
items: [{ productId: 'prod-1', quantity: 2, unitPrice: { amount: 100, currency: 'SAR', formatted: '100 SAR' } }],
|
|
166
|
+
shippingAddress: fullAddress(),
|
|
167
|
+
});
|
|
168
|
+
expect(order.id).toBeTruthy();
|
|
169
|
+
expect(order.status).toBe('pending');
|
|
170
|
+
});
|
|
171
|
+
it('should get an order by id', async () => {
|
|
172
|
+
const created = await adapter.createOrder({
|
|
173
|
+
items: [{ productId: 'prod-1', quantity: 1, unitPrice: { amount: 100, currency: 'SAR', formatted: '100 SAR' } }],
|
|
174
|
+
shippingAddress: fullAddress(),
|
|
175
|
+
});
|
|
176
|
+
const order = await adapter.getOrder(created.id);
|
|
177
|
+
expect(order.id).toBe(created.id);
|
|
178
|
+
});
|
|
179
|
+
it('should list order statuses', async () => {
|
|
180
|
+
const statuses = await adapter.getOrderStatuses();
|
|
181
|
+
expect(statuses.length).toBeGreaterThan(0);
|
|
182
|
+
expect(statuses.find((s) => s.id === 'pending')).toBeTruthy();
|
|
183
|
+
});
|
|
184
|
+
it('should update order status', async () => {
|
|
185
|
+
const order = await adapter.createOrder({
|
|
186
|
+
items: [{ productId: 'prod-1', quantity: 1, unitPrice: { amount: 100, currency: 'SAR', formatted: '100 SAR' } }],
|
|
187
|
+
shippingAddress: fullAddress(),
|
|
188
|
+
});
|
|
189
|
+
await adapter.updateOrderStatus(order.id, { status: 'processing' });
|
|
190
|
+
const updated = await adapter.getOrder(order.id);
|
|
191
|
+
expect(updated.status).toBe('processing');
|
|
192
|
+
});
|
|
193
|
+
it('should track order history', async () => {
|
|
194
|
+
const order = await adapter.createOrder({
|
|
195
|
+
items: [{ productId: 'prod-1', quantity: 1, unitPrice: { amount: 100, currency: 'SAR', formatted: '100 SAR' } }],
|
|
196
|
+
shippingAddress: fullAddress(),
|
|
197
|
+
});
|
|
198
|
+
await adapter.updateOrderStatus(order.id, { status: 'processing' });
|
|
199
|
+
const history = await adapter.getOrderHistory(order.id);
|
|
200
|
+
expect(history.length).toBeGreaterThanOrEqual(2);
|
|
201
|
+
});
|
|
202
|
+
it('should cancel an order', async () => {
|
|
203
|
+
const order = await adapter.createOrder({
|
|
204
|
+
items: [{ productId: 'prod-1', quantity: 1, unitPrice: { amount: 100, currency: 'SAR', formatted: '100 SAR' } }],
|
|
205
|
+
shippingAddress: fullAddress(),
|
|
206
|
+
});
|
|
207
|
+
await adapter.cancelOrder(order.id, 'Changed my mind');
|
|
208
|
+
const cancelled = await adapter.getOrder(order.id);
|
|
209
|
+
expect(cancelled.status).toBe('cancelled');
|
|
210
|
+
});
|
|
211
|
+
it('should duplicate an order', async () => {
|
|
212
|
+
const order = await adapter.createOrder({
|
|
213
|
+
items: [{ productId: 'prod-1', quantity: 2, unitPrice: { amount: 100, currency: 'SAR', formatted: '100 SAR' } }],
|
|
214
|
+
shippingAddress: fullAddress(),
|
|
215
|
+
});
|
|
216
|
+
const dup = await adapter.duplicateOrder(order.id);
|
|
217
|
+
expect(dup.id).not.toBe(order.id);
|
|
218
|
+
expect(dup.items.length).toBe(order.items.length);
|
|
219
|
+
});
|
|
220
|
+
// ---- Store ----
|
|
221
|
+
it('should return store info', async () => {
|
|
222
|
+
const info = await adapter.getStoreInfo();
|
|
223
|
+
expect(info.name.en).toBeTruthy();
|
|
224
|
+
expect(info.currencies.length).toBeGreaterThan(0);
|
|
225
|
+
expect(info.locales.length).toBeGreaterThan(0);
|
|
226
|
+
expect(info.country).toBe('SA');
|
|
227
|
+
});
|
|
228
|
+
it('should auto-seed default store info when none exists', async () => {
|
|
229
|
+
// Create fresh DB without seed
|
|
230
|
+
await opts.setupEmpty();
|
|
231
|
+
const freshAdapter = createPlatformAdapter();
|
|
232
|
+
const info = await freshAdapter.getStoreInfo();
|
|
233
|
+
expect(info.name.en).toBe('My Store');
|
|
234
|
+
});
|
|
235
|
+
// ---- Customers ----
|
|
236
|
+
it('should register a new customer', async () => {
|
|
237
|
+
const customer = await adapter.register({
|
|
238
|
+
email: 'test@example.com',
|
|
239
|
+
password: 'Password123!',
|
|
240
|
+
firstName: 'Test',
|
|
241
|
+
lastName: 'User',
|
|
242
|
+
});
|
|
243
|
+
expect(customer.email).toBe('test@example.com');
|
|
244
|
+
expect(customer.firstName).toBe('Test');
|
|
245
|
+
expect(customer.id).toBeTruthy();
|
|
246
|
+
});
|
|
247
|
+
it('should login an existing customer', async () => {
|
|
248
|
+
await adapter.register({
|
|
249
|
+
email: 'login@example.com',
|
|
250
|
+
password: 'Password123!',
|
|
251
|
+
firstName: 'Login',
|
|
252
|
+
lastName: 'User',
|
|
253
|
+
});
|
|
254
|
+
const customer = await adapter.login('login@example.com', 'Password123!');
|
|
255
|
+
expect(customer.email).toBe('login@example.com');
|
|
256
|
+
});
|
|
257
|
+
it('should reject invalid credentials', async () => {
|
|
258
|
+
await adapter.register({
|
|
259
|
+
email: 'wrong@example.com',
|
|
260
|
+
password: 'Password123!',
|
|
261
|
+
firstName: 'Wrong',
|
|
262
|
+
lastName: 'User',
|
|
263
|
+
});
|
|
264
|
+
await expect(adapter.login('wrong@example.com', 'WrongPassword!')).rejects.toThrow();
|
|
265
|
+
});
|
|
266
|
+
it('should reject duplicate registration', async () => {
|
|
267
|
+
await adapter.register({
|
|
268
|
+
email: 'dup@example.com',
|
|
269
|
+
password: 'Password123!',
|
|
270
|
+
firstName: 'Dup',
|
|
271
|
+
lastName: 'User',
|
|
272
|
+
});
|
|
273
|
+
await expect(adapter.register({
|
|
274
|
+
email: 'dup@example.com',
|
|
275
|
+
password: 'Password123!',
|
|
276
|
+
firstName: 'Dup2',
|
|
277
|
+
lastName: 'User2',
|
|
278
|
+
})).rejects.toThrow();
|
|
279
|
+
});
|
|
280
|
+
it('should manage addresses', async () => {
|
|
281
|
+
await adapter.register({
|
|
282
|
+
email: 'addr@example.com',
|
|
283
|
+
password: 'Password123!',
|
|
284
|
+
firstName: 'Addr',
|
|
285
|
+
lastName: 'User',
|
|
286
|
+
});
|
|
287
|
+
// Login so the domain tracks currentCustomerId
|
|
288
|
+
await adapter.login('addr@example.com', 'Password123!');
|
|
289
|
+
// Add
|
|
290
|
+
const addr = await adapter.addAddress(fullAddress());
|
|
291
|
+
expect(addr.id).toBeTruthy();
|
|
292
|
+
expect(addr.city).toBe('Riyadh');
|
|
293
|
+
// List
|
|
294
|
+
const list = await adapter.getAddresses();
|
|
295
|
+
expect(list.length).toBe(1);
|
|
296
|
+
// Update
|
|
297
|
+
const updated = await adapter.updateAddress(addr.id, { city: 'Jeddah' });
|
|
298
|
+
expect(updated.city).toBe('Jeddah');
|
|
299
|
+
// Delete
|
|
300
|
+
await adapter.deleteAddress(addr.id);
|
|
301
|
+
const afterDelete = await adapter.getAddresses();
|
|
302
|
+
expect(afterDelete.length).toBe(0);
|
|
303
|
+
});
|
|
304
|
+
// ---- Not-supported domains ----
|
|
305
|
+
// ---- Promotions ----
|
|
306
|
+
it('should return empty promotions list', async () => {
|
|
307
|
+
const promos = await adapter.getActivePromotions();
|
|
308
|
+
expect(Array.isArray(promos)).toBe(true);
|
|
309
|
+
expect(promos.length).toBe(0);
|
|
310
|
+
});
|
|
311
|
+
it('should return null for unknown coupon', async () => {
|
|
312
|
+
const coupon = await adapter.validateCoupon('FAKE');
|
|
313
|
+
expect(coupon).toBeNull();
|
|
314
|
+
});
|
|
315
|
+
// ---- Returns ----
|
|
316
|
+
it('should return empty returns list', async () => {
|
|
317
|
+
const result = await adapter.getReturns();
|
|
318
|
+
expect(result.items.length).toBe(0);
|
|
319
|
+
expect(result.total).toBe(0);
|
|
320
|
+
});
|
|
321
|
+
// ---- Reviews ----
|
|
322
|
+
it('should submit and retrieve reviews', async () => {
|
|
323
|
+
const review = await adapter.submitReview({
|
|
324
|
+
productId: 'prod-1',
|
|
325
|
+
authorName: 'Ali',
|
|
326
|
+
rating: 5,
|
|
327
|
+
title: 'Great product',
|
|
328
|
+
body: 'Really liked it',
|
|
329
|
+
});
|
|
330
|
+
expect(review.rating).toBe(5);
|
|
331
|
+
expect(review.authorName).toBe('Ali');
|
|
332
|
+
const result = await adapter.getProductReviews('prod-1');
|
|
333
|
+
// 3 seeded reviews + 1 submitted
|
|
334
|
+
expect(result.items.length).toBe(4);
|
|
335
|
+
expect(result.total).toBe(4);
|
|
336
|
+
const summary = await adapter.getReviewSummary('prod-1');
|
|
337
|
+
// (5+4+5+5)/4 = 4.75 → 4.8
|
|
338
|
+
expect(summary.averageRating).toBe(4.8);
|
|
339
|
+
expect(summary.totalCount).toBe(4);
|
|
340
|
+
// distribution[4] (5-star) should be 3 (Ahmed, Omar, Ali), distribution[3] (4-star) = 1 (Sara)
|
|
341
|
+
expect(summary.distribution[4]).toBe(3);
|
|
342
|
+
expect(summary.distribution[3]).toBe(1);
|
|
343
|
+
});
|
|
344
|
+
// ---- Wishlist ----
|
|
345
|
+
it('should add and remove wishlist items', async () => {
|
|
346
|
+
// Register and login
|
|
347
|
+
await adapter.register({
|
|
348
|
+
email: 'wish@example.com',
|
|
349
|
+
password: 'Password123!',
|
|
350
|
+
firstName: 'Wish',
|
|
351
|
+
lastName: 'User',
|
|
352
|
+
});
|
|
353
|
+
const customer = await adapter.login('wish@example.com', 'Password123!');
|
|
354
|
+
// Get wishlist (auto-created, empty)
|
|
355
|
+
const wl = await adapter.getWishlist(customer.id);
|
|
356
|
+
expect(wl.items).toHaveLength(0);
|
|
357
|
+
expect(wl.itemCount).toBe(0);
|
|
358
|
+
// Add item
|
|
359
|
+
const updated = await adapter.addToWishlist('prod-1', undefined, customer.id);
|
|
360
|
+
expect(updated.items).toHaveLength(1);
|
|
361
|
+
expect(updated.itemCount).toBe(1);
|
|
362
|
+
// Dedup — adding same product again should not duplicate
|
|
363
|
+
const dedup = await adapter.addToWishlist('prod-1', undefined, customer.id);
|
|
364
|
+
expect(dedup.items).toHaveLength(1);
|
|
365
|
+
// Remove
|
|
366
|
+
const removed = await adapter.removeFromWishlist('prod-1', customer.id);
|
|
367
|
+
expect(removed.items).toHaveLength(0);
|
|
368
|
+
});
|
|
369
|
+
// ---- Brands ----
|
|
370
|
+
it('should return seeded brands', async () => {
|
|
371
|
+
const brands = await adapter.getBrands();
|
|
372
|
+
expect(Array.isArray(brands)).toBe(true);
|
|
373
|
+
expect(brands.length).toBe(3);
|
|
374
|
+
const names = brands.map((b) => b.name.en);
|
|
375
|
+
expect(names).toContain('CommerceJS Essentials');
|
|
376
|
+
expect(names).toContain('TechWave');
|
|
377
|
+
expect(names).toContain('Artisan Leather');
|
|
378
|
+
});
|
|
379
|
+
// ---- Countries ----
|
|
380
|
+
it('should return seeded countries', async () => {
|
|
381
|
+
const countries = await adapter.getCountries();
|
|
382
|
+
expect(Array.isArray(countries)).toBe(true);
|
|
383
|
+
expect(countries.length).toBe(6);
|
|
384
|
+
const codes = countries.map((c) => c.code);
|
|
385
|
+
expect(codes).toContain('SA');
|
|
386
|
+
expect(codes).toContain('AE');
|
|
387
|
+
expect(codes).toContain('KW');
|
|
388
|
+
});
|
|
389
|
+
// ---- Capabilities ----
|
|
390
|
+
it('should report supported domains', async () => {
|
|
391
|
+
const caps = adapter.capabilities;
|
|
392
|
+
expect(caps).toContain('catalog');
|
|
393
|
+
expect(caps).toContain('cart');
|
|
394
|
+
expect(caps).toContain('checkout');
|
|
395
|
+
expect(caps).toContain('brands');
|
|
396
|
+
expect(caps).toContain('countries');
|
|
397
|
+
expect(caps).toContain('wishlist');
|
|
398
|
+
expect(caps).toContain('reviews');
|
|
399
|
+
expect(caps).toContain('promotions');
|
|
400
|
+
expect(caps).toContain('returns');
|
|
401
|
+
});
|
|
402
|
+
it('should have correct adapter name', async () => {
|
|
403
|
+
expect(adapter.name).toBe('commercejs');
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
//# sourceMappingURL=platform.suite.js.map
|