@ceylar/ada 0.0.2

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,67 @@
1
+ import js from '@eslint/js';
2
+ import react from 'eslint-plugin-react';
3
+ import reactHooks from 'eslint-plugin-react-hooks';
4
+ import simpleImportSort from 'eslint-plugin-simple-import-sort';
5
+ import globals from 'globals';
6
+ import ts from 'typescript-eslint';
7
+
8
+ /** @type {import('eslint').Linter.Config<Linter.RulesRecord>[]} */
9
+ export default ts.config(
10
+ js.configs.recommended,
11
+ ...ts.configs.recommended,
12
+ {
13
+ plugins: {
14
+ react: react,
15
+ 'react-hooks': reactHooks,
16
+ 'simple-import-sort': simpleImportSort,
17
+ ts: ts.plugin
18
+ },
19
+ rules: {
20
+ 'prefer-const': 'error',
21
+ 'no-else-return': 'error',
22
+
23
+ 'react-hooks/exhaustive-deps': 'off',
24
+
25
+ 'no-console': 'warn',
26
+
27
+ 'simple-import-sort/exports': 'error',
28
+ 'simple-import-sort/imports': [
29
+ 'error',
30
+ {
31
+ groups: [
32
+ ['^react', '^@?\\w'],
33
+ ['^@(([\\/.]?\\w)|assets|test-utils)'],
34
+ ['^\\u0000'],
35
+ ['^\\.\\.(?!/?$)', '^\\.\\./?$'],
36
+ ['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'],
37
+ ['^.+\\.s?css$']
38
+ ]
39
+ }
40
+ ]
41
+ },
42
+ languageOptions: {
43
+ globals: {
44
+ ...globals.node,
45
+ ...globals.browser,
46
+ ...globals.es2022
47
+ }
48
+ }
49
+ },
50
+ {
51
+ languageOptions: {
52
+ parserOptions: {
53
+ project: ['tsconfig.json']
54
+ }
55
+ },
56
+ files: ['/src/**/*.ts', '/src/**/*.tsx']
57
+ },
58
+ {
59
+ languageOptions: {
60
+ parserOptions: react.configs.recommended.parserOptions
61
+ },
62
+ files: ['/src/**/*.js', '/src/**/*.jsx']
63
+ },
64
+ {
65
+ ignores: ['node_modules', 'build', 'dist']
66
+ }
67
+ );
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@ceylar/ada",
3
+ "description": "CLI to help you initialize projects",
4
+ "version": "0.0.2",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "bin": {
8
+ "ada": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "shx rm -rf dist && cross-env NODE_ENV=production rollup -c --bundleConfigAsCjs",
12
+ "dev": "shx rm -rf dist && cross-env NODE_ENV=development rollup -c --bundleConfigAsCjs --watch",
13
+ "lint": "eslint .",
14
+ "lint:fix": "eslint --fix .",
15
+ "format": "prettier --check src --ignore-path .gitignore",
16
+ "format:fix": "prettier --write src --ignore-path .gitignore"
17
+ },
18
+ "devDependencies": {
19
+ "@babel/core": "^7.26.9",
20
+ "@babel/preset-env": "^7.26.9",
21
+ "@babel/preset-react": "^7.26.3",
22
+ "@babel/preset-typescript": "^7.26.0",
23
+ "@eslint/js": "^9.21.0",
24
+ "@rollup/plugin-alias": "^5.1.1",
25
+ "@rollup/plugin-babel": "^6.0.4",
26
+ "@rollup/plugin-commonjs": "^28.0.2",
27
+ "@rollup/plugin-json": "^6.1.0",
28
+ "@rollup/plugin-node-resolve": "^16.0.0",
29
+ "@rollup/plugin-terser": "^0.4.4",
30
+ "@rollup/plugin-typescript": "^12.1.2",
31
+ "@types/node": "^22.13.4",
32
+ "cross-env": "^7.0.3",
33
+ "eslint": "^9.21.0",
34
+ "eslint-plugin-react": "^7.37.4",
35
+ "eslint-plugin-react-hooks": "^5.1.0",
36
+ "eslint-plugin-simple-import-sort": "^12.1.1",
37
+ "globals": "^16.0.0",
38
+ "prettier": "^3.5.2",
39
+ "rollup": "^4.34.8",
40
+ "rollup-plugin-copy": "^3.5.0",
41
+ "shx": "^0.3.4",
42
+ "tslib": "^2.8.1",
43
+ "typescript": "^5.7.3",
44
+ "typescript-eslint": "^8.24.1"
45
+ },
46
+ "dependencies": {
47
+ "commander": "^13.1.0",
48
+ "zod": "^3.24.2"
49
+ },
50
+ "repository": "https://github.com/Ceylar37/ada.git",
51
+ "author": "ceylar37 <ceylar37@gmail.com>"
52
+ }
@@ -0,0 +1,12 @@
1
+ /** @type {import('prettier').Config} */
2
+ export default {
3
+ printWidth: 120,
4
+ singleQuote: true,
5
+ jsxSingleQuote: true,
6
+ trailingComma: 'none',
7
+ semi: true,
8
+ tabWidth: 2,
9
+ useTabs: false,
10
+ endOfLine: 'crlf',
11
+ arrowParens: 'always'
12
+ };
package/readme.md ADDED
@@ -0,0 +1,3 @@
1
+ ### ada
2
+
3
+ CLI to help you initialize your javascript projects
@@ -0,0 +1,67 @@
1
+ import js from '@eslint/js';
2
+ import react from 'eslint-plugin-react';
3
+ import reactHooks from 'eslint-plugin-react-hooks';
4
+ import simpleImportSort from 'eslint-plugin-simple-import-sort';
5
+ import globals from 'globals';
6
+ import ts from 'typescript-eslint';
7
+
8
+ /** @type {import('eslint').Linter.Config<Linter.RulesRecord>[]} */
9
+ export default ts.config(
10
+ js.configs.recommended,
11
+ ...ts.configs.recommended,
12
+ {
13
+ plugins: {
14
+ react: react,
15
+ 'react-hooks': reactHooks,
16
+ 'simple-import-sort': simpleImportSort,
17
+ ts: ts.plugin
18
+ },
19
+ rules: {
20
+ 'prefer-const': 'error',
21
+ 'no-else-return': 'error',
22
+
23
+ 'react-hooks/exhaustive-deps': 'off',
24
+
25
+ 'no-console': 'warn',
26
+
27
+ 'simple-import-sort/exports': 'error',
28
+ 'simple-import-sort/imports': [
29
+ 'error',
30
+ {
31
+ groups: [
32
+ ['^react', '^@?\\w'],
33
+ ['^@(([\\/.]?\\w)|assets|test-utils)'],
34
+ ['^\\u0000'],
35
+ ['^\\.\\.(?!/?$)', '^\\.\\./?$'],
36
+ ['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'],
37
+ ['^.+\\.s?css$']
38
+ ]
39
+ }
40
+ ]
41
+ },
42
+ languageOptions: {
43
+ globals: {
44
+ ...globals.node,
45
+ ...globals.browser,
46
+ ...globals.es2022
47
+ }
48
+ }
49
+ },
50
+ {
51
+ languageOptions: {
52
+ parserOptions: {
53
+ project: ['tsconfig.json']
54
+ }
55
+ },
56
+ files: ['/src/**/*.ts', '/src/**/*.tsx']
57
+ },
58
+ {
59
+ languageOptions: {
60
+ parserOptions: react.configs.recommended.parserOptions
61
+ },
62
+ files: ['/src/**/*.js', '/src/**/*.jsx']
63
+ },
64
+ {
65
+ ignores: ['node_modules', 'build', 'dist']
66
+ }
67
+ );
@@ -0,0 +1,12 @@
1
+ /** @type {import('prettier').Config} */
2
+ export default {
3
+ printWidth: 120,
4
+ singleQuote: true,
5
+ jsxSingleQuote: true,
6
+ trailingComma: 'none',
7
+ semi: true,
8
+ tabWidth: 2,
9
+ useTabs: false,
10
+ endOfLine: 'crlf',
11
+ arrowParens: 'always'
12
+ };
@@ -0,0 +1,7 @@
1
+ /** @type {import('stylelint').Config} */
2
+ export default {
3
+ extends: 'stylelint-config-standard-scss',
4
+ rules: {
5
+ 'selector-class-pattern': ['^[a-z][a-zA-Z0-9]*$', { message: 'Selector should be in camelCase' }]
6
+ }
7
+ };
@@ -0,0 +1,37 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "esnext",
4
+ "lib": [
5
+ "dom",
6
+ "dom.iterable",
7
+ "esnext"
8
+ ],
9
+ "allowJs": true,
10
+ "skipLibCheck": true,
11
+ "esModuleInterop": true,
12
+ "allowSyntheticDefaultImports": true,
13
+ "strict": true,
14
+ "forceConsistentCasingInFileNames": true,
15
+ "module": "esnext",
16
+ "newLine": "lf",
17
+ "moduleResolution": "bundler",
18
+ "isolatedModules": true,
19
+ "resolveJsonModule": true,
20
+ "noEmit": true,
21
+ "jsx": "react-jsx",
22
+ "sourceMap": true,
23
+ "noUnusedLocals": true,
24
+ "noUnusedParameters": true,
25
+ "noFallthroughCasesInSwitch": true,
26
+ "baseUrl": ".",
27
+ "paths": {
28
+ "@/*": [
29
+ "./src/*"
30
+ ],
31
+ }
32
+ },
33
+ "exclude": [
34
+ "dist",
35
+ "node_modules",
36
+ ]
37
+ }
@@ -0,0 +1,59 @@
1
+ import alias from '@rollup/plugin-alias';
2
+ import babel from '@rollup/plugin-babel';
3
+ import commonjs from '@rollup/plugin-commonjs';
4
+ import json from '@rollup/plugin-json';
5
+ import resolve from '@rollup/plugin-node-resolve';
6
+ import terser from '@rollup/plugin-terser';
7
+ import typescript from '@rollup/plugin-typescript';
8
+
9
+ import packageJSON from './package.json';
10
+
11
+ import { resolve as resolvePath } from 'path';
12
+ import copy from 'rollup-plugin-copy';
13
+
14
+ const sourcemap = false;
15
+ const input = 'src/index.ts';
16
+ const banner = `/* @license ${packageJSON.name} v${packageJSON.version} */`;
17
+
18
+ const isDev = process.env.NODE_ENV === 'development';
19
+
20
+ /** @type {import('rollup').RollupOptions[]} */
21
+ export default [
22
+ {
23
+ input,
24
+ output: Object.values(packageJSON.bin).map((bin) => ({
25
+ format: 'esm',
26
+ file: bin,
27
+ sourcemap,
28
+ banner
29
+ })),
30
+ plugins: [
31
+ alias({
32
+ entries: [{ find: '@', replacement: resolvePath(__dirname, './src') }]
33
+ }),
34
+ resolve({
35
+ extensions: ['.js', '.ts']
36
+ }),
37
+ commonjs({
38
+ include: /node_modules/,
39
+ ignoreDynamicRequires: true
40
+ }),
41
+ typescript({
42
+ tsconfig: './tsconfig.json',
43
+ compilerOptions: { noCheck: isDev },
44
+ noForceEmit: true
45
+ }),
46
+ babel({
47
+ exclude: /node_modules/,
48
+ extensions: ['.js', '.ts'],
49
+ babelHelpers: 'bundled',
50
+ presets: ['@babel/preset-env', '@babel/preset-typescript']
51
+ }),
52
+ json(),
53
+ copy({
54
+ targets: [{ src: 'resources/*', dest: 'dist/resources' }]
55
+ }),
56
+ ...(!isDev ? [terser()] : [])
57
+ ]
58
+ }
59
+ ];
@@ -0,0 +1,21 @@
1
+ import { get as getConfig } from '@/config';
2
+ import { selectConfigSchema } from '@/config/schema';
3
+ import { isEmpty } from '@/util';
4
+
5
+ import { AppCommand } from '../type';
6
+
7
+ const get: AppCommand<typeof selectConfigSchema> = {
8
+ name: 'get',
9
+ description: 'get variables from config',
10
+ options: [['-m, --manager', 'package manager that will be used to install dependencies']],
11
+ schema: selectConfigSchema,
12
+ action: (options) => {
13
+ if (isEmpty(options)) {
14
+ console.log(getConfig());
15
+ return;
16
+ }
17
+ console.log(getConfig(options));
18
+ }
19
+ };
20
+
21
+ export { get };
@@ -0,0 +1,3 @@
1
+ export { get } from './get';
2
+ export { init } from './init';
3
+ export { set } from './set';
@@ -0,0 +1,102 @@
1
+ import { get } from '@/config';
2
+ import { Manager, managerSchema } from '@/entities/manager';
3
+ import { logger, resolveCurrentDir } from '@/util';
4
+
5
+ import { AppCommand } from '../type';
6
+
7
+ import { exec } from 'child_process';
8
+ import fsPromises from 'fs/promises';
9
+ import { z } from 'zod';
10
+
11
+ const initSchema = z.object({
12
+ prettier: z.boolean().optional(),
13
+ eslint: z.boolean().optional(),
14
+ typescript: z.boolean().optional(),
15
+ stylelint: z.boolean().optional(),
16
+ manager: managerSchema.optional()
17
+ });
18
+
19
+ const getInstallationString = (manager: Manager, packages: string[]) => {
20
+ switch (manager) {
21
+ case 'npm':
22
+ return `npm install --save-dev ${packages.join(' ')}`;
23
+ case 'yarn':
24
+ return `yarn add --dev ${packages.join(' ')}`;
25
+ case 'pnpm':
26
+ return `pnpm add --save-dev ${packages.join(' ')}`;
27
+ }
28
+ };
29
+
30
+ const installDependencies = (manager: Manager, packages: string[]) => {
31
+ const childProcess = exec(getInstallationString(manager, packages));
32
+ childProcess.stdout?.pipe(process.stdout);
33
+ childProcess.stderr?.pipe(process.stderr);
34
+ };
35
+
36
+ const copyResource = async (resource: string) => {
37
+ await fsPromises.copyFile(resolveCurrentDir('resources', resource), resource);
38
+ };
39
+
40
+ type Init = z.infer<typeof initSchema>;
41
+ const setupFunctionsDictionary: Record<Exclude<keyof Init, 'manager'>, (manager: Manager) => void> = {
42
+ prettier: async (manager) => {
43
+ await copyResource('prettier.config.mjs');
44
+ installDependencies(manager, ['prettier']);
45
+ },
46
+ eslint: async (manager) => {
47
+ await copyResource('eslint.config.mjs');
48
+ installDependencies(manager, [
49
+ 'eslint',
50
+ '@eslint/js',
51
+ 'eslint-plugin-react',
52
+ 'eslint-plugin-react-hooks',
53
+ 'eslint-plugin-simple-import-sort',
54
+ 'globals',
55
+ 'typescript-eslint'
56
+ ]);
57
+ },
58
+ typescript: async (manager) => {
59
+ await copyResource('tsconfig.json');
60
+ installDependencies(manager, ['typescript']);
61
+ },
62
+ stylelint: async (manager) => {
63
+ await copyResource('stylelint.config.mjs');
64
+ installDependencies(manager, ['stylelint', 'stylelint-config-standard-scss']);
65
+ }
66
+ };
67
+
68
+ const init: AppCommand<typeof initSchema> = {
69
+ name: 'init',
70
+ description: 'initialize configs',
71
+ options: [
72
+ ['-p, --prettier', 'setup prettier'],
73
+ ['-e, --eslint', 'setup eslint'],
74
+ ['-t, --typescript', 'setup typescript'],
75
+ ['-s, --stylelint', 'setup stylelint'],
76
+ ['-m, --manager <npm | yarn | pnpm>', 'package manager that will be used to install dependencies']
77
+ ],
78
+ schema: initSchema,
79
+ isDefault: true,
80
+ action: (options) => {
81
+ const optionsWithConfig = {
82
+ ...get(),
83
+ ...options
84
+ };
85
+
86
+ const { manager, ...rest } = optionsWithConfig;
87
+
88
+ if (!manager) {
89
+ return logger.error(
90
+ "Manager didn't specified. Please, set it up with `set` command or use -m or --manager option."
91
+ );
92
+ }
93
+
94
+ Object.entries(rest).forEach(([key, value]) => {
95
+ if (value) {
96
+ setupFunctionsDictionary[key as keyof typeof rest](manager);
97
+ }
98
+ });
99
+ }
100
+ };
101
+
102
+ export { init };
@@ -0,0 +1,13 @@
1
+ import { configSchema, set as setConfig } from '@/config';
2
+
3
+ import { AppCommand } from '../type';
4
+
5
+ const set: AppCommand<typeof configSchema> = {
6
+ name: 'set',
7
+ description: 'sets variable to config',
8
+ options: [['-m, --manager <npm | yarn | pnpm>', 'package manager that will be used to install dependencies']],
9
+ schema: configSchema,
10
+ action: setConfig
11
+ };
12
+
13
+ export { set };
@@ -0,0 +1,12 @@
1
+ import { z } from 'zod';
2
+
3
+ interface AppCommand<Schema extends z.ZodType> {
4
+ name: string;
5
+ description: string;
6
+ options?: [string, string?][];
7
+ action: (options: z.infer<Schema>) => void;
8
+ schema: Schema;
9
+ isDefault?: true;
10
+ }
11
+
12
+ export type { AppCommand };
@@ -0,0 +1,23 @@
1
+ import { ZodError } from 'zod';
2
+
3
+ const getOptionKeys = (option: [string, string?]) => {
4
+ const short = option[0].match(/(?<!-)-(\w)/)?.[1];
5
+ const long = option[0].match(/--(\w+)/)?.[1];
6
+
7
+ return { short, long };
8
+ };
9
+
10
+ const parseCliError = (error: ZodError, argv: string[], declaredOptions: [string, string?][]) => {
11
+ const option = declaredOptions.map(getOptionKeys).find(({ long, short }) => {
12
+ return long ? error.errors[0].path[0] === long : error.errors[0].path[0] === short;
13
+ });
14
+
15
+ if (option) {
16
+ const { short, long } = option;
17
+ const errorOption = argv.findLast((arg) => arg === `-${short}` || arg === `--${long}`);
18
+
19
+ return `Error in option "${errorOption}". ${error.errors[0].message}`;
20
+ }
21
+ };
22
+
23
+ export { parseCliError };
@@ -0,0 +1,38 @@
1
+ import { resolveCurrentDir } from '@/util';
2
+
3
+ import { Config, SelectConfig } from './type';
4
+
5
+ import fs from 'fs';
6
+
7
+ interface Get {
8
+ (): Config;
9
+ <T extends SelectConfig>(configSelect: SelectConfig): Pick<Config, T extends SelectConfig ? keyof T : never>;
10
+ <T extends keyof Config>(key: T): Config[T];
11
+ }
12
+
13
+ const get = ((key: keyof Config | SelectConfig | undefined) => {
14
+ const configPath = resolveCurrentDir('config.json');
15
+ const exists = fs.existsSync(configPath);
16
+
17
+ if (!exists) {
18
+ return {} as Config;
19
+ }
20
+
21
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf-8')) as Config;
22
+
23
+ if (key && typeof key === 'object') {
24
+ return Object.fromEntries(
25
+ Object.entries(key)
26
+ .filter(([key]) => config[key as keyof SelectConfig] !== undefined)
27
+ .map(([key]) => [key, config[key as keyof SelectConfig]] as const)
28
+ ) as Pick<Config, keyof SelectConfig>;
29
+ }
30
+
31
+ if (key) {
32
+ return config[key];
33
+ }
34
+
35
+ return config;
36
+ }) as Get;
37
+
38
+ export { get };
@@ -0,0 +1,4 @@
1
+ export { get } from './get';
2
+ export { configSchema, selectConfigSchema as keysConfigSchema } from './schema';
3
+ export { set } from './set';
4
+ export { type Config } from './type';
@@ -0,0 +1,19 @@
1
+ import { managerSchema } from '@/entities/manager';
2
+
3
+ import { z } from 'zod';
4
+
5
+ const configShape = {
6
+ manager: managerSchema.optional()
7
+ };
8
+ const configSchema = z.object(configShape);
9
+
10
+ type ToSelectConfigType<T> = {
11
+ [K in keyof T]: z.ZodOptional<z.ZodBoolean>;
12
+ };
13
+ const selectConfigSchema = z.object(
14
+ Object.fromEntries(configSchema.keyof().options.map((key) => [key, z.boolean().optional()])) as ToSelectConfigType<
15
+ typeof configShape
16
+ >
17
+ );
18
+
19
+ export { configSchema, selectConfigSchema };
@@ -0,0 +1,14 @@
1
+ import { resolveCurrentDir } from '@/util';
2
+
3
+ import { get } from './get';
4
+ import { Config } from './type';
5
+
6
+ import fs from 'fs';
7
+
8
+ const set = (newConfigData: Config) => {
9
+ const configPath = resolveCurrentDir('config.json');
10
+ const config = get();
11
+ fs.writeFileSync(configPath, JSON.stringify({ ...config, ...newConfigData }));
12
+ };
13
+
14
+ export { set };
@@ -0,0 +1,8 @@
1
+ import { configSchema, selectConfigSchema } from './schema';
2
+
3
+ import { z } from 'zod';
4
+
5
+ type Config = z.infer<typeof configSchema>;
6
+ type SelectConfig = z.infer<typeof selectConfigSchema>;
7
+
8
+ export type { Config, SelectConfig };
@@ -0,0 +1,2 @@
1
+ export { managerSchema } from './schema';
2
+ export type { Manager } from './type';
@@ -0,0 +1,5 @@
1
+ import { z } from 'zod';
2
+
3
+ const managerSchema = z.enum(['npm', 'yarn', 'pnpm']);
4
+
5
+ export { managerSchema };
@@ -0,0 +1,7 @@
1
+ import { managerSchema } from './schema';
2
+
3
+ import { z } from 'zod';
4
+
5
+ type Manager = z.infer<typeof managerSchema>;
6
+
7
+ export type { Manager };
package/src/index.ts ADDED
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env node
2
+ import * as commands from '@/cli/commands';
3
+ import { parseCliError } from '@/cli/util';
4
+ import { logger } from '@/util';
5
+
6
+ import packageJSON from '../package.json';
7
+
8
+ import { program } from 'commander';
9
+
10
+ program.name('ada');
11
+ program.version(packageJSON.version);
12
+
13
+ Object.values(commands).map((command) => {
14
+ const currentCommand = program.command(command.name, { isDefault: command.isDefault });
15
+
16
+ currentCommand.description(command.description);
17
+
18
+ command.options?.forEach((option) => {
19
+ currentCommand.option(option[0], option[1]);
20
+ });
21
+
22
+ currentCommand.action((options) => {
23
+ const { success, data, error } = command.schema.safeParse(options);
24
+ if (success) {
25
+ // @ts-expect-error: type inference
26
+ command.action(data);
27
+ } else {
28
+ logger.error(`${parseCliError(error, process.argv, command.options || [])}`);
29
+ }
30
+ });
31
+ });
32
+
33
+ // program
34
+ // .command('init', { isDefault: true })
35
+ // .description('initialize configs')
36
+ // .option('-p, --prettier', 'setup prettier')
37
+ // .option('-e, --eslint', 'setup eslint')
38
+ // .action((options) => {
39
+ // console.log('init', options);
40
+ // });
41
+
42
+ // program
43
+ // .command('set')
44
+ // .description('sets variable to config')
45
+ // .option('-m, --manager <npm | yarn | pnpm>', 'package manager that will be used to install dependencies')
46
+ // .action((options) => {
47
+ // console.log('set', options);
48
+ // });
49
+
50
+ program.parse(process.argv);
@@ -0,0 +1,3 @@
1
+ export { isEmpty } from './isEmpty';
2
+ export { logger } from './logger';
3
+ export { resolveCurrentDir } from './resolveCurrentDir';
@@ -0,0 +1,11 @@
1
+ const isEmpty = (obj: object) => {
2
+ for (const prop in obj) {
3
+ if (Object.hasOwn(obj, prop)) {
4
+ return false;
5
+ }
6
+ }
7
+
8
+ return true;
9
+ };
10
+
11
+ export { isEmpty };
@@ -0,0 +1,15 @@
1
+ const logger = {
2
+ info(message: string) {
3
+ console.log(`\x1b[32m${message}\x1b[0m`);
4
+ },
5
+
6
+ warn(message: string) {
7
+ console.log(`\x1b[33m${message}\x1b[0m`);
8
+ },
9
+
10
+ error(message: string) {
11
+ console.log(`\x1b[31m${message}\x1b[0m`);
12
+ }
13
+ };
14
+
15
+ export { logger };
@@ -0,0 +1,7 @@
1
+ import { resolve } from 'path';
2
+
3
+ const resolveCurrentDir = (...paths: string[]) => {
4
+ return resolve(import.meta.dirname, ...paths);
5
+ };
6
+
7
+ export { resolveCurrentDir };
package/tsconfig.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": [
5
+ "ES2023",
6
+ "dom"
7
+ ],
8
+ "module": "ESNext",
9
+ "skipLibCheck": true,
10
+ /* Bundler mode */
11
+ "moduleResolution": "bundler",
12
+ "allowImportingTsExtensions": true,
13
+ "isolatedModules": true,
14
+ "moduleDetection": "force",
15
+ "noEmit": true,
16
+ /* Linting */
17
+ "strict": true,
18
+ "noUnusedLocals": true,
19
+ "noUnusedParameters": true,
20
+ "noFallthroughCasesInSwitch": true,
21
+ "noUncheckedSideEffectImports": true,
22
+ "baseUrl": ".",
23
+ "paths": {
24
+ "@/*": [
25
+ "./src/*"
26
+ ]
27
+ }
28
+ },
29
+ "include": [
30
+ "src/**/*.ts"
31
+ ]
32
+ }