feat(tool): nanoid generator
This commit is contained in:
		
							parent
							
								
									b430baef40
								
							
						
					
					
						commit
						2dbc8fadd6
					
				
							
								
								
									
										8
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -126,25 +126,33 @@ declare module '@vue/runtime-core' { | ||||
|     MenuLayout: typeof import('./src/components/MenuLayout.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'] | ||||
|     NAlert: typeof import('naive-ui')['NAlert'] | ||||
|     NanoidGenerator: typeof import('./src/tools/nanoid-generator/nanoid-generator.vue')['default'] | ||||
|     NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default'] | ||||
|     NCode: typeof import('naive-ui')['NCode'] | ||||
|     NCollapseTransition: typeof import('naive-ui')['NCollapseTransition'] | ||||
|     NConfigProvider: typeof import('naive-ui')['NConfigProvider'] | ||||
|     NDivider: typeof import('naive-ui')['NDivider'] | ||||
|     NEllipsis: typeof import('naive-ui')['NEllipsis'] | ||||
|     NForm: typeof import('naive-ui')['NForm'] | ||||
|     NFormItem: typeof import('naive-ui')['NFormItem'] | ||||
|     NGi: typeof import('naive-ui')['NGi'] | ||||
|     NGrid: typeof import('naive-ui')['NGrid'] | ||||
|     NH1: typeof import('naive-ui')['NH1'] | ||||
|     NH3: typeof import('naive-ui')['NH3'] | ||||
|     NIcon: typeof import('naive-ui')['NIcon'] | ||||
|     NInputGroup: typeof import('naive-ui')['NInputGroup'] | ||||
|     NInputGroupLabel: typeof import('naive-ui')['NInputGroupLabel'] | ||||
|     NInputNumber: typeof import('naive-ui')['NInputNumber'] | ||||
|     NLabel: typeof import('naive-ui')['NLabel'] | ||||
|     NLayout: typeof import('naive-ui')['NLayout'] | ||||
|     NLayoutSider: typeof import('naive-ui')['NLayoutSider'] | ||||
|     NMenu: typeof import('naive-ui')['NMenu'] | ||||
|     NScrollbar: typeof import('naive-ui')['NScrollbar'] | ||||
|     NSlider: typeof import('naive-ui')['NSlider'] | ||||
|     NSpin: typeof import('naive-ui')['NSpin'] | ||||
|     NSwitch: typeof import('naive-ui')['NSwitch'] | ||||
|     NText: typeof import('naive-ui')['NText'] | ||||
|     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'] | ||||
|     PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default'] | ||||
|  | ||||
| @ -352,6 +352,22 @@ tools: | ||||
|     title: UUIDs generator | ||||
|     description: A Universally Unique Identifier (UUID) is a 128-bit number used to identify information in computer systems. The number of possible UUIDs is 16^32, which is 2^128 or about 3.4x10^38 (which is a lot!). | ||||
| 
 | ||||
|   nanoid-generator: | ||||
|     title: NanoIDs generator | ||||
|     description: Generate random, unique, and URL-friendly IDs for your applications. | ||||
|     uppercase: Uppercase | ||||
|     lowercase: Lowercase | ||||
|     numbers: Numbers | ||||
|     symbols: Symbols | ||||
|     excludeLookalikes: Exclude lookalikes | ||||
|     length: Length | ||||
|     quantity: Quantity | ||||
|     copied: NanoID copied to the clipboard | ||||
|     button: | ||||
|       copy: Copy | ||||
|       refresh: Refresh | ||||
| 
 | ||||
| 
 | ||||
|   ipv4-address-converter: | ||||
|     title: IPv4 address converter | ||||
|     description: Convert an IP address into decimal, binary, hexadecimal, or even an IPv6 representation of it. | ||||
|  | ||||
| @ -74,6 +74,8 @@ | ||||
|     "mime-types": "^2.1.35", | ||||
|     "monaco-editor": "^0.43.0", | ||||
|     "naive-ui": "^2.35.0", | ||||
|     "nanoid": "^5.0.7", | ||||
|     "nanoid-dictionary": "^4.3.0", | ||||
|     "netmask": "^2.0.2", | ||||
|     "node-forge": "^1.3.1", | ||||
|     "oui-data": "^1.0.10", | ||||
|  | ||||
							
								
								
									
										11159
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										11159
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,6 +1,7 @@ | ||||
| import { tool as base64FileConverter } from './base64-file-converter'; | ||||
| import { tool as base64StringConverter } from './base64-string-converter'; | ||||
| import { tool as basicAuthGenerator } from './basic-auth-generator'; | ||||
| import { tool as nanoidGenerator } from './nanoid-generator'; | ||||
| 
 | ||||
| import { tool as asciiTextDrawer } from './ascii-text-drawer'; | ||||
| 
 | ||||
| @ -85,7 +86,7 @@ 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], | ||||
|     components: [tokenGenerator, hashText, bcrypt, uuidGenerator, nanoidGenerator, ulidGenerator, cypher, bip39, hmacGenerator, rsaKeyPairGenerator, passwordStrengthAnalyser, pdfSignatureChecker], | ||||
|   }, | ||||
|   { | ||||
|     name: 'Converter', | ||||
|  | ||||
							
								
								
									
										13
									
								
								src/tools/nanoid-generator/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/tools/nanoid-generator/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| import { Fingerprint } from '@vicons/tabler'; | ||||
| import { defineTool } from '../tool'; | ||||
| import { translate } from '@/plugins/i18n.plugin'; | ||||
| 
 | ||||
| export const tool = defineTool({ | ||||
|   name: translate('tools.nanoid-generator.title'), | ||||
|   path: '/nanoid-generator', | ||||
|   description: translate('tools.nanoid-generator.description'), | ||||
|   keywords: ['nanoid', 'generator'], | ||||
|   component: () => import('./nanoid-generator.vue'), | ||||
|   icon: Fingerprint, | ||||
|   createdAt: new Date('2024-05-31'), | ||||
| }); | ||||
							
								
								
									
										39
									
								
								src/tools/nanoid-generator/nanoid-generator.service.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/tools/nanoid-generator/nanoid-generator.service.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | ||||
| import { customAlphabet, nanoid } from 'nanoid'; | ||||
| import { lowercase, nolookalikes, numbers, uppercase } from 'nanoid-dictionary'; | ||||
| 
 | ||||
| const symbols = '-_'; | ||||
| 
 | ||||
| export function createNanoid({ | ||||
|   length = 21, | ||||
|   withLowercase = true, | ||||
|   withUppercase = true, | ||||
|   withNumbers = true, | ||||
|   withSymbols = true, | ||||
|   excludeLookalikes = false, | ||||
| }: { | ||||
|   length?: number | ||||
|   withLowercase?: boolean | ||||
|   withUppercase?: boolean | ||||
|   withNumbers?: boolean | ||||
|   withSymbols?: boolean | ||||
|   excludeLookalikes?: boolean | ||||
| }) { | ||||
|   let alphabet = ''; | ||||
| 
 | ||||
|   if (!withLowercase && !withUppercase && !withNumbers && !excludeLookalikes && !withSymbols) { | ||||
|     return nanoid(length); | ||||
|   } | ||||
| 
 | ||||
|   if (excludeLookalikes) { | ||||
|     alphabet = [nolookalikes, withSymbols ? symbols : ''].join(''); | ||||
|   } | ||||
| 
 | ||||
|   alphabet = [ | ||||
|     withLowercase ? lowercase : '', | ||||
|     withUppercase ? uppercase : '', | ||||
|     withNumbers ? numbers : '', | ||||
|     withSymbols ? symbols : '', | ||||
|   ].join(''); | ||||
| 
 | ||||
|   return customAlphabet(alphabet, length); | ||||
| } | ||||
							
								
								
									
										156
									
								
								src/tools/nanoid-generator/nanoid-generator.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								src/tools/nanoid-generator/nanoid-generator.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,156 @@ | ||||
| <script setup lang="ts"> | ||||
| import { InfoCircle } from '@vicons/tabler'; | ||||
| import { createNanoid } from './nanoid-generator.service'; | ||||
| import { computedRefreshable } from '@/composable/computedRefreshable'; | ||||
| import { withDefaultOnError } from '@/utils/defaults'; | ||||
| import { useCopy } from '@/composable/copy'; | ||||
| import { useQueryParam } from '@/composable/queryParams'; | ||||
| 
 | ||||
| const count = useQueryParam({ name: 'count', defaultValue: 1 }); | ||||
| const length = useQueryParam({ name: 'length', defaultValue: 21 }); | ||||
| const withUppercase = useQueryParam({ name: 'uppercase', defaultValue: true }); | ||||
| const withLowercase = useQueryParam({ name: 'lowercase', defaultValue: true }); | ||||
| const withNumbers = useQueryParam({ name: 'numbers', defaultValue: true }); | ||||
| const withSymbols = useQueryParam({ name: 'symbols', defaultValue: true }); | ||||
| const excludeLookalikes = useQueryParam({ name: 'no-lookalikes', defaultValue: false }); | ||||
| 
 | ||||
| const { t } = useI18n(); | ||||
| 
 | ||||
| const [nanoIds, refreshNanoIds] = computedRefreshable(() => | ||||
|   withDefaultOnError( | ||||
|     () => | ||||
|       Array.from({ length: count.value }, (_ignored) => { | ||||
|         const nanoId = createNanoid({ | ||||
|           length: length.value, | ||||
|           withUppercase: withUppercase.value, | ||||
|           withLowercase: withLowercase.value, | ||||
|           withNumbers: withNumbers.value, | ||||
|           withSymbols: withSymbols.value, | ||||
|           excludeLookalikes: excludeLookalikes.value, | ||||
|         }); | ||||
| 
 | ||||
|         return nanoId(); | ||||
|       }).join('\n'), | ||||
|     '', | ||||
|   ), | ||||
| ); | ||||
| 
 | ||||
| const { copy } = useCopy({ source: nanoIds, text: 'NanoIds copied to the clipboard' }); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|   <div> | ||||
|     <n-form label-placement="left" label-width="140"> | ||||
|       <div mb-8 flex justify-center gap-8> | ||||
|         <div class="column"> | ||||
|           <div> | ||||
|             <n-text>{{ t('tools.nanoid-generator.uppercase') }}</n-text> | ||||
|             <c-tooltip | ||||
|               tooltip="ABCDEFGHIJKLMNOPQRSTUVWXYZ" position="bottom" | ||||
|             > | ||||
|               <n-icon size="20" :component="InfoCircle" /> | ||||
|             </c-tooltip> | ||||
|             <n-switch v-model:value="withUppercase" /> | ||||
|           </div> | ||||
| 
 | ||||
|           <div> | ||||
|             <n-text>{{ t('tools.nanoid-generator.lowercase') }}</n-text> | ||||
|             <c-tooltip | ||||
|               tooltip="abcdefghijklmnopqrstuvwxyz" position="bottom" | ||||
|             > | ||||
|               <n-icon size="20" :component="InfoCircle" /> | ||||
|             </c-tooltip> | ||||
|             <n-switch v-model:value="withLowercase" /> | ||||
|           </div> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="column"> | ||||
|           <div> | ||||
|             <n-text> | ||||
|               {{ t('tools.nanoid-generator.numbers') }} | ||||
|             </n-text> | ||||
|             <c-tooltip | ||||
|               tooltip="0123456789" position="bottom" | ||||
|             > | ||||
|               <n-icon size="20" :component="InfoCircle" /> | ||||
|             </c-tooltip> | ||||
|             <n-switch v-model:value="withNumbers" /> | ||||
|           </div> | ||||
| 
 | ||||
|           <div> | ||||
|             <n-text> | ||||
|               {{ t('tools.nanoid-generator.symbols') }} | ||||
|             </n-text> | ||||
|             <c-tooltip | ||||
|               tooltip="-_" position="bottom" | ||||
|             > | ||||
|               <n-icon size="20" :component="InfoCircle" /> | ||||
|             </c-tooltip> | ||||
|             <n-switch v-model:value="withSymbols" /> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="column"> | ||||
|           <div> | ||||
|             <n-text> | ||||
|               {{ t('tools.nanoid-generator.excludeLookalikes') }} | ||||
|             </n-text> | ||||
|             <c-tooltip | ||||
|               tooltip="1lI0Oouv5Ss2Z" position="bottom" | ||||
|             > | ||||
|               <n-icon size="20" :component="InfoCircle" /> | ||||
|             </c-tooltip> | ||||
|             <n-switch v-model:value="excludeLookalikes" /> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </n-form> | ||||
| 
 | ||||
|     <div mb-2 flex items-center> | ||||
|       <span w-100px>{{ t('tools.nanoid-generator.length') }}</span> | ||||
|       <n-input-number v-model:value="length" flex-1 :min="1" :max="100" placeholder="NanoId Length" /> | ||||
|     </div> | ||||
|     <div mb-2 flex items-center> | ||||
|       <span w-100px>{{ t('tools.nanoid-generator.quantity') }}</span> | ||||
|       <n-input-number v-model:value="count" flex-1 :min="1" :max="50" placeholder="NanoIds quantity" /> | ||||
|     </div> | ||||
| 
 | ||||
|     <c-input-text | ||||
|       style="text-align: center; font-family: monospace" | ||||
|       :value="nanoIds" | ||||
|       placeholder="Your uuids" | ||||
|       rows="1" | ||||
|       autosize | ||||
|       readonly | ||||
|       raw-text | ||||
|       multiline | ||||
|       monospace | ||||
|       my-3 | ||||
|       class="uuid-display" | ||||
|     /> | ||||
| 
 | ||||
|     <div flex justify-center gap-3> | ||||
|       <c-button autofocus @click="copy()"> | ||||
|         {{ t('tools.nanoid-generator.button.copy') }} | ||||
|       </c-button> | ||||
|       <c-button @click="refreshNanoIds"> | ||||
|         {{ t('tools.nanoid-generator.button.refresh') }} | ||||
|       </c-button> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped lang="less"> | ||||
| .n-icon { | ||||
|   margin-right: 8px; | ||||
| } | ||||
| 
 | ||||
| .n-text { | ||||
|   margin-right: 8px; | ||||
| } | ||||
| 
 | ||||
| .column { | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   gap: 8px; | ||||
| } | ||||
| </style> | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user