nitrostack 1.0.0 → 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/CHANGELOG.md +15 -0
- package/package.json +1 -1
- package/templates/typescript-auth/.env.example +23 -0
- package/templates/typescript-auth/src/app.module.ts +103 -0
- package/templates/typescript-auth/src/db/database.ts +163 -0
- package/templates/typescript-auth/src/db/seed.ts +374 -0
- package/templates/typescript-auth/src/db/setup.ts +87 -0
- package/templates/typescript-auth/src/events/analytics.service.ts +52 -0
- package/templates/typescript-auth/src/events/notification.service.ts +40 -0
- package/templates/typescript-auth/src/filters/global-exception.filter.ts +28 -0
- package/templates/typescript-auth/src/guards/README.md +75 -0
- package/templates/typescript-auth/src/guards/jwt.guard.ts +105 -0
- package/templates/typescript-auth/src/health/database.health.ts +41 -0
- package/templates/typescript-auth/src/index.ts +26 -0
- package/templates/typescript-auth/src/interceptors/transform.interceptor.ts +24 -0
- package/templates/typescript-auth/src/middleware/logging.middleware.ts +42 -0
- package/templates/typescript-auth/src/modules/addresses/addresses.module.ts +16 -0
- package/templates/typescript-auth/src/modules/addresses/addresses.prompts.ts +114 -0
- package/templates/typescript-auth/src/modules/addresses/addresses.resources.ts +40 -0
- package/templates/typescript-auth/src/modules/addresses/addresses.tools.ts +241 -0
- package/templates/typescript-auth/src/modules/auth/auth.module.ts +16 -0
- package/templates/typescript-auth/src/modules/auth/auth.prompts.ts +147 -0
- package/templates/typescript-auth/src/modules/auth/auth.resources.ts +84 -0
- package/templates/typescript-auth/src/modules/auth/auth.tools.ts +139 -0
- package/templates/typescript-auth/src/modules/cart/cart.module.ts +16 -0
- package/templates/typescript-auth/src/modules/cart/cart.prompts.ts +95 -0
- package/templates/typescript-auth/src/modules/cart/cart.resources.ts +44 -0
- package/templates/typescript-auth/src/modules/cart/cart.tools.ts +281 -0
- package/templates/typescript-auth/src/modules/orders/orders.module.ts +16 -0
- package/templates/typescript-auth/src/modules/orders/orders.prompts.ts +88 -0
- package/templates/typescript-auth/src/modules/orders/orders.resources.ts +48 -0
- package/templates/typescript-auth/src/modules/orders/orders.tools.ts +281 -0
- package/templates/typescript-auth/src/modules/products/products.module.ts +16 -0
- package/templates/typescript-auth/src/modules/products/products.prompts.ts +146 -0
- package/templates/typescript-auth/src/modules/products/products.resources.ts +98 -0
- package/templates/typescript-auth/src/modules/products/products.tools.ts +266 -0
- package/templates/typescript-auth/src/pipes/validation.pipe.ts +42 -0
- package/templates/typescript-auth/src/services/database.service.ts +90 -0
- package/templates/typescript-auth/src/widgets/app/add-to-cart/page.tsx +122 -0
- package/templates/typescript-auth/src/widgets/app/address-added/page.tsx +116 -0
- package/templates/typescript-auth/src/widgets/app/address-deleted/page.tsx +105 -0
- package/templates/typescript-auth/src/widgets/app/address-list/page.tsx +139 -0
- package/templates/typescript-auth/src/widgets/app/address-updated/page.tsx +153 -0
- package/templates/typescript-auth/src/widgets/app/cart-cleared/page.tsx +86 -0
- package/templates/typescript-auth/src/widgets/app/cart-updated/page.tsx +116 -0
- package/templates/typescript-auth/src/widgets/app/categories/page.tsx +134 -0
- package/templates/typescript-auth/src/widgets/app/layout.tsx +21 -0
- package/templates/typescript-auth/src/widgets/app/login-result/page.tsx +129 -0
- package/templates/typescript-auth/src/widgets/app/order-confirmation/page.tsx +206 -0
- package/templates/typescript-auth/src/widgets/app/order-details/page.tsx +225 -0
- package/templates/typescript-auth/src/widgets/app/order-history/page.tsx +218 -0
- package/templates/typescript-auth/src/widgets/app/product-card/page.tsx +121 -0
- package/templates/typescript-auth/src/widgets/app/products-grid/page.tsx +173 -0
- package/templates/typescript-auth/src/widgets/app/shopping-cart/page.tsx +187 -0
- package/templates/typescript-auth/src/widgets/app/whoami/page.tsx +165 -0
- package/templates/typescript-auth/src/widgets/next.config.js +38 -0
- package/templates/typescript-auth/src/widgets/package.json +18 -0
- package/templates/typescript-auth/src/widgets/styles/ecommerce.ts +169 -0
- package/templates/typescript-auth/src/widgets/tsconfig.json +28 -0
- package/templates/typescript-auth/src/widgets/types/tool-data.ts +141 -0
- package/templates/typescript-auth/src/widgets/widget-manifest.json +464 -0
- package/templates/typescript-auth/tsconfig.json +27 -0
- package/templates/typescript-auth-api-key/.env +15 -0
- package/templates/typescript-auth-api-key/.env.example +4 -0
- package/templates/typescript-auth-api-key/src/app.module.ts +38 -0
- package/templates/typescript-auth-api-key/src/guards/apikey.guard.ts +47 -0
- package/templates/typescript-auth-api-key/src/guards/multi-auth.guard.ts +157 -0
- package/templates/typescript-auth-api-key/src/health/system.health.ts +55 -0
- package/templates/typescript-auth-api-key/src/index.ts +47 -0
- package/templates/typescript-auth-api-key/src/modules/calculator/calculator.module.ts +12 -0
- package/templates/typescript-auth-api-key/src/modules/calculator/calculator.prompts.ts +73 -0
- package/templates/typescript-auth-api-key/src/modules/calculator/calculator.resources.ts +60 -0
- package/templates/typescript-auth-api-key/src/modules/calculator/calculator.tools.ts +71 -0
- package/templates/typescript-auth-api-key/src/modules/demo/demo.module.ts +18 -0
- package/templates/typescript-auth-api-key/src/modules/demo/demo.tools.ts +155 -0
- package/templates/typescript-auth-api-key/src/modules/demo/multi-auth.tools.ts +123 -0
- package/templates/typescript-auth-api-key/src/widgets/app/calculator-operations/page.tsx +133 -0
- package/templates/typescript-auth-api-key/src/widgets/app/calculator-result/page.tsx +134 -0
- package/templates/typescript-auth-api-key/src/widgets/app/layout.tsx +14 -0
- package/templates/typescript-auth-api-key/src/widgets/next.config.js +37 -0
- package/templates/typescript-auth-api-key/src/widgets/package.json +24 -0
- package/templates/typescript-auth-api-key/src/widgets/tsconfig.json +28 -0
- package/templates/typescript-auth-api-key/src/widgets/widget-manifest.json +48 -0
- package/templates/typescript-auth-api-key/tsconfig.json +23 -0
- package/templates/typescript-oauth/.env.example +91 -0
- package/templates/typescript-oauth/src/app.module.ts +89 -0
- package/templates/typescript-oauth/src/guards/oauth.guard.ts +127 -0
- package/templates/typescript-oauth/src/index.ts +74 -0
- package/templates/typescript-oauth/src/modules/demo/demo.module.ts +16 -0
- package/templates/typescript-oauth/src/modules/demo/demo.tools.ts +190 -0
- package/templates/typescript-oauth/src/widgets/app/calculator-operations/page.tsx +133 -0
- package/templates/typescript-oauth/src/widgets/app/calculator-result/page.tsx +134 -0
- package/templates/typescript-oauth/src/widgets/app/layout.tsx +14 -0
- package/templates/typescript-oauth/src/widgets/next.config.js +37 -0
- package/templates/typescript-oauth/src/widgets/package.json +24 -0
- package/templates/typescript-oauth/src/widgets/tsconfig.json +28 -0
- package/templates/typescript-oauth/src/widgets/widget-manifest.json +48 -0
- package/templates/typescript-oauth/tsconfig.json +23 -0
- package/templates/typescript-starter/.env.example +4 -0
- package/templates/typescript-starter/src/app.module.ts +34 -0
- package/templates/typescript-starter/src/health/system.health.ts +55 -0
- package/templates/typescript-starter/src/index.ts +27 -0
- package/templates/typescript-starter/src/modules/calculator/calculator.module.ts +12 -0
- package/templates/typescript-starter/src/modules/calculator/calculator.prompts.ts +73 -0
- package/templates/typescript-starter/src/modules/calculator/calculator.resources.ts +60 -0
- package/templates/typescript-starter/src/modules/calculator/calculator.tools.ts +71 -0
- package/templates/typescript-starter/src/widgets/app/calculator-operations/page.tsx +133 -0
- package/templates/typescript-starter/src/widgets/app/calculator-result/page.tsx +134 -0
- package/templates/typescript-starter/src/widgets/app/layout.tsx +14 -0
- package/templates/typescript-starter/src/widgets/next.config.js +37 -0
- package/templates/typescript-starter/src/widgets/package.json +24 -0
- package/templates/typescript-starter/src/widgets/tsconfig.json +28 -0
- package/templates/typescript-starter/src/widgets/widget-manifest.json +48 -0
- package/templates/typescript-starter/tsconfig.json +23 -0
- package/LICENSE_URLS_UPDATE_COMPLETE.md +0 -388
package/CHANGELOG.md
CHANGED
|
@@ -7,10 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.0.1] - 2025-10-27
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **Critical**: Fixed `.npmignore` to include template `src/` folders
|
|
14
|
+
- Changed `src/` to `/src/` to only exclude root source files
|
|
15
|
+
- Template source files are now properly included in the package
|
|
16
|
+
- Users can now successfully generate projects with all necessary files
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- Updated `.npmignore` patterns to use leading slashes for root-only exclusions
|
|
20
|
+
- Keep template `.env.example` files by excluding only root `.env` files
|
|
21
|
+
|
|
22
|
+
## [1.0.0] - 2025-10-27
|
|
23
|
+
|
|
10
24
|
### Changed
|
|
11
25
|
- **License**: Changed from MIT to Apache License 2.0
|
|
12
26
|
- **Copyright**: Copyright holder is Abhishek Pandit
|
|
13
27
|
- **Author**: Updated author to Abhishek Pandit
|
|
28
|
+
- **Package Name**: Renamed from hypermcp to nitrostack
|
|
14
29
|
- Updated all documentation links to official website (https://nitrostack.vercel.app/) and docs (https://nitrostack-docs.vercel.app/)
|
|
15
30
|
- Added NOTICE file for Apache 2.0 compliance with dependency attributions
|
|
16
31
|
- Updated CONTRIBUTING.md with Apache 2.0 license headers and contributor agreement
|
package/package.json
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# E-commerce MCP Server Configuration
|
|
2
|
+
|
|
3
|
+
# Server
|
|
4
|
+
PORT=3000
|
|
5
|
+
|
|
6
|
+
# JWT Authentication (REQUIRED for this template)
|
|
7
|
+
# Generate with: npm run setup-db (this will generate a secret for you)
|
|
8
|
+
JWT_SECRET=your-jwt-secret-here-change-this
|
|
9
|
+
JWT_AUDIENCE=ecommerce-mcp-server
|
|
10
|
+
JWT_ISSUER=ecommerce-app
|
|
11
|
+
|
|
12
|
+
# Database
|
|
13
|
+
# Note: Use absolute path for production, relative path works for development
|
|
14
|
+
DATABASE_PATH=./data/ecommerce.db
|
|
15
|
+
|
|
16
|
+
# Logging
|
|
17
|
+
LOG_LEVEL=info
|
|
18
|
+
|
|
19
|
+
# Test Users (created by setup-db script)
|
|
20
|
+
# Username: alice@example.com | Password: password123
|
|
21
|
+
# Username: bob@example.com | Password: password123
|
|
22
|
+
# Username: charlie@example.com | Password: password123
|
|
23
|
+
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { McpApp, Module, ConfigModule, JWTModule } from 'nitrostack';
|
|
2
|
+
|
|
3
|
+
// Services
|
|
4
|
+
import { DatabaseService } from './services/database.service.js';
|
|
5
|
+
|
|
6
|
+
// Modules
|
|
7
|
+
import { AuthModule } from './modules/auth/auth.module.js';
|
|
8
|
+
import { ProductsModule } from './modules/products/products.module.js';
|
|
9
|
+
import { CartModule } from './modules/cart/cart.module.js';
|
|
10
|
+
import { OrdersModule } from './modules/orders/orders.module.js';
|
|
11
|
+
import { AddressesModule } from './modules/addresses/addresses.module.js';
|
|
12
|
+
|
|
13
|
+
// Middleware
|
|
14
|
+
import { LoggingMiddleware } from './middleware/logging.middleware.js';
|
|
15
|
+
|
|
16
|
+
// Interceptors
|
|
17
|
+
import { TransformInterceptor } from './interceptors/transform.interceptor.js';
|
|
18
|
+
|
|
19
|
+
// Pipes
|
|
20
|
+
import { ValidationPipe } from './pipes/validation.pipe.js';
|
|
21
|
+
|
|
22
|
+
// Filters
|
|
23
|
+
import { GlobalExceptionFilter } from './filters/global-exception.filter.js';
|
|
24
|
+
|
|
25
|
+
// Events
|
|
26
|
+
import { AnalyticsService } from './events/analytics.service.js';
|
|
27
|
+
import { NotificationService } from './events/notification.service.js';
|
|
28
|
+
|
|
29
|
+
// Health
|
|
30
|
+
import { DatabaseHealthCheck } from './health/database.health.js';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Root Application Module
|
|
34
|
+
*
|
|
35
|
+
* This is the main module that bootstraps the MCP server.
|
|
36
|
+
* It registers all feature modules, services, and global providers.
|
|
37
|
+
*/
|
|
38
|
+
@McpApp({
|
|
39
|
+
module: AppModule,
|
|
40
|
+
server: {
|
|
41
|
+
name: 'E-commerce MCP Server',
|
|
42
|
+
version: '3.0.0',
|
|
43
|
+
},
|
|
44
|
+
logging: {
|
|
45
|
+
level: (process.env.LOG_LEVEL as any) || 'info',
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
@Module({
|
|
49
|
+
name: 'app',
|
|
50
|
+
description: 'Root application module',
|
|
51
|
+
imports: [
|
|
52
|
+
// Configuration
|
|
53
|
+
ConfigModule.forRoot({
|
|
54
|
+
envFilePath: '.env',
|
|
55
|
+
defaults: {
|
|
56
|
+
DATABASE_PATH: './data/ecommerce.db',
|
|
57
|
+
LOG_LEVEL: 'info',
|
|
58
|
+
},
|
|
59
|
+
}),
|
|
60
|
+
|
|
61
|
+
// JWT Authentication
|
|
62
|
+
JWTModule.forRoot({
|
|
63
|
+
secret: process.env.JWT_SECRET || 'your-secret-key',
|
|
64
|
+
expiresIn: '7d',
|
|
65
|
+
issuer: process.env.JWT_ISSUER || 'ecommerce-app',
|
|
66
|
+
audience: process.env.JWT_AUDIENCE || 'ecommerce-mcp-server',
|
|
67
|
+
}),
|
|
68
|
+
|
|
69
|
+
// Feature Modules
|
|
70
|
+
AuthModule,
|
|
71
|
+
ProductsModule,
|
|
72
|
+
CartModule,
|
|
73
|
+
OrdersModule,
|
|
74
|
+
AddressesModule,
|
|
75
|
+
],
|
|
76
|
+
controllers: [],
|
|
77
|
+
providers: [
|
|
78
|
+
// Global Services
|
|
79
|
+
DatabaseService,
|
|
80
|
+
|
|
81
|
+
// Global Middleware
|
|
82
|
+
LoggingMiddleware,
|
|
83
|
+
|
|
84
|
+
// Global Interceptors
|
|
85
|
+
TransformInterceptor,
|
|
86
|
+
|
|
87
|
+
// Global Pipes
|
|
88
|
+
ValidationPipe,
|
|
89
|
+
|
|
90
|
+
// Global Filters
|
|
91
|
+
GlobalExceptionFilter,
|
|
92
|
+
|
|
93
|
+
// Event Handlers
|
|
94
|
+
AnalyticsService,
|
|
95
|
+
NotificationService,
|
|
96
|
+
|
|
97
|
+
// Health Checks
|
|
98
|
+
DatabaseHealthCheck,
|
|
99
|
+
],
|
|
100
|
+
exports: [DatabaseService],
|
|
101
|
+
})
|
|
102
|
+
export class AppModule {}
|
|
103
|
+
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Database connection and utilities
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
let db: Database.Database | null = null;
|
|
10
|
+
|
|
11
|
+
export function getDatabase(): Database.Database {
|
|
12
|
+
if (!db) {
|
|
13
|
+
const envPath = process.env.DATABASE_PATH || './data/ecommerce.db';
|
|
14
|
+
|
|
15
|
+
// Resolve relative paths from the project root (process.cwd())
|
|
16
|
+
// Absolute paths are used as-is
|
|
17
|
+
const dbPath = path.isAbsolute(envPath)
|
|
18
|
+
? envPath
|
|
19
|
+
: path.resolve(process.cwd(), envPath);
|
|
20
|
+
|
|
21
|
+
const dbDir = path.dirname(dbPath);
|
|
22
|
+
|
|
23
|
+
// Ensure data directory exists
|
|
24
|
+
if (!fs.existsSync(dbDir)) {
|
|
25
|
+
fs.mkdirSync(dbDir, { recursive: true });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
db = new Database(dbPath);
|
|
29
|
+
db.pragma('journal_mode = WAL');
|
|
30
|
+
db.pragma('foreign_keys = ON');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return db;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function closeDatabase(): void {
|
|
37
|
+
if (db) {
|
|
38
|
+
db.close();
|
|
39
|
+
db = null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Initialize database schema
|
|
45
|
+
*/
|
|
46
|
+
export function initializeSchema(): void {
|
|
47
|
+
const db = getDatabase();
|
|
48
|
+
|
|
49
|
+
// Users table
|
|
50
|
+
db.exec(`
|
|
51
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
52
|
+
id TEXT PRIMARY KEY,
|
|
53
|
+
email TEXT UNIQUE NOT NULL,
|
|
54
|
+
password_hash TEXT NOT NULL,
|
|
55
|
+
name TEXT NOT NULL,
|
|
56
|
+
profile_picture TEXT,
|
|
57
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
58
|
+
)
|
|
59
|
+
`);
|
|
60
|
+
|
|
61
|
+
// Products table
|
|
62
|
+
db.exec(`
|
|
63
|
+
CREATE TABLE IF NOT EXISTS products (
|
|
64
|
+
id TEXT PRIMARY KEY,
|
|
65
|
+
name TEXT NOT NULL,
|
|
66
|
+
description TEXT,
|
|
67
|
+
price REAL NOT NULL,
|
|
68
|
+
category TEXT NOT NULL,
|
|
69
|
+
stock INTEGER NOT NULL DEFAULT 0,
|
|
70
|
+
image_url TEXT,
|
|
71
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
72
|
+
)
|
|
73
|
+
`);
|
|
74
|
+
|
|
75
|
+
// Addresses table
|
|
76
|
+
db.exec(`
|
|
77
|
+
CREATE TABLE IF NOT EXISTS addresses (
|
|
78
|
+
id TEXT PRIMARY KEY,
|
|
79
|
+
user_id TEXT NOT NULL,
|
|
80
|
+
full_name TEXT NOT NULL,
|
|
81
|
+
street TEXT NOT NULL,
|
|
82
|
+
city TEXT NOT NULL,
|
|
83
|
+
state TEXT NOT NULL,
|
|
84
|
+
zip_code TEXT NOT NULL,
|
|
85
|
+
country TEXT NOT NULL DEFAULT 'USA',
|
|
86
|
+
phone TEXT NOT NULL,
|
|
87
|
+
is_default INTEGER DEFAULT 0,
|
|
88
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
89
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
90
|
+
)
|
|
91
|
+
`);
|
|
92
|
+
|
|
93
|
+
// Carts table
|
|
94
|
+
db.exec(`
|
|
95
|
+
CREATE TABLE IF NOT EXISTS carts (
|
|
96
|
+
id TEXT PRIMARY KEY,
|
|
97
|
+
user_id TEXT NOT NULL,
|
|
98
|
+
product_id TEXT NOT NULL,
|
|
99
|
+
quantity INTEGER NOT NULL DEFAULT 1,
|
|
100
|
+
added_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
101
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
102
|
+
FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE,
|
|
103
|
+
UNIQUE(user_id, product_id)
|
|
104
|
+
)
|
|
105
|
+
`);
|
|
106
|
+
|
|
107
|
+
// Orders table
|
|
108
|
+
db.exec(`
|
|
109
|
+
CREATE TABLE IF NOT EXISTS orders (
|
|
110
|
+
id TEXT PRIMARY KEY,
|
|
111
|
+
user_id TEXT NOT NULL,
|
|
112
|
+
address_id TEXT NOT NULL,
|
|
113
|
+
total_amount REAL NOT NULL,
|
|
114
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
115
|
+
payment_method TEXT NOT NULL DEFAULT 'cash_on_delivery',
|
|
116
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
117
|
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
118
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
119
|
+
FOREIGN KEY (address_id) REFERENCES addresses(id)
|
|
120
|
+
)
|
|
121
|
+
`);
|
|
122
|
+
|
|
123
|
+
// Order items table
|
|
124
|
+
db.exec(`
|
|
125
|
+
CREATE TABLE IF NOT EXISTS order_items (
|
|
126
|
+
id TEXT PRIMARY KEY,
|
|
127
|
+
order_id TEXT NOT NULL,
|
|
128
|
+
product_id TEXT NOT NULL,
|
|
129
|
+
product_name TEXT NOT NULL,
|
|
130
|
+
product_price REAL NOT NULL,
|
|
131
|
+
quantity INTEGER NOT NULL,
|
|
132
|
+
subtotal REAL NOT NULL,
|
|
133
|
+
FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE,
|
|
134
|
+
FOREIGN KEY (product_id) REFERENCES products(id)
|
|
135
|
+
)
|
|
136
|
+
`);
|
|
137
|
+
|
|
138
|
+
// Create indexes
|
|
139
|
+
db.exec(`
|
|
140
|
+
CREATE INDEX IF NOT EXISTS idx_carts_user_id ON carts(user_id);
|
|
141
|
+
CREATE INDEX IF NOT EXISTS idx_orders_user_id ON orders(user_id);
|
|
142
|
+
CREATE INDEX IF NOT EXISTS idx_order_items_order_id ON order_items(order_id);
|
|
143
|
+
CREATE INDEX IF NOT EXISTS idx_addresses_user_id ON addresses(user_id);
|
|
144
|
+
`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Clear all data (for testing)
|
|
149
|
+
*/
|
|
150
|
+
export function clearAllData(): void {
|
|
151
|
+
const db = getDatabase();
|
|
152
|
+
|
|
153
|
+
db.exec(`
|
|
154
|
+
DELETE FROM order_items;
|
|
155
|
+
DELETE FROM orders;
|
|
156
|
+
DELETE FROM carts;
|
|
157
|
+
DELETE FROM addresses;
|
|
158
|
+
DELETE FROM products;
|
|
159
|
+
DELETE FROM users;
|
|
160
|
+
`);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
+
import bcrypt from 'bcryptjs';
|
|
3
|
+
import { getDatabase } from './database.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Seed database with initial data
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export function seedUsers(): void {
|
|
10
|
+
const db = getDatabase();
|
|
11
|
+
|
|
12
|
+
// Data from https://dummyjson.com/users
|
|
13
|
+
const users = [
|
|
14
|
+
{
|
|
15
|
+
id: 'user-emily',
|
|
16
|
+
email: 'emily.johnson@x.dummyjson.com',
|
|
17
|
+
password: 'password123',
|
|
18
|
+
name: 'Emily Johnson',
|
|
19
|
+
profile_picture: 'https://dummyjson.com/icon/emilys/128',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: 'user-michael',
|
|
23
|
+
email: 'michael.williams@x.dummyjson.com',
|
|
24
|
+
password: 'password123',
|
|
25
|
+
name: 'Michael Williams',
|
|
26
|
+
profile_picture: 'https://dummyjson.com/icon/michaelw/128',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: 'user-sophia',
|
|
30
|
+
email: 'sophia.brown@x.dummyjson.com',
|
|
31
|
+
password: 'password123',
|
|
32
|
+
name: 'Sophia Brown',
|
|
33
|
+
profile_picture: 'https://dummyjson.com/icon/sophiab/128',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: 'user-james',
|
|
37
|
+
email: 'james.davis@x.dummyjson.com',
|
|
38
|
+
password: 'password123',
|
|
39
|
+
name: 'James Davis',
|
|
40
|
+
profile_picture: 'https://dummyjson.com/icon/jamesd/128',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: 'user-emma',
|
|
44
|
+
email: 'emma.miller@x.dummyjson.com',
|
|
45
|
+
password: 'password123',
|
|
46
|
+
name: 'Emma Miller',
|
|
47
|
+
profile_picture: 'https://dummyjson.com/icon/emmaj/128',
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
const stmt = db.prepare(`
|
|
52
|
+
INSERT OR REPLACE INTO users (id, email, password_hash, name, profile_picture)
|
|
53
|
+
VALUES (?, ?, ?, ?, ?)
|
|
54
|
+
`);
|
|
55
|
+
|
|
56
|
+
for (const user of users) {
|
|
57
|
+
const passwordHash = bcrypt.hashSync(user.password, 10);
|
|
58
|
+
stmt.run(user.id, user.email, passwordHash, user.name, user.profile_picture);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
console.log(`✅ Seeded ${users.length} users (from DummyJSON)`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function seedProducts(): void {
|
|
65
|
+
const db = getDatabase();
|
|
66
|
+
|
|
67
|
+
// Data from https://dummyjson.com/products
|
|
68
|
+
const products = [
|
|
69
|
+
// Beauty Products
|
|
70
|
+
{
|
|
71
|
+
id: 'prod-1',
|
|
72
|
+
name: 'Essence Mascara Lash Princess',
|
|
73
|
+
description: 'The Essence Mascara Lash Princess is a popular mascara known for its volumizing and lengthening effects.',
|
|
74
|
+
price: 9.99,
|
|
75
|
+
category: 'Beauty',
|
|
76
|
+
stock: 99,
|
|
77
|
+
image_url: 'https://cdn.dummyjson.com/product-images/beauty/essence-mascara-lash-princess/thumbnail.webp',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
id: 'prod-2',
|
|
81
|
+
name: 'Eyeshadow Palette with Mirror',
|
|
82
|
+
description: 'The Eyeshadow Palette offers a versatile range of eyeshadow shades for creating stunning eye looks.',
|
|
83
|
+
price: 19.99,
|
|
84
|
+
category: 'Beauty',
|
|
85
|
+
stock: 34,
|
|
86
|
+
image_url: 'https://cdn.dummyjson.com/product-images/beauty/eyeshadow-palette-with-mirror/thumbnail.webp',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: 'prod-3',
|
|
90
|
+
name: 'Powder Canister',
|
|
91
|
+
description: 'The Powder Canister is a finely milled setting powder designed to set makeup and control shine.',
|
|
92
|
+
price: 14.99,
|
|
93
|
+
category: 'Beauty',
|
|
94
|
+
stock: 89,
|
|
95
|
+
image_url: 'https://cdn.dummyjson.com/product-images/beauty/powder-canister/thumbnail.webp',
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
id: 'prod-4',
|
|
99
|
+
name: 'Red Lipstick',
|
|
100
|
+
description: 'The Red Lipstick is a classic and bold choice for adding a pop of color to your lips.',
|
|
101
|
+
price: 12.99,
|
|
102
|
+
category: 'Beauty',
|
|
103
|
+
stock: 91,
|
|
104
|
+
image_url: 'https://cdn.dummyjson.com/product-images/beauty/red-lipstick/thumbnail.webp',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
id: 'prod-5',
|
|
108
|
+
name: 'Red Nail Polish',
|
|
109
|
+
description: 'The Red Nail Polish offers a rich and glossy red hue for vibrant and polished nails.',
|
|
110
|
+
price: 8.99,
|
|
111
|
+
category: 'Beauty',
|
|
112
|
+
stock: 79,
|
|
113
|
+
image_url: 'https://cdn.dummyjson.com/product-images/beauty/red-nail-polish/thumbnail.webp',
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
// Fragrances
|
|
117
|
+
{
|
|
118
|
+
id: 'prod-6',
|
|
119
|
+
name: 'Calvin Klein CK One',
|
|
120
|
+
description: 'CK One by Calvin Klein is a classic unisex fragrance, known for its fresh and clean scent.',
|
|
121
|
+
price: 49.99,
|
|
122
|
+
category: 'Fragrances',
|
|
123
|
+
stock: 17,
|
|
124
|
+
image_url: 'https://cdn.dummyjson.com/product-images/fragrances/calvin-klein-ck-one/thumbnail.webp',
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
id: 'prod-7',
|
|
128
|
+
name: 'Chanel Coco Noir Eau De',
|
|
129
|
+
description: 'Coco Noir by Chanel is an elegant and mysterious fragrance, featuring notes of grapefruit and rose.',
|
|
130
|
+
price: 129.99,
|
|
131
|
+
category: 'Fragrances',
|
|
132
|
+
stock: 41,
|
|
133
|
+
image_url: 'https://cdn.dummyjson.com/product-images/fragrances/chanel-coco-noir-eau-de/thumbnail.webp',
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
id: 'prod-8',
|
|
137
|
+
name: 'Dior J\'adore',
|
|
138
|
+
description: 'J\'adore by Dior is a luxurious and floral fragrance, known for its sophisticated blend of ylang-ylang.',
|
|
139
|
+
price: 89.99,
|
|
140
|
+
category: 'Fragrances',
|
|
141
|
+
stock: 91,
|
|
142
|
+
image_url: 'https://cdn.dummyjson.com/product-images/fragrances/dior-j-adore/thumbnail.webp',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
id: 'prod-9',
|
|
146
|
+
name: 'Dolce Shine Eau de',
|
|
147
|
+
description: 'Dolce Shine by Dolce & Gabbana is a vibrant and fruity fragrance, featuring notes of mango and jasmine.',
|
|
148
|
+
price: 69.99,
|
|
149
|
+
category: 'Fragrances',
|
|
150
|
+
stock: 3,
|
|
151
|
+
image_url: 'https://cdn.dummyjson.com/product-images/fragrances/dolce-shine-eau-de/thumbnail.webp',
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
id: 'prod-10',
|
|
155
|
+
name: 'Gucci Bloom Eau de',
|
|
156
|
+
description: 'Gucci Bloom by Gucci is a floral and captivating fragrance, with notes of tuberose and jasmine.',
|
|
157
|
+
price: 79.99,
|
|
158
|
+
category: 'Fragrances',
|
|
159
|
+
stock: 93,
|
|
160
|
+
image_url: 'https://cdn.dummyjson.com/product-images/fragrances/gucci-bloom-eau-de/thumbnail.webp',
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
// Furniture
|
|
164
|
+
{
|
|
165
|
+
id: 'prod-11',
|
|
166
|
+
name: 'Annibale Colombo Bed',
|
|
167
|
+
description: 'The Annibale Colombo Bed is a luxurious and elegant bed frame, crafted with high-quality materials.',
|
|
168
|
+
price: 1899.99,
|
|
169
|
+
category: 'Furniture',
|
|
170
|
+
stock: 47,
|
|
171
|
+
image_url: 'https://cdn.dummyjson.com/product-images/furniture/annibale-colombo-bed/thumbnail.webp',
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
id: 'prod-12',
|
|
175
|
+
name: 'Annibale Colombo Sofa',
|
|
176
|
+
description: 'The Annibale Colombo Sofa is a sophisticated and comfortable seating option, featuring exquisite design.',
|
|
177
|
+
price: 2499.99,
|
|
178
|
+
category: 'Furniture',
|
|
179
|
+
stock: 16,
|
|
180
|
+
image_url: 'https://cdn.dummyjson.com/product-images/furniture/annibale-colombo-sofa/thumbnail.webp',
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
id: 'prod-13',
|
|
184
|
+
name: 'Bedside Table African Cherry',
|
|
185
|
+
description: 'The Bedside Table in African Cherry is a stylish and functional addition to your bedroom.',
|
|
186
|
+
price: 299.99,
|
|
187
|
+
category: 'Furniture',
|
|
188
|
+
stock: 16,
|
|
189
|
+
image_url: 'https://cdn.dummyjson.com/product-images/furniture/bedside-table-african-cherry/thumbnail.webp',
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
id: 'prod-14',
|
|
193
|
+
name: 'Knoll Saarinen Executive Conference Chair',
|
|
194
|
+
description: 'The Knoll Saarinen Executive Conference Chair is a modern and ergonomic chair, perfect for your office.',
|
|
195
|
+
price: 499.99,
|
|
196
|
+
category: 'Furniture',
|
|
197
|
+
stock: 47,
|
|
198
|
+
image_url: 'https://cdn.dummyjson.com/product-images/furniture/knoll-saarinen-executive-conference-chair/thumbnail.webp',
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
id: 'prod-15',
|
|
202
|
+
name: 'Wooden Bathroom Sink With Mirror',
|
|
203
|
+
description: 'The Wooden Bathroom Sink with Mirror is a unique and stylish addition to your bathroom.',
|
|
204
|
+
price: 799.99,
|
|
205
|
+
category: 'Furniture',
|
|
206
|
+
stock: 95,
|
|
207
|
+
image_url: 'https://cdn.dummyjson.com/product-images/furniture/wooden-bathroom-sink-with-mirror/thumbnail.webp',
|
|
208
|
+
},
|
|
209
|
+
|
|
210
|
+
// Groceries
|
|
211
|
+
{
|
|
212
|
+
id: 'prod-16',
|
|
213
|
+
name: 'Apple',
|
|
214
|
+
description: 'Fresh and crisp apples, perfect for snacking or incorporating into various recipes.',
|
|
215
|
+
price: 1.99,
|
|
216
|
+
category: 'Groceries',
|
|
217
|
+
stock: 9,
|
|
218
|
+
image_url: 'https://cdn.dummyjson.com/product-images/groceries/apple/thumbnail.webp',
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
id: 'prod-17',
|
|
222
|
+
name: 'Beef Steak',
|
|
223
|
+
description: 'High-quality beef steak, great for grilling or cooking to your preferred level of doneness.',
|
|
224
|
+
price: 12.99,
|
|
225
|
+
category: 'Groceries',
|
|
226
|
+
stock: 96,
|
|
227
|
+
image_url: 'https://cdn.dummyjson.com/product-images/groceries/beef-steak/thumbnail.webp',
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
id: 'prod-18',
|
|
231
|
+
name: 'Cat Food',
|
|
232
|
+
description: 'Nutritious cat food formulated to meet the dietary needs of your feline friend.',
|
|
233
|
+
price: 8.99,
|
|
234
|
+
category: 'Groceries',
|
|
235
|
+
stock: 13,
|
|
236
|
+
image_url: 'https://cdn.dummyjson.com/product-images/groceries/cat-food/thumbnail.webp',
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
id: 'prod-19',
|
|
240
|
+
name: 'Chicken Meat',
|
|
241
|
+
description: 'Fresh and tender chicken meat, suitable for various culinary preparations.',
|
|
242
|
+
price: 9.99,
|
|
243
|
+
category: 'Groceries',
|
|
244
|
+
stock: 69,
|
|
245
|
+
image_url: 'https://cdn.dummyjson.com/product-images/groceries/chicken-meat/thumbnail.webp',
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
id: 'prod-20',
|
|
249
|
+
name: 'Cooking Oil',
|
|
250
|
+
description: 'Versatile cooking oil suitable for frying, sautéing, and various culinary applications.',
|
|
251
|
+
price: 4.99,
|
|
252
|
+
category: 'Groceries',
|
|
253
|
+
stock: 22,
|
|
254
|
+
image_url: 'https://cdn.dummyjson.com/product-images/groceries/cooking-oil/thumbnail.webp',
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
id: 'prod-21',
|
|
258
|
+
name: 'Cucumber',
|
|
259
|
+
description: 'Crisp and hydrating cucumbers, ideal for salads, snacks, or as a refreshing side.',
|
|
260
|
+
price: 1.49,
|
|
261
|
+
category: 'Groceries',
|
|
262
|
+
stock: 22,
|
|
263
|
+
image_url: 'https://cdn.dummyjson.com/product-images/groceries/cucumber/thumbnail.webp',
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
id: 'prod-22',
|
|
267
|
+
name: 'Dog Food',
|
|
268
|
+
description: 'Specially formulated dog food designed to provide essential nutrients for your canine companion.',
|
|
269
|
+
price: 10.99,
|
|
270
|
+
category: 'Groceries',
|
|
271
|
+
stock: 40,
|
|
272
|
+
image_url: 'https://cdn.dummyjson.com/product-images/groceries/dog-food/thumbnail.webp',
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
id: 'prod-23',
|
|
276
|
+
name: 'Eggs',
|
|
277
|
+
description: 'Fresh eggs, a versatile ingredient for baking, cooking, or breakfast.',
|
|
278
|
+
price: 2.99,
|
|
279
|
+
category: 'Groceries',
|
|
280
|
+
stock: 10,
|
|
281
|
+
image_url: 'https://cdn.dummyjson.com/product-images/groceries/eggs/thumbnail.webp',
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
id: 'prod-24',
|
|
285
|
+
name: 'Fish Steak',
|
|
286
|
+
description: 'Quality fish steak, suitable for grilling, baking, or pan-searing.',
|
|
287
|
+
price: 14.99,
|
|
288
|
+
category: 'Groceries',
|
|
289
|
+
stock: 99,
|
|
290
|
+
image_url: 'https://cdn.dummyjson.com/product-images/groceries/fish-steak/thumbnail.webp',
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
id: 'prod-25',
|
|
294
|
+
name: 'Green Bell Pepper',
|
|
295
|
+
description: 'Fresh green bell pepper, perfect for adding color and flavor to your dishes.',
|
|
296
|
+
price: 1.29,
|
|
297
|
+
category: 'Groceries',
|
|
298
|
+
stock: 89,
|
|
299
|
+
image_url: 'https://cdn.dummyjson.com/product-images/groceries/green-bell-pepper/thumbnail.webp',
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
id: 'prod-26',
|
|
303
|
+
name: 'Green Chili Pepper',
|
|
304
|
+
description: 'Spicy green chili pepper, ideal for adding heat to your favorite recipes.',
|
|
305
|
+
price: 0.99,
|
|
306
|
+
category: 'Groceries',
|
|
307
|
+
stock: 8,
|
|
308
|
+
image_url: 'https://cdn.dummyjson.com/product-images/groceries/green-chili-pepper/thumbnail.webp',
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
id: 'prod-27',
|
|
312
|
+
name: 'Honey Jar',
|
|
313
|
+
description: 'Pure and natural honey in a convenient jar, perfect for sweetening beverages or drizzling over food.',
|
|
314
|
+
price: 6.99,
|
|
315
|
+
category: 'Groceries',
|
|
316
|
+
stock: 34,
|
|
317
|
+
image_url: 'https://cdn.dummyjson.com/product-images/groceries/honey-jar/thumbnail.webp',
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
id: 'prod-28',
|
|
321
|
+
name: 'Ice Cream',
|
|
322
|
+
description: 'Creamy and delicious ice cream, available in various flavors for a delightful treat.',
|
|
323
|
+
price: 5.49,
|
|
324
|
+
category: 'Groceries',
|
|
325
|
+
stock: 27,
|
|
326
|
+
image_url: 'https://cdn.dummyjson.com/product-images/groceries/ice-cream/thumbnail.webp',
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
id: 'prod-29',
|
|
330
|
+
name: 'Juice',
|
|
331
|
+
description: 'Refreshing fruit juice, packed with vitamins and great for staying hydrated.',
|
|
332
|
+
price: 3.99,
|
|
333
|
+
category: 'Groceries',
|
|
334
|
+
stock: 50,
|
|
335
|
+
image_url: 'https://cdn.dummyjson.com/product-images/groceries/juice/thumbnail.webp',
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
id: 'prod-30',
|
|
339
|
+
name: 'Kiwi',
|
|
340
|
+
description: 'Nutrient-rich kiwi, perfect for snacking or adding a tropical twist to your dishes.',
|
|
341
|
+
price: 2.49,
|
|
342
|
+
category: 'Groceries',
|
|
343
|
+
stock: 99,
|
|
344
|
+
image_url: 'https://cdn.dummyjson.com/product-images/groceries/kiwi/thumbnail.webp',
|
|
345
|
+
},
|
|
346
|
+
];
|
|
347
|
+
|
|
348
|
+
const stmt = db.prepare(`
|
|
349
|
+
INSERT OR REPLACE INTO products (id, name, description, price, category, stock, image_url)
|
|
350
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
351
|
+
`);
|
|
352
|
+
|
|
353
|
+
for (const product of products) {
|
|
354
|
+
stmt.run(
|
|
355
|
+
product.id,
|
|
356
|
+
product.name,
|
|
357
|
+
product.description,
|
|
358
|
+
product.price,
|
|
359
|
+
product.category,
|
|
360
|
+
product.stock,
|
|
361
|
+
product.image_url
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
console.log(`✅ Seeded ${products.length} products (from DummyJSON)`);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
export function seedAll(): void {
|
|
369
|
+
console.log('🌱 Seeding database...');
|
|
370
|
+
seedUsers();
|
|
371
|
+
seedProducts();
|
|
372
|
+
console.log('✅ Database seeding complete!');
|
|
373
|
+
}
|
|
374
|
+
|