diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index b544877..edb634c 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,10 +4,23 @@
-
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
@@ -48,7 +61,7 @@
"git-widget-placeholder": "main",
"ignore.virus.scanning.warn.message": "true",
"kotlin-language-version-configured": "true",
- "last_opened_file_path": "C:/Users/HP/IdeaProjects/omni-tools/src/pages/string/split",
+ "last_opened_file_path": "C:/Users/HP/IdeaProjects/omni-tools/src/pages/string",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
@@ -56,6 +69,7 @@
"nodejs_package_manager_path": "npm",
"npm.dev.executor": "Run",
"npm.prebuild.executor": "Run",
+ "npm.script:create:tool.executor": "Run",
"prettierjs.PrettierConfiguration.Package": "C:\\Users\\HP\\IdeaProjects\\omni-tools\\node_modules\\prettier",
"project.structure.last.edited": "Problems",
"project.structure.proportion": "0.0",
@@ -76,11 +90,11 @@
+
-
@@ -88,7 +102,7 @@
-
+
@@ -109,8 +123,19 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -134,7 +159,9 @@
-
+
+
+
@@ -400,7 +427,15 @@
1719165093734
-
+
+
+ 1719165600245
+
+
+
+ 1719165600245
+
+
@@ -428,7 +463,6 @@
-
@@ -446,7 +480,8 @@
-
+
+
diff --git a/Readme.md b/Readme.md
index 9d70d93..63c722f 100644
--- a/Readme.md
+++ b/Readme.md
@@ -46,6 +46,10 @@ npm i
npm run dev
```
+### Create a new tool
+
+`npm run script:create:tool my-tool-name folder1/folder2`
+
## Contributors
diff --git a/package.json b/package.json
index a186631..4a5dec7 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"serve": "vite preview",
"test": "vitest",
"test:ui": "vitest --ui",
+ "script:create:tool": "node scripts/create-tool.mjs",
"lint": "eslint src --max-warnings=0",
"typecheck": "tsc --project tsconfig.json --noEmit",
"prepare": "husky install"
diff --git a/scripts/create-tool.mjs b/scripts/create-tool.mjs
new file mode 100644
index 0000000..66b44ec
--- /dev/null
+++ b/scripts/create-tool.mjs
@@ -0,0 +1,115 @@
+import { mkdir, readFile, writeFile } from 'fs/promises'
+import { dirname, join } from 'path'
+import { fileURLToPath } from 'url'
+
+const currentDirname = dirname(fileURLToPath(import.meta.url))
+
+const toolName = process.argv[2]
+const folder = process.argv[3]
+
+const toolsDir = join(currentDirname, '..', 'src', 'pages', folder ?? '')
+
+if (!toolName) {
+ throw new Error('Please specify a toolname.')
+}
+
+function capitalizeFirstLetter(string) {
+ return string.charAt(0).toUpperCase() + string.slice(1)
+}
+
+const toolNameCamelCase = toolName.replace(/-./g, (x) => x[1].toUpperCase())
+const toolNameTitleCase =
+ toolName[0].toUpperCase() + toolName.slice(1).replace(/-/g, ' ')
+const toolDir = join(toolsDir, toolName)
+
+await mkdir(toolDir)
+console.log(`Directory created: ${toolDir}`)
+
+const createToolFile = async (name, content) => {
+ const filePath = join(toolDir, name)
+ await writeFile(filePath, content.trim())
+ console.log(`File created: ${filePath}`)
+}
+
+createToolFile(
+ `index.tsx`,
+ `
+import { Box } from '@mui/material';
+import React from 'react';
+import * as Yup from 'yup';
+
+const initialValues = {};
+const validationSchema = Yup.object({
+ // splitSeparator: Yup.string().required('The separator is required')
+});
+export default function ${capitalizeFirstLetter(toolNameCamelCase)}() {
+ return Lorem ipsum;
+}
+`
+)
+
+createToolFile(
+ `meta.ts`,
+ `
+import { defineTool } from '@tools/defineTool';
+import { lazy } from 'react';
+import image from '../../../assets/text.png';
+
+export const tool = defineTool('${folder}', {
+ name: '${toolNameTitleCase}',
+ path: '/${toolName}',
+ image,
+ description: '',
+ keywords: ['${toolName.split('-').join('\', \'')}'],
+ component: lazy(() => import('./index'))
+});
+`
+)
+
+createToolFile(`service.ts`, ``)
+createToolFile(
+ `${toolName}.service.test.ts`,
+ `
+import { expect, describe, it } from 'vitest';
+// import { } from './service';
+//
+// describe('${toolName}', () => {
+//
+// })
+`
+)
+
+// createToolFile(
+// `${toolName}.e2e.spec.ts`,
+// `
+// import { test, expect } from '@playwright/test';
+//
+// test.describe('Tool - ${toolNameTitleCase}', () => {
+// test.beforeEach(async ({ page }) => {
+// await page.goto('/${toolName}');
+// });
+//
+// test('Has correct title', async ({ page }) => {
+// await expect(page).toHaveTitle('${toolNameTitleCase} - IT Tools');
+// });
+//
+// test('', async ({ page }) => {
+//
+// });
+// });
+//
+// `
+// )
+
+const toolsIndex = join(toolsDir, 'index.ts')
+const indexContent = await readFile(toolsIndex, { encoding: 'utf-8' }).then(
+ (r) => r.split('\n')
+)
+
+indexContent.splice(
+ 0,
+ 0,
+ `import { tool as ${toolNameCamelCase} } from './${toolName}/meta';`
+)
+writeFile(toolsIndex, indexContent.join('\n'))
+console.log(`Added import in: ${toolsIndex}`)
diff --git a/src/pages/image/png/change-colors-in-png/change-colors-in-png.service.test.ts b/src/pages/image/png/change-colors-in-png/change-colors-in-png.service.test.ts
new file mode 100644
index 0000000..1c0493f
--- /dev/null
+++ b/src/pages/image/png/change-colors-in-png/change-colors-in-png.service.test.ts
@@ -0,0 +1,6 @@
+import { expect, describe, it } from 'vitest';
+// import { } from './service';
+//
+// describe('change-colors-in-png', () => {
+//
+// })
\ No newline at end of file
diff --git a/src/pages/image/png/change-colors-in-png/index.tsx b/src/pages/image/png/change-colors-in-png/index.tsx
new file mode 100644
index 0000000..b08b174
--- /dev/null
+++ b/src/pages/image/png/change-colors-in-png/index.tsx
@@ -0,0 +1,11 @@
+import { Box } from '@mui/material';
+import React from 'react';
+import * as Yup from 'yup';
+
+const initialValues = {};
+const validationSchema = Yup.object({
+ // splitSeparator: Yup.string().required('The separator is required')
+});
+export default function ChangeColorsInPng() {
+ return Lorem ipsum;
+}
\ No newline at end of file
diff --git a/src/pages/image/png/change-colors-in-png/meta.ts b/src/pages/image/png/change-colors-in-png/meta.ts
new file mode 100644
index 0000000..c37413c
--- /dev/null
+++ b/src/pages/image/png/change-colors-in-png/meta.ts
@@ -0,0 +1,12 @@
+import { defineTool } from '@tools/defineTool';
+import { lazy } from 'react';
+import image from '../../../assets/text.png';
+
+export const tool = defineTool('image/png', {
+ name: 'Change colors in png',
+ path: '/change-colors-in-png',
+ image,
+ description: '',
+ keywords: ['change', 'colors', 'in', 'png'],
+ component: lazy(() => import('./index'))
+});
diff --git a/src/pages/image/png/change-colors-in-png/service.ts b/src/pages/image/png/change-colors-in-png/service.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/pages/images/imageTools.ts b/src/pages/images/imageTools.ts
deleted file mode 100644
index fd68239..0000000
--- a/src/pages/images/imageTools.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import { pngTools } from './png/pngTools';
-
-export const imageTools = [...pngTools];
diff --git a/src/pages/images/png/change-colors-in-png/index.tsx b/src/pages/images/png/change-colors-in-png/index.tsx
deleted file mode 100644
index 666797a..0000000
--- a/src/pages/images/png/change-colors-in-png/index.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import { Box } from '@mui/material';
-
-export default function ChangeColorsInPng() {
- return ;
-}
diff --git a/src/pages/images/png/change-colors-in-png/meta.ts b/src/pages/images/png/change-colors-in-png/meta.ts
deleted file mode 100644
index bb83fd8..0000000
--- a/src/pages/images/png/change-colors-in-png/meta.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { defineTool } from '../../../../tools/defineTool';
-import { lazy } from 'react';
-
-export const tool = defineTool('png', {
- path: 'change-colors',
- name: 'PNG color replacer',
- description:
- "World's simplest online Portable Network Graphics (PNG) color changer. Just import your PNG image in the editor on the left, select which colors to change, and you'll instantly get a new PNG with the new colors on the right. Free, quick, and very powerful. Import a PNG – replace its colors",
- keywords: ['png', 'color'],
- component: lazy(() => import('./index'))
-});
diff --git a/src/pages/images/png/pngTools.ts b/src/pages/images/png/pngTools.ts
deleted file mode 100644
index 1f59860..0000000
--- a/src/pages/images/png/pngTools.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import { tool as changeColorsInPng } from './change-colors-in-png/meta';
-
-export const pngTools = [changeColorsInPng];
diff --git a/src/pages/string/stringTools.ts b/src/pages/string/index.ts
similarity index 100%
rename from src/pages/string/stringTools.ts
rename to src/pages/string/index.ts
diff --git a/src/pages/string/join/string-join.test.ts b/src/pages/string/join/string-join.service.test.ts
similarity index 100%
rename from src/pages/string/join/string-join.test.ts
rename to src/pages/string/join/string-join.service.test.ts
diff --git a/src/pages/string/split/string-split.test.ts b/src/pages/string/split/string-split.service.test.ts
similarity index 100%
rename from src/pages/string/split/string-split.test.ts
rename to src/pages/string/split/string-split.service.test.ts
diff --git a/src/tools/index.ts b/src/tools/index.ts
index 9b56afb..2f5e19b 100644
--- a/src/tools/index.ts
+++ b/src/tools/index.ts
@@ -1,5 +1,5 @@
-import { stringTools } from '../pages/string/stringTools';
-import { imageTools } from '../pages/images/imageTools';
+import { stringTools } from '../pages/string';
+import { imageTools } from '../pages/image';
import { DefinedTool } from './defineTool';
import { capitalizeFirstLetter } from '../utils/string';
diff --git a/tsconfig.json b/tsconfig.json
index ca346f3..56a88aa 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -2,7 +2,11 @@
"compilerOptions": {
"baseUrl": "./src",
"target": "esnext",
- "lib": ["dom", "dom.iterable", "esnext"],
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
@@ -15,8 +19,21 @@
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
- "types": ["vite/client", "vitest/globals", "@testing-library/jest-dom"]
+ "types": [
+ "vite/client",
+ "vitest/globals",
+ "@testing-library/jest-dom"
+ ],
+ "paths": {
+ "@tools/*": [
+ "./tools/*"
+ ]
+ }
},
- "include": ["src"],
- "exclude": ["node_modules"]
+ "include": [
+ "src"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
}