@86d-app/products 0.0.3

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.
Files changed (94) hide show
  1. package/AGENTS.md +65 -0
  2. package/COMPONENTS.md +231 -0
  3. package/README.md +201 -0
  4. package/package.json +46 -0
  5. package/src/__tests__/controllers.test.ts +2227 -0
  6. package/src/__tests__/state.test.ts +138 -0
  7. package/src/admin/components/categories-admin.mdx +3 -0
  8. package/src/admin/components/categories-admin.tsx +449 -0
  9. package/src/admin/components/category-form.mdx +9 -0
  10. package/src/admin/components/category-form.tsx +490 -0
  11. package/src/admin/components/category-list.mdx +75 -0
  12. package/src/admin/components/category-list.tsx +168 -0
  13. package/src/admin/components/collections-admin.mdx +3 -0
  14. package/src/admin/components/collections-admin.tsx +771 -0
  15. package/src/admin/components/index.tsx +8 -0
  16. package/src/admin/components/product-detail.mdx +12 -0
  17. package/src/admin/components/product-detail.tsx +790 -0
  18. package/src/admin/components/product-edit.tsx +60 -0
  19. package/src/admin/components/product-form.tsx +793 -0
  20. package/src/admin/components/product-list.mdx +3 -0
  21. package/src/admin/components/product-list.tsx +1125 -0
  22. package/src/admin/components/product-new.tsx +38 -0
  23. package/src/admin/endpoints/add-collection-product.ts +17 -0
  24. package/src/admin/endpoints/bulk-action.ts +43 -0
  25. package/src/admin/endpoints/create-category.ts +52 -0
  26. package/src/admin/endpoints/create-collection.ts +35 -0
  27. package/src/admin/endpoints/create-product.ts +50 -0
  28. package/src/admin/endpoints/create-variant.ts +45 -0
  29. package/src/admin/endpoints/delete-category.ts +27 -0
  30. package/src/admin/endpoints/delete-collection.ts +12 -0
  31. package/src/admin/endpoints/delete-product.ts +27 -0
  32. package/src/admin/endpoints/delete-variant.ts +27 -0
  33. package/src/admin/endpoints/get-product.ts +23 -0
  34. package/src/admin/endpoints/import-products.ts +47 -0
  35. package/src/admin/endpoints/index.ts +43 -0
  36. package/src/admin/endpoints/list-categories.ts +21 -0
  37. package/src/admin/endpoints/list-collections.ts +20 -0
  38. package/src/admin/endpoints/list-products.ts +25 -0
  39. package/src/admin/endpoints/remove-collection-product.ts +15 -0
  40. package/src/admin/endpoints/update-category.ts +82 -0
  41. package/src/admin/endpoints/update-collection.ts +22 -0
  42. package/src/admin/endpoints/update-product.ts +67 -0
  43. package/src/admin/endpoints/update-variant.ts +41 -0
  44. package/src/controllers.ts +1410 -0
  45. package/src/index.ts +120 -0
  46. package/src/markdown.ts +150 -0
  47. package/src/mdx.d.ts +5 -0
  48. package/src/schema.ts +352 -0
  49. package/src/state.ts +84 -0
  50. package/src/store/components/_hooks.ts +78 -0
  51. package/src/store/components/_types.ts +73 -0
  52. package/src/store/components/_utils.ts +14 -0
  53. package/src/store/components/back-in-stock-notify.tsx +97 -0
  54. package/src/store/components/collection-card.mdx +42 -0
  55. package/src/store/components/collection-card.tsx +12 -0
  56. package/src/store/components/collection-detail.mdx +12 -0
  57. package/src/store/components/collection-detail.tsx +149 -0
  58. package/src/store/components/collection-grid.mdx +9 -0
  59. package/src/store/components/collection-grid.tsx +80 -0
  60. package/src/store/components/featured-products.mdx +9 -0
  61. package/src/store/components/featured-products.tsx +75 -0
  62. package/src/store/components/filter-chip.mdx +25 -0
  63. package/src/store/components/filter-chip.tsx +12 -0
  64. package/src/store/components/index.tsx +39 -0
  65. package/src/store/components/product-card.mdx +69 -0
  66. package/src/store/components/product-card.tsx +71 -0
  67. package/src/store/components/product-detail.mdx +30 -0
  68. package/src/store/components/product-detail.tsx +488 -0
  69. package/src/store/components/product-listing.mdx +7 -0
  70. package/src/store/components/product-listing.tsx +423 -0
  71. package/src/store/components/product-reviews-section.mdx +21 -0
  72. package/src/store/components/product-reviews-section.tsx +372 -0
  73. package/src/store/components/recently-viewed.tsx +100 -0
  74. package/src/store/components/related-products.mdx +6 -0
  75. package/src/store/components/related-products.tsx +62 -0
  76. package/src/store/components/star-display.mdx +18 -0
  77. package/src/store/components/star-display.tsx +27 -0
  78. package/src/store/components/star-picker.mdx +21 -0
  79. package/src/store/components/star-picker.tsx +21 -0
  80. package/src/store/components/stock-badge.mdx +12 -0
  81. package/src/store/components/stock-badge.tsx +19 -0
  82. package/src/store/endpoints/get-category.ts +61 -0
  83. package/src/store/endpoints/get-collection.ts +46 -0
  84. package/src/store/endpoints/get-featured.ts +18 -0
  85. package/src/store/endpoints/get-product.ts +52 -0
  86. package/src/store/endpoints/get-related.ts +20 -0
  87. package/src/store/endpoints/index.ts +23 -0
  88. package/src/store/endpoints/list-categories.ts +13 -0
  89. package/src/store/endpoints/list-collections.ts +22 -0
  90. package/src/store/endpoints/list-products.ts +28 -0
  91. package/src/store/endpoints/search-products.ts +18 -0
  92. package/src/store/endpoints/store-search.ts +111 -0
  93. package/tsconfig.json +9 -0
  94. package/vitest.config.ts +7 -0
package/AGENTS.md ADDED
@@ -0,0 +1,65 @@
1
+ # Products Module
2
+
3
+ Product catalog with variants and hierarchical categories. Full CRUD for admin, read-only browsing and search for storefront.
4
+
5
+ ## Structure
6
+
7
+ ```
8
+ src/
9
+ index.ts Factory: products(options?) => Module + admin nav registration
10
+ schema.ts Zod models: product, productVariant, category
11
+ controllers.ts All business logic (product, variant, category controllers)
12
+ components/
13
+ store/ Customer-facing MDX components
14
+ index.tsx ProductCard, ProductGrid, CategoryList, CategoryItem (.tsx logic)
15
+ *.mdx Store template variants
16
+ admin/ Store admin MDX components
17
+ index.tsx Product table, product editor, category manager (.tsx logic)
18
+ *.mdx Admin template variants
19
+ endpoints/
20
+ store/ Customer-facing (6 endpoints)
21
+ list-products.ts GET /products
22
+ get-product.ts GET /products/:id (by ID or slug)
23
+ get-featured.ts GET /products/featured
24
+ search-products.ts GET /products/search?q=
25
+ list-categories.ts GET /categories
26
+ get-category.ts GET /categories/:id
27
+ admin/ Protected (12 endpoints)
28
+ create-product.ts POST /admin/products
29
+ list-products.ts GET /admin/products/list
30
+ get-product.ts GET /admin/products/:id
31
+ update-product.ts PUT /admin/products/:id
32
+ delete-product.ts DELETE /admin/products/:id
33
+ create-variant.ts POST /admin/products/:productId/variants
34
+ update-variant.ts PUT /admin/variants/:id
35
+ delete-variant.ts DELETE /admin/variants/:id
36
+ create-category.ts POST /admin/categories
37
+ list-categories.ts GET /admin/categories/list
38
+ update-category.ts PUT /admin/categories/:id
39
+ delete-category.ts DELETE /admin/categories/:id
40
+ ```
41
+
42
+ ## Options
43
+
44
+ ```ts
45
+ ProductsOptions {
46
+ defaultPageSize?: number // default 20
47
+ maxPageSize?: number // default 100
48
+ trackInventory?: boolean // default true
49
+ }
50
+ ```
51
+
52
+ ## Data models
53
+
54
+ - **product**: id, name, slug (unique), price, compareAtPrice, costPrice, sku?, inventory, status (draft|active|archived), categoryId?, images[], tags[], isFeatured, weight/weightUnit
55
+ - **productVariant**: id, productId (FK cascade), name, sku?, price, inventory, options (Record<string,string> for size/color/etc.), position
56
+ - **category**: id, name, slug (unique), parentId? (self-referential for hierarchy), position, isVisible
57
+
58
+ ## Patterns
59
+
60
+ - Uses core data layer directly (no adapter) — `data.get()`, `data.findMany()`, `data.upsert()`, `data.delete()`
61
+ - Product IDs: `prod_${timestamp}`, variant IDs: `var_${timestamp}`
62
+ - Store endpoints only return active products; admin endpoints return all statuses
63
+ - Variant writes also update parent product's `updatedAt`
64
+ - Category deletion orphans children and products (sets their categoryId to null)
65
+ - `getTree()` builds hierarchical category structure from flat list
package/COMPONENTS.md ADDED
@@ -0,0 +1,231 @@
1
+ # Products Module — Store Components
2
+
3
+ Components exported for use in store MDX templates. Import via the component registry (auto-registered when the module is in `templates/brisa/config.json`).
4
+
5
+ ## ProductCard
6
+
7
+ Displays a single product card with image, name, price, discount badge, and optional "Add to Cart" button.
8
+
9
+ ### Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ |------|------|---------|-------------|
13
+ | `product` | `Product` | — | Product object with id, name, slug, price, images, etc. |
14
+ | `showAddToCart` | `boolean` | `true` | Show the "Add to Cart" button |
15
+
16
+ ### Usage in MDX
17
+
18
+ ```mdx
19
+ <ProductCard product={product} />
20
+
21
+ <ProductCard product={product} showAddToCart={false} />
22
+ ```
23
+
24
+ ## FeaturedProducts
25
+
26
+ Displays a responsive grid of featured products. Fetches its own data.
27
+
28
+ ### Props
29
+
30
+ | Prop | Type | Default | Description |
31
+ |------|------|---------|-------------|
32
+ | `limit` | `number` | — | Max number of featured products to display |
33
+ | `title` | `string` | — | Section heading |
34
+
35
+ ### Usage in MDX
36
+
37
+ ```mdx
38
+ <FeaturedProducts />
39
+
40
+ <FeaturedProducts limit={4} title="Staff Picks" />
41
+ ```
42
+
43
+ ## ProductListing
44
+
45
+ Full product listing with search, category/price/stock/tag filters, sorting, and pagination. Fetches its own data.
46
+
47
+ ### Props
48
+
49
+ | Prop | Type | Default | Description |
50
+ |------|------|---------|-------------|
51
+ | `initialCategory` | `string` | — | Pre-select a category filter |
52
+ | `initialSearch` | `string` | — | Pre-fill the search query |
53
+ | `pageSize` | `number` | — | Products per page |
54
+
55
+ ### Usage in MDX
56
+
57
+ ```mdx
58
+ <ProductListing />
59
+
60
+ <ProductListing initialCategory="shoes" pageSize={12} />
61
+ ```
62
+
63
+ ## ProductDetail
64
+
65
+ Full product detail page with image gallery, variant selector, pricing, inventory status, reviews, and related products. Fetches its own data.
66
+
67
+ ### Props
68
+
69
+ | Prop | Type | Description |
70
+ |------|------|-------------|
71
+ | `slug` | `string` | Product slug (from URL) |
72
+ | `params` | `Record<string, string>` | Route params (params.slug) |
73
+
74
+ ### Usage
75
+
76
+ Loaded dynamically by the store catch-all route for `/products/:slug`.
77
+
78
+ ## RelatedProducts
79
+
80
+ Horizontal grid of related products for a given product. Fetches its own data.
81
+
82
+ ### Props
83
+
84
+ | Prop | Type | Default | Description |
85
+ |------|------|---------|-------------|
86
+ | `productId` | `string` | — | Product ID to find related products for |
87
+ | `limit` | `number` | — | Max related products to show |
88
+ | `title` | `string` | — | Section heading |
89
+
90
+ ### Usage in MDX
91
+
92
+ ```mdx
93
+ <RelatedProducts productId={product.id} />
94
+
95
+ <RelatedProducts productId={product.id} limit={4} title="You may also like" />
96
+ ```
97
+
98
+ ## CollectionCard
99
+
100
+ Displays a single collection card with image, name, and description.
101
+
102
+ ### Props
103
+
104
+ | Prop | Type | Description |
105
+ |------|------|-------------|
106
+ | `collection` | `CollectionCardData` | Collection object with id, name, slug, description, image |
107
+
108
+ ### Usage in MDX
109
+
110
+ ```mdx
111
+ <CollectionCard collection={collection} />
112
+ ```
113
+
114
+ ## CollectionGrid
115
+
116
+ Grid of collections with optional featured-only filtering. Fetches its own data.
117
+
118
+ ### Props
119
+
120
+ | Prop | Type | Default | Description |
121
+ |------|------|---------|-------------|
122
+ | `title` | `string` | — | Section heading |
123
+ | `featured` | `boolean` | — | Only show featured collections |
124
+
125
+ ### Usage in MDX
126
+
127
+ ```mdx
128
+ <CollectionGrid />
129
+
130
+ <CollectionGrid title="Shop by Category" featured={true} />
131
+ ```
132
+
133
+ ## CollectionDetail
134
+
135
+ Full collection page with image, description, product count, and products grid. Fetches its own data.
136
+
137
+ ### Props
138
+
139
+ | Prop | Type | Description |
140
+ |------|------|-------------|
141
+ | `slug` | `string` | Collection slug (from URL) |
142
+ | `params` | `Record<string, string>` | Route params (params.slug) |
143
+
144
+ ### Usage
145
+
146
+ Loaded dynamically by the store catch-all route for `/collections/:slug`.
147
+
148
+ ## FilterChip
149
+
150
+ Small removable tag displaying an active filter. Used internally by ProductListing.
151
+
152
+ ### Props
153
+
154
+ | Prop | Type | Description |
155
+ |------|------|-------------|
156
+ | `label` | `string` | Filter display text |
157
+ | `onRemove` | `() => void` | Callback when the chip is dismissed |
158
+
159
+ ### Usage in MDX
160
+
161
+ ```mdx
162
+ <FilterChip label="Shoes" onRemove={handleRemove} />
163
+ ```
164
+
165
+ ## StarDisplay
166
+
167
+ Read-only star rating display.
168
+
169
+ ### Props
170
+
171
+ | Prop | Type | Default | Description |
172
+ |------|------|---------|-------------|
173
+ | `rating` | `number` | — | Rating value (0–5) |
174
+ | `size` | `"sm" \| "md" \| "lg"` | `"md"` | Star size |
175
+
176
+ ### Usage in MDX
177
+
178
+ ```mdx
179
+ <StarDisplay rating={4.5} />
180
+
181
+ <StarDisplay rating={product.averageRating} size="sm" />
182
+ ```
183
+
184
+ ## StarPicker
185
+
186
+ Interactive star rating input for review submission.
187
+
188
+ ### Props
189
+
190
+ | Prop | Type | Description |
191
+ |------|------|-------------|
192
+ | `value` | `number` | Current rating value |
193
+ | `onChange` | `(n: number) => void` | Callback when user selects a rating |
194
+
195
+ ### Usage in MDX
196
+
197
+ ```mdx
198
+ <StarPicker value={rating} onChange={setRating} />
199
+ ```
200
+
201
+ ## StockBadge
202
+
203
+ Inventory status badge. Shows "Out of stock", "Only X left", or "In stock".
204
+
205
+ ### Props
206
+
207
+ | Prop | Type | Description |
208
+ |------|------|-------------|
209
+ | `inventory` | `number` | Available inventory count |
210
+
211
+ ### Usage in MDX
212
+
213
+ ```mdx
214
+ <StockBadge inventory={product.inventory} />
215
+ ```
216
+
217
+ ## ProductReviewsSection
218
+
219
+ Complete review section with rating summary, review list with pagination, and review submission form. Fetches its own data.
220
+
221
+ ### Props
222
+
223
+ | Prop | Type | Description |
224
+ |------|------|-------------|
225
+ | `productId` | `string` | Product ID to show reviews for |
226
+
227
+ ### Usage in MDX
228
+
229
+ ```mdx
230
+ <ProductReviewsSection productId={product.id} />
231
+ ```
package/README.md ADDED
@@ -0,0 +1,201 @@
1
+ <p align="center">
2
+ <a href="https://86d.app">
3
+ <img src="https://86d.app/logo" height="96" alt="86d" />
4
+ </a>
5
+ </p>
6
+
7
+ <p align="center">
8
+ Dynamic Commerce
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://vercel.com/changelog"><strong>npm</strong></a> ·
13
+ <a href="https://x.com/86d_app"><strong>X</strong></a> ·
14
+ <a href="https://vercel.com/templates"><strong>LinkedIn</strong></a>
15
+ </p>
16
+ <br/>
17
+
18
+ > [!WARNING]
19
+ > This project is under active development and is not ready for production use. Please proceed with caution. Use at your own risk.
20
+
21
+ # @86d-app/products
22
+
23
+ Product catalog module with variants and hierarchical categories. Full CRUD for the admin panel and read-only browsing with search and filtering for the storefront.
24
+
25
+ ## Installation
26
+
27
+ ```sh
28
+ npm install @86d-app/products
29
+ ```
30
+
31
+ ## Usage
32
+
33
+ ```ts
34
+ import products from "@86d-app/products";
35
+
36
+ const module = products({
37
+ defaultPageSize: 20,
38
+ maxPageSize: 100,
39
+ trackInventory: true,
40
+ });
41
+ ```
42
+
43
+ ## Configuration
44
+
45
+ | Option | Type | Default | Description |
46
+ |---|---|---|---|
47
+ | `defaultPageSize` | `number` | `20` | Default number of products per page |
48
+ | `maxPageSize` | `number` | `100` | Maximum products per page |
49
+ | `trackInventory` | `boolean` | `true` | Enable inventory tracking by default |
50
+
51
+ ## Store Endpoints
52
+
53
+ | Method | Path | Description |
54
+ |---|---|---|
55
+ | `GET` | `/products` | List active products (paginated, filterable) |
56
+ | `GET` | `/products/featured` | Get featured products |
57
+ | `GET` | `/products/:slug` | Get a single product by slug (includes variants) |
58
+ | `GET` | `/products/search?q=` | Search products by name, description, or SKU |
59
+ | `GET` | `/categories` | List visible categories |
60
+ | `GET` | `/categories/:slug` | Get a single category by slug |
61
+
62
+ Query parameters for `GET /products`:
63
+
64
+ | Param | Type | Description |
65
+ |---|---|---|
66
+ | `page` | `number` | Page number (default `1`) |
67
+ | `limit` | `number` | Items per page (capped at `maxPageSize`) |
68
+ | `category` | `string` | Filter by category slug |
69
+ | `status` | `string` | Product status (storefront always uses `active`) |
70
+ | `featured` | `boolean` | Filter featured products |
71
+
72
+ ## Admin Endpoints
73
+
74
+ | Method | Path | Description |
75
+ |---|---|---|
76
+ | `POST` | `/admin/products` | Create a new product |
77
+ | `GET` | `/admin/products/list` | List all products (all statuses) |
78
+ | `GET` | `/admin/products/:id` | Get a product by ID |
79
+ | `PUT` | `/admin/products/:id` | Update a product |
80
+ | `DELETE` | `/admin/products/:id` | Delete a product |
81
+ | `POST` | `/admin/products/:productId/variants` | Add a variant to a product |
82
+ | `PUT` | `/admin/variants/:id` | Update a variant |
83
+ | `DELETE` | `/admin/variants/:id` | Delete a variant |
84
+ | `POST` | `/admin/categories` | Create a category |
85
+ | `GET` | `/admin/categories/list` | List all categories |
86
+ | `PUT` | `/admin/categories/:id` | Update a category |
87
+ | `DELETE` | `/admin/categories/:id` | Delete a category |
88
+
89
+ ## Controller API
90
+
91
+ Controllers are accessed via the runtime context. Three sub-controllers are available: `product`, `variant`, and `category`.
92
+
93
+ ```ts
94
+ // product controller
95
+ context.controllers.product.getById(ctx) // Product | null
96
+ context.controllers.product.getBySlug(ctx) // Product | null
97
+ context.controllers.product.getWithVariants(ctx) // ProductWithVariants | null
98
+ context.controllers.product.list(ctx) // { products: Product[]; total: number }
99
+ context.controllers.product.create(ctx) // Product
100
+ context.controllers.product.update(ctx) // Product | null
101
+ context.controllers.product.delete(ctx) // void
102
+
103
+ // variant controller
104
+ context.controllers.variant.create(ctx) // ProductVariant
105
+ context.controllers.variant.update(ctx) // ProductVariant | null
106
+ context.controllers.variant.delete(ctx) // void
107
+
108
+ // category controller
109
+ context.controllers.category.getById(ctx) // Category | null
110
+ context.controllers.category.getBySlug(ctx) // Category | null
111
+ context.controllers.category.list(ctx) // { categories: Category[]; total: number }
112
+ context.controllers.category.getTree(ctx) // Category[] (hierarchical)
113
+ context.controllers.category.create(ctx) // Category
114
+ context.controllers.category.update(ctx) // Category | null
115
+ context.controllers.category.delete(ctx) // void
116
+ ```
117
+
118
+ Each controller method receives a `ctx` object:
119
+
120
+ ```ts
121
+ {
122
+ context: { data: ModuleDataService };
123
+ params: Record<string, string>;
124
+ query: Record<string, string>;
125
+ body: Record<string, unknown>;
126
+ }
127
+ ```
128
+
129
+ ## Types
130
+
131
+ ```ts
132
+ interface Product {
133
+ id: string;
134
+ name: string;
135
+ slug: string;
136
+ description?: string;
137
+ shortDescription?: string;
138
+ price: number; // in cents
139
+ compareAtPrice?: number;
140
+ costPrice?: number;
141
+ sku?: string;
142
+ barcode?: string;
143
+ inventory: number;
144
+ trackInventory: boolean;
145
+ allowBackorder: boolean;
146
+ status: "draft" | "active" | "archived";
147
+ categoryId?: string;
148
+ images: string[];
149
+ tags: string[];
150
+ isFeatured: boolean;
151
+ weight?: number;
152
+ weightUnit?: "kg" | "lb" | "oz" | "g";
153
+ metadata?: Record<string, unknown>;
154
+ createdAt: Date;
155
+ updatedAt: Date;
156
+ }
157
+
158
+ interface ProductVariant {
159
+ id: string;
160
+ productId: string;
161
+ name: string;
162
+ sku?: string;
163
+ price: number;
164
+ compareAtPrice?: number;
165
+ costPrice?: number;
166
+ inventory: number;
167
+ options: Record<string, string>; // e.g. { size: "M", color: "Blue" }
168
+ images: string[];
169
+ position: number;
170
+ weight?: number;
171
+ weightUnit?: "kg" | "lb" | "oz" | "g";
172
+ createdAt: Date;
173
+ updatedAt: Date;
174
+ }
175
+
176
+ interface Category {
177
+ id: string;
178
+ name: string;
179
+ slug: string;
180
+ description?: string;
181
+ parentId?: string; // Self-referential for nested categories
182
+ image?: string;
183
+ position: number;
184
+ isVisible: boolean;
185
+ metadata?: Record<string, unknown>;
186
+ createdAt: Date;
187
+ updatedAt: Date;
188
+ }
189
+
190
+ interface ProductWithVariants extends Product {
191
+ variants: ProductVariant[];
192
+ category?: Category;
193
+ }
194
+ ```
195
+
196
+ ## Notes
197
+
198
+ - Store endpoints return only `active` products; admin endpoints return all statuses (`draft`, `active`, `archived`).
199
+ - Product IDs are prefixed: `prod_${timestamp}`. Variant IDs: `var_${timestamp}`.
200
+ - Deleting a category orphans its child categories and products (sets `categoryId` to `null`) rather than cascading.
201
+ - `getTree()` builds a hierarchical category tree from the flat list using `parentId` references.
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@86d-app/products",
3
+ "version": "0.0.3",
4
+ "description": "Product catalog module for 86d commerce platform",
5
+ "keywords": [
6
+ "commerce",
7
+ "products",
8
+ "catalog",
9
+ "categories",
10
+ "86d"
11
+ ],
12
+ "license": "MIT",
13
+ "author": "86d <chat@86d.app>",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/86d-app/86d.git",
17
+ "directory": "modules/products"
18
+ },
19
+ "homepage": "https://github.com/86d-app/86d/tree/main/modules/products",
20
+ "type": "module",
21
+ "exports": {
22
+ "./components": "./src/store/components",
23
+ "./admin-components": "./src/admin/components",
24
+ "./*": "./src/*"
25
+ },
26
+ "scripts": {
27
+ "build": "tsc",
28
+ "check": "biome check src",
29
+ "check:fix": "biome check --write src",
30
+ "clean": "git clean -xdf .cache .turbo dist node_modules",
31
+ "dev": "tsc",
32
+ "test": "vitest run",
33
+ "test:watch": "vitest watch",
34
+ "typecheck": "tsc --noEmit --emitDeclarationOnly false"
35
+ },
36
+ "dependencies": {
37
+ "@86d-app/core": "workspace:*"
38
+ },
39
+ "devDependencies": {
40
+ "@biomejs/biome": "catalog:",
41
+ "@types/mdx": "catalog:mdx",
42
+ "@types/react": "catalog:react",
43
+ "typescript": "catalog:",
44
+ "vitest": "catalog:vite"
45
+ }
46
+ }