Skip to content

Commit

Permalink
feat: allow defining actions for make:controller command
Browse files Browse the repository at this point in the history
  • Loading branch information
thetutlage committed Nov 23, 2023
1 parent e2d03e1 commit d6a29fe
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 4 deletions.
28 changes: 24 additions & 4 deletions commands/make/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
* file that was distributed with this source code.
*/

import { args, flags, BaseCommand } from '../../modules/ace/main.js'
import string from '@poppinss/utils/string'
import { stubsRoot } from '../../stubs/main.js'
import { args, flags, BaseCommand } from '../../modules/ace/main.js'

/**
* The make controller command to create an HTTP controller
Expand All @@ -20,6 +21,9 @@ export default class MakeController extends BaseCommand {
@args.string({ description: 'The name of the controller' })
declare name: string

@args.spread({ description: 'Method names to pre-define on the controller', required: false })
declare actions?: string[]

@flags.boolean({
description: 'Convert controller class and file name to its singular form',
alias: 'r',
Expand Down Expand Up @@ -47,24 +51,39 @@ export default class MakeController extends BaseCommand {
* Preparing the command state
*/
async prepare() {
/**
* Use actions stub
*/
if (this.actions) {
this.stubPath = 'make/controller/actions.stub'
}

/**
* Use resource stub
*/
if (this.resource) {
this.stubPath = 'make/controller/resource.stub'
if (this.actions) {
this.logger.warning('Cannot use --resource flag with actions. Ignoring --resource')
} else {
this.stubPath = 'make/controller/resource.stub'
}
}

/**
* Use api stub
*/
if (this.api) {
this.stubPath = 'make/controller/api.stub'
if (this.actions) {
this.logger.warning('Cannot use --api flag with actions. Ignoring --api')
} else {
this.stubPath = 'make/controller/api.stub'
}
}

/**
* Log warning when both flags are used together
*/
if (this.resource && this.api) {
if (this.resource && this.api && !this.actions) {
this.logger.warning('--api and --resource flags cannot be used together. Ignoring --resource')
}
}
Expand All @@ -73,6 +92,7 @@ export default class MakeController extends BaseCommand {
const codemods = await this.createCodemods()
await codemods.makeUsingStub(stubsRoot, this.stubPath, {
flags: this.parsed.flags,
actions: this.actions?.map((action) => string.camelCase(action)),
entity: this.app.generators.createEntity(this.name),
})
}
Expand Down
14 changes: 14 additions & 0 deletions stubs/make/controller/actions.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{{#var controllerName = generators.controllerName(entity.name)}}
{{#var controllerFileName = generators.controllerFileName(entity.name)}}
{{{
exports({
to: app.httpControllersPath(entity.path, controllerFileName)
})
}}}
import type { HttpContext } from '@adonisjs/core/http'

export default class {{ controllerName }} {
{{#each actions as action}}
async {{action}}({}: HttpContext) {}
{{/each}}
}
105 changes: 105 additions & 0 deletions tests/commands/make_controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,109 @@ test.group('Make controller', () => {
},
])
})

test('create controller with actions', async ({ assert, fs }) => {
const ace = await new AceFactory().make(fs.baseUrl, {
importer: (filePath) => import(filePath),
})
await ace.app.init()
ace.ui.switchMode('raw')

const command = await ace.create(MakeControllerCommand, [
'user',
'index',
'show',
'delete-profile',
])
await command.exec()

const { contents } = await new StubsFactory().prepare('make/controller/actions.stub', {
entity: ace.app.generators.createEntity('user'),
actions: ['index', 'show', 'deleteProfile'],
})

await assert.fileEquals('app/controllers/users_controller.ts', contents)

assert.deepEqual(ace.ui.logger.getLogs(), [
{
message: 'green(DONE:) create app/controllers/users_controller.ts',
stream: 'stdout',
},
])
})

test('warn when using --resource flag with actions', async ({ assert, fs }) => {
const ace = await new AceFactory().make(fs.baseUrl, {
importer: (filePath) => import(filePath),
})
await ace.app.init()
ace.ui.switchMode('raw')

const command = await ace.create(MakeControllerCommand, [
'user',
'index',
'show',
'delete-profile',
'--resource',
])
await command.exec()

const { contents } = await new StubsFactory().prepare('make/controller/actions.stub', {
entity: ace.app.generators.createEntity('user'),
actions: ['index', 'show', 'deleteProfile'],
})

await assert.fileEquals('app/controllers/users_controller.ts', contents)

assert.deepEqual(ace.ui.logger.getLogs(), [
{
message: '[ yellow(warn) ] Cannot use --resource flag with actions. Ignoring --resource',
stream: 'stdout',
},
{
message: 'green(DONE:) create app/controllers/users_controller.ts',
stream: 'stdout',
},
])
})

test('warn when using --resource and --api flag with actions', async ({ assert, fs }) => {
const ace = await new AceFactory().make(fs.baseUrl, {
importer: (filePath) => import(filePath),
})
await ace.app.init()
ace.ui.switchMode('raw')

const command = await ace.create(MakeControllerCommand, [
'user',
'index',
'show',
'delete-profile',
'--resource',
'--api',
])
await command.exec()

const { contents } = await new StubsFactory().prepare('make/controller/actions.stub', {
entity: ace.app.generators.createEntity('user'),
actions: ['index', 'show', 'deleteProfile'],
})

await assert.fileEquals('app/controllers/users_controller.ts', contents)

assert.deepEqual(ace.ui.logger.getLogs(), [
{
message: '[ yellow(warn) ] Cannot use --resource flag with actions. Ignoring --resource',
stream: 'stdout',
},
{
message: '[ yellow(warn) ] Cannot use --api flag with actions. Ignoring --api',
stream: 'stdout',
},
{
message: 'green(DONE:) create app/controllers/users_controller.ts',
stream: 'stdout',
},
])
})
})
22 changes: 22 additions & 0 deletions tests/stubs/make_controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,26 @@ test.group('Make controller', () => {
assert.match(contents, new RegExp('async update\\({ params, request }: HttpContext\\) {}'))
assert.match(contents, new RegExp('async destroy\\({ params }: HttpContext\\) {}'))
})

test('prepare actions controller stub', async ({ assert }) => {
const app = new AppFactory().create(BASE_URL, () => {})
await app.init()

const stubs = await app.stubs.create()

const stub = await stubs.build('make/controller/actions.stub', {
source: stubsRoot,
})
const { contents, destination } = await stub.prepare({
entity: app.generators.createEntity('user'),
actions: ['index', 'show', 'deleteProfile'],
})

assert.equal(destination, join(BASE_PATH, 'app/controllers/users_controller.ts'))
assert.match(contents, /export default class UsersController {/)
assert.match(contents, new RegExp("import type { HttpContext } from '@adonisjs/core/http'"))
assert.match(contents, new RegExp('async index\\({}: HttpContext\\) {}'))
assert.match(contents, new RegExp('async show\\({}: HttpContext\\) {}'))
assert.match(contents, new RegExp('async deleteProfile\\({}: HttpContext\\) {}'))
})
})

0 comments on commit d6a29fe

Please sign in to comment.