Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions configure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
* file that was distributed with this source code.
*/

import { existsSync } from 'node:fs'
import { readFile, writeFile } from 'node:fs/promises'

import { stubsRoot } from './stubs/main.js'
import type Configure from '@adonisjs/core/commands/configure'

Expand All @@ -22,6 +25,34 @@ const DRIVERS_INFO: Record<
database: {},
}

type PackageJson = Record<string, unknown> & {
imports?: Record<string, string>
}

/**
* Defines the "#jobs/*" subpath import inside the project package.json
* file. Job classes are referenced using this alias (for example inside
* the scheduler preload file), so we make sure it is always defined.
*/
async function defineJobsImport(packageJsonPath: string) {
/**
* Do not create a package.json from scratch. Only update the
* one that already exists.
*/
if (!existsSync(packageJsonPath)) {
return
}

const packageJson: PackageJson = JSON.parse(await readFile(packageJsonPath, 'utf-8'))

packageJson.imports = {
...packageJson.imports,
'#jobs/*': './app/jobs/*.js',
}

await writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`)
}

/**
* Configures the package
*/
Expand All @@ -44,6 +75,11 @@ export async function configure(command: Configure) {
.addPreloadFile('#start/scheduler', ['web'])
})

/**
* Define the "#jobs/*" import alias used to reference job classes
*/
await defineJobsImport(command.app.makePath('package.json'))

/**
* Define environment variables
*/
Expand Down
71 changes: 70 additions & 1 deletion tests/configure.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import { test } from '@japa/runner'
import { fileURLToPath } from 'node:url'
import { readdir } from 'node:fs/promises'
import { readdir, readFile } from 'node:fs/promises'
import { join } from 'node:path'
import { IgnitorFactory } from '@adonisjs/core/factories'
import Configure from '@adonisjs/core/commands/configure'
Expand All @@ -25,6 +25,7 @@ test.group('Configure', (group) => {
context.fs.basePath = fileURLToPath(BASE_URL)

await context.fs.create('.env', '')
await context.fs.createJson('package.json', { name: 'tmp-app', type: 'module' })
await context.fs.createJson('tsconfig.json', {})
await context.fs.create('start/env.ts', `export default Env.create(new URL('./'), {})`)
await context.fs.create('adonisrc.ts', `export default defineConfig({})`)
Expand Down Expand Up @@ -116,6 +117,74 @@ test.group('Configure', (group) => {
await assert.fileContains('start/env.ts', 'QUEUE_DRIVER')
})

test('should define the "#jobs/*" import alias', async ({ assert }) => {
const ignitor = new IgnitorFactory()
.withCoreProviders()
.withCoreConfig()
.create(BASE_URL, {
importer: (filePath) => {
if (filePath.startsWith('./') || filePath.startsWith('../')) {
return import(new URL(filePath, BASE_URL).href)
}

return import(filePath)
},
})

const app = ignitor.createApp('web')
await app.init().then(() => app.boot())

const ace = await app.container.make('ace')
ace.prompt.trap('Select the queue driver you plan to use').chooseOption(0)
ace.ui.switchMode('raw')

const command = await ace.create(Configure, ['../../index.js'])
await command.exec()

const packageJson = JSON.parse(await readFile(join(BASE_PATH, 'package.json'), 'utf-8'))
assert.deepEqual(packageJson.imports, { '#jobs/*': './app/jobs/*.js' })
})

test('should preserve existing imports when defining the "#jobs/*" alias', async ({
assert,
fs,
}) => {
await fs.createJson('package.json', {
name: 'tmp-app',
type: 'module',
imports: { '#controllers/*': './app/controllers/*.js' },
})

const ignitor = new IgnitorFactory()
.withCoreProviders()
.withCoreConfig()
.create(BASE_URL, {
importer: (filePath) => {
if (filePath.startsWith('./') || filePath.startsWith('../')) {
return import(new URL(filePath, BASE_URL).href)
}

return import(filePath)
},
})

const app = ignitor.createApp('web')
await app.init().then(() => app.boot())

const ace = await app.container.make('ace')
ace.prompt.trap('Select the queue driver you plan to use').chooseOption(0)
ace.ui.switchMode('raw')

const command = await ace.create(Configure, ['../../index.js'])
await command.exec()

const packageJson = JSON.parse(await readFile(join(BASE_PATH, 'package.json'), 'utf-8'))
assert.deepEqual(packageJson.imports, {
'#controllers/*': './app/controllers/*.js',
'#jobs/*': './app/jobs/*.js',
})
})

test('should create redis config when redis driver selected', async ({ assert }) => {
const ignitor = new IgnitorFactory()
.withCoreProviders()
Expand Down