kontas-express 1.0.11 → 1.0.12

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.
Files changed (2) hide show
  1. package/dist/index.js +473 -57
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  // src/database/mongodb/repository.template.js
3
3
  var generateMongoRepository = (name, pluralName) => `import { ObjectId } from "mongodb"
4
- import { connectToDatabase, getDatabaseCollection } from "../../config"
4
+ import { db } from "../../config"
5
5
  import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema"
6
6
  import { ${name} } from "./${name.toLowerCase()}.schema"
7
7
 
@@ -18,27 +18,16 @@ type ${name}Response<T> = {
18
18
 
19
19
  export class ${name}Repository {
20
20
  private readonly collectionName = "${pluralName}"
21
- private collection: ReturnType<typeof getDatabaseCollection> | null = null
22
-
23
- private async getCollection() {
24
- if (!this.collection) {
25
- await connectToDatabase()
26
- this.collection = getDatabaseCollection(this.collectionName)
27
- }
28
- return this.collection
29
- }
30
21
 
31
22
  async create(data: Readonly<Create${name}>): Promise<${name}Response<${pluralName}>> {
32
23
  try {
33
- const collection = await this.getCollection()
34
-
35
24
  const doc = {
36
25
  ...data,
37
26
  createdAt: new Date(),
38
27
  updatedAt: new Date()
39
28
  } as const
40
29
 
41
- const result = await collection.insertOne(doc)
30
+ const result = await db.collection(this.collectionName).insertOne(doc)
42
31
  return {
43
32
  success: true,
44
33
  message: "${name} created successfully",
@@ -55,18 +44,25 @@ export class ${name}Repository {
55
44
  }
56
45
 
57
46
  async findAll(): Promise<${name}Response<${name}[]>> {
58
- const collection = await this.getCollection()
59
- const docs = await collection.find({}).toArray() as ${pluralName}[]
60
- return {
61
- success: true,
62
- value: docs.map(doc => new ${name}(doc))
47
+ try {
48
+ const docs = await db.collection(this.collectionName).find({}).toArray() as ${pluralName}[]
49
+ return {
50
+ success: true,
51
+ value: docs.map(doc => new ${name}(doc))
52
+ }
53
+ } catch (error) {
54
+ return {
55
+ success: false,
56
+ message: "Failed to find ${name.toLowerCase()}s",
57
+ error,
58
+ value: null
59
+ }
63
60
  }
64
61
  }
65
62
 
66
63
  async findById({ id }: Readonly<${name}Id>): Promise<${name}Response<${name} | null>> {
67
64
  try {
68
- const collection = await this.getCollection()
69
- const doc = await collection.findOne({ _id: new ObjectId(id) }) as ${pluralName} | null
65
+ const doc = await db.collection(this.collectionName).findOne({ _id: new ObjectId(id) }) as ${pluralName} | null
70
66
  return {
71
67
  success: true,
72
68
  value: doc ? new ${name}(doc) : null
@@ -83,9 +79,7 @@ export class ${name}Repository {
83
79
 
84
80
  async update({ id }: Readonly<${name}Id>, data: Readonly<Update${name}>): Promise<${name}Response<${pluralName} | null>> {
85
81
  try {
86
- const collection = await this.getCollection()
87
-
88
- const result = await collection.findOneAndUpdate(
82
+ const result = await db.collection(this.collectionName).findOneAndUpdate(
89
83
  { _id: new ObjectId(id) },
90
84
  {
91
85
  $set: {
@@ -112,29 +106,36 @@ export class ${name}Repository {
112
106
  }
113
107
 
114
108
  async delete({ id }: ${name}Id): Promise<${name}Response<${pluralName} | null>> {
115
- const collection = await this.getCollection()
116
-
117
- const doc = await collection.findOne({ _id: new ObjectId(id) })
118
- if (!doc) {
109
+ try {
110
+ const doc = await db.collection(this.collectionName).findOne({ _id: new ObjectId(id) })
111
+ if (!doc) {
112
+ return {
113
+ success: true,
114
+ message: "${name} not found",
115
+ value: null
116
+ }
117
+ }
118
+
119
+ await db.collection(this.collectionName).deleteOne({ _id: new ObjectId(id) })
119
120
  return {
120
121
  success: true,
121
- message: "${name} not found",
122
+ message: "${name} deleted successfully",
123
+ value: new ${name}(doc) as ${pluralName}
124
+ }
125
+ } catch (error) {
126
+ return {
127
+ success: false,
128
+ message: "Failed to delete ${name.toLowerCase()}",
129
+ error,
122
130
  value: null
123
131
  }
124
132
  }
125
-
126
- await collection.deleteOne({ _id: new ObjectId(id) })
127
- return {
128
- success: true,
129
- message: "${name} deleted successfully",
130
- value: new ${name}(doc) as ${pluralName}
131
- }
132
133
  }
133
134
  }
134
135
 
135
136
  export const ${name.toLowerCase()} = new ${name}Repository()`;
136
137
  // src/database/postgresql/repository.template.js
137
- var generatePostgresRepository = (name, pluralName) => `import { getPool } from "../../config"
138
+ var generatePostgresRepository = (name, pluralName) => `import { db } from "../../config"
138
139
  import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema"
139
140
  import { ${name} } from "./${name.toLowerCase()}.schema"
140
141
 
@@ -154,8 +155,6 @@ export class ${name}Repository {
154
155
 
155
156
  async create(data: Readonly<Create${name}>): Promise<${name}Response<${pluralName}>> {
156
157
  try {
157
- const pool = await getPool()
158
-
159
158
  const fields = Object.keys(data)
160
159
  const values = Object.values(data)
161
160
  const placeholders = values.map((_, i) => \`$\${i + 1}\`).join(', ')
@@ -167,7 +166,7 @@ export class ${name}Repository {
167
166
  RETURNING *
168
167
  \`
169
168
 
170
- const result = await pool.query(query, values)
169
+ const result = await db.query(query, values)
171
170
  return {
172
171
  success: true,
173
172
  message: "${name} created successfully",
@@ -185,12 +184,11 @@ export class ${name}Repository {
185
184
 
186
185
  async findAll(): Promise<${name}Response<${name}[]>> {
187
186
  try {
188
- const pool = await getPool()
189
- const result = await pool.query(\`SELECT * FROM \${this.tableName}\`)
187
+ const result = await db.query(\`SELECT * FROM \${this.tableName}\`)
190
188
 
191
189
  return {
192
190
  success: true,
193
- value: result.rows.map(row => new ${name}(row))
191
+ value: result.rows.map((row: ${pluralName}) => new ${name}(row))
194
192
  }
195
193
  } catch (error) {
196
194
  return {
@@ -204,8 +202,7 @@ export class ${name}Repository {
204
202
 
205
203
  async findById({ id }: Readonly<${name}Id>): Promise<${name}Response<${name} | null>> {
206
204
  try {
207
- const pool = await getPool()
208
- const result = await pool.query(
205
+ const result = await db.query(
209
206
  \`SELECT * FROM \${this.tableName} WHERE id = $1\`,
210
207
  [id]
211
208
  )
@@ -226,8 +223,6 @@ export class ${name}Repository {
226
223
 
227
224
  async update({ id }: Readonly<${name}Id>, data: Readonly<Update${name}>): Promise<${name}Response<${pluralName} | null>> {
228
225
  try {
229
- const pool = await getPool()
230
-
231
226
  const fields = Object.keys(data)
232
227
  const values = Object.values(data)
233
228
  const setClause = fields
@@ -241,7 +236,7 @@ export class ${name}Repository {
241
236
  RETURNING *
242
237
  \`
243
238
 
244
- const result = await pool.query(query, [...values, id])
239
+ const result = await db.query(query, [...values, id])
245
240
 
246
241
  return {
247
242
  success: true,
@@ -260,9 +255,7 @@ export class ${name}Repository {
260
255
 
261
256
  async delete({ id }: ${name}Id): Promise<${name}Response<${pluralName} | null>> {
262
257
  try {
263
- const pool = await getPool()
264
-
265
- const result = await pool.query(
258
+ const result = await db.query(
266
259
  \`DELETE FROM \${this.tableName} WHERE id = $1 RETURNING *\`,
267
260
  [id]
268
261
  )
@@ -297,12 +290,10 @@ var generatePostgresMigration = (name, pluralName, fields) => {
297
290
  return ` ${field.name} ${pgType}`;
298
291
  }).join(`,
299
292
  `);
300
- return `import { getPool } from "../../config"
293
+ return `import { db } from "../../config"
301
294
 
302
295
  export async function up() {
303
- const pool = await getPool()
304
-
305
- await pool.query(\`
296
+ await db.query(\`
306
297
  CREATE TABLE IF NOT EXISTS ${pluralName.toLowerCase()} (
307
298
  id SERIAL PRIMARY KEY,
308
299
  ${columns},
@@ -315,9 +306,430 @@ ${columns},
315
306
  }
316
307
 
317
308
  export async function down() {
318
- const pool = await getPool()
309
+ await db.query(\`
310
+ DROP TABLE IF EXISTS ${pluralName.toLowerCase()}
311
+ \`)
312
+
313
+ console.log('\u2705 Migration ${name} dropped successfully')
314
+ }
315
+
316
+ // Jalankan migration
317
+ if (process.argv[2] === 'up') {
318
+ up()
319
+ .catch(console.error)
320
+ .finally(() => process.exit())
321
+ }
322
+
323
+ if (process.argv[2] === 'down') {
324
+ down()
325
+ .catch(console.error)
326
+ .finally(() => process.exit())
327
+ }`;
328
+ };
329
+ // src/database/mariadb/repository.template.js
330
+ var generateMariadbRepository = (name, pluralName) => `import { db } from "../../config"
331
+ import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema"
332
+ import { ${name} } from "./${name.toLowerCase()}.schema"
333
+
334
+ type ${name}Response<T> = {
335
+ success: true
336
+ message?: string
337
+ value: T
338
+ } | {
339
+ success: false
340
+ message: string
341
+ error: unknown
342
+ value: null
343
+ }
344
+
345
+ export class ${name}Repository {
346
+ private readonly tableName = "${pluralName.toLowerCase()}"
347
+
348
+ async create(data: Readonly<Create${name}>): Promise<${name}Response<${pluralName}>> {
349
+ try {
350
+ const fields = Object.keys(data)
351
+ const values = Object.values(data)
352
+ const placeholders = values.map(() => '?').join(', ')
353
+
354
+ const query = \`
355
+ INSERT INTO \${this.tableName}
356
+ (\${fields.join(', ')}, created_at, updated_at)
357
+ VALUES (\${placeholders}, NOW(), NOW())
358
+ \`
359
+
360
+ const result = await db.query(query, values)
361
+ const [newData] = await db.query(
362
+ \`SELECT * FROM \${this.tableName} WHERE id = ?\`,
363
+ [result.insertId]
364
+ )
365
+
366
+ return {
367
+ success: true,
368
+ message: "${name} created successfully",
369
+ value: new ${name}(newData) as ${pluralName}
370
+ }
371
+ } catch (error) {
372
+ return {
373
+ success: false,
374
+ message: "Failed to create ${name.toLowerCase()}",
375
+ error,
376
+ value: null
377
+ }
378
+ }
379
+ }
380
+
381
+ async findAll(): Promise<${name}Response<${name}[]>> {
382
+ try {
383
+ const result = await db.query(\`SELECT * FROM \${this.tableName}\`)
384
+
385
+ return {
386
+ success: true,
387
+ value: result.map((row: ${pluralName}) => new ${name}(row))
388
+ }
389
+ } catch (error) {
390
+ return {
391
+ success: false,
392
+ message: "Failed to fetch ${pluralName.toLowerCase()}",
393
+ error,
394
+ value: null
395
+ }
396
+ }
397
+ }
398
+
399
+ async findById({ id }: Readonly<${name}Id>): Promise<${name}Response<${name} | null>> {
400
+ try {
401
+ const [result] = await db.query(
402
+ \`SELECT * FROM \${this.tableName} WHERE id = ?\`,
403
+ [id]
404
+ )
405
+
406
+ return {
407
+ success: true,
408
+ value: result ? new ${name}(result) : null
409
+ }
410
+ } catch (error) {
411
+ return {
412
+ success: false,
413
+ message: "Failed to find ${name.toLowerCase()}",
414
+ error,
415
+ value: null
416
+ }
417
+ }
418
+ }
419
+
420
+ async update({ id }: Readonly<${name}Id>, data: Readonly<Update${name}>): Promise<${name}Response<${pluralName} | null>> {
421
+ try {
422
+ const fields = Object.keys(data)
423
+ const values = Object.values(data)
424
+ const setClause = fields
425
+ .map(field => \`\${field} = ?\`)
426
+ .join(', ')
427
+
428
+ const query = \`
429
+ UPDATE \${this.tableName}
430
+ SET \${setClause}, updated_at = NOW()
431
+ WHERE id = ?
432
+ \`
433
+
434
+ await db.query(query, [...values, id])
435
+ const [updated] = await db.query(
436
+ \`SELECT * FROM \${this.tableName} WHERE id = ?\`,
437
+ [id]
438
+ )
439
+
440
+ return {
441
+ success: true,
442
+ message: updated ? "${name} updated successfully" : "${name} not found",
443
+ value: updated ? new ${name}(updated) as ${pluralName} : null
444
+ }
445
+ } catch (error) {
446
+ return {
447
+ success: false,
448
+ message: "Failed to update ${name.toLowerCase()}",
449
+ error,
450
+ value: null
451
+ }
452
+ }
453
+ }
454
+
455
+ async delete({ id }: ${name}Id): Promise<${name}Response<${pluralName} | null>> {
456
+ try {
457
+ const [existing] = await db.query(
458
+ \`SELECT * FROM \${this.tableName} WHERE id = ?\`,
459
+ [id]
460
+ )
461
+
462
+ if (!existing) {
463
+ return {
464
+ success: true,
465
+ message: "${name} not found",
466
+ value: null
467
+ }
468
+ }
469
+
470
+ await db.query(
471
+ \`DELETE FROM \${this.tableName} WHERE id = ?\`,
472
+ [id]
473
+ )
474
+
475
+ return {
476
+ success: true,
477
+ message: "${name} deleted successfully",
478
+ value: new ${name}(existing) as ${pluralName}
479
+ }
480
+ } catch (error) {
481
+ return {
482
+ success: false,
483
+ message: "Failed to delete ${name.toLowerCase()}",
484
+ error,
485
+ value: null
486
+ }
487
+ }
488
+ }
489
+ }
490
+
491
+ export const ${name.toLowerCase()} = new ${name}Repository()`;
492
+ // src/database/mariadb/migration.template.js
493
+ var generateMariadbMigration = (name, pluralName, fields) => {
494
+ const mariaTypes = {
495
+ string: "VARCHAR(255)",
496
+ number: "INT",
497
+ boolean: "BOOLEAN",
498
+ date: "DATETIME"
499
+ };
500
+ const columns = fields.map((field) => {
501
+ const mariaType = mariaTypes[field.type] || "VARCHAR(255)";
502
+ return ` ${field.name} ${mariaType}`;
503
+ }).join(`,
504
+ `);
505
+ return `import { db } from "../../config"
506
+
507
+ export async function up() {
508
+ await db.query(\`
509
+ CREATE TABLE IF NOT EXISTS ${pluralName.toLowerCase()} (
510
+ id INT AUTO_INCREMENT PRIMARY KEY,
511
+ ${columns},
512
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
513
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
514
+ )
515
+ \`)
516
+
517
+ console.log('\u2705 Migration ${name} created successfully')
518
+ }
519
+
520
+ export async function down() {
521
+ await db.query(\`
522
+ DROP TABLE IF EXISTS ${pluralName.toLowerCase()}
523
+ \`)
524
+
525
+ console.log('\u2705 Migration ${name} dropped successfully')
526
+ }
527
+
528
+ // Jalankan migration
529
+ if (process.argv[2] === 'up') {
530
+ up()
531
+ .catch(console.error)
532
+ .finally(() => process.exit())
533
+ }
534
+
535
+ if (process.argv[2] === 'down') {
536
+ down()
537
+ .catch(console.error)
538
+ .finally(() => process.exit())
539
+ }`;
540
+ };
541
+ // src/database/sqlite/repository.template.js
542
+ var generateSqliteRepository = (name, pluralName) => `import { db } from "../../config"
543
+ import type { Create${name}, Update${name}, ${pluralName}, ${name}Id } from "./${name.toLowerCase()}.schema"
544
+ import { ${name} } from "./${name.toLowerCase()}.schema"
545
+
546
+ type ${name}Response<T> = {
547
+ success: true
548
+ message?: string
549
+ value: T
550
+ } | {
551
+ success: false
552
+ message: string
553
+ error: unknown
554
+ value: null
555
+ }
556
+
557
+ export class ${name}Repository {
558
+ private readonly tableName = "${pluralName.toLowerCase()}"
559
+
560
+ async create(data: Readonly<Create${name}>): Promise<${name}Response<${pluralName}>> {
561
+ try {
562
+ const fields = Object.keys(data)
563
+ const values = Object.values(data)
564
+ const placeholders = values.map(() => '?').join(', ')
565
+
566
+ const query = \`
567
+ INSERT INTO \${this.tableName}
568
+ (\${fields.join(', ')}, created_at, updated_at)
569
+ VALUES (\${placeholders}, datetime('now'), datetime('now'))
570
+ \`
571
+
572
+ await db.query(query, values)
573
+ const result = await db.query(
574
+ \`SELECT * FROM \${this.tableName} WHERE id = last_insert_rowid()\`
575
+ )
576
+
577
+ return {
578
+ success: true,
579
+ message: "${name} created successfully",
580
+ value: new ${name}(result[0]) as ${pluralName}
581
+ }
582
+ } catch (error) {
583
+ return {
584
+ success: false,
585
+ message: "Failed to create ${name.toLowerCase()}",
586
+ error,
587
+ value: null
588
+ }
589
+ }
590
+ }
591
+
592
+ async findAll(): Promise<${name}Response<${name}[]>> {
593
+ try {
594
+ const result = await db.query(\`SELECT * FROM \${this.tableName}\`)
595
+
596
+ return {
597
+ success: true,
598
+ value: result.map((row: ${pluralName}) => new ${name}(row))
599
+ }
600
+ } catch (error) {
601
+ return {
602
+ success: false,
603
+ message: "Failed to fetch ${pluralName.toLowerCase()}",
604
+ error,
605
+ value: null
606
+ }
607
+ }
608
+ }
609
+
610
+ async findById({ id }: Readonly<${name}Id>): Promise<${name}Response<${name} | null>> {
611
+ try {
612
+ const result = await db.query(
613
+ \`SELECT * FROM \${this.tableName} WHERE id = ?\`,
614
+ [id]
615
+ )
616
+
617
+ return {
618
+ success: true,
619
+ value: result[0] ? new ${name}(result[0]) : null
620
+ }
621
+ } catch (error) {
622
+ return {
623
+ success: false,
624
+ message: "Failed to find ${name.toLowerCase()}",
625
+ error,
626
+ value: null
627
+ }
628
+ }
629
+ }
630
+
631
+ async update({ id }: Readonly<${name}Id>, data: Readonly<Update${name}>): Promise<${name}Response<${pluralName} | null>> {
632
+ try {
633
+ const fields = Object.keys(data)
634
+ const values = Object.values(data)
635
+ const setClause = fields
636
+ .map(field => \`\${field} = ?\`)
637
+ .join(', ')
638
+
639
+ const query = \`
640
+ UPDATE \${this.tableName}
641
+ SET \${setClause}, updated_at = datetime('now')
642
+ WHERE id = ?
643
+ \`
644
+
645
+ await db.query(query, [...values, id])
646
+ const result = await db.query(
647
+ \`SELECT * FROM \${this.tableName} WHERE id = ?\`,
648
+ [id]
649
+ )
650
+
651
+ return {
652
+ success: true,
653
+ message: result[0] ? "${name} updated successfully" : "${name} not found",
654
+ value: result[0] ? new ${name}(result[0]) as ${pluralName} : null
655
+ }
656
+ } catch (error) {
657
+ return {
658
+ success: false,
659
+ message: "Failed to update ${name.toLowerCase()}",
660
+ error,
661
+ value: null
662
+ }
663
+ }
664
+ }
319
665
 
320
- await pool.query(\`
666
+ async delete({ id }: ${name}Id): Promise<${name}Response<${pluralName} | null>> {
667
+ try {
668
+ const existing = await db.query(
669
+ \`SELECT * FROM \${this.tableName} WHERE id = ?\`,
670
+ [id]
671
+ )
672
+
673
+ if (!existing[0]) {
674
+ return {
675
+ success: true,
676
+ message: "${name} not found",
677
+ value: null
678
+ }
679
+ }
680
+
681
+ await db.query(
682
+ \`DELETE FROM \${this.tableName} WHERE id = ?\`,
683
+ [id]
684
+ )
685
+
686
+ return {
687
+ success: true,
688
+ message: "${name} deleted successfully",
689
+ value: new ${name}(existing[0]) as ${pluralName}
690
+ }
691
+ } catch (error) {
692
+ return {
693
+ success: false,
694
+ message: "Failed to delete ${name.toLowerCase()}",
695
+ error,
696
+ value: null
697
+ }
698
+ }
699
+ }
700
+ }
701
+
702
+ export const ${name.toLowerCase()} = new ${name}Repository()`;
703
+ // src/database/sqlite/migration.template.js
704
+ var generateSqliteMigration = (name, pluralName, fields) => {
705
+ const sqliteTypes = {
706
+ string: "TEXT",
707
+ number: "INTEGER",
708
+ boolean: "INTEGER",
709
+ date: "TEXT"
710
+ };
711
+ const columns = fields.map((field) => {
712
+ const sqliteType = sqliteTypes[field.type] || "TEXT";
713
+ return ` ${field.name} ${sqliteType}`;
714
+ }).join(`,
715
+ `);
716
+ return `import { db } from "../../config"
717
+
718
+ export async function up() {
719
+ await db.query(\`
720
+ CREATE TABLE IF NOT EXISTS ${pluralName.toLowerCase()} (
721
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
722
+ ${columns},
723
+ created_at TEXT DEFAULT (datetime('now')),
724
+ updated_at TEXT DEFAULT (datetime('now'))
725
+ )
726
+ \`)
727
+
728
+ console.log('\u2705 Migration ${name} created successfully')
729
+ }
730
+
731
+ export async function down() {
732
+ await db.query(\`
321
733
  DROP TABLE IF EXISTS ${pluralName.toLowerCase()}
322
734
  \`)
323
735
 
@@ -338,7 +750,11 @@ if (process.argv[2] === 'down') {
338
750
  }`;
339
751
  };
340
752
  export {
753
+ generateSqliteRepository,
754
+ generateSqliteMigration,
341
755
  generatePostgresRepository,
342
756
  generatePostgresMigration,
343
- generateMongoRepository
757
+ generateMongoRepository,
758
+ generateMariadbRepository,
759
+ generateMariadbMigration
344
760
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kontas-express",
3
- "version": "1.0.11",
3
+ "version": "1.0.12",
4
4
  "main": "dist/index.js",
5
5
  "scripts": {
6
6
  "build": "bun build ./index.js --outdir ./dist --target bun",