magector 1.0.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.
@@ -0,0 +1,672 @@
1
+ /**
2
+ * Generates synthetic Magento code for validation testing
3
+ */
4
+
5
+ export const MOCK_MODULES = [
6
+ 'Acme_Catalog',
7
+ 'Acme_Checkout',
8
+ 'Acme_Customer',
9
+ 'Acme_Sales',
10
+ 'Acme_Inventory'
11
+ ];
12
+
13
+ export function generateMockController(moduleName, controllerName, action = 'execute') {
14
+ const [vendor, module] = moduleName.split('_');
15
+ return {
16
+ path: `app/code/${vendor}/${module}/Controller/${controllerName}.php`,
17
+ content: `<?php
18
+ declare(strict_types=1);
19
+
20
+ namespace ${vendor}\\${module}\\Controller;
21
+
22
+ use Magento\\Framework\\App\\Action\\HttpGetActionInterface;
23
+ use Magento\\Framework\\Controller\\ResultFactory;
24
+ use Magento\\Framework\\View\\Result\\Page;
25
+
26
+ /**
27
+ * ${controllerName} controller action
28
+ */
29
+ class ${controllerName} implements HttpGetActionInterface
30
+ {
31
+ private ResultFactory \$resultFactory;
32
+
33
+ public function __construct(
34
+ ResultFactory \$resultFactory
35
+ ) {
36
+ \$this->resultFactory = \$resultFactory;
37
+ }
38
+
39
+ /**
40
+ * Execute action
41
+ * @return Page
42
+ */
43
+ public function ${action}(): Page
44
+ {
45
+ /** @var Page \$page */
46
+ \$page = \$this->resultFactory->create(ResultFactory::TYPE_PAGE);
47
+ return \$page;
48
+ }
49
+ }
50
+ `,
51
+ metadata: {
52
+ type: 'php',
53
+ magentoType: 'Controller',
54
+ module: moduleName,
55
+ className: controllerName,
56
+ methodName: action,
57
+ isController: true
58
+ }
59
+ };
60
+ }
61
+
62
+ export function generateMockModel(moduleName, modelName, tableName) {
63
+ const [vendor, module] = moduleName.split('_');
64
+ return {
65
+ path: `app/code/${vendor}/${module}/Model/${modelName}.php`,
66
+ content: `<?php
67
+ declare(strict_types=1);
68
+
69
+ namespace ${vendor}\\${module}\\Model;
70
+
71
+ use Magento\\Framework\\Model\\AbstractModel;
72
+ use ${vendor}\\${module}\\Model\\ResourceModel\\${modelName} as ResourceModel;
73
+
74
+ /**
75
+ * ${modelName} model
76
+ */
77
+ class ${modelName} extends AbstractModel
78
+ {
79
+ protected \$_eventPrefix = '${tableName}';
80
+
81
+ protected function _construct(): void
82
+ {
83
+ \$this->_init(ResourceModel::class);
84
+ }
85
+
86
+ protected function _beforeSave(): AbstractModel
87
+ {
88
+ // Custom before save logic
89
+ return parent::_beforeSave();
90
+ }
91
+
92
+ protected function _afterLoad(): AbstractModel
93
+ {
94
+ // Custom after load logic
95
+ return parent::_afterLoad();
96
+ }
97
+
98
+ public function getName(): ?string
99
+ {
100
+ return \$this->getData('name');
101
+ }
102
+
103
+ public function setName(string \$name): self
104
+ {
105
+ return \$this->setData('name', \$name);
106
+ }
107
+ }
108
+ `,
109
+ metadata: {
110
+ type: 'php',
111
+ magentoType: 'Model',
112
+ module: moduleName,
113
+ className: modelName,
114
+ isModel: true,
115
+ tableName
116
+ }
117
+ };
118
+ }
119
+
120
+ export function generateMockRepository(moduleName, entityName) {
121
+ const [vendor, module] = moduleName.split('_');
122
+ return {
123
+ path: `app/code/${vendor}/${module}/Model/${entityName}Repository.php`,
124
+ content: `<?php
125
+ declare(strict_types=1);
126
+
127
+ namespace ${vendor}\\${module}\\Model;
128
+
129
+ use ${vendor}\\${module}\\Api\\${entityName}RepositoryInterface;
130
+ use ${vendor}\\${module}\\Api\\Data\\${entityName}Interface;
131
+ use ${vendor}\\${module}\\Model\\ResourceModel\\${entityName} as ResourceModel;
132
+ use Magento\\Framework\\Api\\SearchCriteriaInterface;
133
+ use Magento\\Framework\\Api\\SearchResultsInterface;
134
+ use Magento\\Framework\\Exception\\CouldNotSaveException;
135
+ use Magento\\Framework\\Exception\\NoSuchEntityException;
136
+
137
+ /**
138
+ * ${entityName} repository implementation
139
+ */
140
+ class ${entityName}Repository implements ${entityName}RepositoryInterface
141
+ {
142
+ private ResourceModel \$resourceModel;
143
+ private ${entityName}Factory \$${entityName.toLowerCase()}Factory;
144
+
145
+ public function __construct(
146
+ ResourceModel \$resourceModel,
147
+ ${entityName}Factory \$${entityName.toLowerCase()}Factory
148
+ ) {
149
+ \$this->resourceModel = \$resourceModel;
150
+ \$this->${entityName.toLowerCase()}Factory = \$${entityName.toLowerCase()}Factory;
151
+ }
152
+
153
+ public function getById(int \$id): ${entityName}Interface
154
+ {
155
+ \$entity = \$this->${entityName.toLowerCase()}Factory->create();
156
+ \$this->resourceModel->load(\$entity, \$id);
157
+ if (!\$entity->getId()) {
158
+ throw new NoSuchEntityException(__('Entity with id "%1" does not exist.', \$id));
159
+ }
160
+ return \$entity;
161
+ }
162
+
163
+ public function save(${entityName}Interface \$entity): ${entityName}Interface
164
+ {
165
+ try {
166
+ \$this->resourceModel->save(\$entity);
167
+ } catch (\\Exception \$e) {
168
+ throw new CouldNotSaveException(__(\$e->getMessage()));
169
+ }
170
+ return \$entity;
171
+ }
172
+
173
+ public function delete(${entityName}Interface \$entity): bool
174
+ {
175
+ \$this->resourceModel->delete(\$entity);
176
+ return true;
177
+ }
178
+
179
+ public function deleteById(int \$id): bool
180
+ {
181
+ return \$this->delete(\$this->getById(\$id));
182
+ }
183
+
184
+ public function getList(SearchCriteriaInterface \$searchCriteria): SearchResultsInterface
185
+ {
186
+ // Implementation
187
+ }
188
+ }
189
+ `,
190
+ metadata: {
191
+ type: 'php',
192
+ magentoType: 'Repository',
193
+ module: moduleName,
194
+ className: `${entityName}Repository`,
195
+ isRepository: true,
196
+ repositoryMethods: ['getById', 'save', 'delete', 'deleteById', 'getList']
197
+ }
198
+ };
199
+ }
200
+
201
+ export function generateMockPlugin(moduleName, targetClass, targetMethod) {
202
+ const [vendor, module] = moduleName.split('_');
203
+ const pluginName = `${targetClass}${targetMethod.charAt(0).toUpperCase() + targetMethod.slice(1)}Plugin`;
204
+ return {
205
+ path: `app/code/${vendor}/${module}/Plugin/${pluginName}.php`,
206
+ content: `<?php
207
+ declare(strict_types=1);
208
+
209
+ namespace ${vendor}\\${module}\\Plugin;
210
+
211
+ use ${targetClass.includes('\\') ? targetClass : `Magento\\Framework\\${targetClass}`};
212
+
213
+ /**
214
+ * Plugin for ${targetClass}::${targetMethod}
215
+ */
216
+ class ${pluginName}
217
+ {
218
+ /**
219
+ * Before ${targetMethod}
220
+ */
221
+ public function before${targetMethod.charAt(0).toUpperCase() + targetMethod.slice(1)}(
222
+ ${targetClass.split('\\').pop()} \$subject,
223
+ ...\$args
224
+ ): array {
225
+ // Modify arguments before method execution
226
+ return \$args;
227
+ }
228
+
229
+ /**
230
+ * After ${targetMethod}
231
+ */
232
+ public function after${targetMethod.charAt(0).toUpperCase() + targetMethod.slice(1)}(
233
+ ${targetClass.split('\\').pop()} \$subject,
234
+ \$result
235
+ ) {
236
+ // Modify result after method execution
237
+ return \$result;
238
+ }
239
+
240
+ /**
241
+ * Around ${targetMethod}
242
+ */
243
+ public function around${targetMethod.charAt(0).toUpperCase() + targetMethod.slice(1)}(
244
+ ${targetClass.split('\\').pop()} \$subject,
245
+ callable \$proceed,
246
+ ...\$args
247
+ ) {
248
+ // Execute before
249
+ \$result = \$proceed(...\$args);
250
+ // Execute after
251
+ return \$result;
252
+ }
253
+ }
254
+ `,
255
+ metadata: {
256
+ type: 'php',
257
+ magentoType: 'Plugin',
258
+ module: moduleName,
259
+ className: pluginName,
260
+ isPlugin: true,
261
+ targetClass,
262
+ targetMethod,
263
+ pluginMethods: [
264
+ { type: 'before', name: `before${targetMethod.charAt(0).toUpperCase() + targetMethod.slice(1)}` },
265
+ { type: 'after', name: `after${targetMethod.charAt(0).toUpperCase() + targetMethod.slice(1)}` },
266
+ { type: 'around', name: `around${targetMethod.charAt(0).toUpperCase() + targetMethod.slice(1)}` }
267
+ ]
268
+ }
269
+ };
270
+ }
271
+
272
+ export function generateMockObserver(moduleName, eventName, observerName) {
273
+ const [vendor, module] = moduleName.split('_');
274
+ return {
275
+ path: `app/code/${vendor}/${module}/Observer/${observerName}.php`,
276
+ content: `<?php
277
+ declare(strict_types=1);
278
+
279
+ namespace ${vendor}\\${module}\\Observer;
280
+
281
+ use Magento\\Framework\\Event\\Observer;
282
+ use Magento\\Framework\\Event\\ObserverInterface;
283
+ use Psr\\Log\\LoggerInterface;
284
+
285
+ /**
286
+ * Observer for ${eventName} event
287
+ */
288
+ class ${observerName} implements ObserverInterface
289
+ {
290
+ private LoggerInterface \$logger;
291
+
292
+ public function __construct(LoggerInterface \$logger)
293
+ {
294
+ \$this->logger = \$logger;
295
+ }
296
+
297
+ /**
298
+ * Execute observer
299
+ * @param Observer \$observer
300
+ * @return void
301
+ */
302
+ public function execute(Observer \$observer): void
303
+ {
304
+ \$event = \$observer->getEvent();
305
+ \$this->logger->info('Event ${eventName} triggered');
306
+ // Observer logic here
307
+ }
308
+ }
309
+ `,
310
+ metadata: {
311
+ type: 'php',
312
+ magentoType: 'Observer',
313
+ module: moduleName,
314
+ className: observerName,
315
+ isObserver: true,
316
+ eventName
317
+ }
318
+ };
319
+ }
320
+
321
+ export function generateMockDiXml(moduleName, configs) {
322
+ const [vendor, module] = moduleName.split('_');
323
+ let content = `<?xml version="1.0"?>
324
+ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
325
+ xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
326
+ `;
327
+
328
+ for (const config of configs) {
329
+ if (config.type === 'preference') {
330
+ content += ` <preference for="${config.for}" type="${config.implementation}" />\n`;
331
+ } else if (config.type === 'plugin') {
332
+ content += ` <type name="${config.target}">
333
+ <plugin name="${config.name}" type="${config.class}" sortOrder="${config.sortOrder || 10}" />
334
+ </type>\n`;
335
+ } else if (config.type === 'virtualType') {
336
+ content += ` <virtualType name="${config.name}" type="${config.extends}">
337
+ <arguments>
338
+ <argument name="${config.argName}" xsi:type="string">${config.argValue}</argument>
339
+ </arguments>
340
+ </virtualType>\n`;
341
+ }
342
+ }
343
+
344
+ content += `</config>`;
345
+
346
+ return {
347
+ path: `app/code/${vendor}/${module}/etc/di.xml`,
348
+ content,
349
+ metadata: {
350
+ type: 'xml',
351
+ magentoType: 'di.xml',
352
+ module: moduleName,
353
+ preferences: configs.filter(c => c.type === 'preference'),
354
+ plugins: configs.filter(c => c.type === 'plugin'),
355
+ virtualTypes: configs.filter(c => c.type === 'virtualType')
356
+ }
357
+ };
358
+ }
359
+
360
+ export function generateMockEventsXml(moduleName, events) {
361
+ const [vendor, module] = moduleName.split('_');
362
+ let content = `<?xml version="1.0"?>
363
+ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
364
+ xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
365
+ `;
366
+
367
+ for (const event of events) {
368
+ content += ` <event name="${event.name}">
369
+ <observer name="${event.observerName}" instance="${vendor}\\${module}\\Observer\\${event.observerClass}" />
370
+ </event>\n`;
371
+ }
372
+
373
+ content += `</config>`;
374
+
375
+ return {
376
+ path: `app/code/${vendor}/${module}/etc/events.xml`,
377
+ content,
378
+ metadata: {
379
+ type: 'xml',
380
+ magentoType: 'events.xml',
381
+ module: moduleName,
382
+ events: events.map(e => e.name),
383
+ observers: events.map(e => ({ name: e.observerName, instance: `${vendor}\\${module}\\Observer\\${e.observerClass}` }))
384
+ }
385
+ };
386
+ }
387
+
388
+ export function generateMockWebApiXml(moduleName, routes) {
389
+ const [vendor, module] = moduleName.split('_');
390
+ let content = `<?xml version="1.0"?>
391
+ <routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
392
+ xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
393
+ `;
394
+
395
+ for (const route of routes) {
396
+ content += ` <route url="${route.url}" method="${route.method}">
397
+ <service class="${vendor}\\${module}\\Api\\${route.serviceClass}" method="${route.serviceMethod}" />
398
+ <resources>
399
+ <resource ref="${route.resource || 'anonymous'}" />
400
+ </resources>
401
+ </route>\n`;
402
+ }
403
+
404
+ content += `</routes>`;
405
+
406
+ return {
407
+ path: `app/code/${vendor}/${module}/etc/webapi.xml`,
408
+ content,
409
+ metadata: {
410
+ type: 'xml',
411
+ magentoType: 'webapi.xml',
412
+ module: moduleName,
413
+ apiRoutes: routes.map(r => ({ url: r.url, method: r.method })),
414
+ apiServices: routes.map(r => ({ class: `${vendor}\\${module}\\Api\\${r.serviceClass}`, method: r.serviceMethod }))
415
+ }
416
+ };
417
+ }
418
+
419
+ export function generateMockGraphqlSchema(moduleName, types, queries, mutations) {
420
+ const [vendor, module] = moduleName.split('_');
421
+ let content = '';
422
+
423
+ for (const type of types) {
424
+ content += `type ${type.name} ${type.implements ? `implements ${type.implements}` : ''} {
425
+ ${type.fields.map(f => ` ${f.name}: ${f.type}`).join('\n')}
426
+ }\n\n`;
427
+ }
428
+
429
+ if (queries.length > 0) {
430
+ content += `type Query {\n`;
431
+ for (const q of queries) {
432
+ content += ` ${q.name}(${q.args || ''}): ${q.returnType} @resolver(class: "${vendor}\\\\${module}\\\\Model\\\\Resolver\\\\${q.resolver}")\n`;
433
+ }
434
+ content += `}\n\n`;
435
+ }
436
+
437
+ if (mutations.length > 0) {
438
+ content += `type Mutation {\n`;
439
+ for (const m of mutations) {
440
+ content += ` ${m.name}(${m.args || ''}): ${m.returnType} @resolver(class: "${vendor}\\\\${module}\\\\Model\\\\Resolver\\\\${m.resolver}")\n`;
441
+ }
442
+ content += `}\n`;
443
+ }
444
+
445
+ return {
446
+ path: `app/code/${vendor}/${module}/etc/schema.graphqls`,
447
+ content,
448
+ metadata: {
449
+ type: 'graphql',
450
+ magentoType: 'graphql_schema',
451
+ module: moduleName,
452
+ types: types.map(t => t.name),
453
+ queries: queries.map(q => q.name),
454
+ mutations: mutations.map(m => m.name),
455
+ resolvers: [...queries, ...mutations].map(x => x.resolver)
456
+ }
457
+ };
458
+ }
459
+
460
+ export function generateMockResolver(moduleName, resolverName, queryName) {
461
+ const [vendor, module] = moduleName.split('_');
462
+ return {
463
+ path: `app/code/${vendor}/${module}/Model/Resolver/${resolverName}.php`,
464
+ content: `<?php
465
+ declare(strict_types=1);
466
+
467
+ namespace ${vendor}\\${module}\\Model\\Resolver;
468
+
469
+ use Magento\\Framework\\GraphQl\\Config\\Element\\Field;
470
+ use Magento\\Framework\\GraphQl\\Query\\ResolverInterface;
471
+ use Magento\\Framework\\GraphQl\\Schema\\Type\\ResolveInfo;
472
+
473
+ /**
474
+ * GraphQL resolver for ${queryName}
475
+ */
476
+ class ${resolverName} implements ResolverInterface
477
+ {
478
+ /**
479
+ * @inheritdoc
480
+ */
481
+ public function resolve(
482
+ Field \$field,
483
+ \$context,
484
+ ResolveInfo \$info,
485
+ array \$value = null,
486
+ array \$args = null
487
+ ) {
488
+ // Resolver implementation
489
+ return [];
490
+ }
491
+ }
492
+ `,
493
+ metadata: {
494
+ type: 'php',
495
+ magentoType: 'GraphQlResolver',
496
+ module: moduleName,
497
+ className: resolverName,
498
+ isResolver: true,
499
+ queryName
500
+ }
501
+ };
502
+ }
503
+
504
+ export function generateMockBlock(moduleName, blockName) {
505
+ const [vendor, module] = moduleName.split('_');
506
+ return {
507
+ path: `app/code/${vendor}/${module}/Block/${blockName}.php`,
508
+ content: `<?php
509
+ declare(strict_types=1);
510
+
511
+ namespace ${vendor}\\${module}\\Block;
512
+
513
+ use Magento\\Framework\\View\\Element\\Template;
514
+ use Magento\\Framework\\View\\Element\\Template\\Context;
515
+
516
+ /**
517
+ * ${blockName} block
518
+ */
519
+ class ${blockName} extends Template
520
+ {
521
+ protected \$_template = '${vendor}_${module}::${blockName.toLowerCase()}.phtml';
522
+
523
+ public function __construct(Context \$context, array \$data = [])
524
+ {
525
+ parent::__construct(\$context, \$data);
526
+ }
527
+
528
+ protected function _prepareLayout(): self
529
+ {
530
+ parent::_prepareLayout();
531
+ return \$this;
532
+ }
533
+
534
+ protected function _toHtml(): string
535
+ {
536
+ return parent::_toHtml();
537
+ }
538
+
539
+ public function getItems(): array
540
+ {
541
+ return [];
542
+ }
543
+ }
544
+ `,
545
+ metadata: {
546
+ type: 'php',
547
+ magentoType: 'Block',
548
+ module: moduleName,
549
+ className: blockName,
550
+ isBlock: true
551
+ }
552
+ };
553
+ }
554
+
555
+ export function generateMockCronJob(moduleName, cronName, schedule = '0 * * * *') {
556
+ const [vendor, module] = moduleName.split('_');
557
+ return {
558
+ php: {
559
+ path: `app/code/${vendor}/${module}/Cron/${cronName}.php`,
560
+ content: `<?php
561
+ declare(strict_types=1);
562
+
563
+ namespace ${vendor}\\${module}\\Cron;
564
+
565
+ use Psr\\Log\\LoggerInterface;
566
+
567
+ /**
568
+ * ${cronName} cron job
569
+ */
570
+ class ${cronName}
571
+ {
572
+ private LoggerInterface \$logger;
573
+
574
+ public function __construct(LoggerInterface \$logger)
575
+ {
576
+ \$this->logger = \$logger;
577
+ }
578
+
579
+ public function execute(): void
580
+ {
581
+ \$this->logger->info('Cron job ${cronName} executed');
582
+ // Cron logic here
583
+ }
584
+ }
585
+ `,
586
+ metadata: {
587
+ type: 'php',
588
+ magentoType: 'Cron',
589
+ module: moduleName,
590
+ className: cronName,
591
+ isCron: true
592
+ }
593
+ },
594
+ xml: {
595
+ path: `app/code/${vendor}/${module}/etc/crontab.xml`,
596
+ content: `<?xml version="1.0"?>
597
+ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
598
+ xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
599
+ <group id="default">
600
+ <job name="${vendor.toLowerCase()}_${module.toLowerCase()}_${cronName.toLowerCase()}"
601
+ instance="${vendor}\\${module}\\Cron\\${cronName}"
602
+ method="execute">
603
+ <schedule>${schedule}</schedule>
604
+ </job>
605
+ </group>
606
+ </config>`,
607
+ metadata: {
608
+ type: 'xml',
609
+ magentoType: 'crontab.xml',
610
+ module: moduleName,
611
+ cronJobs: [{ name: `${vendor.toLowerCase()}_${module.toLowerCase()}_${cronName.toLowerCase()}`, instance: `${vendor}\\${module}\\Cron\\${cronName}` }]
612
+ }
613
+ }
614
+ };
615
+ }
616
+
617
+ /**
618
+ * Generate a complete mock module with all components
619
+ */
620
+ export function generateCompleteMockModule(moduleName) {
621
+ const [vendor, module] = moduleName.split('_');
622
+ const files = [];
623
+
624
+ // Controllers
625
+ files.push(generateMockController(moduleName, 'Index', 'execute'));
626
+ files.push(generateMockController(moduleName, 'View', 'execute'));
627
+
628
+ // Models
629
+ files.push(generateMockModel(moduleName, 'Item', `${vendor.toLowerCase()}_${module.toLowerCase()}_item`));
630
+ files.push(generateMockRepository(moduleName, 'Item'));
631
+
632
+ // Plugin
633
+ files.push(generateMockPlugin(moduleName, 'Magento\\Catalog\\Model\\Product', 'getPrice'));
634
+
635
+ // Observer
636
+ files.push(generateMockObserver(moduleName, 'catalog_product_save_after', 'ProductSaveObserver'));
637
+
638
+ // Block
639
+ files.push(generateMockBlock(moduleName, 'ItemList'));
640
+
641
+ // DI config
642
+ files.push(generateMockDiXml(moduleName, [
643
+ { type: 'preference', for: `${vendor}\\${module}\\Api\\ItemRepositoryInterface`, implementation: `${vendor}\\${module}\\Model\\ItemRepository` },
644
+ { type: 'plugin', target: 'Magento\\Catalog\\Model\\Product', name: `${vendor.toLowerCase()}_${module.toLowerCase()}_product_price`, class: `${vendor}\\${module}\\Plugin\\ProductGetPricePlugin` }
645
+ ]));
646
+
647
+ // Events
648
+ files.push(generateMockEventsXml(moduleName, [
649
+ { name: 'catalog_product_save_after', observerName: `${vendor.toLowerCase()}_product_save`, observerClass: 'ProductSaveObserver' }
650
+ ]));
651
+
652
+ // Web API
653
+ files.push(generateMockWebApiXml(moduleName, [
654
+ { url: `/V1/${module.toLowerCase()}/items/:id`, method: 'GET', serviceClass: 'ItemRepositoryInterface', serviceMethod: 'getById' },
655
+ { url: `/V1/${module.toLowerCase()}/items`, method: 'POST', serviceClass: 'ItemRepositoryInterface', serviceMethod: 'save' }
656
+ ]));
657
+
658
+ // GraphQL
659
+ files.push(generateMockGraphqlSchema(moduleName,
660
+ [{ name: `${module}Item`, fields: [{ name: 'id', type: 'Int!' }, { name: 'name', type: 'String' }] }],
661
+ [{ name: `${module.toLowerCase()}Item`, args: 'id: Int!', returnType: `${module}Item`, resolver: 'ItemResolver' }],
662
+ [{ name: `create${module}Item`, args: 'input: CreateItemInput!', returnType: `${module}Item`, resolver: 'CreateItemResolver' }]
663
+ ));
664
+ files.push(generateMockResolver(moduleName, 'ItemResolver', `${module.toLowerCase()}Item`));
665
+
666
+ // Cron
667
+ const cronJob = generateMockCronJob(moduleName, 'CleanupJob');
668
+ files.push(cronJob.php);
669
+ files.push(cronJob.xml);
670
+
671
+ return files;
672
+ }