Skip to content

Commit

Permalink
Create theme command (#1)
Browse files Browse the repository at this point in the history
* Add create theme command

* delete jsdom

* delete proxu agent

* change option copy
  • Loading branch information
ErnestTeluk authored Nov 29, 2024
1 parent cf416f2 commit 336d0d7
Show file tree
Hide file tree
Showing 11 changed files with 354 additions and 5 deletions.
4 changes: 3 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"import/no-extraneous-dependencies": 0,
"import/prefer-default-export": 0,
"@typescript-eslint/no-shadow": 0,
"no-restricted-syntax": 0
"no-restricted-syntax": 0,
"no-await-in-loop": 0,
"no-promise-executor-return": 0
}
}
93 changes: 92 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@
"eslint-config-airbnb-typescript": "18.0.0",
"eslint-config-prettier": "9.1.0",
"kolorist": "1.7.0",
"node-fetch": "3.3.2",
"prettier": "3.3.3",
"prompts": "^2.4.2",
"prompts": "2.4.2",
"typescript": "5.6.3",
"typescript-eslint": "8.8.1",
"unbuild": "2.0.0"
Expand Down
5 changes: 4 additions & 1 deletion src/commands/createForm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ const customDirPathPrompt: PromptObject = {
export const createForm = new Command()
.name('createForm')
.description('Creates new uniforms form template')
.option('-s, --skip', 'skip custom dir question, and create in current dir')
.option(
'-s, --skip',
'skip custom directory question, and create in current directory',
)
.option(
'-e, --extension <extension>',
`Select extension (${fileTypes.map(({ value }) => value).join(', ')})`,
Expand Down
128 changes: 128 additions & 0 deletions src/commands/createTheme/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { Command } from 'commander';
import { execSync } from 'node:child_process';
import prompts, { PromptObject } from 'prompts';
import { bold, red } from 'kolorist';
import { fetchFiles } from '../../lib/fetchFilesFromGithub';
import { createTsConfigFileInFolder } from '../../lib/createTsConfigFileInFolder';
import { fileTypes } from '../../consts';
import { deleteSpecificFilesInFolder } from '../../lib/deleteSpecificFilesInFolder';
import { createFolder } from '../../lib/createFolder';
import { copyFiles } from '../../lib/copyFiles';

const extensionPrompt: PromptObject = {
type: 'select',
name: 'extension',
message: bold('Select extension:'),
choices: () =>
fileTypes.map(({ title, color, value }) => ({
title: color(title),
value,
})),
};

const themeNamePrompt: PromptObject = {
type: 'text',
name: 'themeName',
message: bold('Insert theme name:'),
initial: 'my-custom-theme',
};

const customDirPrompt: PromptObject = {
type: 'confirm',
name: 'customDir',
message: bold('Choose custom directory?:'),
};
const customDirPathPrompt: PromptObject = {
type: 'text',
name: 'customDirPath',
message: bold('Insert path to custom directory:'),
};

export const createTheme = new Command()
.name('createTheme')
.description('Creates new uniforms theme template')
.option('-n, --name <name>', 'Insert theme name')
.option(
'-s, --skip',
'skip custom directory question, and create in current directory',
)
.option(
'-e, --extension <extension>',
`Select extension (${fileTypes.map(({ value }) => value).join(', ')})`,
)
.action(async (options) => {
const {
skip: skipFlag,
extension: extensionFlag,
name: themeName,
} = options;
const findExtension = fileTypes.find(
({ value }) => value === extensionFlag,
);

let result: prompts.Answers<'extension' | 'customDir' | 'themeName'>;
try {
result = await prompts(
[
// @ts-expect-error
...[themeName ? [] : themeNamePrompt],
// @ts-expect-error
...[findExtension ? [] : extensionPrompt],
// @ts-expect-error
...[skipFlag ? [] : customDirPrompt],
],
{
onCancel: (error) => {
console.log('error', error);

Check warning on line 76 in src/commands/createTheme/index.ts

View workflow job for this annotation

GitHub Actions / CI

Unexpected console statement
throw new Error(red('✖') + bold(' Operation cancelled'));
},
},
);
} catch (error: any) {
console.log(error.message);

Check warning on line 82 in src/commands/createTheme/index.ts

View workflow job for this annotation

GitHub Actions / CI

Unexpected console statement
return;
}

let customDirPath: string | undefined;
let dirPathPromptResult: prompts.Answers<'customDirPath'>;
if (result.customDir) {
try {
dirPathPromptResult = await prompts([customDirPathPrompt], {
onCancel: () => {
throw new Error(red('✖') + bold(' Operation cancelled'));
},
});
customDirPath = dirPathPromptResult.customDirPath;
} catch (error: any) {
console.log(error.message);

Check warning on line 97 in src/commands/createTheme/index.ts

View workflow job for this annotation

GitHub Actions / CI

Unexpected console statement
return;
}
}

console.log('Fetching custom theme...');

Check warning on line 102 in src/commands/createTheme/index.ts

View workflow job for this annotation

GitHub Actions / CI

Unexpected console statement
const { tempDir } = await fetchFiles();
console.log('Custom theme fetched successfully.');

Check warning on line 104 in src/commands/createTheme/index.ts

View workflow job for this annotation

GitHub Actions / CI

Unexpected console statement

const extension = findExtension?.value || result.extension;

const isJsx = extension === 'jsx';

if (isJsx) {
console.log('Parsing files...');

Check warning on line 111 in src/commands/createTheme/index.ts

View workflow job for this annotation

GitHub Actions / CI

Unexpected console statement
createTsConfigFileInFolder(tempDir);
execSync(
`npm install -g typescript --quiet && cd ${tempDir} && npx --yes tsc --noCheck`,
);
deleteSpecificFilesInFolder(`${tempDir}/striped`, ['types.js']);
console.log('Files parsed successfully.');

Check warning on line 117 in src/commands/createTheme/index.ts

View workflow job for this annotation

GitHub Actions / CI

Unexpected console statement
}

console.log('Creating theme...');
const createdFolderPath = createFolder({
folderName: themeName || result.themeName,
customDirPath,
directory: process.cwd(),
});
copyFiles(isJsx ? `${tempDir}/striped` : `${tempDir}`, createdFolderPath);
console.log('Theme created successfully.');
});
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import { Command } from 'commander';
import { version } from '../package.json';
import { init } from './commands/init';
import { createForm } from './commands/createForm';
import { createTheme } from './commands/createTheme';

(async () => {
const program = new Command();

program.version(version).description('CLI for uniforms');

program.addCommand(init).addCommand(createForm);
program.addCommand(init).addCommand(createForm).addCommand(createTheme);

program.parse();
})();
23 changes: 23 additions & 0 deletions src/lib/copyFiles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import fs from 'node:fs';
import path from 'node:path';

export const copyFiles = (sourceFolder: string, destinationFolder: string) => {
if (!fs.existsSync(sourceFolder)) {
console.error(`Source folder not found: ${sourceFolder}`);
return;
}

if (!fs.existsSync(destinationFolder)) {
fs.mkdirSync(destinationFolder, { recursive: true });
}

const files = fs.readdirSync(sourceFolder);
for (const file of files) {
const sourceFilePath = path.join(sourceFolder, file);
const destinationFilePath = path.join(destinationFolder, file);

if (fs.lstatSync(sourceFilePath).isFile()) {
fs.copyFileSync(sourceFilePath, destinationFilePath);
}
}
};
24 changes: 24 additions & 0 deletions src/lib/createFolder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import path from 'node:path';
import fs from 'node:fs';

export const createFolder = ({
folderName,
directory = process.cwd(),
customDirPath,
}: {
folderName: string;
directory?: string;
customDirPath?: string;
}) => {
const dirPath = path.join(
directory,
customDirPath ? `/${customDirPath}` : '',
folderName,
);

if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, { recursive: true });
}

return dirPath;
};
20 changes: 20 additions & 0 deletions src/lib/createTsConfigFileInFolder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import fs from 'node:fs';
import path from 'node:path';

export const createTsConfigFileInFolder = (folderPath: string) => {
const tsConfig = {
include: [`./**/*`],
compilerOptions: {
outDir: `./striped`,
target: 'es2020',
module: 'es2020',
strict: false,
esModuleInterop: true,
jsx: 'react',
moduleResolution: 'node',
},
};

const filePath = path.join(folderPath, 'tsconfig.json');
fs.writeFileSync(filePath, JSON.stringify(tsConfig, null, 2));
};
Loading

0 comments on commit 336d0d7

Please sign in to comment.