Skip to content

Commit 063184f

Browse files
committed
docs: update README with all codemod utilities
1 parent c9b9a26 commit 063184f

1 file changed

Lines changed: 260 additions & 0 deletions

File tree

README.md

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,266 @@ export const policies = {
420420
}
421421
```
422422

423+
### addValidator
424+
Create a new validator file or add a validator to an existing file. If the file does not exist, it will be created with the provided contents. If it exists and the export name is not already defined, the validator will be appended to the file.
425+
426+
> [!IMPORTANT]
427+
> This codemod respects the `validators` directory configured in `adonisrc.ts` and defaults to `app/validators`.
428+
429+
```ts
430+
const transformer = new CodeTransformer(appRoot)
431+
432+
try {
433+
await transformer.addValidator({
434+
validatorFileName: 'user.ts',
435+
exportName: 'loginValidator',
436+
contents: `export const loginValidator = vine.compile(
437+
vine.object({
438+
email: vine.string().email(),
439+
password: vine.string().minLength(8)
440+
})
441+
)`
442+
})
443+
} catch (error) {
444+
console.error('Unable to add validator')
445+
console.error(error)
446+
}
447+
```
448+
449+
Output (app/validators/user.ts)
450+
451+
```ts
452+
export const loginValidator = vine.compile(
453+
vine.object({
454+
email: vine.string().email(),
455+
password: vine.string().minLength(8)
456+
})
457+
)
458+
```
459+
460+
### addLimiter
461+
Create a new rate limiter file or add a limiter to an existing file. If the file does not exist, it will be created with the provided contents. If it exists and the export name is not already defined, the limiter will be appended to the file.
462+
463+
> [!IMPORTANT]
464+
> Limiters are created in the `start` directory configured in `adonisrc.ts` and defaults to `start`.
465+
466+
```ts
467+
const transformer = new CodeTransformer(appRoot)
468+
469+
try {
470+
await transformer.addLimiter({
471+
limiterFileName: 'limiters.ts',
472+
exportName: 'apiThrottle',
473+
contents: `export const apiThrottle = limiter.define('api', () => {
474+
return limiter.allowRequests(10).every('1 minute')
475+
})`
476+
})
477+
} catch (error) {
478+
console.error('Unable to add limiter')
479+
console.error(error)
480+
}
481+
```
482+
483+
Output (start/limiters.ts)
484+
485+
```ts
486+
export const apiThrottle = limiter.define('api', () => {
487+
return limiter.allowRequests(10).every('1 minute')
488+
})
489+
```
490+
491+
### addModelMixins
492+
Apply one or more mixins to a model class. This wraps the model's extends clause with the `compose` helper and applies the specified mixins.
493+
494+
> [!IMPORTANT]
495+
> This codemod expects the model file to exist with a default exported class that extends a base class.
496+
497+
```ts
498+
const transformer = new CodeTransformer(appRoot)
499+
500+
try {
501+
await transformer.addModelMixins('user.ts', [
502+
{
503+
name: 'SoftDeletes',
504+
importPath: '@adonisjs/lucid/orm/mixins/soft_deletes',
505+
importType: 'named'
506+
},
507+
{
508+
name: 'Sluggable',
509+
importPath: '#mixins/sluggable',
510+
importType: 'default',
511+
args: ['title', '{ strategy: "dbIncrement" }']
512+
}
513+
])
514+
} catch (error) {
515+
console.error('Unable to add mixins to model')
516+
console.error(error)
517+
}
518+
```
519+
520+
Input (app/models/user.ts)
521+
522+
```ts
523+
import { BaseModel } from '@adonisjs/lucid/orm'
524+
525+
export default class User extends BaseModel {
526+
// ...
527+
}
528+
```
529+
530+
Output (app/models/user.ts)
531+
532+
```ts
533+
import { BaseModel } from '@adonisjs/lucid/orm'
534+
import { compose } from '@adonisjs/core/helpers'
535+
import { SoftDeletes } from '@adonisjs/lucid/orm/mixins/soft_deletes'
536+
import Sluggable from '#mixins/sluggable'
537+
538+
export default class User extends compose(BaseModel, SoftDeletes(), Sluggable(title, { strategy: "dbIncrement" })) {
539+
// ...
540+
}
541+
```
542+
543+
### addControllerMethod
544+
Create a new controller file or add a method to an existing controller class. If the controller file does not exist, it will be created with the class and method. If it exists and the method is not already defined, the method will be added to the class.
545+
546+
> [!IMPORTANT]
547+
> This codemod respects the `controllers` directory configured in `adonisrc.ts` and defaults to `app/controllers`.
548+
549+
```ts
550+
const transformer = new CodeTransformer(appRoot)
551+
552+
try {
553+
await transformer.addControllerMethod({
554+
controllerFileName: 'users_controller.ts',
555+
className: 'UsersController',
556+
name: 'destroy',
557+
contents: `async destroy({ params, response }: HttpContext) {
558+
const user = await User.findOrFail(params.id)
559+
await user.delete()
560+
return response.noContent()
561+
}`,
562+
imports: [
563+
{ isType: false, isNamed: true, name: 'HttpContext', path: '@adonisjs/core/http' },
564+
{ isType: false, isNamed: false, name: 'User', path: '#models/user' }
565+
]
566+
})
567+
} catch (error) {
568+
console.error('Unable to add controller method')
569+
console.error(error)
570+
}
571+
```
572+
573+
Output (app/controllers/users_controller.ts)
574+
575+
```ts
576+
import type { HttpContext } from '@adonisjs/core/http'
577+
import User from '#models/user'
578+
579+
export default class UsersController {
580+
async destroy({ params, response }: HttpContext) {
581+
const user = await User.findOrFail(params.id)
582+
await user.delete()
583+
return response.noContent()
584+
}
585+
}
586+
```
587+
588+
### RcFileTransformer additional methods
589+
590+
The `RcFileTransformer` class (accessible via `updateRcFile` callback) now supports additional methods for managing imports and hooks.
591+
592+
#### addNamedImport
593+
Add a named import to the `adonisrc.ts` file.
594+
595+
```ts
596+
const transformer = new CodeTransformer(appRoot)
597+
598+
try {
599+
await transformer.updateRcFile((rcFile) => {
600+
rcFile.addNamedImport('@adonisjs/core/types', ['Middleware', 'Provider'])
601+
})
602+
} catch (error) {
603+
console.error('Unable to add named import')
604+
console.error(error)
605+
}
606+
```
607+
608+
Output
609+
610+
```ts
611+
import { defineConfig } from '@adonisjs/core/app'
612+
import { Middleware, Provider } from '@adonisjs/core/types'
613+
614+
export default defineConfig({
615+
// ...
616+
})
617+
```
618+
619+
#### addDefaultImport
620+
Add a default import to the `adonisrc.ts` file.
621+
622+
```ts
623+
const transformer = new CodeTransformer(appRoot)
624+
625+
try {
626+
await transformer.updateRcFile((rcFile) => {
627+
rcFile.addDefaultImport('#config/database', 'databaseConfig')
628+
})
629+
} catch (error) {
630+
console.error('Unable to add default import')
631+
console.error(error)
632+
}
633+
```
634+
635+
Output
636+
637+
```ts
638+
import { defineConfig } from '@adonisjs/core/app'
639+
import databaseConfig from '#config/database'
640+
641+
export default defineConfig({
642+
// ...
643+
})
644+
```
645+
646+
#### addAssemblerHook
647+
Add assembler hooks to the `adonisrc.ts` file. Hooks can be added as thunk imports (lazy loaded) or as raw values for direct import references.
648+
649+
```ts
650+
const transformer = new CodeTransformer(appRoot)
651+
652+
try {
653+
await transformer.updateRcFile((rcFile) => {
654+
// Add a thunk-style hook (lazy import)
655+
rcFile.addAssemblerHook('onBuildStarting', './commands/build_hook.js')
656+
657+
// Add a raw hook (direct import reference)
658+
rcFile.addAssemblerHook('onBuildCompleted', 'buildCompletedHook', true)
659+
})
660+
} catch (error) {
661+
console.error('Unable to add assembler hook')
662+
console.error(error)
663+
}
664+
```
665+
666+
Output
667+
668+
```ts
669+
import { defineConfig } from '@adonisjs/core/app'
670+
671+
export default defineConfig({
672+
hooks: {
673+
onBuildStarting: [
674+
() => import('./commands/build_hook.js')
675+
],
676+
onBuildCompleted: [
677+
buildCompletedHook
678+
]
679+
}
680+
})
681+
```
682+
423683
## Index generator
424684

425685
The `IndexGenerator` is a core concept in Assembler that is used to watch the filesystem and create barrel files or types from a source directory.

0 commit comments

Comments
 (0)