@ereactthohir/cli 1.3.0 → 1.5.0

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.
@@ -5,6 +5,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.makeController = makeController;
7
7
  exports.makeModel = makeModel;
8
+ exports.makeFactory = makeFactory;
9
+ exports.makeException = makeException;
10
+ exports.makeValidator = makeValidator;
8
11
  exports.makeService = makeService;
9
12
  exports.makeScreen = makeScreen;
10
13
  exports.makeComponent = makeComponent;
@@ -14,6 +17,16 @@ exports.makeProvider = makeProvider;
14
17
  exports.makeMiddleware = makeMiddleware;
15
18
  exports.makeJob = makeJob;
16
19
  exports.makePolicy = makePolicy;
20
+ exports.makeTest = makeTest;
21
+ exports.makeMail = makeMail;
22
+ exports.makeNotification = makeNotification;
23
+ exports.makeCommand = makeCommand;
24
+ exports.makeResource = makeResource;
25
+ exports.makeEvent = makeEvent;
26
+ exports.makeListener = makeListener;
27
+ exports.makeCRUD = makeCRUD;
28
+ exports.makeAIDriver = makeAIDriver;
29
+ exports.makePaymentProvider = makePaymentProvider;
17
30
  const fs_extra_1 = __importDefault(require("fs-extra"));
18
31
  const path_1 = __importDefault(require("path"));
19
32
  const chalk_1 = __importDefault(require("chalk"));
@@ -36,211 +49,178 @@ async function generateFile(type, name, template, folder) {
36
49
  await fs_extra_1.default.writeFile(targetPath, template);
37
50
  spinner.succeed(chalk_1.default.green(`${type} created: ${path_1.default.relative(projectRoot, targetPath)}`));
38
51
  }
39
- async function makeController(name) {
40
- const template = `import { Controller } from '@ereactthohir/core';
41
-
42
- /**
43
- * ${name} Controller
44
- *
45
- * RESTful API endpoints for ${name} resource
46
- */
47
- export default class ${name} extends Controller {
52
+ /**
53
+ * Enhanced Controller Generator
54
+ */
55
+ async function makeController(name, options = {}) {
56
+ let methods = '';
57
+ if (options.resource) {
58
+ methods = `
48
59
  /**
49
- * Display all resources
50
- * GET /${name.toLowerCase()}
60
+ * Display a listing of the resource.
51
61
  */
52
62
  public async index(req: any, res: any) {
53
- try {
54
- // const items = await YourModel.paginate(15);
55
- return res.json({
56
- message: 'Resources retrieved successfully',
57
- data: [],
58
- meta: { page: 1, total: 0 }
59
- });
60
- } catch (error) {
61
- return res.status(500).json({ error: 'Failed to fetch resources' });
62
- }
63
+ return res.json({ message: 'Index of ${name}' });
63
64
  }
64
65
 
65
66
  /**
66
- * Store a new resource
67
- * POST /${name.toLowerCase()}
67
+ * Show the form for creating a new resource.
68
68
  */
69
- public async store(req: any, res: any) {
70
- try {
71
- // Validate input
72
- // const validated = await req.validate({
73
- // name: 'required|string|max:255',
74
- // email: 'required|email|unique:users'
75
- // });
69
+ public async create(req: any, res: any) {
70
+ return res.json({ message: 'Create form for ${name}' });
71
+ }
76
72
 
77
- // const item = await YourModel.create(validated);
78
- return res.status(201).json({
79
- message: 'Resource created successfully',
80
- data: {}
81
- });
82
- } catch (error) {
83
- return res.status(422).json({ error: 'Validation failed' });
84
- }
73
+ /**
74
+ * Store a newly created resource in storage.
75
+ */
76
+ public async store(req: any, res: any) {
77
+ return res.send('Stored ${name}');
85
78
  }
86
79
 
87
80
  /**
88
- * Display a specific resource
89
- * GET /${name.toLowerCase()}/:id
81
+ * Display the specified resource.
90
82
  */
91
83
  public async show(req: any, res: any) {
92
- try {
93
- // const item = await YourModel.findOrFail(req.param('id'));
94
- return res.json({ data: {} });
95
- } catch (error) {
96
- return res.status(404).json({ error: 'Resource not found' });
97
- }
84
+ return res.json({ message: 'Showing ${name} ID: ' + req.params.id });
85
+ }
86
+
87
+ /**
88
+ * Show the form for editing the specified resource.
89
+ */
90
+ public async edit(req: any, res: any) {
91
+ return res.json({ message: 'Editing ${name} ID: ' + req.params.id });
98
92
  }
99
93
 
100
94
  /**
101
- * Update a resource
102
- * PUT /${name.toLowerCase()}/:id
95
+ * Update the specified resource in storage.
103
96
  */
104
97
  public async update(req: any, res: any) {
105
- try {
106
- // const validated = await req.validate({ ... });
107
- // const item = await YourModel.findOrFail(req.param('id'));
108
- // await item.update(validated);
109
- return res.json({
110
- message: 'Resource updated successfully',
111
- data: {}
112
- });
113
- } catch (error) {
114
- return res.status(422).json({ error: 'Update failed' });
115
- }
98
+ return res.send('Updated ${name}');
116
99
  }
117
100
 
118
101
  /**
119
- * Delete a resource
120
- * DELETE /${name.toLowerCase()}/:id
102
+ * Remove the specified resource from storage.
121
103
  */
122
104
  public async destroy(req: any, res: any) {
123
- try {
124
- // const item = await YourModel.findOrFail(req.param('id'));
125
- // await item.delete();
126
- return res.json({ message: 'Resource deleted successfully' });
127
- } catch (error) {
128
- return res.status(404).json({ error: 'Resource not found' });
129
- }
105
+ return res.send('Deleted ${name}');
106
+ }
107
+ `;
108
+ }
109
+ else if (options.api) {
110
+ methods = `
111
+ public async index(req: any, res: any) {
112
+ return res.json({ data: [] });
113
+ }
114
+
115
+ public async store(req: any, res: any) {
116
+ return res.status(201).json({ message: 'Created' });
130
117
  }
118
+
119
+ public async show(req: any, res: any) {
120
+ return res.json({ data: {} });
121
+ }
122
+
123
+ public async update(req: any, res: any) {
124
+ return res.json({ message: 'Updated' });
125
+ }
126
+
127
+ public async destroy(req: any, res: any) {
128
+ return res.status(204).send();
129
+ }
130
+ `;
131
+ }
132
+ const template = `import { Controller } from '@ereactthohir/core';
133
+ ${options.model ? `import ${options.model} from '../Models/${options.model}';` : ''}
134
+
135
+ /**
136
+ * ${name} Controller
137
+ */
138
+ export default class ${name} extends Controller {
139
+ ${methods || ` public async index(req: any, res: any) {
140
+ return res.json({ message: 'Hello from ${name} Controller' });
141
+ }`}
131
142
  }
132
143
  `;
133
144
  await generateFile('Controller', name, template, 'app/Controllers');
145
+ if (options.model && !fs_extra_1.default.existsSync(path_1.default.join(process.cwd(), 'app/Models', `${options.model}.ts`))) {
146
+ await makeModel(options.model);
147
+ }
134
148
  }
135
- async function makeModel(name) {
149
+ /**
150
+ * Enhanced Model Generator
151
+ */
152
+ async function makeModel(name, options = {}) {
136
153
  const template = `import { Model } from '@ereactthohir/core';
137
154
 
138
155
  /**
139
156
  * ${name} Model
140
- *
141
- * @example
142
- * const ${name.toLowerCase()} = await ${name}.find(1);
143
- * const all = await ${name}.all();
144
157
  */
145
158
  export default class ${name} extends Model {
146
- /**
147
- * The table associated with the model.
148
- */
149
159
  static table = '${name.toLowerCase()}s';
150
-
151
- /**
152
- * The attributes that are mass assignable.
153
- */
154
160
  protected fillable = [];
161
+ }
162
+ `;
163
+ await generateFile('Model', name, template, 'app/Models');
164
+ if (options.migration) {
165
+ await makeMigration(`create_${name.toLowerCase()}s_table`);
166
+ }
167
+ if (options.controller) {
168
+ await makeController(`${name}Controller`, { model: name });
169
+ }
170
+ if (options.factory) {
171
+ await makeFactory(name);
172
+ }
173
+ }
174
+ async function makeFactory(name) {
175
+ const template = `import { Factory } from '@ereactthohir/core';
155
176
 
156
- /**
157
- * The attributes that should be cast.
158
- */
159
- protected casts: Record<string, string> = {
160
- created_at: 'datetime',
161
- updated_at: 'datetime'
162
- };
163
-
164
- /**
165
- * Model properties
166
- */
167
- public id!: number;
168
- public created_at!: Date;
169
- public updated_at!: Date;
170
-
171
- /**
172
- * Relationships
173
- */
174
- // public relatedModel() {
175
- // return this.belongsTo(RelatedModel, 'related_id');
176
- // }
177
-
178
- /**
179
- * Query Scopes
180
- */
181
- // public scopeActive(query: any) {
182
- // return query.where('active', true);
183
- // }
177
+ export default class ${name}Factory extends Factory {
178
+ public definition(): Record<string, any> {
179
+ return {
180
+ // name: this.faker.person.fullName(),
181
+ // email: this.faker.internet.email(),
182
+ };
183
+ }
184
+ }
185
+ `;
186
+ await generateFile('Factory', `${name}Factory`, template, 'database/factories');
187
+ }
188
+ async function makeException(name) {
189
+ const template = `export default class ${name} extends Error {
190
+ constructor(message: string, public status: number = 500) {
191
+ super(message);
192
+ this.name = '${name}';
193
+ }
194
+ }
195
+ `;
196
+ await generateFile('Exception', name, template, 'app/Exceptions');
197
+ }
198
+ async function makeValidator(name) {
199
+ const template = `export default class ${name} {
200
+ public rules() {
201
+ return {
202
+ // 'title': 'required|min:5',
203
+ };
204
+ }
184
205
 
185
- /**
186
- * Accessors & Mutators
187
- */
188
- // public getFullNameAttribute(): string {
189
- // return \`\${this.first_name} \${this.last_name}\`;
190
- // }
206
+ public messages() {
207
+ return {
208
+ // 'title.required': 'Judul wajib diisi',
209
+ };
210
+ }
191
211
  }
192
212
  `;
193
- await generateFile('Model', name, template, 'app/Models');
213
+ await generateFile('Validator', name, template, 'app/Validators');
194
214
  }
195
215
  async function makeService(name) {
196
216
  const template = `import { Service } from '@ereactthohir/core';
197
217
 
198
218
  /**
199
219
  * ${name} Service
200
- *
201
- * Business logic service for ${name} domain
202
- *
203
- * @example
204
- * const service = new ${name}();
205
- * const result = await service.execute(params);
206
220
  */
207
221
  export default class ${name} extends Service {
208
- /**
209
- * Constructor
210
- * Initialize service dependencies
211
- */
212
- constructor() {
213
- super();
214
- }
215
-
216
- /**
217
- * Execute the service logic
218
- *
219
- * @param params Service parameters
220
- * @returns Service result
221
- */
222
- public async execute(params?: Record<string, any>) {
223
- try {
224
- // Implement your business logic here
225
- console.log('Executing ${name} service with params:', params);
226
-
227
- return {
228
- success: true,
229
- message: '${name} service executed successfully',
230
- data: null
231
- };
232
- } catch (error) {
233
- console.error('${name} service error:', error);
234
- throw error;
235
- }
236
- }
237
-
238
- /**
239
- * Validate input parameters
240
- */
241
- protected validate(params: Record<string, any>): boolean {
242
- // Add validation logic
243
- return true;
222
+ public async execute() {
223
+ // Business logic here
244
224
  }
245
225
  }
246
226
  `;
@@ -249,13 +229,11 @@ export default class ${name} extends Service {
249
229
  async function makeScreen(name) {
250
230
  const template = `import React from 'react';
251
231
  import { View, Text } from 'react-native';
252
- import { Button } from '@ereactthohir/rice-ui';
253
232
 
254
233
  export default function ${name}() {
255
234
  return (
256
- <View className="flex-1 items-center justify-center bg-white">
257
- <Text className="text-2xl font-bold">${name} Screen</Text>
258
- <Button label="Click Me" onClick={() => console.log('Hello')} />
235
+ <View className="flex-1 items-center justify-center">
236
+ <Text>${name} Screen</Text>
259
237
  </View>
260
238
  );
261
239
  }
@@ -265,44 +243,9 @@ export default function ${name}() {
265
243
  async function makeComponent(name) {
266
244
  const template = `import React from 'react';
267
245
 
268
- /**
269
- * ${name} Component
270
- *
271
- * @example
272
- * <${name} title="Hello" onClick={() => console.log('clicked')} />
273
- */
274
- interface ${name}Props {
275
- /**
276
- * Title text to display
277
- */
278
- title?: string;
279
-
280
- /**
281
- * Optional CSS class
282
- */
283
- className?: string;
284
-
285
- /**
286
- * Click handler
287
- */
288
- onClick?: () => void;
289
- }
290
-
291
- export const ${name}: React.FC<${name}Props> = ({
292
- title = '${name}',
293
- className = '',
294
- onClick
295
- }) => {
246
+ export const ${name} = () => {
296
247
  return (
297
- <div
298
- className={\`p-4 border border-gray-200 rounded-lg shadow-sm hover:shadow-md transition cursor-pointer \${className}\`}
299
- onClick={onClick}
300
- >
301
- <h3 className="text-lg font-semibold text-gray-900 mb-2">{title}</h3>
302
- <p className="text-gray-600 text-sm">
303
- This is a ${name} component. Customize its content as needed.
304
- </p>
305
- </div>
248
+ <div>${name} Component</div>
306
249
  );
307
250
  };
308
251
 
@@ -314,36 +257,16 @@ async function makeMigration(name) {
314
257
  const timestamp = new Date().getTime();
315
258
  const template = `import { Schema } from '@ereactthohir/core';
316
259
 
317
- /**
318
- * Migration: ${name}
319
- *
320
- * Description: Create or modify database table for ${name}
321
- */
322
260
  export default class ${name} {
323
- /**
324
- * Run the migration
325
- *
326
- * Called when migration is executed
327
- */
328
261
  public async up() {
329
- // Example table creation
330
- // await Schema.create('table_name', (table) => {
331
- // table.increments('id');
332
- // table.string('name').notNullable();
333
- // table.string('email').unique();
334
- // table.text('description').nullable();
335
- // table.boolean('active').defaultTo(true);
336
- // table.timestamps();
337
- // });
262
+ await Schema.create('${name.split('_')[1] || 'table'}', (table) => {
263
+ table.increments('id');
264
+ table.timestamps();
265
+ });
338
266
  }
339
267
 
340
- /**
341
- * Rollback the migration
342
- *
343
- * Called when migration is rolled back
344
- */
345
268
  public async down() {
346
- // await Schema.dropIfExists('table_name');
269
+ await Schema.dropIfExists('${name.split('_')[1] || 'table'}');
347
270
  }
348
271
  }
349
272
  `;
@@ -354,7 +277,7 @@ async function makeSeeder(name) {
354
277
 
355
278
  export default class ${name} extends Seeder {
356
279
  public async run() {
357
- // Logic to seed database
280
+ // Seed logic
358
281
  }
359
282
  }
360
283
  `;
@@ -364,57 +287,16 @@ async function makeProvider(name) {
364
287
  const template = `import { ServiceProvider } from '@ereactthohir/core';
365
288
 
366
289
  export default class ${name} extends ServiceProvider {
367
- public register() {
368
- // Register bindings
369
- }
370
-
371
- public boot() {
372
- // Boot logic
373
- }
290
+ public register() {}
291
+ public boot() {}
374
292
  }
375
293
  `;
376
294
  await generateFile('Provider', name, template, 'app/Providers');
377
295
  }
378
296
  async function makeMiddleware(name) {
379
- const template = `/**
380
- * ${name} Middleware
381
- *
382
- * Used for filtering requests and performing actions before reaching controller
383
- *
384
- * @example
385
- * Route.middleware([${name}]).group(() => {
386
- * Route.get('/protected', 'ProtectedController@show');
387
- * });
388
- */
389
- export default class ${name} {
390
- /**
391
- * Handle the request
392
- *
393
- * @param req Request object
394
- * @param res Response object
395
- * @param next Next middleware function
396
- */
397
- public async handle(
398
- req: any,
399
- res: any,
400
- next: () => Promise<any>
401
- ): Promise<any> {
402
- // Pre-request logic
403
- console.log('${name} middleware - Before:', req.method, req.path);
404
-
405
- try {
406
- // Call next middleware or controller
407
- const result = await next();
408
-
409
- // Post-request logic
410
- console.log('${name} middleware - After: Request completed');
411
-
412
- return result;
413
- } catch (error) {
414
- // Error handling
415
- console.error('${name} middleware - Error:', error);
416
- throw error;
417
- }
297
+ const template = `export default class ${name} {
298
+ public async handle(req: any, res: any, next: any) {
299
+ return await next();
418
300
  }
419
301
  }
420
302
  `;
@@ -423,7 +305,7 @@ export default class ${name} {
423
305
  async function makeJob(name) {
424
306
  const template = `export default class ${name} {
425
307
  public async handle() {
426
- // Job logic
308
+ // Background job logic
427
309
  }
428
310
  }
429
311
  `;
@@ -431,11 +313,195 @@ async function makeJob(name) {
431
313
  }
432
314
  async function makePolicy(name) {
433
315
  const template = `export default class ${name} {
434
- public view(user: any, model: any) {
435
- return true;
436
- }
316
+ public view() { return true; }
437
317
  }
438
318
  `;
439
319
  await generateFile('Policy', name, template, 'app/Policies');
440
320
  }
321
+ async function makeTest(name) {
322
+ const template = `import { describe, it, expect } from 'vitest';
323
+
324
+ describe('${name}', () => {
325
+ it('works', () => {
326
+ expect(true).toBe(true);
327
+ });
328
+ });
329
+ `;
330
+ await generateFile('Test', name, template, 'tests');
331
+ }
332
+ async function makeMail(name) {
333
+ const template = `export default class ${name} {
334
+ public build() {
335
+ return { subject: '${name}', view: 'emails.${name.toLowerCase()}' };
336
+ }
337
+ }
338
+ `;
339
+ await generateFile('Mail', name, template, 'app/Mail');
340
+ }
341
+ async function makeNotification(name) {
342
+ const template = `export default class ${name} {
343
+ public via() { return ['mail']; }
344
+ }
345
+ `;
346
+ await generateFile('Notification', name, template, 'app/Notifications');
347
+ }
348
+ async function makeCommand(name) {
349
+ const template = `import { Command } from '@ereactthohir/core';
350
+
351
+ export default class ${name} extends Command {
352
+ static signature = '${name.toLowerCase()}';
353
+ public async handle() {
354
+ this.info('Running ${name}');
355
+ }
356
+ }
357
+ `;
358
+ await generateFile('Command', name, template, 'app/Commands');
359
+ }
360
+ async function makeResource(name) {
361
+ const template = `import { Resource } from '@ereactthohir/core';
362
+
363
+ export default class ${name} extends Resource {
364
+ public toArray() {
365
+ return { ...this.resource };
366
+ }
367
+ }
368
+ `;
369
+ await generateFile('Resource', name, template, 'app/Resources');
370
+ }
371
+ async function makeEvent(name) {
372
+ const template = `export default class ${name} {
373
+ constructor(public data: any) {}
374
+ }
375
+ `;
376
+ await generateFile('Event', name, template, 'app/Events');
377
+ }
378
+ async function makeListener(name) {
379
+ const template = `export default class ${name} {
380
+ public async handle(event: any) {
381
+ // Handle event logic
382
+ }
383
+ }
384
+ `;
385
+ await generateFile('Listener', name, template, 'app/Listeners');
386
+ }
387
+ /**
388
+ * Create a full CRUD structure (Model, Migration, Controller, Factory, Page)
389
+ */
390
+ async function makeCRUD(name) {
391
+ const spinner = (0, ora_1.default)(chalk_1.default.cyan(`Building Powerful CRUD for ${name}...`)).start();
392
+ try {
393
+ // 1. Create Model with Migration, Controller, and Factory
394
+ await makeModel(name, {
395
+ migration: true,
396
+ controller: true,
397
+ factory: true
398
+ });
399
+ // 2. Create a standard Resource Page
400
+ const pageTemplate = `import React from 'react';
401
+
402
+ export default function ${name}Page() {
403
+ return (
404
+ <div className="p-8 max-w-7xl mx-auto">
405
+ <div className="flex justify-between items-center mb-8">
406
+ <h1 className="text-3xl font-black">${name} Management</h1>
407
+ <button className="px-5 py-2.5 bg-slate-900 text-white rounded-xl font-bold shadow-lg hover:scale-105 transition-all">
408
+ + Create ${name}
409
+ </button>
410
+ </div>
411
+
412
+ <div className="bg-white border border-slate-200 rounded-3xl overflow-hidden shadow-sm">
413
+ <table className="w-full text-left">
414
+ <thead className="bg-slate-50 border-b border-slate-100">
415
+ <tr>
416
+ <th className="px-6 py-4 font-bold text-slate-500 text-xs uppercase tracking-wider">ID</th>
417
+ <th className="px-6 py-4 font-bold text-slate-500 text-xs uppercase tracking-wider">NAME</th>
418
+ <th className="px-6 py-4 font-bold text-slate-500 text-xs uppercase tracking-wider">STATUS</th>
419
+ <th className="px-6 py-4 font-bold text-slate-500 text-xs uppercase tracking-wider">ACTIONS</th>
420
+ </tr>
421
+ </thead>
422
+ <tbody className="divide-y divide-slate-100">
423
+ <tr>
424
+ <td className="px-6 py-4 font-medium">#1</td>
425
+ <td className="px-6 py-4 font-medium">Sample ${name}</td>
426
+ <td className="px-6 py-4">
427
+ <span className="px-3 py-1 bg-green-100 text-green-700 rounded-full text-[10px] font-black tracking-wide">ACTIVE</span>
428
+ </td>
429
+ <td className="px-6 py-4 flex gap-3">
430
+ <button className="text-slate-400 hover:text-slate-900 transition-colors">Edit</button>
431
+ <button className="text-red-400 hover:text-red-700 transition-colors">Delete</button>
432
+ </td>
433
+ </tr>
434
+ </tbody>
435
+ </table>
436
+ </div>
437
+ </div>
438
+ );
439
+ }
440
+ `;
441
+ await generateFile('Page', `${name}Page`, pageTemplate, 'resources/pages');
442
+ spinner.succeed(chalk_1.default.green(`Successfully generated full CRUD suite for ${name}!`));
443
+ console.log(chalk_1.default.blue(`\nNext steps:`));
444
+ console.log(chalk_1.default.white(` 1. Run migrations: `) + chalk_1.default.yellow(`ereact migrate`));
445
+ console.log(chalk_1.default.white(` 2. Register route in routes/web.ts: `) + chalk_1.default.cyan(`Route.get('/${name.toLowerCase()}', (req, res) => res.view('${name}Page'))`));
446
+ }
447
+ catch (error) {
448
+ spinner.fail(chalk_1.default.red('Failed to generate CRUD suite.'));
449
+ }
450
+ }
451
+ /**
452
+ * AI Driver Generator
453
+ */
454
+ async function makeAIDriver(name) {
455
+ const template = `import { AiDriver } from '@ereactthohir/core';
456
+
457
+ /**
458
+ * ${name} AI Driver
459
+ */
460
+ export default class ${name}Driver extends AiDriver {
461
+ /**
462
+ * Complete a prompt using ${name}
463
+ */
464
+ public async prompt(text: string, options: any = {}): Promise<string> {
465
+ // Implementation for ${name} API call
466
+ return "Response from ${name}";
467
+ }
468
+
469
+ /**
470
+ * Generate an image using ${name}
471
+ */
472
+ public async generateImage(prompt: string): Promise<string> {
473
+ return "url-to-generated-image";
474
+ }
475
+ }
476
+ `;
477
+ await generateFile('AI Driver', `${name}Driver`, template, 'app/Services/AI/Drivers');
478
+ }
479
+ /**
480
+ * Payment Provider Generator
481
+ */
482
+ async function makePaymentProvider(name) {
483
+ const template = `import { PaymentProvider } from '@ereactthohir/core';
484
+
485
+ /**
486
+ * ${name} Payment Provider
487
+ */
488
+ export default class ${name}Provider extends PaymentProvider {
489
+ /**
490
+ * Create a payment transaction
491
+ */
492
+ public async createTransaction(data: any): Promise<any> {
493
+ // Implementation for ${name} payment gateway
494
+ return { id: 'TRX_123', status: 'pending' };
495
+ }
496
+
497
+ /**
498
+ * Handle payment notification/webhook
499
+ */
500
+ public async handleNotification(payload: any): Promise<any> {
501
+ // Implementation for processing notifications
502
+ }
503
+ }
504
+ `;
505
+ await generateFile('Payment Provider', `${name}Provider`, template, 'app/Services/Payments/Providers');
506
+ }
441
507
  //# sourceMappingURL=generators.js.map