@cobrastyle/adapter-dummy-data 1.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Cobrastyle
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ import type { StorefrontAdapter } from '@cobrastyle/shared-types';
2
+ export declare const dummyDataAdapter: StorefrontAdapter;
3
+ export default dummyDataAdapter;
@@ -0,0 +1,669 @@
1
+ import { products, productListItems } from './fixtures/products';
2
+ import { categories, navigation } from './fixtures/categories';
3
+ import { cmsPages } from './fixtures/cms';
4
+ // Simulated latency for realistic behavior
5
+ const LATENCY_MS = 100;
6
+ const delay = (ms = LATENCY_MS) => new Promise((resolve) => setTimeout(resolve, ms));
7
+ // In-memory cart storage
8
+ const carts = new Map();
9
+ // Mock shipping methods
10
+ const shippingMethods = [
11
+ { carrierCode: 'flatrate', carrierTitle: 'Flat Rate', methodCode: 'flatrate', methodTitle: 'Fixed', amount: 10, currency: 'USD' },
12
+ { carrierCode: 'freeshipping', carrierTitle: 'Free Shipping', methodCode: 'freeshipping', methodTitle: 'Free', amount: 0, currency: 'USD' },
13
+ { carrierCode: 'tablerate', carrierTitle: 'Express', methodCode: 'express', methodTitle: '2-3 Business Days', amount: 15, currency: 'USD' },
14
+ ];
15
+ // Mock payment methods
16
+ const paymentMethods = [
17
+ { code: 'checkmo', title: 'Check / Money Order' },
18
+ { code: 'stripe', title: 'Credit Card (Stripe)' },
19
+ { code: 'paypal', title: 'PayPal' },
20
+ ];
21
+ // Helper to generate cart ID
22
+ const generateCartId = () => `cart_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
23
+ // Helper to calculate cart totals
24
+ const calculateTotals = (items, shipping) => {
25
+ const subtotal = items.reduce((sum, item) => sum + item.prices.rowTotal, 0);
26
+ const shippingAmount = shipping ?? 0;
27
+ return {
28
+ subtotal,
29
+ subtotalIncludingTax: subtotal * 1.08, // 8% tax
30
+ grandTotal: subtotal * 1.08 + shippingAmount,
31
+ discounts: [],
32
+ taxes: [{ amount: subtotal * 0.08, label: 'Tax', rate: 8 }],
33
+ shipping: shippingAmount,
34
+ currency: 'USD',
35
+ };
36
+ };
37
+ // Create empty cart
38
+ const createEmptyCart = (id) => ({
39
+ id,
40
+ items: [],
41
+ totals: calculateTotals([]),
42
+ appliedCoupons: [],
43
+ shippingAddresses: [],
44
+ availableShippingMethods: shippingMethods,
45
+ availablePaymentMethods: paymentMethods,
46
+ });
47
+ export const dummyDataAdapter = {
48
+ product: {
49
+ get: async (id) => {
50
+ await delay();
51
+ return products.find((p) => p.id === id) ?? null;
52
+ },
53
+ getByUrlKey: async (urlKey) => {
54
+ await delay();
55
+ return products.find((p) => p.urlKey === urlKey) ?? null;
56
+ },
57
+ getRelated: async () => {
58
+ await delay();
59
+ return productListItems.slice(0, 4);
60
+ },
61
+ getUpsells: async () => {
62
+ await delay();
63
+ return productListItems.slice(4, 8);
64
+ },
65
+ },
66
+ category: {
67
+ get: async (id) => {
68
+ await delay();
69
+ const findCategory = (cats) => {
70
+ for (const cat of cats) {
71
+ if (cat.id === id)
72
+ return cat;
73
+ if (cat.children.length) {
74
+ const found = findCategory(cat.children);
75
+ if (found)
76
+ return found;
77
+ }
78
+ }
79
+ return null;
80
+ };
81
+ return findCategory(categories);
82
+ },
83
+ getByUrlKey: async (urlKey) => {
84
+ await delay();
85
+ const findCategory = (cats) => {
86
+ for (const cat of cats) {
87
+ if (cat.urlKey === urlKey)
88
+ return cat;
89
+ if (cat.children.length) {
90
+ const found = findCategory(cat.children);
91
+ if (found)
92
+ return found;
93
+ }
94
+ }
95
+ return null;
96
+ };
97
+ return findCategory(categories);
98
+ },
99
+ getProducts: async (input) => {
100
+ await delay();
101
+ let filteredProducts = [...productListItems];
102
+ // Apply filters (basic simulation)
103
+ if (input.filters) {
104
+ for (const [code, values] of Object.entries(input.filters)) {
105
+ const filterValues = Array.isArray(values) ? values : [values];
106
+ // For dummy data, we just simulate filtering by reducing the result count
107
+ // In a real implementation, you'd filter based on product attributes
108
+ if (filterValues.length > 0) {
109
+ // Simulate filtering by taking a subset
110
+ filteredProducts = filteredProducts.slice(0, Math.max(1, filteredProducts.length - filterValues.length));
111
+ }
112
+ }
113
+ }
114
+ // Apply sorting
115
+ if (input.sort) {
116
+ filteredProducts.sort((a, b) => {
117
+ let comparison = 0;
118
+ if (input.sort.field === 'price') {
119
+ comparison = a.price.final - b.price.final;
120
+ }
121
+ else if (input.sort.field === 'name') {
122
+ comparison = a.name.localeCompare(b.name);
123
+ }
124
+ return input.sort.direction === 'DESC' ? -comparison : comparison;
125
+ });
126
+ }
127
+ const page = input.page ?? 1;
128
+ const pageSize = input.pageSize ?? 12;
129
+ const start = (page - 1) * pageSize;
130
+ const items = filteredProducts.slice(start, start + pageSize);
131
+ return {
132
+ items,
133
+ totalCount: filteredProducts.length,
134
+ pageInfo: {
135
+ currentPage: page,
136
+ pageSize,
137
+ totalPages: Math.ceil(filteredProducts.length / pageSize),
138
+ },
139
+ filters: [
140
+ {
141
+ code: 'price',
142
+ label: 'Price',
143
+ type: 'range',
144
+ values: [
145
+ { value: '0-50', label: 'Under $50', count: 5 },
146
+ { value: '50-100', label: '$50 - $100', count: 7 },
147
+ ],
148
+ },
149
+ {
150
+ code: 'size',
151
+ label: 'Size',
152
+ type: 'multiselect',
153
+ values: [
154
+ { value: 's', label: 'S', count: 10 },
155
+ { value: 'm', label: 'M', count: 12 },
156
+ { value: 'l', label: 'L', count: 10 },
157
+ { value: 'xl', label: 'XL', count: 8 },
158
+ ],
159
+ },
160
+ ],
161
+ sortOptions: [
162
+ { value: 'position', label: 'Position' },
163
+ { value: 'name', label: 'Name' },
164
+ { value: 'price_asc', label: 'Price: Low to High' },
165
+ { value: 'price_desc', label: 'Price: High to Low' },
166
+ ],
167
+ };
168
+ },
169
+ getRootCategories: async () => {
170
+ await delay();
171
+ return categories;
172
+ },
173
+ },
174
+ navigation: {
175
+ get: async () => {
176
+ await delay();
177
+ return navigation;
178
+ },
179
+ },
180
+ cart: {
181
+ create: async () => {
182
+ await delay();
183
+ const id = generateCartId();
184
+ const cart = createEmptyCart(id);
185
+ carts.set(id, cart);
186
+ return cart;
187
+ },
188
+ get: async (cartId) => {
189
+ await delay();
190
+ return carts.get(cartId) ?? null;
191
+ },
192
+ addItem: async (cartId, input) => {
193
+ await delay();
194
+ let cart = carts.get(cartId);
195
+ if (!cart) {
196
+ cart = createEmptyCart(cartId);
197
+ }
198
+ const product = products.find((p) => p.sku === input.sku);
199
+ if (!product)
200
+ throw new Error(`Product not found: ${input.sku}`);
201
+ const itemUid = `item_${Date.now()}`;
202
+ const newItem = {
203
+ id: itemUid,
204
+ uid: itemUid,
205
+ product: {
206
+ id: product.id,
207
+ sku: product.sku,
208
+ name: product.name,
209
+ urlKey: product.urlKey,
210
+ thumbnail: { url: product.images[0].url, label: product.images[0].label },
211
+ },
212
+ quantity: input.quantity,
213
+ prices: {
214
+ price: product.price.final,
215
+ rowTotal: product.price.final * input.quantity,
216
+ rowTotalIncludingTax: product.price.final * input.quantity * 1.08,
217
+ currency: 'USD',
218
+ },
219
+ };
220
+ cart = {
221
+ ...cart,
222
+ items: [...cart.items, newItem],
223
+ };
224
+ cart.totals = calculateTotals(cart.items, cart.totals.shipping);
225
+ carts.set(cartId, cart);
226
+ return cart;
227
+ },
228
+ updateItem: async (cartId, input) => {
229
+ await delay();
230
+ const cart = carts.get(cartId);
231
+ if (!cart)
232
+ throw new Error('Cart not found');
233
+ const updatedItems = cart.items.map((item) => {
234
+ if (item.uid === input.itemUid) {
235
+ return {
236
+ ...item,
237
+ quantity: input.quantity,
238
+ prices: {
239
+ ...item.prices,
240
+ rowTotal: item.prices.price * input.quantity,
241
+ rowTotalIncludingTax: item.prices.price * input.quantity * 1.08,
242
+ },
243
+ };
244
+ }
245
+ return item;
246
+ });
247
+ const updatedCart = {
248
+ ...cart,
249
+ items: updatedItems,
250
+ totals: calculateTotals(updatedItems, cart.totals.shipping),
251
+ };
252
+ carts.set(cartId, updatedCart);
253
+ return updatedCart;
254
+ },
255
+ removeItem: async (cartId, itemUid) => {
256
+ await delay();
257
+ const cart = carts.get(cartId);
258
+ if (!cart)
259
+ throw new Error('Cart not found');
260
+ const filteredItems = cart.items.filter((item) => item.uid !== itemUid);
261
+ const updatedCart = {
262
+ ...cart,
263
+ items: filteredItems,
264
+ totals: calculateTotals(filteredItems, cart.totals.shipping),
265
+ };
266
+ carts.set(cartId, updatedCart);
267
+ return updatedCart;
268
+ },
269
+ applyCoupon: async (cartId, input) => {
270
+ await delay();
271
+ const cart = carts.get(cartId);
272
+ if (!cart)
273
+ throw new Error('Cart not found');
274
+ if (input.couponCode.toUpperCase() === 'SAVE10') {
275
+ const updatedCart = {
276
+ ...cart,
277
+ appliedCoupons: [{ code: input.couponCode }],
278
+ totals: {
279
+ ...cart.totals,
280
+ discounts: [{ amount: cart.totals.subtotal * 0.1, label: '10% OFF' }],
281
+ grandTotal: cart.totals.grandTotal * 0.9,
282
+ },
283
+ };
284
+ carts.set(cartId, updatedCart);
285
+ return updatedCart;
286
+ }
287
+ throw new Error('Invalid coupon code');
288
+ },
289
+ removeCoupon: async (cartId) => {
290
+ await delay();
291
+ const cart = carts.get(cartId);
292
+ if (!cart)
293
+ throw new Error('Cart not found');
294
+ const updatedCart = {
295
+ ...cart,
296
+ appliedCoupons: [],
297
+ totals: calculateTotals(cart.items, cart.totals.shipping),
298
+ };
299
+ carts.set(cartId, updatedCart);
300
+ return updatedCart;
301
+ },
302
+ setEmail: async (cartId, email) => {
303
+ await delay();
304
+ let cart = carts.get(cartId);
305
+ if (!cart) {
306
+ // Create cart if it doesn't exist (handles server restart case)
307
+ cart = createEmptyCart(cartId);
308
+ }
309
+ const updatedCart = { ...cart, email };
310
+ carts.set(cartId, updatedCart);
311
+ return updatedCart;
312
+ },
313
+ },
314
+ checkout: {
315
+ setShippingAddress: async (cartId, input) => {
316
+ await delay();
317
+ let cart = carts.get(cartId);
318
+ if (!cart) {
319
+ cart = createEmptyCart(cartId);
320
+ }
321
+ const updatedCart = {
322
+ ...cart,
323
+ shippingAddresses: [{
324
+ ...input.address,
325
+ country: 'United States',
326
+ }],
327
+ };
328
+ carts.set(cartId, updatedCart);
329
+ return updatedCart;
330
+ },
331
+ setBillingAddress: async (cartId, input) => {
332
+ await delay();
333
+ let cart = carts.get(cartId);
334
+ if (!cart) {
335
+ cart = createEmptyCart(cartId);
336
+ }
337
+ if (input.sameAsShipping && cart.shippingAddresses[0]) {
338
+ const updatedCart = {
339
+ ...cart,
340
+ billingAddress: cart.shippingAddresses[0],
341
+ };
342
+ carts.set(cartId, updatedCart);
343
+ return updatedCart;
344
+ }
345
+ const updatedCart = {
346
+ ...cart,
347
+ billingAddress: {
348
+ ...input.address,
349
+ country: 'United States',
350
+ },
351
+ };
352
+ carts.set(cartId, updatedCart);
353
+ return updatedCart;
354
+ },
355
+ setShippingMethod: async (cartId, input) => {
356
+ await delay();
357
+ let cart = carts.get(cartId);
358
+ if (!cart) {
359
+ cart = createEmptyCart(cartId);
360
+ }
361
+ const method = shippingMethods.find((m) => m.carrierCode === input.carrierCode && m.methodCode === input.methodCode);
362
+ if (!method)
363
+ throw new Error('Shipping method not found');
364
+ const updatedCart = {
365
+ ...cart,
366
+ selectedShippingMethod: method,
367
+ totals: calculateTotals(cart.items, method.amount),
368
+ };
369
+ carts.set(cartId, updatedCart);
370
+ return updatedCart;
371
+ },
372
+ setPaymentMethod: async (cartId, input) => {
373
+ await delay();
374
+ let cart = carts.get(cartId);
375
+ if (!cart) {
376
+ cart = createEmptyCart(cartId);
377
+ }
378
+ const method = paymentMethods.find((m) => m.code === input.code);
379
+ if (!method)
380
+ throw new Error('Payment method not found');
381
+ const updatedCart = {
382
+ ...cart,
383
+ selectedPaymentMethod: method,
384
+ };
385
+ carts.set(cartId, updatedCart);
386
+ return updatedCart;
387
+ },
388
+ placeOrder: async (cartId) => {
389
+ await delay(500); // Simulate longer processing
390
+ const cart = carts.get(cartId);
391
+ if (!cart || cart.items.length === 0) {
392
+ throw new Error('Cart is empty. Items may have been lost due to server restart.');
393
+ }
394
+ const orderNumber = `ORD-${Date.now()}`;
395
+ carts.delete(cartId); // Clear the cart
396
+ return {
397
+ success: true,
398
+ orderId: `order_${Date.now()}`,
399
+ orderNumber,
400
+ };
401
+ },
402
+ },
403
+ cms: {
404
+ getPage: async (identifier) => {
405
+ await delay();
406
+ return cmsPages.find((p) => p.identifier === identifier) ?? null;
407
+ },
408
+ getPageByUrlKey: async (urlKey) => {
409
+ await delay();
410
+ return cmsPages.find((p) => p.urlKey === urlKey) ?? null;
411
+ },
412
+ resolveUrl: async (urlKey) => {
413
+ await delay();
414
+ // Check products
415
+ const product = products.find((p) => p.urlKey === urlKey);
416
+ if (product) {
417
+ return { type: 'PRODUCT', id: product.id, urlKey };
418
+ }
419
+ // Check categories (including nested)
420
+ const findCategory = (cats) => {
421
+ for (const cat of cats) {
422
+ if (cat.urlKey === urlKey)
423
+ return cat;
424
+ if (cat.children.length) {
425
+ const found = findCategory(cat.children);
426
+ if (found)
427
+ return found;
428
+ }
429
+ }
430
+ return null;
431
+ };
432
+ const category = findCategory(categories);
433
+ if (category) {
434
+ return { type: 'CATEGORY', id: category.id, urlKey };
435
+ }
436
+ // Check CMS pages
437
+ const cmsPage = cmsPages.find((p) => p.urlKey === urlKey);
438
+ if (cmsPage) {
439
+ return { type: 'CMS_PAGE', id: cmsPage.id, urlKey };
440
+ }
441
+ return { type: 'NOT_FOUND', id: '', urlKey };
442
+ },
443
+ },
444
+ search: {
445
+ search: async (query, options) => {
446
+ await delay();
447
+ const lowerQuery = query.toLowerCase();
448
+ const filtered = productListItems.filter((p) => p.name.toLowerCase().includes(lowerQuery) ||
449
+ p.sku.toLowerCase().includes(lowerQuery));
450
+ const page = options?.page ?? 1;
451
+ const pageSize = options?.pageSize ?? 12;
452
+ const start = (page - 1) * pageSize;
453
+ return {
454
+ items: filtered.slice(start, start + pageSize),
455
+ totalCount: filtered.length,
456
+ pageInfo: {
457
+ currentPage: page,
458
+ pageSize,
459
+ totalPages: Math.ceil(filtered.length / pageSize),
460
+ },
461
+ suggestions: [],
462
+ };
463
+ },
464
+ getSuggestions: async (query) => {
465
+ await delay(50);
466
+ const lowerQuery = query.toLowerCase();
467
+ return productListItems
468
+ .filter((p) => p.name.toLowerCase().includes(lowerQuery))
469
+ .slice(0, 5)
470
+ .map((p) => p.name);
471
+ },
472
+ },
473
+ customer: {
474
+ login: async (credentials) => {
475
+ await delay();
476
+ // Mock login - accept any email/password combination
477
+ if (credentials.email && credentials.password) {
478
+ const customer = {
479
+ id: 'cust_1',
480
+ email: credentials.email,
481
+ firstname: 'John',
482
+ lastname: 'Doe',
483
+ createdAt: new Date().toISOString(),
484
+ addresses: [],
485
+ };
486
+ return {
487
+ customer,
488
+ token: `token_${Date.now()}`,
489
+ expiresAt: new Date(Date.now() + 86400000).toISOString(), // 24 hours
490
+ };
491
+ }
492
+ throw new Error('Invalid credentials');
493
+ },
494
+ register: async (input) => {
495
+ await delay();
496
+ const customer = {
497
+ id: `cust_${Date.now()}`,
498
+ email: input.email,
499
+ firstname: input.firstname,
500
+ lastname: input.lastname,
501
+ dateOfBirth: input.dateOfBirth,
502
+ gender: input.gender,
503
+ createdAt: new Date().toISOString(),
504
+ addresses: [],
505
+ };
506
+ return {
507
+ customer,
508
+ token: `token_${Date.now()}`,
509
+ expiresAt: new Date(Date.now() + 86400000).toISOString(),
510
+ };
511
+ },
512
+ logout: async () => {
513
+ await delay();
514
+ // No-op for mock
515
+ },
516
+ get: async (token) => {
517
+ await delay();
518
+ if (token) {
519
+ return {
520
+ id: 'cust_1',
521
+ email: 'john@example.com',
522
+ firstname: 'John',
523
+ lastname: 'Doe',
524
+ createdAt: new Date().toISOString(),
525
+ addresses: [],
526
+ };
527
+ }
528
+ return null;
529
+ },
530
+ update: async (token, input) => {
531
+ await delay();
532
+ return {
533
+ id: 'cust_1',
534
+ email: input.email ?? 'john@example.com',
535
+ firstname: input.firstname ?? 'John',
536
+ lastname: input.lastname ?? 'Doe',
537
+ dateOfBirth: input.dateOfBirth,
538
+ gender: input.gender,
539
+ createdAt: new Date().toISOString(),
540
+ addresses: [],
541
+ };
542
+ },
543
+ changePassword: async (_token, _input) => {
544
+ await delay();
545
+ return true;
546
+ },
547
+ requestPasswordReset: async (_email) => {
548
+ await delay();
549
+ return true;
550
+ },
551
+ resetPassword: async (_token, _newPassword) => {
552
+ await delay();
553
+ return true;
554
+ },
555
+ getOrders: async (_token, page = 1, pageSize = 10) => {
556
+ await delay();
557
+ // Generate mock orders
558
+ const mockOrders = [
559
+ {
560
+ id: 'order_1',
561
+ orderNumber: '100000001',
562
+ createdAt: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(),
563
+ status: 'Complete',
564
+ total: 149.99,
565
+ currency: 'USD',
566
+ items: [
567
+ {
568
+ id: 'item_1',
569
+ productName: 'Performance Running Shoes',
570
+ sku: 'RUN-001',
571
+ quantity: 1,
572
+ price: 149.99,
573
+ thumbnail: 'https://picsum.photos/seed/item1/100/100',
574
+ },
575
+ ],
576
+ shippingAddress: {
577
+ firstname: 'John',
578
+ lastname: 'Doe',
579
+ street: ['123 Main St'],
580
+ city: 'New York',
581
+ region: 'NY',
582
+ postcode: '10001',
583
+ country: 'United States',
584
+ countryCode: 'US',
585
+ telephone: '555-1234',
586
+ },
587
+ },
588
+ {
589
+ id: 'order_2',
590
+ orderNumber: '100000002',
591
+ createdAt: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString(),
592
+ status: 'Complete',
593
+ total: 89.95,
594
+ currency: 'USD',
595
+ items: [
596
+ {
597
+ id: 'item_2',
598
+ productName: 'Athletic T-Shirt',
599
+ sku: 'TSH-002',
600
+ quantity: 2,
601
+ price: 29.99,
602
+ thumbnail: 'https://picsum.photos/seed/item2/100/100',
603
+ },
604
+ {
605
+ id: 'item_3',
606
+ productName: 'Sports Shorts',
607
+ sku: 'SHR-003',
608
+ quantity: 1,
609
+ price: 29.97,
610
+ thumbnail: 'https://picsum.photos/seed/item3/100/100',
611
+ },
612
+ ],
613
+ shippingAddress: {
614
+ firstname: 'John',
615
+ lastname: 'Doe',
616
+ street: ['123 Main St'],
617
+ city: 'New York',
618
+ region: 'NY',
619
+ postcode: '10001',
620
+ country: 'United States',
621
+ countryCode: 'US',
622
+ telephone: '555-1234',
623
+ },
624
+ },
625
+ {
626
+ id: 'order_3',
627
+ orderNumber: '100000003',
628
+ createdAt: new Date(Date.now() - 60 * 24 * 60 * 60 * 1000).toISOString(),
629
+ status: 'Shipped',
630
+ total: 249.00,
631
+ currency: 'USD',
632
+ items: [
633
+ {
634
+ id: 'item_4',
635
+ productName: 'Premium Gym Bag',
636
+ sku: 'BAG-004',
637
+ quantity: 1,
638
+ price: 249.00,
639
+ thumbnail: 'https://picsum.photos/seed/item4/100/100',
640
+ },
641
+ ],
642
+ shippingAddress: {
643
+ firstname: 'John',
644
+ lastname: 'Doe',
645
+ street: ['123 Main St'],
646
+ city: 'New York',
647
+ region: 'NY',
648
+ postcode: '10001',
649
+ country: 'United States',
650
+ countryCode: 'US',
651
+ telephone: '555-1234',
652
+ },
653
+ },
654
+ ];
655
+ const start = (page - 1) * pageSize;
656
+ const paginatedOrders = mockOrders.slice(start, start + pageSize);
657
+ return {
658
+ items: paginatedOrders,
659
+ totalCount: mockOrders.length,
660
+ pageInfo: {
661
+ currentPage: page,
662
+ pageSize,
663
+ totalPages: Math.ceil(mockOrders.length / pageSize),
664
+ },
665
+ };
666
+ },
667
+ },
668
+ };
669
+ export default dummyDataAdapter;
@@ -0,0 +1,3 @@
1
+ import type { Category, NavigationItem } from '@cobrastyle/shared-types';
2
+ export declare const categories: Category[];
3
+ export declare const navigation: NavigationItem[];
@@ -0,0 +1,134 @@
1
+ export const categories = [
2
+ {
3
+ id: '1',
4
+ name: 'Shop All',
5
+ urlKey: 'shop',
6
+ description: 'Browse our complete collection of athletic wear and equipment.',
7
+ productCount: 12,
8
+ children: [],
9
+ breadcrumbs: [],
10
+ metaTitle: 'Shop All - Cobrastyle Express',
11
+ metaDescription: 'Browse our complete collection of athletic wear and equipment.',
12
+ },
13
+ {
14
+ id: '2',
15
+ name: 'Apparel',
16
+ urlKey: 'apparel',
17
+ description: 'High-performance athletic apparel designed for comfort and durability.',
18
+ productCount: 7,
19
+ children: [
20
+ {
21
+ id: '2-1',
22
+ name: 'Tops',
23
+ urlKey: 'apparel/tops',
24
+ description: 'Athletic tops for every workout.',
25
+ productCount: 3,
26
+ children: [],
27
+ breadcrumbs: [{ id: '2', name: 'Apparel', urlKey: 'apparel' }],
28
+ },
29
+ {
30
+ id: '2-2',
31
+ name: 'Bottoms',
32
+ urlKey: 'apparel/bottoms',
33
+ description: 'Shorts, pants, and leggings.',
34
+ productCount: 3,
35
+ children: [],
36
+ breadcrumbs: [{ id: '2', name: 'Apparel', urlKey: 'apparel' }],
37
+ },
38
+ {
39
+ id: '2-3',
40
+ name: 'Outerwear',
41
+ urlKey: 'apparel/outerwear',
42
+ description: 'Jackets and hoodies for any weather.',
43
+ productCount: 2,
44
+ children: [],
45
+ breadcrumbs: [{ id: '2', name: 'Apparel', urlKey: 'apparel' }],
46
+ },
47
+ ],
48
+ breadcrumbs: [],
49
+ metaTitle: 'Apparel - Cobrastyle Express',
50
+ metaDescription: 'High-performance athletic apparel designed for comfort and durability.',
51
+ },
52
+ {
53
+ id: '3',
54
+ name: 'Equipment',
55
+ urlKey: 'equipment',
56
+ description: 'Professional-grade fitness equipment for home and gym.',
57
+ productCount: 5,
58
+ children: [
59
+ {
60
+ id: '3-1',
61
+ name: 'Weights',
62
+ urlKey: 'equipment/weights',
63
+ description: 'Dumbbells, kettlebells, and more.',
64
+ productCount: 1,
65
+ children: [],
66
+ breadcrumbs: [{ id: '3', name: 'Equipment', urlKey: 'equipment' }],
67
+ },
68
+ {
69
+ id: '3-2',
70
+ name: 'Accessories',
71
+ urlKey: 'equipment/accessories',
72
+ description: 'Bands, mats, rollers, and more.',
73
+ productCount: 4,
74
+ children: [],
75
+ breadcrumbs: [{ id: '3', name: 'Equipment', urlKey: 'equipment' }],
76
+ },
77
+ ],
78
+ breadcrumbs: [],
79
+ metaTitle: 'Equipment - Cobrastyle Express',
80
+ metaDescription: 'Professional-grade fitness equipment for home and gym.',
81
+ },
82
+ {
83
+ id: '4',
84
+ name: 'Sale',
85
+ urlKey: 'sale',
86
+ description: 'Limited time offers on select items.',
87
+ productCount: 0,
88
+ children: [],
89
+ breadcrumbs: [],
90
+ metaTitle: 'Sale - Cobrastyle Express',
91
+ metaDescription: 'Limited time offers on select items.',
92
+ },
93
+ ];
94
+ export const navigation = [
95
+ {
96
+ id: '1',
97
+ name: 'Shop All',
98
+ urlKey: 'shop',
99
+ level: 1,
100
+ position: 1,
101
+ children: [],
102
+ },
103
+ {
104
+ id: '2',
105
+ name: 'Apparel',
106
+ urlKey: 'apparel',
107
+ level: 1,
108
+ position: 2,
109
+ children: [
110
+ { id: '2-1', name: 'Tops', urlKey: 'apparel/tops', level: 2, position: 1, children: [] },
111
+ { id: '2-2', name: 'Bottoms', urlKey: 'apparel/bottoms', level: 2, position: 2, children: [] },
112
+ { id: '2-3', name: 'Outerwear', urlKey: 'apparel/outerwear', level: 2, position: 3, children: [] },
113
+ ],
114
+ },
115
+ {
116
+ id: '3',
117
+ name: 'Equipment',
118
+ urlKey: 'equipment',
119
+ level: 1,
120
+ position: 3,
121
+ children: [
122
+ { id: '3-1', name: 'Weights', urlKey: 'equipment/weights', level: 2, position: 1, children: [] },
123
+ { id: '3-2', name: 'Accessories', urlKey: 'equipment/accessories', level: 2, position: 2, children: [] },
124
+ ],
125
+ },
126
+ {
127
+ id: '4',
128
+ name: 'Sale',
129
+ urlKey: 'sale',
130
+ level: 1,
131
+ position: 4,
132
+ children: [],
133
+ },
134
+ ];
@@ -0,0 +1,2 @@
1
+ import type { CmsPage } from '@cobrastyle/shared-types';
2
+ export declare const cmsPages: CmsPage[];
@@ -0,0 +1,79 @@
1
+ export const cmsPages = [
2
+ {
3
+ id: 'home',
4
+ identifier: 'home',
5
+ title: 'Welcome to Cobrastyle Express',
6
+ urlKey: '',
7
+ content: `
8
+ <div class="hero">
9
+ <h1>Unleash Your Potential</h1>
10
+ <p>Premium athletic wear and equipment for every workout.</p>
11
+ </div>
12
+ `,
13
+ metaTitle: 'Cobrastyle Express - Premium Athletic Gear',
14
+ metaDescription: 'Shop premium athletic wear and equipment at Cobrastyle Express.',
15
+ },
16
+ {
17
+ id: 'about',
18
+ identifier: 'about-us',
19
+ title: 'About Us',
20
+ urlKey: 'about-us',
21
+ content: `
22
+ <h1>About Cobrastyle Express</h1>
23
+ <p>Founded with a passion for fitness and performance, Cobrastyle Express delivers premium athletic gear to help you achieve your goals.</p>
24
+ <h2>Our Mission</h2>
25
+ <p>To provide high-quality, stylish, and functional athletic wear that empowers athletes at every level.</p>
26
+ `,
27
+ metaTitle: 'About Us - Cobrastyle Express',
28
+ metaDescription: 'Learn about Cobrastyle Express and our mission.',
29
+ },
30
+ {
31
+ id: 'contact',
32
+ identifier: 'contact',
33
+ title: 'Contact Us',
34
+ urlKey: 'contact',
35
+ content: `
36
+ <h1>Contact Us</h1>
37
+ <p>Have questions? We're here to help.</p>
38
+ <p>Email: support@cobrastyle-express.com</p>
39
+ <p>Phone: 1-800-COBRA-FIT</p>
40
+ `,
41
+ metaTitle: 'Contact Us - Cobrastyle Express',
42
+ metaDescription: 'Get in touch with Cobrastyle Express.',
43
+ },
44
+ {
45
+ id: 'shipping',
46
+ identifier: 'shipping-policy',
47
+ title: 'Shipping Policy',
48
+ urlKey: 'shipping-policy',
49
+ content: `
50
+ <h1>Shipping Policy</h1>
51
+ <h2>Free Shipping</h2>
52
+ <p>Enjoy free standard shipping on all orders over $75.</p>
53
+ <h2>Delivery Times</h2>
54
+ <ul>
55
+ <li>Standard Shipping: 5-7 business days</li>
56
+ <li>Express Shipping: 2-3 business days</li>
57
+ <li>Next Day: Available for select areas</li>
58
+ </ul>
59
+ `,
60
+ metaTitle: 'Shipping Policy - Cobrastyle Express',
61
+ metaDescription: 'Learn about our shipping options and delivery times.',
62
+ },
63
+ {
64
+ id: 'returns',
65
+ identifier: 'returns-policy',
66
+ title: 'Returns & Exchanges',
67
+ urlKey: 'returns-policy',
68
+ content: `
69
+ <h1>Returns & Exchanges</h1>
70
+ <p>We want you to be completely satisfied with your purchase.</p>
71
+ <h2>30-Day Returns</h2>
72
+ <p>Return any unworn item within 30 days for a full refund.</p>
73
+ <h2>Easy Exchanges</h2>
74
+ <p>Need a different size? Exchange for free.</p>
75
+ `,
76
+ metaTitle: 'Returns & Exchanges - Cobrastyle Express',
77
+ metaDescription: 'Our hassle-free return and exchange policy.',
78
+ },
79
+ ];
@@ -0,0 +1,3 @@
1
+ export { products, productListItems } from './products';
2
+ export { categories, navigation } from './categories';
3
+ export { cmsPages } from './cms';
@@ -0,0 +1,3 @@
1
+ export { products, productListItems } from './products';
2
+ export { categories, navigation } from './categories';
3
+ export { cmsPages } from './cms';
@@ -0,0 +1,3 @@
1
+ import type { ProductListItem, AnyProduct } from '@cobrastyle/shared-types';
2
+ export declare const products: AnyProduct[];
3
+ export declare const productListItems: ProductListItem[];
@@ -0,0 +1,119 @@
1
+ const createSimpleProduct = (id, name, urlKey, price, categoryId) => ({
2
+ id,
3
+ sku: `SKU-${id}`,
4
+ name,
5
+ type: 'simple',
6
+ description: `<p>High-quality ${name.toLowerCase()} designed for performance and style. Made with premium materials.</p>`,
7
+ shortDescription: `Premium ${name.toLowerCase()} for the modern athlete.`,
8
+ urlKey,
9
+ price: {
10
+ regular: price,
11
+ final: price,
12
+ currency: 'USD',
13
+ },
14
+ images: [
15
+ {
16
+ url: `https://picsum.photos/seed/${urlKey}/800/800`,
17
+ label: name,
18
+ position: 0,
19
+ isMain: true,
20
+ },
21
+ {
22
+ url: `https://picsum.photos/seed/${urlKey}-2/800/800`,
23
+ label: `${name} - View 2`,
24
+ position: 1,
25
+ },
26
+ ],
27
+ categories: [{ id: categoryId, name: 'Category', urlKey: 'category' }],
28
+ stock: { inStock: true, qty: 100 },
29
+ attributes: [],
30
+ metaTitle: name,
31
+ metaDescription: `Shop ${name} at Cobrastyle Express`,
32
+ });
33
+ const createConfigurableProduct = (id, name, urlKey, basePrice, categoryId) => ({
34
+ ...createSimpleProduct(id, name, urlKey, basePrice, categoryId),
35
+ type: 'configurable',
36
+ configurableOptions: [
37
+ {
38
+ id: 'size',
39
+ attributeCode: 'size',
40
+ label: 'Size',
41
+ values: [
42
+ { id: 's', label: 'S', value: 's' },
43
+ { id: 'm', label: 'M', value: 'm' },
44
+ { id: 'l', label: 'L', value: 'l' },
45
+ { id: 'xl', label: 'XL', value: 'xl' },
46
+ ],
47
+ },
48
+ {
49
+ id: 'color',
50
+ attributeCode: 'color',
51
+ label: 'Color',
52
+ values: [
53
+ { id: 'black', label: 'Black', value: 'black', swatch: { type: 'color', value: '#000000' } },
54
+ { id: 'white', label: 'White', value: 'white', swatch: { type: 'color', value: '#FFFFFF' } },
55
+ { id: 'navy', label: 'Navy', value: 'navy', swatch: { type: 'color', value: '#001F3F' } },
56
+ ],
57
+ },
58
+ ],
59
+ variants: [
60
+ {
61
+ id: `${id}-s-black`,
62
+ sku: `SKU-${id}-S-BLK`,
63
+ name: `${name} - S / Black`,
64
+ price: { regular: basePrice, final: basePrice, currency: 'USD' },
65
+ stock: { inStock: true, qty: 25 },
66
+ attributes: [
67
+ { code: 'size', label: 'Size', value: 's' },
68
+ { code: 'color', label: 'Color', value: 'black' },
69
+ ],
70
+ },
71
+ {
72
+ id: `${id}-m-black`,
73
+ sku: `SKU-${id}-M-BLK`,
74
+ name: `${name} - M / Black`,
75
+ price: { regular: basePrice, final: basePrice, currency: 'USD' },
76
+ stock: { inStock: true, qty: 30 },
77
+ attributes: [
78
+ { code: 'size', label: 'Size', value: 'm' },
79
+ { code: 'color', label: 'Color', value: 'black' },
80
+ ],
81
+ },
82
+ {
83
+ id: `${id}-l-white`,
84
+ sku: `SKU-${id}-L-WHT`,
85
+ name: `${name} - L / White`,
86
+ price: { regular: basePrice, final: basePrice, currency: 'USD' },
87
+ stock: { inStock: true, qty: 20 },
88
+ attributes: [
89
+ { code: 'size', label: 'Size', value: 'l' },
90
+ { code: 'color', label: 'Color', value: 'white' },
91
+ ],
92
+ },
93
+ ],
94
+ });
95
+ export const products = [
96
+ createConfigurableProduct('1', 'Performance Running Tee', 'performance-running-tee', 49.99, '2'),
97
+ createConfigurableProduct('2', 'Training Shorts Pro', 'training-shorts-pro', 59.99, '2'),
98
+ createSimpleProduct('3', 'Resistance Band Set', 'resistance-band-set', 29.99, '3'),
99
+ createConfigurableProduct('4', 'Compression Leggings', 'compression-leggings', 79.99, '2'),
100
+ createSimpleProduct('5', 'Yoga Mat Premium', 'yoga-mat-premium', 45.00, '3'),
101
+ createConfigurableProduct('6', 'Windbreaker Jacket', 'windbreaker-jacket', 89.99, '2'),
102
+ createSimpleProduct('7', 'Foam Roller Recovery', 'foam-roller-recovery', 34.99, '3'),
103
+ createConfigurableProduct('8', 'Athletic Hoodie', 'athletic-hoodie', 69.99, '2'),
104
+ createSimpleProduct('9', 'Jump Rope Speed', 'jump-rope-speed', 19.99, '3'),
105
+ createConfigurableProduct('10', 'Track Pants Slim', 'track-pants-slim', 64.99, '2'),
106
+ createSimpleProduct('11', 'Kettlebell 20lb', 'kettlebell-20lb', 49.99, '3'),
107
+ createConfigurableProduct('12', 'Sports Bra High Support', 'sports-bra-high-support', 54.99, '2'),
108
+ ];
109
+ export const productListItems = products.map((p) => ({
110
+ id: p.id,
111
+ sku: p.sku,
112
+ name: p.name,
113
+ urlKey: p.urlKey,
114
+ price: p.price,
115
+ thumbnail: p.images[0],
116
+ hoverImage: p.images[1],
117
+ stock: p.stock,
118
+ type: p.type,
119
+ }));
@@ -0,0 +1,2 @@
1
+ export { dummyDataAdapter, dummyDataAdapter as default } from './adapter';
2
+ export * from './fixtures';
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { dummyDataAdapter, dummyDataAdapter as default } from './adapter';
2
+ export * from './fixtures';
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@cobrastyle/adapter-dummy-data",
3
+ "version": "1.0.1",
4
+ "main": "./dist/index.js",
5
+ "types": "./dist/index.d.ts",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "default": "./dist/index.js"
10
+ }
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "dependencies": {
16
+ "@cobrastyle/shared-types": "1.0.1"
17
+ },
18
+ "devDependencies": {
19
+ "typescript": "^5.3.0",
20
+ "@cobrastyle/adapter-conformance": "1.0.1"
21
+ },
22
+ "license": "MIT",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/eComero/cobrastyle-express-next.git",
26
+ "directory": "packages/adapters/dummy-data"
27
+ },
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "scripts": {
32
+ "build": "tsc --project tsconfig.build.json",
33
+ "type-check": "tsc --noEmit"
34
+ }
35
+ }