diff --git a/configure.ts b/configure.ts index 8ce7009..3688643 100644 --- a/configure.ts +++ b/configure.ts @@ -18,6 +18,7 @@ const STORAGE_SERVICES = { fs: { name: 'Local filesystem', env: [], + dependencies: [], }, s3: { name: 'AWS S3', @@ -27,6 +28,7 @@ const STORAGE_SERVICES = { { name: 'AWS_REGION', value: '', schema: 'Env.schema.string()' }, { name: 'S3_BUCKET', value: '', schema: 'Env.schema.string()' }, ], + dependencies: ['@aws-sdk/client-s3', '@aws-sdk/s3-request-presigner'], }, do: { name: 'Digital Ocean Spaces', @@ -41,6 +43,7 @@ const STORAGE_SERVICES = { schema: 'Env.schema.string()', }, ], + dependencies: ['@aws-sdk/client-s3', '@aws-sdk/s3-request-presigner'], }, r2: { name: 'Cloudflare R2', @@ -50,6 +53,7 @@ const STORAGE_SERVICES = { { name: 'R2_BUCKET', value: '', schema: 'Env.schema.string()' }, { name: 'R2_ENDPOINT', value: '', schema: 'Env.schema.string()' }, ], + dependencies: ['@aws-sdk/client-s3', '@aws-sdk/s3-request-presigner'], }, gcs: { name: 'Google Cloud Storage', @@ -57,6 +61,7 @@ const STORAGE_SERVICES = { { name: 'GCS_KEY', value: 'file://./gcs_key.json', schema: 'Env.schema.string()' }, { name: 'GCS_BUCKET', value: '', schema: 'Env.schema.string()' }, ], + dependencies: ['@google-cloud/storage'], }, } @@ -74,6 +79,11 @@ export async function configure(command: ConfigureCommand) { | (keyof typeof STORAGE_SERVICES)[] | undefined = command.parsedFlags.services + /** + * Should dependencies be installed + */ + let shouldInstallPackages: boolean | undefined = command.parsedFlags.install + /** * Display prompt when no services are specified * via the CLI flag. @@ -161,4 +171,32 @@ export async function configure(command: ConfigureCommand) { } ), }) + + /** + * Create a flat collection of dependencies to install + * based upon the configured services. + */ + const pkgsToInstall = services + .flatMap((service) => STORAGE_SERVICES[service].dependencies) + .map((pkg) => { + return { name: pkg, isDevDependency: false } + }) + if (!pkgsToInstall.length) { + return + } + + /** + * Prompt to install additional services + */ + if (!shouldInstallPackages) { + shouldInstallPackages = await command.prompt.confirm( + 'Do you want to install additional packages required by "@adonisjs/drive"?' + ) + } + + if (shouldInstallPackages) { + await codemods.installPackages(pkgsToInstall) + } else { + await codemods.listPackagesToInstall(pkgsToInstall) + } } diff --git a/tests/configure.spec.ts b/tests/configure.spec.ts index 3907b8a..ee9a4a8 100644 --- a/tests/configure.spec.ts +++ b/tests/configure.spec.ts @@ -41,6 +41,7 @@ test.group('Configure', (group) => { await fs.create('.env', '') await fs.createJson('tsconfig.json', {}) + await fs.createJson('package.json', {}) await fs.create('start/env.ts', `export default Env.create(new URL('./'), {})`) await fs.create('adonisrc.ts', `export default defineConfig({})`) @@ -49,6 +50,7 @@ test.group('Configure', (group) => { '../../index.js', '--services=fs', '--services=s3', + '--install', ]) await command.exec() @@ -79,9 +81,9 @@ test.group('Configure', (group) => { ` fs: services.fs({ location: app.makePath('storage'), - visibility: 'public', serveFiles: true, routeBasePath: '/uploads', + visibility: 'public', }),` ) await assert.fileContains( @@ -123,6 +125,11 @@ test.group('Configure', (group) => { const ace = await app.container.make('ace') const command = await ace.create(Configure, ['../../index.js']) + + command.prompt + .trap('Do you want to install additional packages required by "@adonisjs/drive"?') + .reject() + command.prompt .trap('Select the storage services you want to use') .assertFails('', 'Please select one or more services') @@ -193,6 +200,7 @@ test.group('Configure', (group) => { const ace = await app.container.make('ace') const command = await ace.create(Configure, ['../../index.js']) command.prompt.trap('Select the storage services you want to use').chooseOption(0) + await command.exec() await assert.fileExists('.env') @@ -204,15 +212,15 @@ test.group('Configure', (group) => { await assert.fileContains('config/drive.ts', 'defineConfig') await assert.fileContains('config/drive.ts', `declare module '@adonisjs/drive/types' {`) - await assert.fileEquals('.env', '') - await assert.fileEquals('start/env.ts', `export default Env.create(new URL('./'), {})\n`) + await assert.fileContains('.env', 'DRIVE_DISK=fs') + await assert.fileContains('start/env.ts', `DRIVE_DISK: Env.schema.enum(['fs'])`) await assert.fileContains('config/drive.ts', [ `fs: services.fs({ location: app.makePath('storage'), - visibility: 'public', serveFiles: true, routeBasePath: '/uploads', + visibility: 'public', }),`, `import app from '@adonisjs/core/services/app'`, ])