Skip to content

Commit

Permalink
enh: rework cli UX
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandrebodin committed May 6, 2024
1 parent 19fab61 commit dae9cce
Show file tree
Hide file tree
Showing 38 changed files with 484 additions and 633 deletions.
17 changes: 16 additions & 1 deletion examples/kitchensink-ts/src/admin/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
{
"extends": "@strapi/typescript-utils/tsconfigs/admin",
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["../plugins/**/admin/src/**/*", "./"],
"exclude": ["node_modules/", "build/", "dist/", "**/*.test.ts"]
}
17 changes: 15 additions & 2 deletions examples/kitchensink-ts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
{
"extends": "@strapi/typescript-utils/tsconfigs/server",
"compilerOptions": {
"outDir": "dist",
"rootDir": "."
"rootDir": ".",
"module": "CommonJS",
"moduleResolution": "Node",
"lib": ["ES2020"],
"target": "ES2019",

"strict": false,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,

"incremental": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"noEmitOnError": true,
"noImplicitThis": true
},
"include": ["./", "src/**/*.json"],
"exclude": [
Expand Down
1 change: 1 addition & 0 deletions packages/cli/create-strapi-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
},
"devDependencies": {
"@strapi/pack-up": "5.0.0",
"@types/inquirer": "8.2.5",
"eslint-config-custom": "5.0.0-beta.5",
"tsconfig": "5.0.0-beta.5"
},
Expand Down
99 changes: 31 additions & 68 deletions packages/cli/create-strapi-app/src/create-strapi-app.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';
import commander from 'commander';
import { checkInstallPath, generateNewApp } from '@strapi/generate-new';
import promptUser from './utils/prompt-user';
import { generateNewApp, Options } from '@strapi/generate-new';
import type { Program } from './types';

const packageJson = JSON.parse(readFileSync(resolve(__dirname, '../package.json'), 'utf8'));

const command = new commander.Command(packageJson.name);

const databaseOptions: Array<keyof Program> = [
'dbclient',
'dbhost',
'dbport',
'dbname',
'dbusername',
'dbpassword',
'dbssl',
'dbfile',
];

command
.version(packageJson.version)
.arguments('[directory]')
.option('--no-run', 'Do not start the application after it is created')
.option('--use-npm', 'Force usage of npm instead of yarn to create the project')
.option('--debug', 'Display database connection error')
.option('--quickstart', 'Quickstart app creation')
.option('--quick, --quickstart', 'Quickstart app creation')
.option('--run', 'Do not start the application after it is created')

// setup options
.option('--ts, --typescript', 'Initialize the project with TypeScript (default)')
.option('--js, --javascript', 'Initialize the project with Javascript')

// Package manager options
.option('--use-npm', 'Use npm as the project package manager')
.option('--use-yarn', 'Use yarn as the project package manager')
.option('--use-pnpm', 'Use pnpm as the project package manager')

// Database options
.option('--dbclient <dbclient>', 'Database client')
.option('--dbhost <dbhost>', 'Database host')
.option('--dbport <dbport>', 'Database port')
Expand All @@ -35,33 +32,29 @@ command
.option('--dbpassword <dbpassword>', 'Database password')
.option('--dbssl <dbssl>', 'Database SSL')
.option('--dbfile <dbfile>', 'Database file path for sqlite')
.option('--dbforce', 'Overwrite database content if any')

// templates
.option('--template <templateurl>', 'Specify a Strapi template')
.option('--ts, --typescript', 'Use TypeScript to generate the project')
.description('create a new application')
.action((directory, programArgs) => {
initProject(directory, programArgs);
})
.parse(process.argv);

function generateApp(projectName: string, options: unknown) {
if (!projectName) {
console.error('Please specify the <directory> of your project when using --quickstart');
process.exit(1);
}

return generateNewApp(projectName, options).then(() => {
if (process.platform === 'win32') {
process.exit(0);
}
});
function generateApp(options: Partial<Options>) {
return generateNewApp(options)
.then(() => {
if (process.platform === 'win32') {
process.exit(0);
}
})
.catch((error) => {
console.error(`Error: ${error.message}`);
process.exit(1);
});
}

async function initProject(projectName: string, programArgs: Program) {
if (projectName) {
await checkInstallPath(resolve(projectName));
}

async function initProject(directory: string, programArgs: Program) {
const programFlags = command
.createHelp()
.visibleOptions(command)
Expand All @@ -73,38 +66,8 @@ async function initProject(projectName: string, programArgs: Program) {
process.exit(1);
}

const hasDatabaseOptions = databaseOptions.some((opt) => programArgs[opt]);

if (programArgs.quickstart && hasDatabaseOptions) {
console.error(
`The quickstart option is incompatible with the following options: ${databaseOptions.join(
', '
)}`
);
process.exit(1);
}

if (hasDatabaseOptions) {
programArgs.quickstart = false; // Will disable the quickstart question because != 'undefined'
}

if (programArgs.quickstart) {
return generateApp(projectName, programArgs);
}

const prompt = await promptUser(projectName, programArgs, hasDatabaseOptions);
const directory = prompt.directory || projectName;
await checkInstallPath(resolve(directory));

const options = {
template: programArgs.template,
quickstart: prompt.quick || programArgs.quickstart,
};

const generateStrapiAppOptions = {
return generateApp({
...programArgs,
...options,
};

return generateApp(directory, generateStrapiAppOptions);
directory,
});
}
3 changes: 1 addition & 2 deletions packages/cli/create-strapi-app/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ export interface Program {
useNpm?: boolean;
debug?: boolean;
quickstart?: boolean;
dbclient?: string;
dbclient?: 'mysql' | 'postgres' | 'sqlite';
dbhost?: string;
dbport?: string;
dbname?: string;
dbusername?: string;
dbpassword?: string;
dbssl?: string;
dbfile?: string;
dbforce?: boolean;
template?: string;
typescript?: boolean;
}
39 changes: 0 additions & 39 deletions packages/cli/create-strapi-app/src/utils/prompt-user.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ program
.version(packageJson.version)
.arguments('[directory], [starter]')
.option('--use-npm', 'Force usage of npm instead of yarn to create the project')
.option('--debug', 'Display database connection error')
.option('--quickstart', 'Quickstart app creation')
.option('--dbclient <dbclient>', 'Database client')
.option('--dbhost <dbhost>', 'Database host')
Expand All @@ -41,7 +40,6 @@ program
.option('--dbpassword <dbpassword>', 'Database password')
.option('--dbssl <dbssl>', 'Database SSL')
.option('--dbfile <dbfile>', 'Database file path for sqlite')
.option('--dbforce', 'Overwrite database content if any')
.description(
'Create a fullstack monorepo application using the strapi backend template specified in the provided starter'
)
Expand Down
1 change: 0 additions & 1 deletion packages/cli/create-strapi-starter/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,5 @@ export interface Program {
dbpassword?: string;
dbssl?: string;
dbfile?: string;
dbforce?: boolean;
template?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,22 @@ const ADMIN: TsConfigFiles = {
name: 'admin/tsconfig.json',
contents: outdent`
{
"extends": "@strapi/typescript-utils/tsconfigs/admin",
"compilerOptions: {
target: 'ESNext',
module: 'ESNext',
moduleResolution: 'Bundler',
useDefineForClassFields: true,
lib: ['DOM', 'DOM.Iterable', 'ESNext'],
allowJs: false,
skipLibCheck: true,
esModuleInterop: true,
allowSyntheticDefaultImports: true,
strict: true,
forceConsistentCasingInFileNames: true,
resolveJsonModule: true,
noEmit: true,
jsx: 'react-jsx',
},
"include": ["./src", "./custom.d.ts"],
"compilerOptions": {
"rootDir": "../",
Expand Down Expand Up @@ -42,11 +57,24 @@ const SERVER: TsConfigFiles = {
name: 'server/tsconfig.json',
contents: outdent`
{
"extends": "@strapi/typescript-utils/tsconfigs/server",
"include": ["./src"],
"compilerOptions": {
"rootDir": "../",
"baseUrl": ".",
"module": "CommonJS",
"moduleResolution": "Node",
"lib": ["ES2020"],
"target": "ES2019",
"strict": false,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"incremental": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"noEmitOnError": true,
"noImplicitThis": true
},
}
`,
Expand Down
1 change: 1 addition & 0 deletions packages/generators/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"devDependencies": {
"@strapi/pack-up": "5.0.0",
"@types/fs-extra": "11.0.4",
"@types/inquirer": "8.2.5",
"copyfiles": "2.4.1"
},
"engines": {
Expand Down
35 changes: 0 additions & 35 deletions packages/generators/app/src/create-cli-db-project.ts

This file was deleted.

Loading

0 comments on commit dae9cce

Please sign in to comment.