This commit is contained in:
jincan 2025-01-04 22:00:33 +08:00 committed by GitHub
commit 7b8f760d9b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
92 changed files with 131 additions and 212 deletions

12
components.d.ts vendored
View file

@ -129,19 +129,31 @@ declare module '@vue/runtime-core' {
MenuLayout: typeof import('./src/components/MenuLayout.vue')['default'] MenuLayout: typeof import('./src/components/MenuLayout.vue')['default']
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default'] MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default'] MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
MyNewTool: typeof import('./src/tools/my-new-tool/my-new-tool.vue')['default']
NardyEncTool: typeof import('./src/tools/nardy-enc-tool/nardy-enc-tool.vue')['default']
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default'] NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
NCheckbox: typeof import('naive-ui')['NCheckbox'] NCheckbox: typeof import('naive-ui')['NCheckbox']
NCode: typeof import('naive-ui')['NCode']
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition'] NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
NColorPicker: typeof import('naive-ui')['NColorPicker']
NConfigProvider: typeof import('naive-ui')['NConfigProvider'] NConfigProvider: typeof import('naive-ui')['NConfigProvider']
NDivider: typeof import('naive-ui')['NDivider'] NDivider: typeof import('naive-ui')['NDivider']
NEllipsis: typeof import('naive-ui')['NEllipsis'] NEllipsis: typeof import('naive-ui')['NEllipsis']
NFormItem: typeof import('naive-ui')['NFormItem']
NGi: typeof import('naive-ui')['NGi']
NGrid: typeof import('naive-ui')['NGrid']
NH1: typeof import('naive-ui')['NH1'] NH1: typeof import('naive-ui')['NH1']
NH3: typeof import('naive-ui')['NH3'] NH3: typeof import('naive-ui')['NH3']
NIcon: typeof import('naive-ui')['NIcon'] NIcon: typeof import('naive-ui')['NIcon']
NInputNumber: typeof import('naive-ui')['NInputNumber']
NLayout: typeof import('naive-ui')['NLayout'] NLayout: typeof import('naive-ui')['NLayout']
NLayoutSider: typeof import('naive-ui')['NLayoutSider'] NLayoutSider: typeof import('naive-ui')['NLayoutSider']
NMenu: typeof import('naive-ui')['NMenu'] NMenu: typeof import('naive-ui')['NMenu']
NScrollbar: typeof import('naive-ui')['NScrollbar']
NSlider: typeof import('naive-ui')['NSlider']
NSpace: typeof import('naive-ui')['NSpace'] NSpace: typeof import('naive-ui')['NSpace']
NSpin: typeof import('naive-ui')['NSpin']
NSwitch: typeof import('naive-ui')['NSwitch']
NTable: typeof import('naive-ui')['NTable'] NTable: typeof import('naive-ui')['NTable']
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default'] NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default'] OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']

View file

@ -1,29 +1,30 @@
import { mkdir, readFile, writeFile } from 'fs/promises'; import { mkdir, readFile, writeFile } from 'node:fs/promises';
import { dirname, join } from 'path'; import { dirname, join } from 'node:path';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'node:url';
const currentDirname = dirname(fileURLToPath(import.meta.url)); const currentDirname = dirname(fileURLToPath(import.meta.url));
const toolsDir = join(currentDirname, '..', 'src', 'tools'); const toolsDir = join(currentDirname, '..', 'src', 'tools');
// eslint-disable-next-line no-undef
const toolName = process.argv[2]; const toolName = process.argv[2];
if (!toolName) { if (!toolName) {
throw new Error('Please specify a toolname.'); throw new Error('Please specify a toolname.');
} }
const toolNameCamelCase = toolName.replace(/-./g, (x) => x[1].toUpperCase()); const toolCategory = process.argv[3] || 'Default';
const toolNameTitleCase = toolName[0].toUpperCase() + toolName.slice(1).replace(/-/g, ' '); const toolNameTitleCase = toolName[0].toUpperCase() + toolName.slice(1).replace(/-/g, ' ');
const toolDir = join(toolsDir, toolName); const toolDir = join(toolsDir, toolName);
await mkdir(toolDir); await mkdir(toolDir);
console.log(`Directory created: ${toolDir}`); console.log(`Directory created: ${toolDir}`);
const createToolFile = async (name, content) => { async function createToolFile(name, content) {
const filePath = join(toolDir, name); const filePath = join(toolDir, name);
await writeFile(filePath, content.trim()); await writeFile(filePath, content.trim());
console.log(`File created: ${filePath}`); console.log(`File created: ${filePath}`);
}; }
createToolFile( createToolFile(
`${toolName}.vue`, `${toolName}.vue`,
@ -44,7 +45,7 @@ createToolFile(
); );
createToolFile( createToolFile(
`index.ts`, 'index.ts',
` `
import { ArrowsShuffle } from '@vicons/tabler'; import { ArrowsShuffle } from '@vicons/tabler';
import { defineTool } from '../tool'; import { defineTool } from '../tool';
@ -53,15 +54,16 @@ export const tool = defineTool({
name: '${toolNameTitleCase}', name: '${toolNameTitleCase}',
path: '/${toolName}', path: '/${toolName}',
description: '', description: '',
keywords: ['${toolName.split('-').join("', '")}'], keywords: ['${toolName.split('-').join('\', \'')}'],
component: () => import('./${toolName}.vue'), component: () => import('./${toolName}.vue'),
icon: ArrowsShuffle, icon: ArrowsShuffle,
createdAt: new Date('${new Date().toISOString().split('T')[0]}'), createdAt: new Date('${new Date().toISOString().split('T')[0]}'),
category: '${toolCategory}',
}); });
`, `,
); );
createToolFile(`${toolName}.service.ts`, ``); createToolFile(`${toolName}.service.ts`, '');
createToolFile( createToolFile(
`${toolName}.service.test.ts`, `${toolName}.service.test.ts`,
` `
@ -92,13 +94,6 @@ test.describe('Tool - ${toolNameTitleCase}', () => {
}); });
}); });
`, `,
); );
const toolsIndex = join(toolsDir, 'index.ts');
const indexContent = await readFile(toolsIndex, { encoding: 'utf-8' }).then((r) => r.split('\n'));
indexContent.splice(3, 0, `import { tool as ${toolNameCamelCase} } from './${toolName}';`);
writeFile(toolsIndex, indexContent.join('\n'));
console.log(`Added import in: ${toolsIndex}`);

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
component: () => import('./ascii-text-drawer.vue'), component: () => import('./ascii-text-drawer.vue'),
icon: Artboard, icon: Artboard,
createdAt: new Date('2024-03-03'), createdAt: new Date('2024-03-03'),
category: 'Text',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['base64', 'converter', 'upload', 'image', 'file', 'conversion', 'web', 'data', 'format'], keywords: ['base64', 'converter', 'upload', 'image', 'file', 'conversion', 'web', 'data', 'format'],
component: () => import('./base64-file-converter.vue'), component: () => import('./base64-file-converter.vue'),
icon: FileDigit, icon: FileDigit,
category: 'Converter',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./base64-string-converter.vue'), component: () => import('./base64-string-converter.vue'),
icon: FileDigit, icon: FileDigit,
redirectFrom: ['/file-to-base64', '/base64-converter'], redirectFrom: ['/file-to-base64', '/base64-converter'],
category: 'Converter',
}); });

View file

@ -19,4 +19,5 @@ export const tool = defineTool({
], ],
component: () => import('./basic-auth-generator.vue'), component: () => import('./basic-auth-generator.vue'),
icon: PasswordRound, icon: PasswordRound,
category: 'Web',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['bcrypt', 'hash', 'compare', 'password', 'salt', 'round', 'storage', 'crypto'], keywords: ['bcrypt', 'hash', 'compare', 'password', 'salt', 'round', 'storage', 'crypto'],
component: () => import('./bcrypt.vue'), component: () => import('./bcrypt.vue'),
icon: LockSquare, icon: LockSquare,
category: 'Crypto',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./benchmark-builder.vue'), component: () => import('./benchmark-builder.vue'),
icon: SpeedFilled, icon: SpeedFilled,
createdAt: new Date('2023-04-05'), createdAt: new Date('2023-04-05'),
category: 'Measurement',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['BIP39', 'passphrase', 'generator', 'mnemonic', 'entropy'], keywords: ['BIP39', 'passphrase', 'generator', 'mnemonic', 'entropy'],
component: () => import('./bip39-generator.vue'), component: () => import('./bip39-generator.vue'),
icon: AlignJustified, icon: AlignJustified,
category: 'Crypto',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./camera-recorder.vue'), component: () => import('./camera-recorder.vue'),
icon: Camera, icon: Camera,
createdAt: new Date('2023-05-15'), createdAt: new Date('2023-05-15'),
category: 'Images and videos',
}); });

View file

@ -23,4 +23,5 @@ export const tool = defineTool({
], ],
component: () => import('./case-converter.vue'), component: () => import('./case-converter.vue'),
icon: LetterCaseToggle, icon: LetterCaseToggle,
category: 'Converter',
}); });

View file

@ -20,4 +20,5 @@ export const tool = defineTool({
], ],
component: () => import('./chmod-calculator.vue'), component: () => import('./chmod-calculator.vue'),
icon: FileInvoice, icon: FileInvoice,
category: 'Development',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['chronometer', 'time', 'lap', 'duration', 'measure', 'pause', 'resume', 'stopwatch'], keywords: ['chronometer', 'time', 'lap', 'duration', 'measure', 'pause', 'resume', 'stopwatch'],
component: () => import('./chronometer.vue'), component: () => import('./chronometer.vue'),
icon: TimerOutlined, icon: TimerOutlined,
category: 'Measurement',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./color-converter.vue'), component: () => import('./color-converter.vue'),
icon: Palette, icon: Palette,
redirectFrom: ['/color-picker-converter'], redirectFrom: ['/color-picker-converter'],
category: 'Converter',
}); });

View file

@ -23,4 +23,5 @@ export const tool = defineTool({
], ],
component: () => import('./crontab-generator.vue'), component: () => import('./crontab-generator.vue'),
icon: Alarm, icon: Alarm,
category: 'Development',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['date', 'time', 'converter', 'iso', 'utc', 'timezone', 'year', 'month', 'day', 'minute', 'seconde'], keywords: ['date', 'time', 'converter', 'iso', 'utc', 'timezone', 'year', 'month', 'day', 'minute', 'seconde'],
component: () => import('./date-time-converter.vue'), component: () => import('./date-time-converter.vue'),
icon: Calendar, icon: Calendar,
category: 'Converter',
}); });

View file

@ -21,4 +21,5 @@ export const tool = defineTool({
], ],
component: () => import('./device-information.vue'), component: () => import('./device-information.vue'),
icon: DeviceDesktop, icon: DeviceDesktop,
category: 'Web',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['docker', 'run', 'compose', 'yaml', 'yml', 'convert', 'deamon'], keywords: ['docker', 'run', 'compose', 'yaml', 'yml', 'convert', 'deamon'],
component: () => import('./docker-run-to-docker-compose-converter.vue'), component: () => import('./docker-run-to-docker-compose-converter.vue'),
icon: BrandDocker, icon: BrandDocker,
category: 'Development',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
component: () => import('./email-normalizer.vue'), component: () => import('./email-normalizer.vue'),
icon: Mail, icon: Mail,
createdAt: new Date('2024-08-15'), createdAt: new Date('2024-08-15'),
category: 'Development',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./emoji-picker.vue'), component: () => import('./emoji-picker.vue'),
icon: MoodSmile, icon: MoodSmile,
createdAt: new Date('2023-08-07'), createdAt: new Date('2023-08-07'),
category: 'Text',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./encryption.vue'), component: () => import('./encryption.vue'),
icon: Lock, icon: Lock,
redirectFrom: ['/cypher'], redirectFrom: ['/cypher'],
category: 'Crypto',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['eta', 'calculator', 'estimated', 'time', 'arrival', 'average'], keywords: ['eta', 'calculator', 'estimated', 'time', 'arrival', 'average'],
component: () => import('./eta-calculator.vue'), component: () => import('./eta-calculator.vue'),
icon: Hourglass, icon: Hourglass,
category: 'Math',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['git', 'push', 'force', 'pull', 'commit', 'amend', 'rebase', 'merge', 'reset', 'soft', 'hard', 'lease'], keywords: ['git', 'push', 'force', 'pull', 'commit', 'amend', 'rebase', 'merge', 'reset', 'soft', 'hard', 'lease'],
component: () => import('./git-memo.vue'), component: () => import('./git-memo.vue'),
icon: BrandGit, icon: BrandGit,
category: 'Development',
}); });

View file

@ -24,4 +24,5 @@ export const tool = defineTool({
component: () => import('./hash-text.vue'), component: () => import('./hash-text.vue'),
icon: EyeOff, icon: EyeOff,
redirectFrom: ['/hash'], redirectFrom: ['/hash'],
category: 'Crypto',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['hmac', 'generator', 'MD5', 'SHA1', 'SHA256', 'SHA224', 'SHA512', 'SHA384', 'SHA3', 'RIPEMD160'], keywords: ['hmac', 'generator', 'MD5', 'SHA1', 'SHA256', 'SHA224', 'SHA512', 'SHA384', 'SHA3', 'RIPEMD160'],
component: () => import('./hmac-generator.vue'), component: () => import('./hmac-generator.vue'),
icon: ShortTextRound, icon: ShortTextRound,
category: 'Crypto',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['html', 'entities', 'escape', 'unescape', 'special', 'characters', 'tags'], keywords: ['html', 'entities', 'escape', 'unescape', 'special', 'characters', 'tags'],
component: () => import('./html-entities.vue'), component: () => import('./html-entities.vue'),
icon: Code, icon: Code,
category: 'Web',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['html', 'wysiwyg', 'editor', 'p', 'ul', 'ol', 'converter', 'live'], keywords: ['html', 'wysiwyg', 'editor', 'p', 'ul', 'ol', 'converter', 'live'],
component: () => import('./html-wysiwyg-editor.vue'), component: () => import('./html-wysiwyg-editor.vue'),
icon: Edit, icon: Edit,
category: 'Web',
}); });

View file

@ -17,4 +17,5 @@ export const tool = defineTool({
component: () => import('./http-status-codes.vue'), component: () => import('./http-status-codes.vue'),
icon: HttpRound, icon: HttpRound,
createdAt: new Date('2023-04-13'), createdAt: new Date('2023-04-13'),
category: 'Web',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./iban-validator-and-parser.vue'), component: () => import('./iban-validator-and-parser.vue'),
icon: Bank, icon: Bank,
createdAt: new Date('2023-08-26'), createdAt: new Date('2023-08-26'),
category: 'Data',
}); });

View file

@ -1,196 +1,19 @@
import { tool as base64FileConverter } from './base64-file-converter'; import type { ToolCategory, ToolWithCategory } from './tools.types';
import { tool as base64StringConverter } from './base64-string-converter';
import { tool as basicAuthGenerator } from './basic-auth-generator';
import { tool as emailNormalizer } from './email-normalizer';
import { tool as asciiTextDrawer } from './ascii-text-drawer'; const modules = import.meta.glob<true, string, ToolWithCategory>('./*/index.ts', { eager: true, import: 'tool' });
import { tool as textToUnicode } from './text-to-unicode'; export const toolsByCategory = Object.values(modules).reduce((la, moduleDef) => {
import { tool as safelinkDecoder } from './safelink-decoder'; let found = la.find(l => l.name === moduleDef.category);
import { tool as xmlToJson } from './xml-to-json'; if (!found) {
import { tool as jsonToXml } from './json-to-xml'; found = {
import { tool as regexTester } from './regex-tester'; name: moduleDef.category,
import { tool as regexMemo } from './regex-memo'; components: [],
import { tool as markdownToHtml } from './markdown-to-html'; };
import { tool as pdfSignatureChecker } from './pdf-signature-checker'; la.push(found);
import { tool as numeronymGenerator } from './numeronym-generator'; }
import { tool as macAddressGenerator } from './mac-address-generator'; found.components.push(moduleDef);
import { tool as textToBinary } from './text-to-binary'; return la;
import { tool as ulidGenerator } from './ulid-generator'; }, [] as ToolCategory[]);
import { tool as ibanValidatorAndParser } from './iban-validator-and-parser';
import { tool as stringObfuscator } from './string-obfuscator';
import { tool as textDiff } from './text-diff';
import { tool as emojiPicker } from './emoji-picker';
import { tool as passwordStrengthAnalyser } from './password-strength-analyser';
import { tool as yamlToToml } from './yaml-to-toml';
import { tool as jsonToToml } from './json-to-toml';
import { tool as tomlToYaml } from './toml-to-yaml';
import { tool as tomlToJson } from './toml-to-json';
import { tool as jsonToCsv } from './json-to-csv';
import { tool as cameraRecorder } from './camera-recorder';
import { tool as listConverter } from './list-converter';
import { tool as phoneParserAndFormatter } from './phone-parser-and-formatter';
import { tool as jsonDiff } from './json-diff';
import { tool as ipv4RangeExpander } from './ipv4-range-expander';
import { tool as httpStatusCodes } from './http-status-codes';
import { tool as yamlToJson } from './yaml-to-json-converter';
import { tool as jsonToYaml } from './json-to-yaml-converter';
import { tool as ipv6UlaGenerator } from './ipv6-ula-generator';
import { tool as ipv4AddressConverter } from './ipv4-address-converter';
import { tool as benchmarkBuilder } from './benchmark-builder';
import { tool as userAgentParser } from './user-agent-parser';
import { tool as ipv4SubnetCalculator } from './ipv4-subnet-calculator';
import { tool as dockerRunToDockerComposeConverter } from './docker-run-to-docker-compose-converter';
import { tool as htmlWysiwygEditor } from './html-wysiwyg-editor';
import { tool as rsaKeyPairGenerator } from './rsa-key-pair-generator';
import { tool as textToNatoAlphabet } from './text-to-nato-alphabet';
import { tool as slugifyString } from './slugify-string';
import { tool as keycodeInfo } from './keycode-info';
import { tool as jsonMinify } from './json-minify';
import { tool as bcrypt } from './bcrypt';
import { tool as bip39 } from './bip39-generator';
import { tool as caseConverter } from './case-converter';
import { tool as chmodCalculator } from './chmod-calculator';
import { tool as chronometer } from './chronometer';
import { tool as colorConverter } from './color-converter';
import { tool as crontabGenerator } from './crontab-generator';
import { tool as dateTimeConverter } from './date-time-converter';
import { tool as deviceInformation } from './device-information';
import { tool as cypher } from './encryption';
import { tool as etaCalculator } from './eta-calculator';
import { tool as percentageCalculator } from './percentage-calculator';
import { tool as gitMemo } from './git-memo';
import { tool as hashText } from './hash-text';
import { tool as hmacGenerator } from './hmac-generator';
import { tool as htmlEntities } from './html-entities';
import { tool as baseConverter } from './integer-base-converter';
import { tool as jsonViewer } from './json-viewer';
import { tool as jwtParser } from './jwt-parser';
import { tool as loremIpsumGenerator } from './lorem-ipsum-generator';
import { tool as mathEvaluator } from './math-evaluator';
import { tool as metaTagGenerator } from './meta-tag-generator';
import { tool as mimeTypes } from './mime-types';
import { tool as otpCodeGeneratorAndValidator } from './otp-code-generator-and-validator';
import { tool as qrCodeGenerator } from './qr-code-generator';
import { tool as wifiQrCodeGenerator } from './wifi-qr-code-generator';
import { tool as randomPortGenerator } from './random-port-generator';
import { tool as romanNumeralConverter } from './roman-numeral-converter';
import { tool as sqlPrettify } from './sql-prettify';
import { tool as svgPlaceholderGenerator } from './svg-placeholder-generator';
import { tool as temperatureConverter } from './temperature-converter';
import { tool as textStatistics } from './text-statistics';
import { tool as tokenGenerator } from './token-generator';
import type { ToolCategory } from './tools.types';
import { tool as urlEncoder } from './url-encoder';
import { tool as urlParser } from './url-parser';
import { tool as uuidGenerator } from './uuid-generator';
import { tool as macAddressLookup } from './mac-address-lookup';
import { tool as xmlFormatter } from './xml-formatter';
import { tool as yamlViewer } from './yaml-viewer';
export const toolsByCategory: ToolCategory[] = [
{
name: 'Crypto',
components: [tokenGenerator, hashText, bcrypt, uuidGenerator, ulidGenerator, cypher, bip39, hmacGenerator, rsaKeyPairGenerator, passwordStrengthAnalyser, pdfSignatureChecker],
},
{
name: 'Converter',
components: [
dateTimeConverter,
baseConverter,
romanNumeralConverter,
base64StringConverter,
base64FileConverter,
colorConverter,
caseConverter,
textToNatoAlphabet,
textToBinary,
textToUnicode,
yamlToJson,
yamlToToml,
jsonToYaml,
jsonToToml,
listConverter,
tomlToJson,
tomlToYaml,
xmlToJson,
jsonToXml,
markdownToHtml,
],
},
{
name: 'Web',
components: [
urlEncoder,
htmlEntities,
urlParser,
deviceInformation,
basicAuthGenerator,
metaTagGenerator,
otpCodeGeneratorAndValidator,
mimeTypes,
jwtParser,
keycodeInfo,
slugifyString,
htmlWysiwygEditor,
userAgentParser,
httpStatusCodes,
jsonDiff,
safelinkDecoder,
],
},
{
name: 'Images and videos',
components: [qrCodeGenerator, wifiQrCodeGenerator, svgPlaceholderGenerator, cameraRecorder],
},
{
name: 'Development',
components: [
gitMemo,
randomPortGenerator,
crontabGenerator,
jsonViewer,
jsonMinify,
jsonToCsv,
sqlPrettify,
chmodCalculator,
dockerRunToDockerComposeConverter,
xmlFormatter,
yamlViewer,
emailNormalizer,
regexTester,
regexMemo,
],
},
{
name: 'Network',
components: [ipv4SubnetCalculator, ipv4AddressConverter, ipv4RangeExpander, macAddressLookup, macAddressGenerator, ipv6UlaGenerator],
},
{
name: 'Math',
components: [mathEvaluator, etaCalculator, percentageCalculator],
},
{
name: 'Measurement',
components: [chronometer, temperatureConverter, benchmarkBuilder],
},
{
name: 'Text',
components: [
loremIpsumGenerator,
textStatistics,
emojiPicker,
stringObfuscator,
textDiff,
numeronymGenerator,
asciiTextDrawer,
],
},
{
name: 'Data',
components: [phoneParserAndFormatter, ibanValidatorAndParser],
},
];
export const tools = toolsByCategory.flatMap(({ components }) => components); export const tools = toolsByCategory.flatMap(({ components }) => components);
export const toolsWithCategory = toolsByCategory.flatMap(({ components, name }) => export const toolsWithCategory = toolsByCategory.flatMap(({ components, name }) =>

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['integer', 'number', 'base', 'conversion', 'decimal', 'hexadecimal', 'binary', 'octal', 'base64'], keywords: ['integer', 'number', 'base', 'conversion', 'decimal', 'hexadecimal', 'binary', 'octal', 'base64'],
component: () => import('./integer-base-converter.vue'), component: () => import('./integer-base-converter.vue'),
icon: ArrowsLeftRight, icon: ArrowsLeftRight,
category: 'Converter',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./ipv4-address-converter.vue'), component: () => import('./ipv4-address-converter.vue'),
icon: Binary, icon: Binary,
createdAt: new Date('2023-04-08'), createdAt: new Date('2023-04-08'),
category: 'Network',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./ipv4-range-expander.vue'), component: () => import('./ipv4-range-expander.vue'),
icon: UnfoldMoreOutlined, icon: UnfoldMoreOutlined,
createdAt: new Date('2023-04-19'), createdAt: new Date('2023-04-19'),
category: 'Network',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['ipv4', 'subnet', 'calculator', 'mask', 'network', 'cidr', 'netmask', 'bitmask', 'broadcast', 'address'], keywords: ['ipv4', 'subnet', 'calculator', 'mask', 'network', 'cidr', 'netmask', 'bitmask', 'broadcast', 'address'],
component: () => import('./ipv4-subnet-calculator.vue'), component: () => import('./ipv4-subnet-calculator.vue'),
icon: RouterOutlined, icon: RouterOutlined,
category: 'Network',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./ipv6-ula-generator.vue'), component: () => import('./ipv6-ula-generator.vue'),
icon: BuildingFactory, icon: BuildingFactory,
createdAt: new Date('2023-04-09'), createdAt: new Date('2023-04-09'),
category: 'Network',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./json-diff.vue'), component: () => import('./json-diff.vue'),
icon: CompareArrowsRound, icon: CompareArrowsRound,
createdAt: new Date('2023-04-20'), createdAt: new Date('2023-04-20'),
category: 'Web',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['json', 'minify', 'format'], keywords: ['json', 'minify', 'format'],
component: () => import('./json-minify.vue'), component: () => import('./json-minify.vue'),
icon: Braces, icon: Braces,
category: 'Development',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./json-to-csv.vue'), component: () => import('./json-to-csv.vue'),
icon: List, icon: List,
createdAt: new Date('2023-06-18'), createdAt: new Date('2023-06-18'),
category: 'Development',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./json-to-toml.vue'), component: () => import('./json-to-toml.vue'),
icon: Braces, icon: Braces,
createdAt: new Date('2023-06-23'), createdAt: new Date('2023-06-23'),
category: 'Converter',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
component: () => import('./json-to-xml.vue'), component: () => import('./json-to-xml.vue'),
icon: Braces, icon: Braces,
createdAt: new Date('2024-08-09'), createdAt: new Date('2024-08-09'),
category: 'Converter',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./json-to-yaml.vue'), component: () => import('./json-to-yaml.vue'),
icon: Braces, icon: Braces,
createdAt: new Date('2023-04-10'), createdAt: new Date('2023-04-10'),
category: 'Converter',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./json-viewer.vue'), component: () => import('./json-viewer.vue'),
icon: Braces, icon: Braces,
redirectFrom: ['/json-viewer'], redirectFrom: ['/json-viewer'],
category: 'Development',
}); });

View file

@ -25,4 +25,5 @@ export const tool = defineTool({
], ],
component: () => import('./jwt-parser.vue'), component: () => import('./jwt-parser.vue'),
icon: Key, icon: Key,
category: 'Web',
}); });

View file

@ -24,4 +24,5 @@ export const tool = defineTool({
], ],
component: () => import('./keycode-info.vue'), component: () => import('./keycode-info.vue'),
icon: Keyboard, icon: Keyboard,
category: 'Web',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./list-converter.vue'), component: () => import('./list-converter.vue'),
icon: List, icon: List,
createdAt: new Date('2023-05-07'), createdAt: new Date('2023-05-07'),
category: 'Converter',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['lorem', 'ipsum', 'dolor', 'sit', 'amet', 'placeholder', 'text', 'filler', 'random', 'generator'], keywords: ['lorem', 'ipsum', 'dolor', 'sit', 'amet', 'placeholder', 'text', 'filler', 'random', 'generator'],
component: () => import('./lorem-ipsum-generator.vue'), component: () => import('./lorem-ipsum-generator.vue'),
icon: AlignJustified, icon: AlignJustified,
category: 'Text',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./mac-address-generator.vue'), component: () => import('./mac-address-generator.vue'),
icon: Devices, icon: Devices,
createdAt: new Date('2023-11-31'), createdAt: new Date('2023-11-31'),
category: 'Network',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./mac-address-lookup.vue'), component: () => import('./mac-address-lookup.vue'),
icon: Devices, icon: Devices,
createdAt: new Date('2023-04-06'), createdAt: new Date('2023-04-06'),
category: 'Network',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
component: () => import('./markdown-to-html.vue'), component: () => import('./markdown-to-html.vue'),
icon: Markdown, icon: Markdown,
createdAt: new Date('2024-08-25'), createdAt: new Date('2024-08-25'),
category: 'Converter',
}); });

View file

@ -41,4 +41,5 @@ export const tool = defineTool({
], ],
component: () => import('./math-evaluator.vue'), component: () => import('./math-evaluator.vue'),
icon: Math, icon: Math,
category: 'Math',
}); });

View file

@ -23,4 +23,5 @@ export const tool = defineTool({
], ],
component: () => import('./meta-tag-generator.vue'), component: () => import('./meta-tag-generator.vue'),
icon: Tags, icon: Tags,
category: 'Web',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['mime', 'types', 'extension', 'content', 'type'], keywords: ['mime', 'types', 'extension', 'content', 'type'],
component: () => import('./mime-types.vue'), component: () => import('./mime-types.vue'),
icon: World, icon: World,
category: 'Web',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./numeronym-generator.vue'), component: () => import('./numeronym-generator.vue'),
icon: n7mIcon, icon: n7mIcon,
createdAt: new Date('2023-11-05'), createdAt: new Date('2023-11-05'),
category: 'Text',
}); });

View file

@ -25,4 +25,5 @@ export const tool = defineTool({
], ],
component: () => import('./otp-code-generator-and-validator.vue'), component: () => import('./otp-code-generator-and-validator.vue'),
icon: DeviceMobile, icon: DeviceMobile,
category: 'Web',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./password-strength-analyser.vue'), component: () => import('./password-strength-analyser.vue'),
icon: PasswordIcon, icon: PasswordIcon,
createdAt: new Date('2023-06-24'), createdAt: new Date('2023-06-24'),
category: 'Crypto',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./pdf-signature-checker.vue'), component: () => import('./pdf-signature-checker.vue'),
icon: FileCertIcon, icon: FileCertIcon,
createdAt: new Date('2023-12-09'), createdAt: new Date('2023-12-09'),
category: 'Crypto',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./percentage-calculator.vue'), component: () => import('./percentage-calculator.vue'),
icon: Percentage, icon: Percentage,
createdAt: new Date('2023-06-18'), createdAt: new Date('2023-06-18'),
category: 'Math',
}); });

View file

@ -22,4 +22,5 @@ export const tool = defineTool({
component: () => import('./phone-parser-and-formatter.vue'), component: () => import('./phone-parser-and-formatter.vue'),
icon: Phone, icon: Phone,
createdAt: new Date('2023-05-01'), createdAt: new Date('2023-05-01'),
category: 'Data',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['qr', 'code', 'generator', 'square', 'color', 'link', 'low', 'medium', 'quartile', 'high', 'transparent'], keywords: ['qr', 'code', 'generator', 'square', 'color', 'link', 'low', 'medium', 'quartile', 'high', 'transparent'],
component: () => import('./qr-code-generator.vue'), component: () => import('./qr-code-generator.vue'),
icon: Qrcode, icon: Qrcode,
category: 'Images and videos',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['system', 'port', 'lan', 'generator', 'random', 'development', 'computer'], keywords: ['system', 'port', 'lan', 'generator', 'random', 'development', 'computer'],
component: () => import('./random-port-generator.vue'), component: () => import('./random-port-generator.vue'),
icon: Server, icon: Server,
category: 'Development',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
component: () => import('./regex-memo.vue'), component: () => import('./regex-memo.vue'),
icon: BrandJavascript, icon: BrandJavascript,
createdAt: new Date('2024-09-20'), createdAt: new Date('2024-09-20'),
category: 'Development',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
component: () => import('./regex-tester.vue'), component: () => import('./regex-tester.vue'),
icon: Language, icon: Language,
createdAt: new Date('2024-09-20'), createdAt: new Date('2024-09-20'),
category: 'Development',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['roman', 'arabic', 'converter', 'X', 'I', 'V', 'L', 'C', 'D', 'M'], keywords: ['roman', 'arabic', 'converter', 'X', 'I', 'V', 'L', 'C', 'D', 'M'],
component: () => import('./roman-numeral-converter.vue'), component: () => import('./roman-numeral-converter.vue'),
icon: LetterX, icon: LetterX,
category: 'Converter',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['rsa', 'key', 'pair', 'generator', 'public', 'private', 'secret', 'ssh', 'pem'], keywords: ['rsa', 'key', 'pair', 'generator', 'public', 'private', 'secret', 'ssh', 'pem'],
component: () => import('./rsa-key-pair-generator.vue'), component: () => import('./rsa-key-pair-generator.vue'),
icon: Certificate, icon: Certificate,
category: 'Crypto',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
component: () => import('./safelink-decoder.vue'), component: () => import('./safelink-decoder.vue'),
icon: Mailbox, icon: Mailbox,
createdAt: new Date('2024-03-11'), createdAt: new Date('2024-03-11'),
category: 'Web',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['slugify', 'string', 'escape', 'emoji', 'special', 'character', 'space', 'trim'], keywords: ['slugify', 'string', 'escape', 'emoji', 'special', 'character', 'space', 'trim'],
component: () => import('./slugify-string.vue'), component: () => import('./slugify-string.vue'),
icon: AbcRound, icon: AbcRound,
category: 'Web',
}); });

View file

@ -24,4 +24,5 @@ export const tool = defineTool({
], ],
component: () => import('./sql-prettify.vue'), component: () => import('./sql-prettify.vue'),
icon: Database, icon: Database,
category: 'Development',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./string-obfuscator.vue'), component: () => import('./string-obfuscator.vue'),
icon: EyeOff, icon: EyeOff,
createdAt: new Date('2023-08-16'), createdAt: new Date('2023-08-16'),
category: 'Text',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['svg', 'placeholder', 'generator', 'image', 'size', 'mockup'], keywords: ['svg', 'placeholder', 'generator', 'image', 'size', 'mockup'],
component: () => import('./svg-placeholder-generator.vue'), component: () => import('./svg-placeholder-generator.vue'),
icon: ImageOutlined, icon: ImageOutlined,
category: 'Images and videos',
}); });

View file

@ -21,4 +21,5 @@ export const tool = defineTool({
], ],
component: () => import('./temperature-converter.vue'), component: () => import('./temperature-converter.vue'),
icon: Temperature, icon: Temperature,
category: 'Measurement',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./text-diff.vue'), component: () => import('./text-diff.vue'),
icon: FileDiff, icon: FileDiff,
createdAt: new Date('2023-08-16'), createdAt: new Date('2023-08-16'),
category: 'Text',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./text-statistics.vue'), component: () => import('./text-statistics.vue'),
icon: FileText, icon: FileText,
redirectFrom: ['/text-stats'], redirectFrom: ['/text-stats'],
category: 'Text',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./text-to-binary.vue'), component: () => import('./text-to-binary.vue'),
icon: Binary, icon: Binary,
createdAt: new Date('2023-10-15'), createdAt: new Date('2023-10-15'),
category: 'Converter',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['string', 'nato', 'alphabet', 'phonetic', 'oral', 'transmission'], keywords: ['string', 'nato', 'alphabet', 'phonetic', 'oral', 'transmission'],
component: () => import('./text-to-nato-alphabet.vue'), component: () => import('./text-to-nato-alphabet.vue'),
icon: Speakerphone, icon: Speakerphone,
category: 'Converter',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./text-to-unicode.vue'), component: () => import('./text-to-unicode.vue'),
icon: TextWrap, icon: TextWrap,
createdAt: new Date('2024-01-31'), createdAt: new Date('2024-01-31'),
category: 'Converter',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['token', 'random', 'string', 'alphanumeric', 'symbols', 'number', 'letters', 'lowercase', 'uppercase', 'password'], keywords: ['token', 'random', 'string', 'alphanumeric', 'symbols', 'number', 'letters', 'lowercase', 'uppercase', 'password'],
component: () => import('./token-generator.tool.vue'), component: () => import('./token-generator.tool.vue'),
icon: ArrowsShuffle, icon: ArrowsShuffle,
category: 'Crypto',
}); });

View file

@ -11,4 +11,5 @@ export const tool = defineTool({
component: () => import('./toml-to-json.vue'), component: () => import('./toml-to-json.vue'),
icon: BracketIcon, icon: BracketIcon,
createdAt: new Date('2023-06-23'), createdAt: new Date('2023-06-23'),
category: 'Converter',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./toml-to-yaml.vue'), component: () => import('./toml-to-yaml.vue'),
icon: BracketIcon, icon: BracketIcon,
createdAt: new Date('2023-06-23'), createdAt: new Date('2023-06-23'),
category: 'Converter',
}); });

View file

@ -1,9 +1,9 @@
import { isAfter, subWeeks } from 'date-fns'; import { isAfter, subWeeks } from 'date-fns';
import type { Tool } from './tools.types'; import type { ToolWithCategory } from './tools.types';
type WithOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>; type WithOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
export function defineTool(tool: WithOptional<Tool, 'isNew'>) { export function defineTool(tool: WithOptional<ToolWithCategory, 'isNew'>) {
const isNew = tool.createdAt ? isAfter(tool.createdAt, subWeeks(new Date(), 2)) : false; const isNew = tool.createdAt ? isAfter(tool.createdAt, subWeeks(new Date(), 2)) : false;
return { return {

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./ulid-generator.vue'), component: () => import('./ulid-generator.vue'),
icon: SortDescendingNumbers, icon: SortDescendingNumbers,
createdAt: new Date('2023-09-11'), createdAt: new Date('2023-09-11'),
category: 'Crypto',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['url', 'encode', 'decode', 'percent', '%20', 'format'], keywords: ['url', 'encode', 'decode', 'percent', '%20', 'format'],
component: () => import('./url-encoder.vue'), component: () => import('./url-encoder.vue'),
icon: Link, icon: Link,
category: 'Web',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['url', 'parser', 'protocol', 'origin', 'params', 'port', 'username', 'password', 'href'], keywords: ['url', 'parser', 'protocol', 'origin', 'params', 'port', 'username', 'password', 'href'],
component: () => import('./url-parser.vue'), component: () => import('./url-parser.vue'),
icon: Unlink, icon: Unlink,
category: 'Web',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./user-agent-parser.vue'), component: () => import('./user-agent-parser.vue'),
icon: Browser, icon: Browser,
createdAt: new Date('2023-04-06'), createdAt: new Date('2023-04-06'),
category: 'Web',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
keywords: ['uuid', 'v4', 'random', 'id', 'alphanumeric', 'identity', 'token', 'string', 'identifier', 'unique', 'v1', 'v3', 'v5', 'nil'], keywords: ['uuid', 'v4', 'random', 'id', 'alphanumeric', 'identity', 'token', 'string', 'identifier', 'unique', 'v1', 'v3', 'v5', 'nil'],
component: () => import('./uuid-generator.vue'), component: () => import('./uuid-generator.vue'),
icon: Fingerprint, icon: Fingerprint,
category: 'Crypto',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./wifi-qr-code-generator.vue'), component: () => import('./wifi-qr-code-generator.vue'),
icon: Qrcode, icon: Qrcode,
createdAt: new Date('2023-09-06'), createdAt: new Date('2023-09-06'),
category: 'Images and videos',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./xml-formatter.vue'), component: () => import('./xml-formatter.vue'),
icon: Code, icon: Code,
createdAt: new Date('2023-06-17'), createdAt: new Date('2023-06-17'),
category: 'Development',
}); });

View file

@ -9,4 +9,5 @@ export const tool = defineTool({
component: () => import('./xml-to-json.vue'), component: () => import('./xml-to-json.vue'),
icon: Braces, icon: Braces,
createdAt: new Date('2024-08-09'), createdAt: new Date('2024-08-09'),
category: 'Converter',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./yaml-to-json.vue'), component: () => import('./yaml-to-json.vue'),
icon: AlignJustified, icon: AlignJustified,
createdAt: new Date('2023-04-10'), createdAt: new Date('2023-04-10'),
category: 'Converter',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./yaml-to-toml.vue'), component: () => import('./yaml-to-toml.vue'),
icon: AlignJustified, icon: AlignJustified,
createdAt: new Date('2023-06-23'), createdAt: new Date('2023-06-23'),
category: 'Converter',
}); });

View file

@ -10,4 +10,5 @@ export const tool = defineTool({
component: () => import('./yaml-viewer.vue'), component: () => import('./yaml-viewer.vue'),
icon: AlignJustified, icon: AlignJustified,
createdAt: new Date('2024-01-31'), createdAt: new Date('2024-01-31'),
category: 'Development',
}); });

View file

@ -10,7 +10,9 @@ import {
import { presetScrollbar } from 'unocss-preset-scrollbar'; import { presetScrollbar } from 'unocss-preset-scrollbar';
export default defineConfig({ export default defineConfig({
presets: [presetUno(), presetAttributify(), presetTypography(), presetScrollbar()], presets: [presetUno(), presetAttributify({
ignoreAttributes: ['size'],
}), presetTypography(), presetScrollbar()],
transformers: [transformerDirectives(), transformerVariantGroup()], transformers: [transformerDirectives(), transformerVariantGroup()],
theme: { theme: {
colors: { colors: {

View file

@ -29,6 +29,7 @@ export default defineConfig({
strictMessage: false, strictMessage: false,
include: [ include: [
resolve(__dirname, 'locales/**'), resolve(__dirname, 'locales/**'),
resolve(__dirname, 'src/tools/*/locales/**'),
], ],
}), }),
AutoImport({ AutoImport({