{"_id":"@dylanmurzello/vendure-plugin-wishlist","_rev":"4-5d6f4606f41053d31c6a3ff06a14d0c1","name":"@dylanmurzello/vendure-plugin-wishlist","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@dylanmurzello/vendure-plugin-wishlist","version":"1.0.0","keywords":["vendure","vendure-plugin","wishlist","favorites","ecommerce","shopping","cart","customer"],"author":{"name":"Dylan Murzello"},"license":"MIT","_id":"@dylanmurzello/vendure-plugin-wishlist@1.0.0","maintainers":[{"name":"dylanmurzello","email":"dylanmurzello@gmail.com"}],"homepage":"https://github.com/Dylanmurzello/vendure-plugin-wishlist#readme","bugs":{"url":"https://github.com/Dylanmurzello/vendure-plugin-wishlist/issues"},"dist":{"shasum":"69e25439726bdbd21aaf458de5605ce6eb92179c","tarball":"https://registry.npmjs.org/@dylanmurzello/vendure-plugin-wishlist/-/vendure-plugin-wishlist-1.0.0.tgz","fileCount":28,"integrity":"sha512-bh9VSgY8m6EBxQ3cXOrtvuZXQ+jFOZHJbnamYxd4XfdRDrwa6U+6dd77DqktshluQNqr7spBJu1aguir68HdCg==","signatures":[{"sig":"MEUCIQDDzyjTlxEWusJy01lJR0VAZlTtSEGQoe4OWs7cOERd/gIgEwJ/trxPPlWWRUdBMTN5Vw0kvgiS9tvwftJ4lY/XElY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":47100},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"7c1d70857311bd96eb33b9e3edddd1c8b1a0f027","scripts":{"build":"tsc","watch":"tsc --watch","prepare":"npm run build"},"_npmUser":{"name":"dylanmurzello","email":"dylanmurzello@gmail.com"},"repository":{"url":"git+https://github.com/Dylanmurzello/vendure-plugin-wishlist.git","type":"git"},"_npmVersion":"11.6.0","description":"Full-featured wishlist/favorites plugin for Vendure e-commerce framework with customer persistence and GraphQL API","directories":{},"_nodeVersion":"24.8.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typeorm":"^0.3.0","typescript":"^5.0.0","@types/node":"^20.0.0","graphql-tag":"^2.12.0","@vendure/core":"^3.0.0","@nestjs/common":"^10.0.0","@nestjs/graphql":"^12.0.0"},"peerDependencies":{"typeorm":"^0.3.0","graphql-tag":"^2.12.0","@vendure/core":"^2.0.0 || ^3.0.0","@nestjs/common":"^9.0.0 || ^10.0.0","@nestjs/graphql":"^11.0.0 || ^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/vendure-plugin-wishlist_1.0.0_1759199264111_0.31131572254336315","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2025-09-30T02:27:44.016Z","modified":"2025-09-30T02:37:32.561Z","1.0.0":"2025-09-30T02:27:44.318Z"},"bugs":{"url":"https://github.com/Dylanmurzello/vendure-plugin-wishlist/issues"},"author":{"name":"Dylan Murzello"},"license":"MIT","homepage":"https://github.com/Dylanmurzello/vendure-plugin-wishlist#readme","keywords":["vendure","vendure-plugin","wishlist","favorites","ecommerce","shopping","cart","customer"],"repository":{"url":"git+https://github.com/Dylanmurzello/vendure-plugin-wishlist.git","type":"git"},"description":"Full-featured wishlist/favorites plugin for Vendure e-commerce framework with customer persistence and GraphQL API","maintainers":[{"name":"dylanmurzello","email":"dylanmurzello@gmail.com"}],"readme":"# 🎯 Vendure Wishlist Plugin\n\nA full-featured wishlist/favorites plugin for [Vendure](https://www.vendure.io/) e-commerce framework. Let your customers save products for later with persistent storage and a clean GraphQL API.\n\n[![npm version](https://img.shields.io/npm/v/@dylanmurzello/vendure-plugin-wishlist.svg)](https://www.npmjs.com/package/@dylanmurzello/vendure-plugin-wishlist)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n## ✨ Features\n\n- 🛍️ **Customer Wishlists** - Let customers save products they want to buy later\n- 🔒 **Authentication** - Secure wishlist operations for logged-in users only\n- 💾 **Persistent Storage** - Wishlists stored in database, survive across sessions\n- 📝 **Notes Support** - Optional notes field for each wishlist item\n- 🚫 **Duplicate Prevention** - Unique constraint prevents duplicate entries\n- 📊 **Pagination** - Built-in pagination support for large wishlists\n- 👑 **Admin API** - View customer wishlists from admin panel\n- 🎨 **GraphQL API** - Clean, type-safe GraphQL mutations and queries\n- 📚 **TypeScript** - Full TypeScript support with type definitions\n- 🔥 **Zero Config** - Just add to plugins array and you're good to go\n\n## 📦 Installation\n\n```bash\nnpm install @dylanmurzello/vendure-plugin-wishlist\n# or\nyarn add @dylanmurzello/vendure-plugin-wishlist\n# or\npnpm add @dylanmurzello/vendure-plugin-wishlist\n```\n\n## 🚀 Quick Start\n\n### 1. Add to Vendure Config\n\n```typescript\nimport { WishlistPlugin } from '@dylanmurzello/vendure-plugin-wishlist';\n\nconst config: VendureConfig = {\n  // ... other config\n  plugins: [\n    WishlistPlugin,\n    // ... other plugins\n  ],\n};\n```\n\n### 2. Run Database Migration\n\nThe plugin will automatically create the `wishlist_item` table on first run. If you're using migrations:\n\n```bash\nnpm run migration:generate add-wishlist\nnpm run migration:run\n```\n\n### 3. Start Using!\n\nThat's it! The plugin is now active and your customers can start building wishlists.\n\n## 📖 Usage\n\n### Shop API (Customer-Facing)\n\nAll Shop API operations require authentication and automatically use the active customer.\n\n#### Get Wishlist Items\n\n```graphql\nquery {\n  wishlistItems {\n    items {\n      id\n      productVariant {\n        id\n        name\n        sku\n        price\n        product {\n          name\n          featuredAsset {\n            preview\n          }\n        }\n      }\n      addedAt\n      notes\n    }\n    totalItems\n  }\n}\n```\n\n#### Add to Wishlist\n\n```graphql\nmutation {\n  addToWishlist(\n    productVariantId: \"123\"\n    notes: \"Birthday gift for mom\"\n  ) {\n    id\n    productVariant {\n      name\n    }\n    addedAt\n  }\n}\n```\n\n#### Remove from Wishlist\n\n```graphql\nmutation {\n  removeFromWishlist(productVariantId: \"123\")\n}\n```\n\n#### Check if Item is in Wishlist\n\n```graphql\nquery {\n  isInWishlist(productVariantId: \"123\")\n}\n```\n\n#### Get Wishlist Count\n\n```graphql\nquery {\n  wishlistCount\n}\n```\n\n#### Clear Entire Wishlist\n\n```graphql\nmutation {\n  clearWishlist\n}\n```\n\n### Admin API\n\nAdmin operations require `ReadCustomer` permission.\n\n#### View Customer Wishlist\n\n```graphql\nquery {\n  customerWishlistItems(customerId: \"456\") {\n    items {\n      id\n      productVariant {\n        name\n        sku\n      }\n      customer {\n        emailAddress\n        firstName\n        lastName\n      }\n      addedAt\n      notes\n    }\n    totalItems\n  }\n}\n```\n\n#### Get Customer Wishlist Count\n\n```graphql\nquery {\n  customerWishlistCount(customerId: \"456\")\n}\n```\n\n## 🎨 Frontend Integration\n\n### React Example with Apollo Client\n\n```typescript\nimport { useMutation, useQuery } from '@apollo/client';\nimport gql from 'graphql-tag';\n\nconst GET_WISHLIST = gql`\n  query GetWishlist {\n    wishlistItems {\n      items {\n        id\n        productVariant {\n          id\n          name\n          product {\n            name\n            featuredAsset {\n              preview\n            }\n          }\n        }\n      }\n      totalItems\n    }\n  }\n`;\n\nconst ADD_TO_WISHLIST = gql`\n  mutation AddToWishlist($productVariantId: ID!, $notes: String) {\n    addToWishlist(productVariantId: $productVariantId, notes: $notes) {\n      id\n    }\n  }\n`;\n\nfunction WishlistButton({ productVariantId }) {\n  const { data } = useQuery(GET_WISHLIST);\n  const [addToWishlist] = useMutation(ADD_TO_WISHLIST, {\n    refetchQueries: [{ query: GET_WISHLIST }],\n  });\n\n  const isInWishlist = data?.wishlistItems?.items?.some(\n    item => item.productVariant.id === productVariantId\n  );\n\n  return (\n    <button\n      onClick={() => addToWishlist({ variables: { productVariantId } })}\n      className={isInWishlist ? 'active' : ''}\n    >\n      {isInWishlist ? '❤️ In Wishlist' : '🤍 Add to Wishlist'}\n    </button>\n  );\n}\n```\n\n### Next.js Example\n\n```typescript\n'use client';\n\nimport { useState } from 'react';\n\nexport function WishlistButton({ variantId }: { variantId: string }) {\n  const [inWishlist, setInWishlist] = useState(false);\n\n  const toggleWishlist = async () => {\n    const mutation = inWishlist ? 'removeFromWishlist' : 'addToWishlist';\n    \n    const response = await fetch('/shop-api', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({\n        query: `\n          mutation {\n            ${mutation}(productVariantId: \"${variantId}\") ${\n              inWishlist ? '' : '{ id }'\n            }\n          }\n        `,\n      }),\n    });\n\n    if (response.ok) {\n      setInWishlist(!inWishlist);\n    }\n  };\n\n  return (\n    <button onClick={toggleWishlist}>\n      {inWishlist ? '❤️ In Wishlist' : '🤍 Add to Wishlist'}\n    </button>\n  );\n}\n```\n\n## 🏗️ Architecture\n\n### Database Schema\n\nThe plugin creates a `wishlist_item` table with the following structure:\n\n| Column | Type | Description |\n|--------|------|-------------|\n| `id` | ID | Primary key |\n| `customerId` | ID | Foreign key to customer |\n| `productVariantId` | ID | Foreign key to product variant |\n| `addedAt` | DateTime | Timestamp when item was added |\n| `notes` | String | Optional notes (nullable) |\n\n**Unique Constraint:** `(customerId, productVariantId)` - Prevents duplicate entries.\n\n### Service Methods\n\nThe `WishlistService` provides the following methods:\n\n```typescript\nclass WishlistService {\n  // Get paginated wishlist items\n  getWishlistItems(ctx: RequestContext, customerId: ID, options?: ListQueryOptions): Promise<PaginatedList<WishlistItem>>\n  \n  // Add item to wishlist (updates notes if already exists)\n  addToWishlist(ctx: RequestContext, customerId: ID, productVariantId: ID, notes?: string): Promise<WishlistItem>\n  \n  // Remove item from wishlist\n  removeFromWishlist(ctx: RequestContext, customerId: ID, productVariantId: ID): Promise<boolean>\n  \n  // Clear all items\n  clearWishlist(ctx: RequestContext, customerId: ID): Promise<boolean>\n  \n  // Check if item is in wishlist\n  isInWishlist(ctx: RequestContext, customerId: ID, productVariantId: ID): Promise<boolean>\n  \n  // Get total count\n  getWishlistCount(ctx: RequestContext, customerId: ID): Promise<number>\n}\n```\n\n## 🔧 Advanced Usage\n\n### Using the Service Directly\n\nYou can inject `WishlistService` into your own plugins or resolvers:\n\n```typescript\nimport { WishlistService } from '@gbros/vendure-plugin-wishlist';\n\n@Injectable()\nexport class MyCustomService {\n  constructor(private wishlistService: WishlistService) {}\n\n  async checkCustomerInterest(ctx: RequestContext, customerId: ID) {\n    const count = await this.wishlistService.getWishlistCount(ctx, customerId);\n    return count > 5; // Customer is highly engaged!\n  }\n}\n```\n\n### Custom Resolvers\n\nExtend the plugin's functionality with your own resolvers:\n\n```typescript\n@Resolver()\nexport class CustomWishlistResolver {\n  constructor(private wishlistService: WishlistService) {}\n\n  @Query()\n  @Allow(Permission.Authenticated)\n  async popularWishlistItems(@Ctx() ctx: RequestContext) {\n    // Implement your own logic\n    // Query all wishlist items and aggregate by product\n  }\n}\n```\n\n## 🤝 Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\n## 📝 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 🙏 Acknowledgments\n\n- Built for the [Vendure](https://www.vendure.io/) e-commerce framework\n- Inspired by real-world e-commerce needs\n- Developed with ❤️ by Gbros\n\n## 📮 Support\n\n- 🐛 [Report a bug](https://github.com/Dylanmurzello/vendure-plugin-wishlist/issues)\n- 💡 [Request a feature](https://github.com/Dylanmurzello/vendure-plugin-wishlist/issues)\n- 💬 [Ask a question](https://github.com/Dylanmurzello/vendure-plugin-wishlist/discussions)\n\n## 🔗 Links\n\n- [Vendure Documentation](https://www.vendure.io/docs/)\n- [Vendure Plugin Guide](https://www.vendure.io/docs/plugins/)\n- [npm Package](https://www.npmjs.com/package/@dylanmurzello/vendure-plugin-wishlist)\n- [GitHub Repository](https://github.com/Dylanmurzello/vendure-plugin-wishlist)\n\n---\n\nMade with 🔥 by Dylan Murzello | Supporting your \"I'll buy it later\" customers since 2025\n","readmeFilename":"README.md"}