lapeh 2.0.0 → 2.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/.env.example CHANGED
@@ -3,12 +3,11 @@ DATABASE_PROVIDER="postgresql"
3
3
  DATABASE_URL="postgresql://sianu:12341234@localhost:5432/db_example_test?schema=public"
4
4
  JWT_SECRET="replace_this_with_a_secure_random_string"
5
5
 
6
- # Redis Configuration (Optional)
7
- # If REDIS_URL is not set or connection fails, the framework will automatically
8
- # switch to an in-memory Redis mock (bundled). No installation required for development.
9
-
10
-
11
- # REDIS_URL="redis://localhost:6379"
6
+ # Redis Configuration (Optional)
7
+ # If REDIS_URL is not set or connection fails, the framework will automatically
8
+ # switch to an in-memory Redis mock (bundled). No installation required for development.
9
+ # REDIS_URL="redis://lapeh:12341234@localhost:6379"
10
+ # NO_REDIS="true"
12
11
 
13
12
  # To force disable Redis and use in-memory mock even if Redis is available:
14
13
  # NO_REDIS="true"
@@ -2,7 +2,14 @@ version: "3.9"
2
2
  services:
3
3
  redis:
4
4
  image: redis:7-alpine
5
- command: ["redis-server", "--appendonly", "yes"]
5
+ command:
6
+ - "redis-server"
7
+ - "--appendonly"
8
+ - "yes"
9
+ - "--user"
10
+ - "default on >12341234 ~* +@all"
11
+ - "--user"
12
+ - "lapeh on >12341234 ~* +@all"
6
13
  ports:
7
14
  - "6379:6379"
8
15
  volumes:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lapeh",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Framework API Express yang siap pakai (Standardized)",
5
5
  "main": "index.js",
6
6
  "bin": {
package/readme.md CHANGED
@@ -75,6 +75,44 @@ Jika Anda melakukan setup dengan flag `--full`, database akan terisi dengan akun
75
75
 
76
76
  ---
77
77
 
78
+ ## 🧠 Zero-Config Redis
79
+
80
+ Lapeh otomatis mendeteksi ketersediaan Redis.
81
+
82
+ 1. **Auto-Discovery**: Mencoba terhubung ke Redis URL di `.env` (`REDIS_URL`).
83
+ 2. **Smart Fallback**: Jika Redis tidak tersedia atau koneksi gagal, otomatis beralih ke **In-Memory Mock**.
84
+ - Tidak perlu install Redis di local development.
85
+ - Fitur rate-limiting dan caching tetap berjalan (namun data hilang saat restart).
86
+ 3. **Production Safety**: Memberikan peringatan log jika berjalan di Production menggunakan Mock.
87
+
88
+ **Force Mock Mode:**
89
+ Anda bisa memaksa menggunakan mock (misal untuk testing) dengan menambahkan env variable:
90
+
91
+ ```env
92
+ NO_REDIS=true
93
+ ```
94
+
95
+ ### Optional: Menggunakan Real Redis dengan Docker
96
+
97
+ Jika Anda ingin menggunakan Redis yang sebenarnya di local environment, kami telah menyertakan konfigurasi `docker-compose.yml` yang aman (menggunakan ACL).
98
+
99
+ 1. Jalankan Redis container:
100
+
101
+ ```bash
102
+ docker-compose up -d
103
+ ```
104
+
105
+ 2. Uncomment konfigurasi Redis di file `.env` Anda:
106
+
107
+ ```env
108
+ REDIS_URL="redis://lapeh:12341234@localhost:6379"
109
+ ```
110
+
111
+ > **Credential Default:**
112
+ >
113
+ > - User: `lapeh`
114
+ > - Password: `12341234`
115
+
78
116
  ## šŸ›  Development Tools
79
117
 
80
118
  API Lapeh menyediakan tools untuk mempercepat development, mirip dengan `artisan` di Laravel.
@@ -122,7 +122,22 @@ const selectOption = async (query, options) => {
122
122
  console.log("\nšŸ“¦ Installing dependencies...");
123
123
  execSync("npm install", { stdio: "inherit", cwd: rootDir });
124
124
 
125
- // 4. Generate JWT Secret
125
+ // 4. Create .vscode/settings.json
126
+ console.log("\nšŸ› ļø Configuring VS Code...");
127
+ const vscodeDir = path.join(rootDir, ".vscode");
128
+ if (!fs.existsSync(vscodeDir)) {
129
+ fs.mkdirSync(vscodeDir, { recursive: true });
130
+ }
131
+ const settingsFile = path.join(vscodeDir, "settings.json");
132
+ const settingsContent = {
133
+ "files.associations": {
134
+ "*.model": "prisma"
135
+ }
136
+ };
137
+ fs.writeFileSync(settingsFile, JSON.stringify(settingsContent, null, 2));
138
+ console.log("āœ… VS Code configured (.model support added).");
139
+
140
+ // 5. Generate JWT Secret
126
141
  console.log("\nšŸ”‘ Generating JWT Secret...");
127
142
  try {
128
143
  execSync("node scripts/generate-jwt-secret.js", {
package/src/redis.ts CHANGED
@@ -38,12 +38,10 @@ redis.on("error", (err) => {
38
38
  // Replace the global redis instance with mock
39
39
  // Note: This is a runtime switch. Existing listeners might be lost if we don't handle carefully.
40
40
  // However, for a simple fallback, we can just use the mock for future calls.
41
-
42
- // Better approach: Since we exported 'redis' as a const (reference), we can't reassign it easily
41
+ // Better approach: Since we exported 'redis' as a const (reference), we can't reassign it easily
43
42
  // if other modules already imported it.
44
43
  // BUT, ioredis instance itself is an EventEmitter.
45
-
46
- // Strategy: We keep 'redis' as the main interface.
44
+ // Strategy: We keep 'redis' as the main interface.
47
45
  // If real redis fails, we just don't set isRedisConnected to true for the *real* one.
48
46
  // But wait, the user wants 'bundle redis'.
49
47
  // The best way is to detect failure during init and SWAP the implementation.
@@ -63,6 +61,7 @@ let activeRedis = redis; // Start with real redis attempt
63
61
  export async function initRedis() {
64
62
  if (process.env.NO_REDIS === "true") {
65
63
  activeRedis = mockRedis;
64
+ console.log("āœ… Redis: Active (Source: Zero-Config Redis [NO_REDIS=true])");
66
65
  if (process.env.NODE_ENV === "production") {
67
66
  console.warn(
68
67
  "āš ļø WARNING: Running in PRODUCTION with in-memory Redis mock. Data will be lost on restart and not shared between instances."
@@ -75,9 +74,18 @@ export async function initRedis() {
75
74
  await redis.connect();
76
75
  activeRedis = redis; // Keep using real redis
77
76
  isRedisConnected = true;
77
+
78
+ // Determine source label
79
+ const sourceLabel = process.env.REDIS_URL
80
+ ? redisUrl
81
+ : "Zero-Config Redis (Localhost)";
82
+
83
+ console.log(`āœ… Redis: Active (Source: ${sourceLabel})`);
78
84
  } catch (err) {
79
85
  // Connection failed, switch to mock
80
- // console.log("Redis failed, using in-memory mock");
86
+ console.log(
87
+ `āš ļø Redis: Connection failed to ${redisUrl}, switching to fallback (Source: Zero-Config Redis [Mock])`
88
+ );
81
89
  activeRedis = mockRedis;
82
90
  isRedisConnected = true; // Mock is always "connected"
83
91
  if (process.env.NODE_ENV === "production") {
@@ -118,4 +126,4 @@ export async function delCache(key: string) {
118
126
  }
119
127
 
120
128
  // Export the proxy as 'redis' so consumers use it transparently
121
- export { redisProxy as redis };
129
+ export { redisProxy as redis };