Skip to content

Conversation

Julien-R44
Copy link
Member

@Julien-R44 Julien-R44 commented Aug 18, 2023

The transformer code will be used in particular by the Configure.ts command defined in adonisjs/core. this allows either us or package maintainers to apply certain codemods to Adonis applications. for now we have the following methods:

defineEnvValidations

allows you to add new variables to the start/env.ts file :

const transformer = new CodeTransformer(projectPath)

await transformer.defineEnvValidations({
  leadingComment: 'Redis configuration',
  variables: {
    MY_VAR: 'Env.schema.string.optional()',
    MY_VAR2: 'Env.schema.number()',
  },
})

output will be:

export default await Env.create(new URL('../', import.meta.url), {
  NODE_ENV: Env.schema.enum(['development', 'production', 'test'] as const),
  PORT: Env.schema.number(),

  /*
  |----------------------------------------------------------
  | Redis configuration
  |----------------------------------------------------------
  */
  REDIS_HOST: Env.schema.string.optional(),
  REDIS_PORT: Env.schema.number(),
})
  • if the start/env.ts file doesn't exist, it will throws an error. i think the Configure.ts command that will use this method will be responsible for catching the error and displaying a warning
  • the definition of the rules to add is a simple, untyped string. this seemed to me the simplest while offering the most flexibility. A JSDoc example has been added, so I think it's enough to guide users

addMiddlewareToStack

allows to automatically add a new middleware to one of the 3 stacks: named, router, or server defined in start/kernel.ts

// Server stack
await transformer.addMiddlewareToStack('server', [
  { path: '@adonisjs/static/static_middleware' },
])

// Router stack
await transformer.addMiddlewareToStack('router', [
  { path: '@adonisjs/static/static_middleware', position: 'before' },
  { path: '#foo/middleware.js', position: 'after' }, // 👈👈 note that the order can be specified here
  { path: '#foo/middleware2.js' },
])

// Named middlewares
await transformer.addMiddlewareToStack('named', [
  { name: 'auth', path: '#foo/bar.js' },
  { name: 'rand', path: '@adonisjs/random_middleware' },
])
  • similarly, if the start/kernel.ts file doesn't exist, it throws an error

  • I've exported this class from the main entrypoint and therefore we lazy-load ts-morph. alternatively, perhaps we don't need to lazy-load ts-morph but have a dedicated entrypoint for this class
  • used japa/snapshot for a few assertions that would have been a pain to make without it

will make a PR on adonisjs/core to add it to Configure once it's merged

@Julien-R44
Copy link
Member Author

the new commit introduces the following:

  • specific entry point for the CodeTransformer
  • New RcFileTransformer class with the same methods as the RcEditor in adonisjs/application
    • addSuite
    • setCommandAlias
    • setDirectory
    • addMetaFile
    • addProvider
    • addPreloadFile
    • addCommand

these methods can be used as follows :

const transformer = new CodeTransformer(adonisProjectUrl)

await transformer.updateRcFile((rcFile) => {
  rcFile
	.addPreloadFile('#start/foo.js', ['console', 'repl'])
	.addCommand('#foo/bar.js')
    .addMetaFile('assets/**/*', false)  
})

@Julien-R44
Copy link
Member Author

Julien-R44 commented Aug 19, 2023

one point that I think is important to reiterate: these transformations are highly based on assumptions. Let's imagine the following adonisrc.ts file :

const providers =  [
  () => import('@adonisjs/core/providers/app_provider'),
  {
    file: () => import('@adonisjs/core/providers/repl_provider'),
    environment: ['repl'],
  } 
]

export default defineConfig({
  typescript: true,
  providers,
})

the addProvider call will not work. we can imagine treating this case, it can be done, but if we fix it, then we must also fix the other 200 others probable edge-cases. and the code will become super-complex and a nightmare to maintain 😄

This is the drawback of passing adonisrc in typescript instead of json ( cc @RomainLanz it may also interest you ). but I think if we add a warning in like :

Adding provider xxx with environments xxx and xxx failed. please add it manually
that should be enough. we'll probably also have to warn people in the docs to avoid tweaking this file too much. Ideally, they should keep the default structure

@thetutlage thetutlage merged commit a256b82 into next Aug 20, 2023
@thetutlage
Copy link
Member

Looks cool to me!

@thetutlage thetutlage deleted the feat/code-transformer branch August 20, 2023 10:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants