@futurebrand/dev-tools 2.1.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ import type { Command } from 'commander';
2
+ export declare function addCommands(program: Command): void;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addCommands = addCommands;
4
+ const project_setup_1 = require("./project-setup");
5
+ function addCommands(program) {
6
+ program.addCommand(project_setup_1.default);
7
+ }
@@ -0,0 +1,7 @@
1
+ import type { ProjectType } from '../../types';
2
+ export declare const UNUSED_FILES: string[];
3
+ export declare const ESLINT_CONFIG_FILE = "eslint.config.mjs";
4
+ export declare const PRETTIER_CONFIG_FILE = "prettier.config.mjs";
5
+ export declare const PRETTIER_PLUGIN_NAME = "PrettierConfig";
6
+ export declare const ESLINT_PLUGIN_NAMES: Record<ProjectType, string>;
7
+ export declare const DEV_DEPENDENCIES: string[];
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEV_DEPENDENCIES = exports.ESLINT_PLUGIN_NAMES = exports.PRETTIER_PLUGIN_NAME = exports.PRETTIER_CONFIG_FILE = exports.ESLINT_CONFIG_FILE = exports.UNUSED_FILES = void 0;
4
+ exports.UNUSED_FILES = [
5
+ '.eslintrc.js',
6
+ '.eslintrc.json',
7
+ '.eslintignore',
8
+ '.prettierrc',
9
+ '.lintstagedrc.js',
10
+ '.lintstagedrc.js',
11
+ ];
12
+ exports.ESLINT_CONFIG_FILE = 'eslint.config.mjs';
13
+ exports.PRETTIER_CONFIG_FILE = 'prettier.config.mjs';
14
+ exports.PRETTIER_PLUGIN_NAME = 'PrettierConfig';
15
+ exports.ESLINT_PLUGIN_NAMES = {
16
+ 'next.js': 'EslintNextjsConfigs',
17
+ react: 'EslintReactjsConfigs',
18
+ node: 'EslintNodeConfigs',
19
+ };
20
+ exports.DEV_DEPENDENCIES = [
21
+ '@futurebrand/dev-tools',
22
+ 'eslint',
23
+ 'prettier',
24
+ 'typescript',
25
+ ];
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ declare const projectSetup: Command;
3
+ export default projectSetup;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const commander_1 = require("commander");
4
+ const files_1 = require("../../modules/files");
5
+ const project_type_1 = require("../../modules/project-type");
6
+ const configs_1 = require("./configs");
7
+ const files_2 = require("./modules/files");
8
+ const packages_1 = require("./modules/packages");
9
+ const projectSetup = new commander_1.Command('setup')
10
+ .description('Setup project with default configurations')
11
+ .action(async () => {
12
+ const projectType = await (0, project_type_1.getProjectType)();
13
+ const eslintConfigName = configs_1.ESLINT_PLUGIN_NAMES[projectType];
14
+ await (0, files_1.deleteUnusedFiles)();
15
+ const eslintConfig = (0, files_2.getPluginConfig)(eslintConfigName);
16
+ const prettierConfig = (0, files_2.getPluginConfig)(configs_1.PRETTIER_PLUGIN_NAME);
17
+ await (0, files_1.writeFile)(configs_1.ESLINT_CONFIG_FILE, eslintConfig);
18
+ await (0, files_1.writeFile)(configs_1.PRETTIER_CONFIG_FILE, prettierConfig);
19
+ await (0, packages_1.removeUnusedPackages)();
20
+ await (0, packages_1.installDependencies)();
21
+ });
22
+ exports.default = projectSetup;
@@ -0,0 +1,2 @@
1
+ export declare function deleteUnusedFiles(): Promise<void>;
2
+ export declare function getPluginConfig(pluginImportName: string): string;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deleteUnusedFiles = deleteUnusedFiles;
4
+ exports.getPluginConfig = getPluginConfig;
5
+ const fs = require("node:fs/promises");
6
+ const path = require("node:path");
7
+ const files_1 = require("../../../modules/files");
8
+ const configs_1 = require("../configs");
9
+ async function deleteUnusedFiles() {
10
+ const root = process.cwd();
11
+ for (const file of configs_1.UNUSED_FILES) {
12
+ const filePath = path.join(root, file);
13
+ try {
14
+ if (await (0, files_1.verifyFileExist)(filePath)) {
15
+ await fs.unlink(filePath);
16
+ }
17
+ }
18
+ catch (error) {
19
+ console.error(`Failed to delete ${filePath}`);
20
+ throw error;
21
+ }
22
+ }
23
+ }
24
+ function getPluginConfig(pluginImportName) {
25
+ return `import { ${pluginImportName} } from '@futurebrand/dev-tools/plugins'
26
+
27
+ export default ${pluginImportName}
28
+ `;
29
+ }
@@ -0,0 +1,3 @@
1
+ export declare function removeEslintDependencies(dependencies: Record<string, string>): void;
2
+ export declare function removeUnusedPackages(): Promise<void>;
3
+ export declare function installDependencies(): Promise<void>;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.removeEslintDependencies = removeEslintDependencies;
4
+ exports.removeUnusedPackages = removeUnusedPackages;
5
+ exports.installDependencies = installDependencies;
6
+ const files_1 = require("../../../modules/files");
7
+ const package_manager_1 = require("../../../modules/package-manager");
8
+ const child_process_1 = require("child_process");
9
+ const configs_1 = require("../configs");
10
+ function removeEslintDependencies(dependencies) {
11
+ const keys = Object.keys(dependencies);
12
+ for (const key of keys) {
13
+ if ((key.includes('eslint') && key !== 'eslint') ||
14
+ (key.includes('prettier') && key !== 'prettier')) {
15
+ delete dependencies[key];
16
+ }
17
+ }
18
+ }
19
+ async function removeUnusedPackages() {
20
+ const PackageJson = await (0, files_1.loadPackageJson)();
21
+ removeEslintDependencies(PackageJson.devDependencies);
22
+ removeEslintDependencies(PackageJson.dependencies);
23
+ for (const dependency of configs_1.DEV_DEPENDENCIES) {
24
+ if (PackageJson.dependencies[dependency]) {
25
+ const version = PackageJson.dependencies[dependency];
26
+ delete PackageJson.dependencies[dependency];
27
+ PackageJson.devDependencies[dependency] = version;
28
+ }
29
+ if (!PackageJson.devDependencies[dependency]) {
30
+ PackageJson.devDependencies[dependency] = 'latest';
31
+ }
32
+ }
33
+ await (0, files_1.writePackageJson)(PackageJson);
34
+ }
35
+ async function installDependencies() {
36
+ const packageManager = await (0, package_manager_1.getPackageManager)();
37
+ const command = `${packageManager} install`;
38
+ return new Promise((resolve, reject) => {
39
+ (0, child_process_1.exec)(command, (error) => {
40
+ if (error) {
41
+ reject(error);
42
+ }
43
+ resolve();
44
+ });
45
+ });
46
+ }
package/dist/bin/index.js CHANGED
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const commander_1 = require("commander");
5
5
  const package_json_1 = require("../../package.json");
6
+ const commands_1 = require("./commands");
6
7
  commander_1.program
7
8
  .version(package_json_1.version)
8
9
  .description(package_json_1.description)
@@ -15,4 +16,5 @@ commander_1.program
15
16
  console.warn('Hello Futurebrand!');
16
17
  }
17
18
  });
19
+ (0, commands_1.addCommands)(commander_1.program);
18
20
  commander_1.program.parse(process.argv);
@@ -0,0 +1,6 @@
1
+ import type { PackageJson } from '../types';
2
+ export declare function verifyFileExist(filePath: string): Promise<boolean>;
3
+ export declare function deleteUnusedFiles(): Promise<void>;
4
+ export declare function writeFile(fileName: string, config: string): Promise<void>;
5
+ export declare function loadPackageJson(): Promise<PackageJson>;
6
+ export declare function writePackageJson(data: PackageJson): Promise<void>;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.verifyFileExist = verifyFileExist;
4
+ exports.deleteUnusedFiles = deleteUnusedFiles;
5
+ exports.writeFile = writeFile;
6
+ exports.loadPackageJson = loadPackageJson;
7
+ exports.writePackageJson = writePackageJson;
8
+ const fs = require("node:fs/promises");
9
+ const path = require("node:path");
10
+ const configs_1 = require("../commands/project-setup/configs");
11
+ async function verifyFileExist(filePath) {
12
+ try {
13
+ await fs.access(filePath);
14
+ return true;
15
+ }
16
+ catch {
17
+ return false;
18
+ }
19
+ }
20
+ async function deleteUnusedFiles() {
21
+ const root = process.cwd();
22
+ for (const file of configs_1.UNUSED_FILES) {
23
+ const filePath = path.join(root, file);
24
+ try {
25
+ if (await verifyFileExist(filePath)) {
26
+ await fs.unlink(filePath);
27
+ }
28
+ }
29
+ catch (error) {
30
+ console.error(`Failed to delete ${filePath}`);
31
+ throw error;
32
+ }
33
+ }
34
+ }
35
+ async function writeFile(fileName, config) {
36
+ const root = process.cwd();
37
+ const filePath = path.join(root, fileName);
38
+ try {
39
+ await fs.writeFile(filePath, config);
40
+ }
41
+ catch (error) {
42
+ console.error(`Failed to write ${filePath}`);
43
+ throw error;
44
+ }
45
+ }
46
+ async function loadPackageJson() {
47
+ const root = process.cwd();
48
+ const filePath = path.join(root, 'package.json');
49
+ try {
50
+ const file = await fs.readFile(filePath, 'utf-8');
51
+ return JSON.parse(file);
52
+ }
53
+ catch (error) {
54
+ console.error(`Failed to load ${filePath}`);
55
+ throw error;
56
+ }
57
+ }
58
+ async function writePackageJson(data) {
59
+ const root = process.cwd();
60
+ const filePath = path.join(root, 'package.json');
61
+ try {
62
+ await fs.writeFile(filePath, JSON.stringify(data, null, 2));
63
+ }
64
+ catch (error) {
65
+ console.error(`Failed to load ${filePath}`);
66
+ throw error;
67
+ }
68
+ }
@@ -0,0 +1 @@
1
+ export declare function getPackageManager(): Promise<"pnpm" | "yarn" | "npm">;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPackageManager = getPackageManager;
4
+ const files_1 = require("./files");
5
+ async function getPackageManager() {
6
+ const isPNPM = await (0, files_1.verifyFileExist)('pnpm-lock.yaml');
7
+ if (isPNPM) {
8
+ return 'pnpm';
9
+ }
10
+ const isYarn = await (0, files_1.verifyFileExist)('yarn.lock');
11
+ if (isYarn) {
12
+ return 'yarn';
13
+ }
14
+ return 'npm';
15
+ }
@@ -0,0 +1,2 @@
1
+ import type { ProjectType } from '../types';
2
+ export declare function getProjectType(): Promise<ProjectType>;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getProjectType = getProjectType;
4
+ const files_1 = require("../modules/files");
5
+ const inquirer_1 = require("inquirer");
6
+ const PROJECT_TYPES = ['next.js', 'react', 'node'];
7
+ async function isNextProject() {
8
+ if (await (0, files_1.verifyFileExist)('next.config.js')) {
9
+ return true;
10
+ }
11
+ const packageJson = await (0, files_1.loadPackageJson)();
12
+ return packageJson.dependencies['next'] != null;
13
+ }
14
+ async function isStrapiProject() {
15
+ const packageJson = await (0, files_1.loadPackageJson)();
16
+ return packageJson.dependencies['@strapi/strapi'] != null;
17
+ }
18
+ async function getProjectType() {
19
+ const isNext = await isNextProject();
20
+ if (isNext) {
21
+ return 'next.js';
22
+ }
23
+ const isStrapi = await isStrapiProject();
24
+ if (isStrapi) {
25
+ return 'node';
26
+ }
27
+ const { projectType } = await inquirer_1.default.prompt([
28
+ {
29
+ type: 'list',
30
+ name: 'projectType',
31
+ message: 'Select the project type',
32
+ choices: PROJECT_TYPES,
33
+ },
34
+ ]);
35
+ return projectType;
36
+ }
@@ -0,0 +1,8 @@
1
+ export type ProjectType = 'next.js' | 'react' | 'node';
2
+ export interface PackageJson {
3
+ name: string;
4
+ version: string;
5
+ scripts: Record<string, string>;
6
+ devDependencies: Record<string, string>;
7
+ dependencies: Record<string, string>;
8
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,7 +1,11 @@
1
1
  import { type ConfigArray } from 'typescript-eslint';
2
- export declare const MAX_COMPLEXITY = 15;
2
+ export declare const MAX_COMPLEXITY = 20;
3
3
  export declare const MAX_LINES = 450;
4
- /** @type {import('typescript-eslint').ConfigArray} */
5
- export declare const TypescriptConfigs: ConfigArray;
6
- /** @type {import('typescript-eslint').ConfigArray} */
7
- export declare const JavascriptConfigs: ConfigArray;
4
+ interface IConfigParams {
5
+ node?: boolean;
6
+ browser?: boolean;
7
+ typescript?: boolean;
8
+ prettier?: boolean;
9
+ }
10
+ export declare function getBaseConfig({ node, browser, typescript, prettier, }: IConfigParams): ConfigArray;
11
+ export {};
@@ -1,29 +1,39 @@
1
1
  import pluginJs from '@eslint/js';
2
- import prettier from 'eslint-plugin-prettier/recommended';
2
+ import prettierRecommended from 'eslint-plugin-prettier/recommended';
3
3
  import globals from 'globals';
4
4
  import tseslint from 'typescript-eslint';
5
- export const MAX_COMPLEXITY = 15;
5
+ export const MAX_COMPLEXITY = 20;
6
6
  export const MAX_LINES = 450;
7
- /** @type {import('typescript-eslint').ConfigArray} */
8
- export const TypescriptConfigs = [
9
- { files: ['**/*.{js,jsx,mjs,cjs,ts,tsx,mts}'] },
10
- { languageOptions: { globals: { ...globals.browser, ...globals.node } } },
11
- pluginJs.configs.recommended,
12
- ...tseslint.configs.recommendedTypeChecked,
13
- {
7
+ export function getBaseConfig({ node = false, browser = false, typescript = true, prettier = true, }) {
8
+ const configs = [];
9
+ if (typescript) {
10
+ configs.push({ files: ['**/*.{js,jsx,mjs,cjs,ts,tsx,mts}'] });
11
+ }
12
+ else {
13
+ configs.push({ files: ['**/*.{js,jsx,mjs,cjs}'] });
14
+ }
15
+ configs.push({
14
16
  languageOptions: {
15
- parserOptions: {
16
- projectService: true,
17
- tsconfigRootDir: process.cwd(),
17
+ globals: {
18
+ ...(node ? globals.node : {}),
19
+ ...(browser ? globals.browser : {}),
18
20
  },
19
21
  },
20
- },
21
- prettier,
22
- ];
23
- /** @type {import('typescript-eslint').ConfigArray} */
24
- export const JavascriptConfigs = [
25
- { files: ['**/*.{js,jsx,mjs,cjs}'] },
26
- { languageOptions: { globals: { ...globals.browser, ...globals.node } } },
27
- pluginJs.configs.recommended,
28
- prettier,
29
- ];
22
+ });
23
+ configs.push(pluginJs.configs.recommended);
24
+ if (typescript) {
25
+ configs.push(...tseslint.configs.recommendedTypeChecked);
26
+ configs.push({
27
+ languageOptions: {
28
+ parserOptions: {
29
+ projectService: true,
30
+ tsconfigRootDir: process.cwd(),
31
+ },
32
+ },
33
+ });
34
+ }
35
+ if (prettier) {
36
+ configs.push(prettierRecommended);
37
+ }
38
+ return configs;
39
+ }
@@ -77,8 +77,8 @@ export const IgnoreRules = {
77
77
  '.next/**/*',
78
78
  '.tmp/**/*',
79
79
  'node_modules/**/*',
80
- "eslint.config.mjs",
81
- 'prettier.config.mjs'
80
+ 'eslint.config.mjs',
81
+ 'prettier.config.mjs',
82
82
  ],
83
83
  };
84
84
  export const PrettierRules = {
@@ -1,2 +1,3 @@
1
1
  export * from './next.mjs';
2
2
  export * from './node.mjs';
3
+ export * from './react.mjs';
@@ -1,2 +1,3 @@
1
1
  export * from './next.mjs';
2
2
  export * from './node.mjs';
3
+ export * from './react.mjs';
@@ -1,9 +1,12 @@
1
1
  import next from '@next/eslint-plugin-next';
2
2
  import tseslint from 'typescript-eslint';
3
- import { TypescriptConfigs } from './configs/configs.mjs';
3
+ import { getBaseConfig } from './configs/configs.mjs';
4
4
  import { TypescriptRules } from './configs/rules.mjs';
5
5
  export const EslintNextjsConfigs = tseslint.config([
6
- ...TypescriptConfigs,
6
+ ...getBaseConfig({
7
+ browser: true,
8
+ node: true,
9
+ }),
7
10
  {
8
11
  plugins: {
9
12
  '@next/next': next,
@@ -1,8 +1,10 @@
1
1
  import tseslint from 'typescript-eslint';
2
- import { TypescriptConfigs } from './configs/configs.mjs';
2
+ import { getBaseConfig } from './configs/configs.mjs';
3
3
  import { TypescriptRules } from './configs/rules.mjs';
4
4
  export const EslintNodeConfigs = tseslint.config([
5
- ...TypescriptConfigs,
5
+ ...getBaseConfig({
6
+ node: true,
7
+ }),
6
8
  ...TypescriptRules,
7
9
  {
8
10
  rules: {
@@ -21,9 +23,6 @@ export const EslintNodeConfigs = tseslint.config([
21
23
  },
22
24
  },
23
25
  {
24
- ignores: [
25
- 'strapi/**/*',
26
- 'types/generated/**/*',
27
- ],
28
- }
26
+ ignores: ['strapi/**/*', '.strapi/**/*', 'types/generated/**/*'],
27
+ },
29
28
  ]);
@@ -0,0 +1,2 @@
1
+ import type { ConfigArray } from 'typescript-eslint';
2
+ export declare const EslintReactjsConfigs: ConfigArray;
@@ -0,0 +1,9 @@
1
+ import tseslint from 'typescript-eslint';
2
+ import { getBaseConfig } from './configs/configs.mjs';
3
+ import { TypescriptRules } from './configs/rules.mjs';
4
+ export const EslintReactjsConfigs = tseslint.config([
5
+ ...getBaseConfig({
6
+ browser: true,
7
+ }),
8
+ ...TypescriptRules,
9
+ ]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@futurebrand/dev-tools",
3
- "version": "2.1.1",
3
+ "version": "2.2.0",
4
4
  "description": "FutureBrand Dev Tools",
5
5
  "scripts": {
6
6
  "build": "tsc && tsc-alias",
@@ -52,37 +52,38 @@
52
52
  }
53
53
  },
54
54
  "dependencies": {
55
- "@eslint/js": "^9.21.0",
56
- "@next/eslint-plugin-next": "^15.2.0",
55
+ "@eslint/js": "^9.22.0",
56
+ "@next/eslint-plugin-next": "^15.2.3",
57
57
  "commander": "^13.1.0",
58
- "eslint": "^9.21.0",
59
- "eslint-config-prettier": "^10.0.2",
58
+ "eslint": "^9.22.0",
59
+ "eslint-config-prettier": "^10.1.1",
60
60
  "eslint-plugin-prettier": "^5.2.3",
61
61
  "eslint-plugin-simple-import-sort": "^12.1.1",
62
62
  "globals": "^16.0.0",
63
- "prettier": "^3.5.2",
63
+ "inquirer": "^12.5.0",
64
+ "prettier": "^3.5.3",
64
65
  "prettier-plugin-tailwindcss": "^0.6.11",
65
- "typescript-eslint": "^8.25.0"
66
+ "typescript-eslint": "^8.26.1"
66
67
  },
67
68
  "devDependencies": {
68
- "@types/node": "^22.13.5",
69
- "@typescript-eslint/utils": "^8.25.0",
69
+ "@types/node": "^22.13.10",
70
+ "@typescript-eslint/utils": "^8.26.1",
70
71
  "jiti": "^2.4.2",
71
72
  "tsc-alias": "^1.8.11",
72
- "typescript": "^5.7.3"
73
+ "typescript": "^5.8.2"
73
74
  },
74
75
  "peerDependencies": {
75
76
  "eslint": "^9.21.0",
76
77
  "prettier": "^3.5.2"
77
78
  },
78
79
  "overrides": {
79
- "eslint": "^9.21.0",
80
- "prettier": "^3.5.2"
80
+ "eslint": "^9.22.0",
81
+ "prettier": "^3.5.3"
81
82
  },
82
83
  "pnpm": {
83
84
  "overrides": {
84
- "eslint": "^9.21.0",
85
- "prettier": "^3.5.2"
85
+ "eslint": "^9.22.0",
86
+ "prettier": "^3.5.3"
86
87
  }
87
88
  }
88
89
  }