make-mp-data 3.0.3 → 3.0.5
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 +46 -0
- package/dungeons/array-of-object-lookup-schema.json +327 -0
- package/dungeons/array-of-object-lookup.js +29 -9
- package/dungeons/capstone/capstone-ic3.js +291 -0
- package/dungeons/capstone/capstone-ic4.js +598 -0
- package/dungeons/capstone/capstone-ic5.js +668 -0
- package/dungeons/capstone/generate-product-lookup.js +309 -0
- package/dungeons/ecommerce-schema.json +462 -0
- package/dungeons/{copilot.js → ecommerce.js} +79 -17
- package/dungeons/education-schema.json +2409 -0
- package/dungeons/education.js +226 -462
- package/dungeons/fintech-schema.json +14034 -0
- package/dungeons/fintech.js +134 -413
- package/dungeons/foobar-schema.json +403 -0
- package/dungeons/foobar.js +27 -4
- package/dungeons/food-delivery-schema.json +192 -0
- package/dungeons/food-delivery.js +602 -0
- package/dungeons/food-schema.json +1152 -0
- package/dungeons/food.js +173 -406
- package/dungeons/gaming-schema.json +1270 -0
- package/dungeons/gaming.js +182 -42
- package/dungeons/insurance-application-schema.json +204 -0
- package/dungeons/insurance-application.js +605 -0
- package/dungeons/media-schema.json +906 -0
- package/dungeons/media.js +250 -420
- package/dungeons/retention-cadence-schema.json +78 -0
- package/dungeons/retention-cadence.js +35 -1
- package/dungeons/rpg-schema.json +4526 -0
- package/dungeons/rpg.js +171 -429
- package/dungeons/sanity-schema.json +255 -0
- package/dungeons/sanity.js +21 -10
- package/dungeons/sass-schema.json +1291 -0
- package/dungeons/sass.js +241 -368
- package/dungeons/scd-schema.json +919 -0
- package/dungeons/scd.js +41 -13
- package/dungeons/simple-schema.json +608 -0
- package/dungeons/simple.js +52 -15
- package/dungeons/simplest-schema.json +1418 -0
- package/dungeons/simplest.js +392 -0
- package/dungeons/social-schema.json +1118 -0
- package/dungeons/social.js +150 -391
- package/dungeons/text-generation-schema.json +3096 -0
- package/dungeons/text-generation.js +71 -0
- package/index.js +8 -6
- package/lib/core/config-validator.js +28 -8
- package/lib/core/storage.js +5 -5
- package/lib/generators/events.js +4 -4
- package/lib/orchestrators/mixpanel-sender.js +16 -13
- package/lib/orchestrators/user-loop.js +14 -6
- package/lib/templates/soup-presets.js +188 -0
- package/lib/utils/utils.js +52 -6
- package/package.json +1 -1
- package/types.d.ts +20 -3
- package/dungeons/adspend.js +0 -130
- package/dungeons/anon.js +0 -128
- package/dungeons/benchmark-heavy.js +0 -240
- package/dungeons/benchmark-light.js +0 -140
- package/dungeons/big.js +0 -226
- package/dungeons/business.js +0 -391
- package/dungeons/complex.js +0 -428
- package/dungeons/experiments.js +0 -137
- package/dungeons/funnels.js +0 -309
- package/dungeons/mil.js +0 -323
- package/dungeons/mirror.js +0 -161
- package/dungeons/soup-test.js +0 -52
- package/dungeons/streaming.js +0 -372
- package/dungeons/strict-event-test.js +0 -30
- package/dungeons/student-teacher.js +0 -438
- package/dungeons/too-big-events.js +0 -203
- package/dungeons/user-agent.js +0 -209
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate product_id lookup table
|
|
3
|
+
* This creates a standalone JSONL file with 10,000 products
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import Chance from 'chance';
|
|
7
|
+
import { weighNumRange, integer } from "../brain/utils/utils.js";
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = path.dirname(__filename);
|
|
14
|
+
|
|
15
|
+
// Initialize chance with seed for reproducibility
|
|
16
|
+
const chance = new Chance('its the capstone baby!');
|
|
17
|
+
|
|
18
|
+
// Product catalog
|
|
19
|
+
const productCatalog = {
|
|
20
|
+
electronics: [
|
|
21
|
+
"Wireless Bluetooth Headphones", "USB-C Charging Cable", "Portable Power Bank 20000mAh",
|
|
22
|
+
"Smart Watch Series 7", "Wireless Gaming Mouse", "Mechanical Keyboard RGB",
|
|
23
|
+
"4K Webcam Pro", "Laptop Stand Aluminum", "Phone Case Clear", "Screen Protector Tempered Glass",
|
|
24
|
+
"Bluetooth Speaker Waterproof", "Ring Light for Streaming", "HDMI Cable 6ft",
|
|
25
|
+
"Wall Charger 65W Fast Charge", "Wireless Charging Pad", "USB Hub 7-Port",
|
|
26
|
+
"External SSD 1TB", "Microphone Condenser", "Gaming Headset 7.1 Surround",
|
|
27
|
+
"Smart LED Light Bulb", "Security Camera 1080p", "Tablet Case Leather",
|
|
28
|
+
"Stylus Pen for iPad", "Cable Organizer Set", "Laptop Sleeve 15 inch",
|
|
29
|
+
"Ergonomic Mouse Pad", "Phone Car Mount Magnetic", "Dash Cam Front and Rear",
|
|
30
|
+
"Fitness Tracker Heart Rate", "Earbuds True Wireless", "Drone with 4K Camera",
|
|
31
|
+
"Action Camera Waterproof", "VR Headset Meta Quest", "Smart Doorbell Camera",
|
|
32
|
+
"WiFi Router Dual Band", "Graphics Tablet for Drawing", "Streaming Deck Mini",
|
|
33
|
+
"Portable Monitor 15.6 inch", "Noise Cancelling Headphones", "Smart Thermostat WiFi"
|
|
34
|
+
],
|
|
35
|
+
home_kitchen: [
|
|
36
|
+
"Air Fryer 6 Quart Digital", "Instant Pot 8 Quart", "Blender High Speed 1500W",
|
|
37
|
+
"Coffee Maker Programmable 12 Cup", "Toaster 4 Slice Stainless Steel", "Knife Set 15 Piece",
|
|
38
|
+
"Cutting Board Bamboo Large", "Mixing Bowl Set Stainless", "Measuring Cup and Spoon Set",
|
|
39
|
+
"Cast Iron Skillet 12 inch", "Non-Stick Cookware Set 10 Piece", "Slow Cooker 6 Quart",
|
|
40
|
+
"Electric Kettle 1.7L", "Food Processor 12 Cup", "Stand Mixer 5 Quart",
|
|
41
|
+
"Dish Rack Stainless Steel", "Kitchen Utensil Set 24 Piece", "Spice Rack Organizer",
|
|
42
|
+
"Storage Containers Glass Set", "Baking Sheet Pan Set", "Vacuum Sealer for Food",
|
|
43
|
+
"Wine Glasses Set of 6", "Dinnerware Set 16 Piece", "Silverware Set 20 Piece",
|
|
44
|
+
"Can Opener Electric", "Rice Cooker 10 Cup", "Waffle Maker Belgian",
|
|
45
|
+
"Panini Press Grill", "Juicer Extractor Centrifugal", "Kitchen Scale Digital",
|
|
46
|
+
"Trash Can 13 Gallon Step", "Paper Towel Holder Wall Mount", "Soap Dispenser Automatic",
|
|
47
|
+
"Dish Soap Refill Pack", "Sponges Pack of 24", "Oven Mitts Heat Resistant",
|
|
48
|
+
"Pot Holders Set of 4", "Apron Adjustable Chef", "Dish Towels Cotton Set"
|
|
49
|
+
],
|
|
50
|
+
clothing: [
|
|
51
|
+
"Men's Cotton T-Shirt Basic", "Women's Yoga Pants High Waist", "Unisex Hoodie Pullover",
|
|
52
|
+
"Jeans Slim Fit Blue", "Dress Casual Summer Floral", "Button-Down Shirt Long Sleeve",
|
|
53
|
+
"Sneakers Running Lightweight", "Jacket Windbreaker Waterproof", "Socks Pack of 12",
|
|
54
|
+
"Baseball Cap Adjustable", "Scarf Winter Knit Warm", "Gloves Touchscreen Compatible",
|
|
55
|
+
"Belt Leather Reversible", "Tank Top Athletic Performance", "Shorts Cargo Pockets",
|
|
56
|
+
"Leggings Compression Workout", "Sweater Pullover V-Neck", "Cardigan Open Front",
|
|
57
|
+
"Blazer Business Casual", "Skirt Midi A-Line", "Polo Shirt Pique Cotton",
|
|
58
|
+
"Underwear Pack of 6", "Bra Sports High Support", "Pajama Set Soft Cotton",
|
|
59
|
+
"Slippers Memory Foam Cozy", "Sandals Flip Flops Beach", "Boots Ankle Chelsea",
|
|
60
|
+
"Tie Silk Classic Stripe", "Sunglasses Polarized UV", "Watch Band Leather Replacement",
|
|
61
|
+
"Backpack Laptop Compartment", "Wallet Genuine Leather", "Handbag Crossbody Vegan",
|
|
62
|
+
"Tote Bag Canvas Large", "Duffel Bag Gym Travel", "Beanie Winter Warm Knit",
|
|
63
|
+
"Bucket Hat Summer UV", "Vest Puffer Down Fill", "Raincoat Packable Lightweight"
|
|
64
|
+
]
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// Generate realistic product names from catalog
|
|
68
|
+
function getProductName() {
|
|
69
|
+
const allProducts = Object.values(productCatalog).flat();
|
|
70
|
+
const baseProduct = chance.pickone(allProducts);
|
|
71
|
+
|
|
72
|
+
// Add variation 30% of the time
|
|
73
|
+
if (chance.bool({ likelihood: 30 })) {
|
|
74
|
+
const variations = [
|
|
75
|
+
` - ${chance.pickone(['Black', 'White', 'Blue', 'Red', 'Gray', 'Silver', 'Gold'])}`,
|
|
76
|
+
` - ${chance.pickone(['Small', 'Medium', 'Large', 'X-Large'])}`,
|
|
77
|
+
` - ${chance.pickone(['Pro', 'Plus', 'Lite', 'Max', 'Mini'])}`,
|
|
78
|
+
` (${chance.pickone(['2024 Model', '2025 Edition', 'Gen 2'])})`
|
|
79
|
+
];
|
|
80
|
+
return baseProduct + chance.pickone(variations);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return baseProduct;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Get category for a product
|
|
87
|
+
function getProductCategory() {
|
|
88
|
+
const categories = [
|
|
89
|
+
"Electronics", "Home & Kitchen", "Clothing", "Beauty & Personal Care",
|
|
90
|
+
"Sports & Outdoors", "Books & Media", "Toys & Games", "Pet Supplies",
|
|
91
|
+
"Office Supplies", "Baby Products", "Automotive", "Garden & Outdoor"
|
|
92
|
+
];
|
|
93
|
+
return chance.pickone(categories);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Generate a single product
|
|
97
|
+
function generateProduct(productId) {
|
|
98
|
+
const brands = [
|
|
99
|
+
"TechPro", "HomeEssentials", "FitLife", "StyleCo", "BeautyPlus",
|
|
100
|
+
"OfficeMax", "EcoGoods", "PremiumChoice", "ValueBrand", "GenericCo",
|
|
101
|
+
"ProGear", "UltraLife", "SmartHome", "ActiveWear", "LuxeBeauty",
|
|
102
|
+
"NatureBest", "UrbanLiving", "EliteChoice", "BudgetBuy", "MegaMart",
|
|
103
|
+
"QualityFirst", "FastShip", "GreenEarth", "ModernLife", "ClassicGoods"
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
const categories = [
|
|
107
|
+
"Electronics", "Home & Kitchen", "Clothing", "Beauty & Personal Care",
|
|
108
|
+
"Sports & Outdoors", "Books & Media", "Toys & Games", "Pet Supplies",
|
|
109
|
+
"Office Supplies", "Baby Products", "Automotive", "Garden & Outdoor"
|
|
110
|
+
];
|
|
111
|
+
|
|
112
|
+
const colors = ["Black", "White", "Blue", "Red", "Gray", "Silver", "Gold", "Green", "Pink", "Purple", "Orange", "Brown", "Beige", "Navy", "Teal"];
|
|
113
|
+
const sizes = ["XS", "S", "M", "L", "XL", "XXL", "One Size", "Adjustable", "Small", "Medium", "Large"];
|
|
114
|
+
const materials = ["Cotton", "Polyester", "Plastic", "Metal", "Wood", "Glass", "Silicone", "Leather", "Fabric", "Stainless Steel", "Aluminum", "Bamboo"];
|
|
115
|
+
const conditions = ["New", "New", "New", "New", "Refurbished", "Open Box", "Like New"];
|
|
116
|
+
const shippingClasses = ["Standard", "Standard", "Express", "Prime", "2-Day", "Overnight", "Economy"];
|
|
117
|
+
const warehouses = ["US-East-1", "US-West-2", "EU-Central", "Asia-Pacific", "US-Central", "Canada-1"];
|
|
118
|
+
const suppliers = ["Global Supply Co", "Import Direct", "Wholesale Plus", "Manufacturer Direct", "Trade Partners", "International Goods"];
|
|
119
|
+
const origins = ["USA", "China", "Germany", "Japan", "Italy", "UK", "France", "South Korea", "Taiwan", "Mexico", "Canada", "Vietnam"];
|
|
120
|
+
|
|
121
|
+
const demand = chance.pickone(["very high", "high", "high", "medium", "medium", "low"]);
|
|
122
|
+
const supply = chance.pickone(["abundant", "high", "high", "medium", "medium", "low", "limited"]);
|
|
123
|
+
const isFeatured = chance.pickone([true, false, false, false, false, false, false]);
|
|
124
|
+
const isOnSale = chance.pickone([true, true, false, false, false, false]);
|
|
125
|
+
const isNewArrival = chance.pickone([true, false, false, false, false]);
|
|
126
|
+
const isBestseller = chance.pickone([true, true, false, false, false, false, false]);
|
|
127
|
+
const isLowStock = chance.pickone([true, false, false, false, false]);
|
|
128
|
+
|
|
129
|
+
const basePrice = parseFloat(chance.pickone(weighNumRange(5, 500, 0.25)).toFixed(2));
|
|
130
|
+
const costPrice = parseFloat((basePrice * chance.floating({ min: 0.4, max: 0.7 })).toFixed(2));
|
|
131
|
+
const msrp = parseFloat((basePrice * chance.floating({ min: 1.1, max: 1.5 })).toFixed(2));
|
|
132
|
+
const discountPercent = isOnSale ? integer(5, 50) : 0;
|
|
133
|
+
const salePrice = discountPercent > 0 ? parseFloat((basePrice * (1 - discountPercent / 100)).toFixed(2)) : basePrice;
|
|
134
|
+
|
|
135
|
+
const weight = parseFloat(chance.floating({ min: 0.1, max: 50 }).toFixed(2));
|
|
136
|
+
const length = parseFloat(chance.floating({ min: 1, max: 100 }).toFixed(1));
|
|
137
|
+
const width = parseFloat(chance.floating({ min: 1, max: 80 }).toFixed(1));
|
|
138
|
+
const height = parseFloat(chance.floating({ min: 1, max: 60 }).toFixed(1));
|
|
139
|
+
|
|
140
|
+
const totalReviews = chance.pickone(weighNumRange(0, 5000, 1.8));
|
|
141
|
+
const rating = parseFloat(chance.pickone(weighNumRange(1, 5)).toFixed(1));
|
|
142
|
+
const stockLevel = chance.pickone(weighNumRange(0, 10000, 0.8));
|
|
143
|
+
const reorderPoint = Math.floor(stockLevel * 0.2);
|
|
144
|
+
const reorderQuantity = Math.floor(stockLevel * 0.5);
|
|
145
|
+
|
|
146
|
+
const daysInStock = integer(1, 1000);
|
|
147
|
+
const lastRestocked = new Date(Date.now() - (daysInStock * 24 * 60 * 60 * 1000)).toISOString().split('T')[0];
|
|
148
|
+
const dateAdded = new Date(Date.now() - (integer(1, 730) * 24 * 60 * 60 * 1000)).toISOString().split('T')[0];
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
product_id: productId,
|
|
152
|
+
sku: `SKU-${String(productId).padStart(8, '0')}`,
|
|
153
|
+
upc: chance.string({ length: 12, pool: '0123456789' }),
|
|
154
|
+
product_name: getProductName(),
|
|
155
|
+
category: chance.pickone(categories),
|
|
156
|
+
subcategory: chance.pickone(["Accessories", "Main", "Premium", "Budget", "Specialty"]),
|
|
157
|
+
brand: chance.pickone(brands),
|
|
158
|
+
manufacturer: chance.company(),
|
|
159
|
+
supplier: chance.pickone(suppliers),
|
|
160
|
+
|
|
161
|
+
// Pricing
|
|
162
|
+
price: basePrice,
|
|
163
|
+
cost_price: costPrice,
|
|
164
|
+
msrp: msrp,
|
|
165
|
+
sale_price: salePrice,
|
|
166
|
+
discount_percent: discountPercent,
|
|
167
|
+
profit_margin: parseFloat(((basePrice - costPrice) / basePrice * 100).toFixed(2)),
|
|
168
|
+
currency: "USD",
|
|
169
|
+
tax_rate: parseFloat(chance.pickone([0, 5, 7.5, 8.5, 10]).toFixed(2)),
|
|
170
|
+
|
|
171
|
+
// Inventory
|
|
172
|
+
stock_level: stockLevel,
|
|
173
|
+
reserved_stock: Math.floor(stockLevel * chance.floating({ min: 0, max: 0.15 })),
|
|
174
|
+
available_stock: Math.floor(stockLevel * chance.floating({ min: 0.85, max: 1 })),
|
|
175
|
+
warehouse_location: chance.pickone(warehouses),
|
|
176
|
+
aisle: `${chance.pickone(['A', 'B', 'C', 'D', 'E'])}-${integer(1, 99)}`,
|
|
177
|
+
shelf: integer(1, 20),
|
|
178
|
+
bin: integer(1, 50),
|
|
179
|
+
reorder_point: reorderPoint,
|
|
180
|
+
reorder_quantity: reorderQuantity,
|
|
181
|
+
lead_time_days: integer(1, 60),
|
|
182
|
+
last_restocked: lastRestocked,
|
|
183
|
+
|
|
184
|
+
// Product Details
|
|
185
|
+
color: chance.pickone(colors),
|
|
186
|
+
size: chance.pickone(sizes),
|
|
187
|
+
material: chance.pickone(materials),
|
|
188
|
+
weight_lbs: weight,
|
|
189
|
+
length_in: length,
|
|
190
|
+
width_in: width,
|
|
191
|
+
height_in: height,
|
|
192
|
+
volume_cubic_in: parseFloat((length * width * height).toFixed(2)),
|
|
193
|
+
condition: chance.pickone(conditions),
|
|
194
|
+
origin_country: chance.pickone(origins),
|
|
195
|
+
|
|
196
|
+
// Ratings & Reviews
|
|
197
|
+
rating: rating,
|
|
198
|
+
total_reviews: totalReviews,
|
|
199
|
+
five_star: Math.floor(totalReviews * chance.floating({ min: 0.4, max: 0.7 })),
|
|
200
|
+
four_star: Math.floor(totalReviews * chance.floating({ min: 0.15, max: 0.25 })),
|
|
201
|
+
three_star: Math.floor(totalReviews * chance.floating({ min: 0.05, max: 0.15 })),
|
|
202
|
+
two_star: Math.floor(totalReviews * chance.floating({ min: 0.02, max: 0.08 })),
|
|
203
|
+
one_star: Math.floor(totalReviews * chance.floating({ min: 0.01, max: 0.05 })),
|
|
204
|
+
|
|
205
|
+
// Performance Metrics
|
|
206
|
+
views_last_30_days: integer(0, 50000),
|
|
207
|
+
clicks_last_30_days: integer(0, 10000),
|
|
208
|
+
conversions_last_30_days: integer(0, 1000),
|
|
209
|
+
revenue_last_30_days: parseFloat((integer(0, 50000)).toFixed(2)),
|
|
210
|
+
units_sold_total: integer(0, 100000),
|
|
211
|
+
units_sold_last_30_days: integer(0, 5000),
|
|
212
|
+
units_returned_total: integer(0, 1000),
|
|
213
|
+
return_rate: parseFloat(chance.floating({ min: 0, max: 15 }).toFixed(2)),
|
|
214
|
+
|
|
215
|
+
// Marketing & Sales
|
|
216
|
+
demand: demand,
|
|
217
|
+
supply: supply,
|
|
218
|
+
is_featured: isFeatured,
|
|
219
|
+
is_on_sale: isOnSale,
|
|
220
|
+
is_new_arrival: isNewArrival,
|
|
221
|
+
is_bestseller: isBestseller,
|
|
222
|
+
is_low_stock: isLowStock,
|
|
223
|
+
is_out_of_stock: stockLevel === 0,
|
|
224
|
+
is_backordered: chance.bool({ likelihood: 5 }),
|
|
225
|
+
is_seasonal: chance.bool({ likelihood: 20 }),
|
|
226
|
+
is_gift_wrap_available: chance.bool({ likelihood: 60 }),
|
|
227
|
+
is_free_shipping: chance.bool({ likelihood: 40 }),
|
|
228
|
+
|
|
229
|
+
// Shipping
|
|
230
|
+
shipping_class: chance.pickone(shippingClasses),
|
|
231
|
+
shipping_cost: parseFloat(chance.pickone([0, 4.99, 7.99, 9.99, 12.99, 19.99]).toFixed(2)),
|
|
232
|
+
estimated_delivery_days: integer(1, 14),
|
|
233
|
+
is_hazmat: chance.bool({ likelihood: 2 }),
|
|
234
|
+
is_fragile: chance.bool({ likelihood: 15 }),
|
|
235
|
+
is_perishable: chance.bool({ likelihood: 5 }),
|
|
236
|
+
|
|
237
|
+
// Metadata
|
|
238
|
+
date_added: dateAdded,
|
|
239
|
+
last_updated: new Date(Date.now() - (integer(0, 30) * 24 * 60 * 60 * 1000)).toISOString().split('T')[0],
|
|
240
|
+
age_restricted: chance.bool({ likelihood: 8 }),
|
|
241
|
+
warranty_months: chance.pickone([0, 0, 0, 6, 12, 24, 36]),
|
|
242
|
+
tags: chance.pickset(["popular", "trending", "eco-friendly", "handmade", "luxury", "budget", "clearance"], integer(0, 3)).join(';'),
|
|
243
|
+
search_keywords: chance.pickset(["quality", "affordable", "premium", "durable", "bestselling", "top-rated"], integer(1, 4)).join(';')
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Generate all products
|
|
248
|
+
function generateProductLookup(count = 10000) {
|
|
249
|
+
console.log(`Generating ${count} products...`);
|
|
250
|
+
const jsonlFile = path.join(__dirname, 'product_lookup.jsonl');
|
|
251
|
+
const csvFile = path.join(__dirname, 'product_lookup.csv');
|
|
252
|
+
|
|
253
|
+
// Clear the files if they exist
|
|
254
|
+
fs.writeFileSync(jsonlFile, '', 'utf8');
|
|
255
|
+
|
|
256
|
+
// Write CSV header - all fields
|
|
257
|
+
const csvHeaders = [
|
|
258
|
+
'product_id', 'sku', 'upc', 'product_name', 'category', 'subcategory', 'brand',
|
|
259
|
+
'manufacturer', 'supplier', 'price', 'cost_price', 'msrp', 'sale_price',
|
|
260
|
+
'discount_percent', 'profit_margin', 'currency', 'tax_rate', 'stock_level',
|
|
261
|
+
'reserved_stock', 'available_stock', 'warehouse_location', 'aisle', 'shelf',
|
|
262
|
+
'bin', 'reorder_point', 'reorder_quantity', 'lead_time_days', 'last_restocked',
|
|
263
|
+
'color', 'size', 'material', 'weight_lbs', 'length_in', 'width_in', 'height_in',
|
|
264
|
+
'volume_cubic_in', 'condition', 'origin_country', 'rating', 'total_reviews',
|
|
265
|
+
'five_star', 'four_star', 'three_star', 'two_star', 'one_star',
|
|
266
|
+
'views_last_30_days', 'clicks_last_30_days', 'conversions_last_30_days',
|
|
267
|
+
'revenue_last_30_days', 'units_sold_total', 'units_sold_last_30_days',
|
|
268
|
+
'units_returned_total', 'return_rate', 'demand', 'supply', 'is_featured',
|
|
269
|
+
'is_on_sale', 'is_new_arrival', 'is_bestseller', 'is_low_stock',
|
|
270
|
+
'is_out_of_stock', 'is_backordered', 'is_seasonal', 'is_gift_wrap_available',
|
|
271
|
+
'is_free_shipping', 'shipping_class', 'shipping_cost', 'estimated_delivery_days',
|
|
272
|
+
'is_hazmat', 'is_fragile', 'is_perishable', 'date_added', 'last_updated',
|
|
273
|
+
'age_restricted', 'warranty_months', 'tags', 'search_keywords'
|
|
274
|
+
];
|
|
275
|
+
fs.writeFileSync(csvFile, csvHeaders.join(',') + '\n', 'utf8');
|
|
276
|
+
|
|
277
|
+
// Generate products in batches to avoid memory issues
|
|
278
|
+
const batchSize = 1000;
|
|
279
|
+
for (let i = 1; i <= count; i++) {
|
|
280
|
+
const product = generateProduct(i);
|
|
281
|
+
|
|
282
|
+
// Write JSONL
|
|
283
|
+
fs.appendFileSync(jsonlFile, JSON.stringify(product) + '\n', 'utf8');
|
|
284
|
+
|
|
285
|
+
// Write CSV (escape fields with commas or quotes)
|
|
286
|
+
const escapeCSV = (val) => {
|
|
287
|
+
if (val === null || val === undefined) return '';
|
|
288
|
+
const str = String(val);
|
|
289
|
+
if (str.includes(',') || str.includes('"') || str.includes('\n')) {
|
|
290
|
+
return `"${str.replace(/"/g, '""')}"`;
|
|
291
|
+
}
|
|
292
|
+
return str;
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
const csvRow = csvHeaders.map(header => escapeCSV(product[header]));
|
|
296
|
+
fs.appendFileSync(csvFile, csvRow.join(',') + '\n', 'utf8');
|
|
297
|
+
|
|
298
|
+
if (i % batchSize === 0) {
|
|
299
|
+
console.log(`Generated ${i}/${count} products...`);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
console.log(`✓ Successfully generated ${count} products to:`);
|
|
304
|
+
console.log(` - ${jsonlFile} (${csvHeaders.length} fields)`);
|
|
305
|
+
console.log(` - ${csvFile} (${csvHeaders.length} columns)`);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Run the generator - increase this to 100,000 or 1,000,000 for a huge dataset
|
|
309
|
+
generateProductLookup(275_000);
|