lapeh 3.0.8 → 3.0.9

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.
@@ -2,6 +2,14 @@
2
2
 
3
3
  File ini mencatat semua perubahan, pembaruan, dan perbaikan yang dilakukan pada framework Lapeh, diurutkan berdasarkan tanggal.
4
4
 
5
+ ## [2025-12-30] - Tuesday, December 30, 2025 - Smart Blog Automation (v3.0.8)
6
+
7
+ ### šŸ¤– Release Script Improvements
8
+
9
+ - **Smart Blog Generation**: The `release.js` script now intelligently reads content from `CHANGELOG.md` (both ID and EN) to generate release blog posts. No more generic "Routine maintenance" content!
10
+ - **Flexible Version Detection**: Improved Regex to detect versions in various changelog header formats.
11
+ - **Bilingual Support**: Ensures release notes are accurately available in both Indonesian and English.
12
+
5
13
  ## [2025-12-30] - Tuesday, December 30, 2025 - Documentation & CLI (v3.0.7)
6
14
 
7
15
  ### šŸ“š Documentation
@@ -2,6 +2,14 @@
2
2
 
3
3
  File ini mencatat semua perubahan, pembaruan, dan perbaikan yang dilakukan pada framework Lapeh, diurutkan berdasarkan tanggal.
4
4
 
5
+ ## [2025-12-30] - Selasa, 30 Desember 2025 - Otomatisasi Blog Cerdas (v3.0.8)
6
+
7
+ ### šŸ¤– Peningkatan Script Rilis
8
+
9
+ - **Smart Blog Generation**: Script `release.js` kini secara cerdas membaca konten dari `CHANGELOG.md` (baik ID maupun EN) untuk membuat postingan blog rilis. Tidak ada lagi konten generik "Routine maintenance"!
10
+ - **Deteksi Versi Fleksibel**: Peningkatan Regex untuk mendeteksi versi dalam format header changelog yang bervariasi.
11
+ - **Dukungan Dwibahasa**: Memastikan rilis notes tersedia dalam Bahasa Indonesia dan Inggris secara akurat.
12
+
5
13
  ## [2025-12-30] - Selasa, 30 Desember 2025 - Dokumentasi & CLI (v3.0.7)
6
14
 
7
15
  ### šŸ“š Dokumentasi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lapeh",
3
- "version": "3.0.8",
3
+ "version": "3.0.9",
4
4
  "description": "Framework API Express yang siap pakai (Standardized)",
5
5
  "engines": {
6
6
  "node": ">=18.0.0",
@@ -103,21 +103,45 @@ function generateAutoCommitMessage() {
103
103
  }
104
104
  }
105
105
 
106
- // Helper to extract changelog entry
107
- function extractChangelogEntry(filePath, version) {
106
+ // Helper to parse changelog entry with structure
107
+ function parseChangelogEntry(filePath, version) {
108
108
  try {
109
109
  if (!fs.existsSync(filePath)) return null;
110
110
  const content = fs.readFileSync(filePath, 'utf8');
111
- // Regex to find the section for the version.
112
- // Matches "## [YYYY-MM-DD] ... vX.X.X ..." until the next "## ["
113
- // We allow the version to be anywhere in the header line
114
- const regex = new RegExp(`## \\[.*?\\] - .*?v${version}.*?([\\s\\S]*?)(?=\\n## \\[|$)`, 'i');
115
- const match = content.match(regex);
116
-
117
- if (match && match[1]) {
118
- return match[1].trim();
111
+
112
+ // 1. Find the header line to extract Title
113
+ // Regex matches: ## [Date] - Day, Date - Title (vVersion)
114
+ const headerRegex = new RegExp(`## \\[.*?\\] - .*? - (.*?) \\(v${version}\\)`, 'i');
115
+ const headerMatch = content.match(headerRegex);
116
+ const title = headerMatch ? headerMatch[1].trim() : null;
117
+
118
+ // 2. Extract the body
119
+ const bodyRegex = new RegExp(`## \\[.*?\\] - .*?v${version}.*?([\\s\\S]*?)(?=\\n## \\[|$)`, 'i');
120
+ const bodyMatch = content.match(bodyRegex);
121
+
122
+ if (!bodyMatch) return null;
123
+
124
+ let rawBody = bodyMatch[1].trim();
125
+
126
+ // 3. Extract Intro (text before first ###)
127
+ let intro = '';
128
+ let features = rawBody;
129
+
130
+ const firstHeaderIndex = rawBody.indexOf('###');
131
+ if (firstHeaderIndex > 0) {
132
+ intro = rawBody.substring(0, firstHeaderIndex).trim();
133
+ features = rawBody.substring(firstHeaderIndex).trim();
134
+ } else if (firstHeaderIndex === -1 && !rawBody.startsWith('-') && !rawBody.startsWith('*')) {
135
+ // If no subheaders and doesn't start with list, treat as intro
136
+ intro = rawBody;
137
+ features = '';
119
138
  }
120
- return null;
139
+
140
+ return {
141
+ title,
142
+ intro,
143
+ features
144
+ };
121
145
  } catch (e) {
122
146
  return null;
123
147
  }
@@ -178,47 +202,79 @@ async function main() {
178
202
  let blogTitleEN = '';
179
203
 
180
204
  if (createBlog.toLowerCase() === 'y') {
181
- console.log('\nšŸ¤– Auto-detecting changes from Git & Changelog...');
182
- const changes = getGitChanges();
183
205
 
184
- // Try to read from CHANGELOG.md first
185
- const changelogID = extractChangelogEntry(path.join(rootDir, 'doc/id/CHANGELOG.md'), newVersion);
186
- const changelogEN = extractChangelogEntry(path.join(rootDir, 'doc/en/CHANGELOG.md'), newVersion);
187
-
188
- let titleID, descriptionID, featuresID, featureListID;
189
- let titleEN, descriptionEN, featuresEN, featureListEN;
190
-
191
- if (changelogID) {
192
- console.log('āœ… Found entry in doc/id/CHANGELOG.md');
193
- // Extract title from first line of changelog entry if possible, or use default
194
- // Actually usually changelog entry body starts with ### Section.
195
- // We'll use a generic title and the full body as content.
196
- titleID = `Update Terbaru v${newVersion}`;
197
- // Try to find specific sections for description/features is hard without strict parsing.
198
- // We will treat the entire changelog body as the "Features" section.
199
- descriptionID = `Rilis versi ${newVersion} hadir dengan berbagai pembaruan dan perbaikan.`;
200
- featureListID = changelogID;
201
- } else {
202
- console.log('āš ļø No entry in doc/id/CHANGELOG.md, using git logs...');
203
- titleID = changes.length > 0 ? changes[0] : 'Maintenance Release';
204
- descriptionID = changes.length > 0 ? `Includes: ${changes.slice(0, 2).join(', ')}` : 'Routine maintenance and updates.';
205
- featureListID = changes.length > 0
206
- ? changes.map(f => `* **${f.trim()}**`).join('\n')
207
- : '* **Routine maintenance**';
208
- }
206
+ const useAuto = await question('šŸ¤– Auto-generate content from CHANGELOG/Git? (y/n): ');
207
+
208
+ let titleID, descriptionID, introID, featureListID;
209
+ let titleEN, descriptionEN, introEN, featureListEN;
210
+
211
+ if (useAuto.toLowerCase() === 'y') {
212
+ console.log('\nšŸ¤– Auto-detecting changes from Git & Changelog...');
213
+ const changes = getGitChanges();
214
+
215
+ // Try to read from CHANGELOG.md first
216
+ const parsedID = parseChangelogEntry(path.join(rootDir, 'doc/id/CHANGELOG.md'), newVersion);
217
+ const parsedEN = parseChangelogEntry(path.join(rootDir, 'doc/en/CHANGELOG.md'), newVersion);
218
+
219
+ if (parsedID) {
220
+ console.log('āœ… Found entry in doc/id/CHANGELOG.md');
221
+ titleID = parsedID.title || `Update Terbaru v${newVersion}`;
222
+ introID = parsedID.intro || `Kami dengan bangga mengumumkan rilis **Lapeh v${newVersion}**. Update ini menghadirkan **${parsedID.title || 'berbagai fitur baru'}** untuk meningkatkan pengalaman pengembangan Anda.`;
223
+ descriptionID = parsedID.intro ? parsedID.intro.split('\n')[0] : `Rilis versi ${newVersion} hadir dengan berbagai pembaruan dan perbaikan.`;
224
+ featureListID = parsedID.features;
225
+ } else {
226
+ console.log('āš ļø No entry in doc/id/CHANGELOG.md, using git logs...');
227
+ titleID = changes.length > 0 ? changes[0] : 'Maintenance Release';
228
+ descriptionID = changes.length > 0 ? `Includes: ${changes.slice(0, 2).join(', ')}` : 'Routine maintenance and updates.';
229
+ introID = `Kami dengan bangga mengumumkan rilis **Lapeh v${newVersion}**. Rilis ini mencakup pemeliharaan rutin dan perbaikan bug.`;
230
+ featureListID = changes.length > 0
231
+ ? changes.map(f => `* **${f.trim()}**`).join('\n')
232
+ : '* **Routine maintenance**';
233
+ }
209
234
 
210
- if (changelogEN) {
211
- console.log('āœ… Found entry in doc/en/CHANGELOG.md');
212
- titleEN = `Latest Update v${newVersion}`;
213
- descriptionEN = `Release version ${newVersion} comes with various updates and improvements.`;
214
- featureListEN = changelogEN;
235
+ if (parsedEN) {
236
+ console.log('āœ… Found entry in doc/en/CHANGELOG.md');
237
+ titleEN = parsedEN.title || `Latest Update v${newVersion}`;
238
+ introEN = parsedEN.intro || `We are proud to announce the release of **Lapeh v${newVersion}**. This update brings **${parsedEN.title || 'various new features'}** to enhance your development experience.`;
239
+ descriptionEN = parsedEN.intro ? parsedEN.intro.split('\n')[0] : `Release version ${newVersion} comes with various updates and improvements.`;
240
+ featureListEN = parsedEN.features;
241
+ } else {
242
+ console.log('āš ļø No entry in doc/en/CHANGELOG.md, using git logs...');
243
+ titleEN = changes.length > 0 ? changes[0] : 'Maintenance Release';
244
+ descriptionEN = changes.length > 0 ? `Includes: ${changes.slice(0, 2).join(', ')}` : 'Routine maintenance and updates.';
245
+ introEN = `We are proud to announce the release of **Lapeh v${newVersion}**. This release includes routine maintenance and bug fixes.`;
246
+ featureListEN = changes.length > 0
247
+ ? changes.map(f => `* **${f.trim()}**`).join('\n')
248
+ : '* **Routine maintenance**';
249
+ }
215
250
  } else {
216
- console.log('āš ļø No entry in doc/en/CHANGELOG.md, using git logs...');
217
- titleEN = changes.length > 0 ? changes[0] : 'Maintenance Release';
218
- descriptionEN = changes.length > 0 ? `Includes: ${changes.slice(0, 2).join(', ')}` : 'Routine maintenance and updates.';
219
- featureListEN = changes.length > 0
220
- ? changes.map(f => `* **${f.trim()}**`).join('\n')
221
- : '* **Routine maintenance**';
251
+ console.log('\nšŸ“ Manual Blog Entry');
252
+ console.log('Silakan masukkan detail blog secara manual.');
253
+
254
+ // ID Inputs
255
+ titleID = await question('Judul Blog (ID): ');
256
+ descriptionID = await question('Deskripsi Singkat (ID): ');
257
+ const contentID = await question('Konten Utama/Fitur (ID) - Gunakan format Markdown jika perlu: ');
258
+ introID = `Rilis versi ${newVersion} telah hadir.`; // Fallback for manual
259
+ featureListID = contentID;
260
+
261
+ console.log('\n--- English Version ---');
262
+
263
+ // EN Inputs
264
+ titleEN = await question('Blog Title (EN): ');
265
+ descriptionEN = await question('Short Description (EN): ');
266
+ const contentEN = await question('Main Content/Features (EN): ');
267
+ introEN = `Release version ${newVersion} is here.`; // Fallback for manual
268
+ featureListEN = contentEN;
269
+
270
+ // Set defaults if empty
271
+ if (!titleID) titleID = `Update v${newVersion}`;
272
+ if (!descriptionID) descriptionID = `Pembaruan versi ${newVersion}`;
273
+ if (!featureListID) featureListID = '* Pembaruan rutin';
274
+
275
+ if (!titleEN) titleEN = `Update v${newVersion}`;
276
+ if (!descriptionEN) descriptionEN = `Update version ${newVersion}`;
277
+ if (!featureListEN) featureListEN = '* Routine updates';
222
278
  }
223
279
 
224
280
  blogTitleEN = titleEN; // Save for commit message
@@ -232,52 +288,72 @@ async function main() {
232
288
 
233
289
  // Indonesian Blog Content
234
290
  const idContent = `---
235
- title: "Rilis v${newVersion}"
291
+ title: "Rilis Lapeh v${newVersion}: ${titleID}"
236
292
  date: ${date}
237
293
  author: Tim Lapeh
238
294
  description: "${descriptionID.replace(/"/g, '\\"')}"
239
295
  ---
240
296
 
241
- # Rilis v${newVersion}
297
+ # Rilis Lapeh v${newVersion}: ${titleID}
242
298
 
243
- ${descriptionID}
299
+ Ditulis pada **${dateString}** oleh **Tim Lapeh**
244
300
 
245
- ## Rincian Perubahan šŸ“
301
+ ${introID}
302
+
303
+ ## Apa yang Baru? šŸš€
246
304
 
247
305
  ${featureListID}
248
306
 
249
- ## Cara Update
307
+ ## Cara Upgrade
308
+
309
+ Bagi pengguna baru, cukup jalankan:
310
+
311
+ \`\`\`bash
312
+ npx lapeh init my-project
313
+ \`\`\`
314
+
315
+ Bagi pengguna lama yang ingin update ke versi terbaru:
250
316
 
251
317
  \`\`\`bash
252
318
  npm install lapeh@latest
253
319
  \`\`\`
254
320
 
255
- Terima kasih telah menggunakan Lapeh Framework!
321
+ Terima kasih telah menjadi bagian dari perjalanan Lapeh Framework!
256
322
  `;
257
323
 
258
324
  // English Blog Content
259
325
  const enContent = `---
260
- title: "Release v${newVersion}"
326
+ title: "Release Lapeh v${newVersion}: ${titleEN}"
261
327
  date: ${date}
262
328
  author: Lapeh Team
263
329
  description: "${descriptionEN.replace(/"/g, '\\"')}"
264
330
  ---
265
331
 
266
- # Release v${newVersion}
332
+ # Release Lapeh v${newVersion}: ${titleEN}
333
+
334
+ Written on **${dateStringEn}** by **Lapeh Team**
267
335
 
268
- ${descriptionEN}
336
+ ${introEN}
269
337
 
270
- ## Change Details šŸ“
338
+ ## What's New? šŸš€
271
339
 
272
340
  ${featureListEN}
273
341
 
274
- ## How to Update
342
+ ## How to Upgrade
343
+
344
+ For new users, simply run:
345
+
346
+ \`\`\`bash
347
+ npx lapeh init my-project
348
+ \`\`\`
349
+
350
+ For existing users who want to update to the latest version:
275
351
 
276
352
  \`\`\`bash
277
353
  npm install lapeh@latest
278
354
  \`\`\`
279
355
 
280
- Thank you for using Lapeh Framework!
356
+ Thank you for being part of the Lapeh Framework journey!
281
357
  `;
282
358
 
283
359
  fs.writeFileSync(path.join(websiteDir, 'blog', blogFileName), idContent);