Skip to content

Commit 669a38b

Browse files
committed
feat(tools): port 27 tools from the upstream PR backlog
Upstream has 327 open PRs with a median age of two years and no maintainer triage. Rather than replay individual PR branches - which all collide on the same region of src/tools/index.ts - these are taken from sharevb/it-tools, where the same PRs are already merged and conflict-resolved. Both repositories are GPL-3.0. Crypto: argon2-hash (CorentinTh#363, the maintainer's own PR, open 3.3 years), file-hasher (CorentinTh#1141), crc-calculator (CorentinTh#1140), htpasswd-generator (CorentinTh#902), passphrase-generator (CorentinTh#1260) Text: sensitive-data-masker (CorentinTh#1182), smart-text-replacer (CorentinTh#1290), list-comparer (CorentinTh#1303) Converter: morse-converter (CorentinTh#1021), punycode-converter (CorentinTh#1258), html-to-markdown (CorentinTh#904), json-to-typescript (CorentinTh#1002), json-to-schema (CorentinTh#1166), json-escaper (CorentinTh#966) Development: json-sort-master (CorentinTh#943), html-cleaner (CorentinTh#961), markdown-toc-generator (CorentinTh#1106) Network: ipv6-subnet-calculator (CorentinTh#963), ip-cidr-to-range (CorentinTh#871), ip-range-to-cidr (CorentinTh#869), url-cleaner (CorentinTh#959), port-numbers (CorentinTh#1029) Date & time: timezone-converter (CorentinTh#1284), duration-calculator (CorentinTh#1324) [new category] Measurement: many-units-converter (CorentinTh#1330), sla-calculator (CorentinTh#1304) Data: luhn-validator (CorentinTh#1320) Reconciling the two forks' conventions: - icons move from defineAsyncComponent(() => import('@vicons/tabler/es/X')) to a plain named import; - the per-tool `category` field is dropped, since categories live in toolsByCategory here; - i18n keys are merged into the root locale files for all nine languages this fork ships, so the ports arrive translated rather than showing raw keys. Small compatibility additions rather than importing sharevb's wider infrastructure: useQueryParam accepts and ignores a `tool` property (it namespaces against a per-tool settings store this fork does not have), useITStorage wraps useStorage, multiRandFromArray joins utils/random, Tool gains an optional externAccessDescription, and src/utils/ip.ts plus the IANA registries back the three new network tools. The locale-aware number input is ported as src/ui/n-input-number-i18n. Two upstream behaviours had to be adapted: - json-sort-master used a big-number-preserving JSON.parse that sharevb patches onto the global object; plain JSON.parse is used instead, with a comment. - duration-calculator formatted negative durations as positive ISO 8601, because date-fns v2's intervalToDuration returns absolute components. The sign is now restored per component, which makes its own test pass. Nine candidates were deliberately not ported, each for a stated reason: unicode-search, text-to-unicode-names and iso-3166-searcher need a full Unicode database or countries-db plus a search composable this fork lacks; certificate-key-parser pulls in openpgp and sshpk; jq-tester needs jq-wasm; stacktrace-prettier needs four stack-parsing libraries and a style store; json-linter and docker-compose-to-docker-run-converter need a Monaco editor wrapper; jwt-generator is written against jose v6 and jwt-decode v4. All 27 verified in a real browser: every route renders with no console errors, and spot checks confirm real behaviour (Luhn validates 79927398713 with key 3, the URL cleaner strips utm parameters, port 80/tcp resolves to www-http). Lint, 347 unit tests, typecheck and build all pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019u4HjVENAajio7cxNSDzir
1 parent 572cdee commit 669a38b

96 files changed

Lines changed: 11156 additions & 84 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

components.d.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ declare module '@vue/runtime-core' {
1616
'ApiDocs.page': typeof import('./src/pages/ApiDocs.page.vue')['default']
1717
ApiUsage: typeof import('./src/components/ApiUsage.vue')['default']
1818
App: typeof import('./src/App.vue')['default']
19+
Argon2Hash: typeof import('./src/tools/argon2-hash/argon2-hash.vue')['default']
1920
AsciiTextDrawer: typeof import('./src/tools/ascii-text-drawer/ascii-text-drawer.vue')['default']
2021
'Base.layout': typeof import('./src/layouts/base.layout.vue')['default']
2122
Base64FileConverter: typeof import('./src/tools/base64-file-converter/base64-file-converter.vue')['default']
@@ -59,6 +60,7 @@ declare module '@vue/runtime-core' {
5960
ColoredCard: typeof import('./src/components/ColoredCard.vue')['default']
6061
CommandPalette: typeof import('./src/modules/command-palette/command-palette.vue')['default']
6162
CommandPaletteOption: typeof import('./src/modules/command-palette/components/command-palette-option.vue')['default']
63+
CrcCalculator: typeof import('./src/tools/crc-calculator/crc-calculator.vue')['default']
6264
CrontabGenerator: typeof import('./src/tools/crontab-generator/crontab-generator.vue')['default']
6365
CSelect: typeof import('./src/ui/c-select/c-select.vue')['default']
6466
'CSelect.demo': typeof import('./src/ui/c-select/c-select.demo.vue')['default']
@@ -74,6 +76,7 @@ declare module '@vue/runtime-core' {
7476
DeviceInformation: typeof import('./src/tools/device-information/device-information.vue')['default']
7577
DiffViewer: typeof import('./src/tools/json-diff/diff-viewer/diff-viewer.vue')['default']
7678
DockerRunToDockerComposeConverter: typeof import('./src/tools/docker-run-to-docker-compose-converter/docker-run-to-docker-compose-converter.vue')['default']
79+
DurationCalculator: typeof import('./src/tools/duration-calculator/duration-calculator.vue')['default']
7780
DynamicValues: typeof import('./src/tools/benchmark-builder/dynamic-values.vue')['default']
7881
Editor: typeof import('./src/tools/html-wysiwyg-editor/editor/editor.vue')['default']
7982
EmailNormalizer: typeof import('./src/tools/email-normalizer/email-normalizer.vue')['default']
@@ -83,14 +86,18 @@ declare module '@vue/runtime-core' {
8386
Encryption: typeof import('./src/tools/encryption/encryption.vue')['default']
8487
EtaCalculator: typeof import('./src/tools/eta-calculator/eta-calculator.vue')['default']
8588
FavoriteButton: typeof import('./src/components/FavoriteButton.vue')['default']
89+
FileHasher: typeof import('./src/tools/file-hasher/file-hasher.vue')['default']
8690
FormatTransformer: typeof import('./src/components/FormatTransformer.vue')['default']
8791
GitMemo: typeof import('./src/tools/git-memo/git-memo.vue')['default']
8892
'GitMemo.content': typeof import('./src/tools/git-memo/git-memo.content.md')['default']
8993
HashText: typeof import('./src/tools/hash-text/hash-text.vue')['default']
9094
HmacGenerator: typeof import('./src/tools/hmac-generator/hmac-generator.vue')['default']
9195
'Home.page': typeof import('./src/pages/Home.page.vue')['default']
96+
HtmlCleaner: typeof import('./src/tools/html-cleaner/html-cleaner.vue')['default']
9297
HtmlEntities: typeof import('./src/tools/html-entities/html-entities.vue')['default']
98+
HtmlToMarkdown: typeof import('./src/tools/html-to-markdown/html-to-markdown.vue')['default']
9399
HtmlWysiwygEditor: typeof import('./src/tools/html-wysiwyg-editor/html-wysiwyg-editor.vue')['default']
100+
HtpasswdGenerator: typeof import('./src/tools/htpasswd-generator/htpasswd-generator.vue')['default']
94101
HttpStatusCodes: typeof import('./src/tools/http-status-codes/http-status-codes.vue')['default']
95102
IbanValidatorAndParser: typeof import('./src/tools/iban-validator-and-parser/iban-validator-and-parser.vue')['default']
96103
'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default']
@@ -118,24 +125,35 @@ declare module '@vue/runtime-core' {
118125
IconMdiVideo: typeof import('~icons/mdi/video')['default']
119126
InputCopyable: typeof import('./src/components/InputCopyable.vue')['default']
120127
IntegerBaseConverter: typeof import('./src/tools/integer-base-converter/integer-base-converter.vue')['default']
128+
IpCidrToRange: typeof import('./src/tools/ip-cidr-to-range/ip-cidr-to-range.vue')['default']
129+
IpRangeToCidr: typeof import('./src/tools/ip-range-to-cidr/ip-range-to-cidr.vue')['default']
121130
Ipv4AddressConverter: typeof import('./src/tools/ipv4-address-converter/ipv4-address-converter.vue')['default']
122131
Ipv4RangeExpander: typeof import('./src/tools/ipv4-range-expander/ipv4-range-expander.vue')['default']
123132
Ipv4SubnetCalculator: typeof import('./src/tools/ipv4-subnet-calculator/ipv4-subnet-calculator.vue')['default']
133+
Ipv6SubnetCalculator: typeof import('./src/tools/ipv6-subnet-calculator/ipv6-subnet-calculator.vue')['default']
124134
Ipv6UlaGenerator: typeof import('./src/tools/ipv6-ula-generator/ipv6-ula-generator.vue')['default']
125135
JsonDiff: typeof import('./src/tools/json-diff/json-diff.vue')['default']
136+
JsonEscaper: typeof import('./src/tools/json-escaper/json-escaper.vue')['default']
126137
JsonMinify: typeof import('./src/tools/json-minify/json-minify.vue')['default']
138+
JsonSortMaster: typeof import('./src/tools/json-sort-master/json-sort-master.vue')['default']
127139
JsonToCsv: typeof import('./src/tools/json-to-csv/json-to-csv.vue')['default']
140+
JsonToSchema: typeof import('./src/tools/json-to-schema/json-to-schema.vue')['default']
128141
JsonToToml: typeof import('./src/tools/json-to-toml/json-to-toml.vue')['default']
142+
JsonToTypescript: typeof import('./src/tools/json-to-typescript/json-to-typescript.vue')['default']
129143
JsonToXml: typeof import('./src/tools/json-to-xml/json-to-xml.vue')['default']
130144
JsonToYaml: typeof import('./src/tools/json-to-yaml-converter/json-to-yaml.vue')['default']
131145
JsonViewer: typeof import('./src/tools/json-viewer/json-viewer.vue')['default']
132146
JwtParser: typeof import('./src/tools/jwt-parser/jwt-parser.vue')['default']
133147
KeycodeInfo: typeof import('./src/tools/keycode-info/keycode-info.vue')['default']
148+
ListComparer: typeof import('./src/tools/list-comparer/list-comparer.vue')['default']
134149
ListConverter: typeof import('./src/tools/list-converter/list-converter.vue')['default']
135150
LocaleSelector: typeof import('./src/modules/i18n/components/locale-selector.vue')['default']
136151
LoremIpsumGenerator: typeof import('./src/tools/lorem-ipsum-generator/lorem-ipsum-generator.vue')['default']
152+
LuhnValidator: typeof import('./src/tools/luhn-validator/luhn-validator.vue')['default']
137153
MacAddressGenerator: typeof import('./src/tools/mac-address-generator/mac-address-generator.vue')['default']
138154
MacAddressLookup: typeof import('./src/tools/mac-address-lookup/mac-address-lookup.vue')['default']
155+
ManyUnitsConverter: typeof import('./src/tools/many-units-converter/many-units-converter.vue')['default']
156+
MarkdownTocGenerator: typeof import('./src/tools/markdown-toc-generator/markdown-toc-generator.vue')['default']
139157
MarkdownToHtml: typeof import('./src/tools/markdown-to-html/markdown-to-html.vue')['default']
140158
MathEvaluator: typeof import('./src/tools/math-evaluator/math-evaluator.vue')['default']
141159
MenuBar: typeof import('./src/tools/html-wysiwyg-editor/editor/menu-bar.vue')['default']
@@ -144,9 +162,11 @@ declare module '@vue/runtime-core' {
144162
MenuLayout: typeof import('./src/components/MenuLayout.vue')['default']
145163
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
146164
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
165+
MorseConverter: typeof import('./src/tools/morse-converter/morse-converter.vue')['default']
147166
NAlert: typeof import('naive-ui')['NAlert']
148167
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
149168
NButton: typeof import('naive-ui')['NButton']
169+
NCard: typeof import('naive-ui')['NCard']
150170
NCheckbox: typeof import('naive-ui')['NCheckbox']
151171
NCode: typeof import('naive-ui')['NCode']
152172
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
@@ -165,14 +185,18 @@ declare module '@vue/runtime-core' {
165185
NH3: typeof import('naive-ui')['NH3']
166186
NIcon: typeof import('naive-ui')['NIcon']
167187
NImage: typeof import('naive-ui')['NImage']
188+
NInput: typeof import('naive-ui')['NInput']
168189
NInputGroup: typeof import('naive-ui')['NInputGroup']
169190
NInputGroupLabel: typeof import('naive-ui')['NInputGroupLabel']
170191
NInputNumber: typeof import('naive-ui')['NInputNumber']
192+
NInputNumberI18n: typeof import('./src/ui/n-input-number-i18n/n-input-number-i18n.vue')['default']
171193
NLayout: typeof import('naive-ui')['NLayout']
172194
NLayoutSider: typeof import('naive-ui')['NLayoutSider']
173195
NMenu: typeof import('naive-ui')['NMenu']
196+
NP: typeof import('naive-ui')['NP']
174197
NProgress: typeof import('naive-ui')['NProgress']
175198
NScrollbar: typeof import('naive-ui')['NScrollbar']
199+
NSelect: typeof import('naive-ui')['NSelect']
176200
NSlider: typeof import('naive-ui')['NSlider']
177201
NSpace: typeof import('naive-ui')['NSpace']
178202
NSpin: typeof import('naive-ui')['NSpin']
@@ -182,11 +206,14 @@ declare module '@vue/runtime-core' {
182206
NTag: typeof import('naive-ui')['NTag']
183207
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
184208
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
209+
PassphraseGenerator: typeof import('./src/tools/passphrase-generator/passphrase-generator.vue')['default']
185210
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
186211
PdfSignatureChecker: typeof import('./src/tools/pdf-signature-checker/pdf-signature-checker.vue')['default']
187212
PdfSignatureDetails: typeof import('./src/tools/pdf-signature-checker/components/pdf-signature-details.vue')['default']
188213
PercentageCalculator: typeof import('./src/tools/percentage-calculator/percentage-calculator.vue')['default']
189214
PhoneParserAndFormatter: typeof import('./src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue')['default']
215+
PortNumbers: typeof import('./src/tools/port-numbers/port-numbers.vue')['default']
216+
PunycodeConverter: typeof import('./src/tools/punycode-converter/punycode-converter.vue')['default']
190217
QrCodeGenerator: typeof import('./src/tools/qr-code-generator/qr-code-generator.vue')['default']
191218
RandomPortGenerator: typeof import('./src/tools/random-port-generator/random-port-generator.vue')['default']
192219
RegexMemo: typeof import('./src/tools/regex-memo/regex-memo.vue')['default']
@@ -198,7 +225,10 @@ declare module '@vue/runtime-core' {
198225
RouterView: typeof import('vue-router')['RouterView']
199226
RsaKeyPairGenerator: typeof import('./src/tools/rsa-key-pair-generator/rsa-key-pair-generator.vue')['default']
200227
SafelinkDecoder: typeof import('./src/tools/safelink-decoder/safelink-decoder.vue')['default']
228+
SensitiveDataMasker: typeof import('./src/tools/sensitive-data-masker/sensitive-data-masker.vue')['default']
229+
SlaCalculator: typeof import('./src/tools/sla-calculator/sla-calculator.vue')['default']
201230
SlugifyString: typeof import('./src/tools/slugify-string/slugify-string.vue')['default']
231+
SmartTextReplacer: typeof import('./src/tools/smart-text-replacer/smart-text-replacer.vue')['default']
202232
SpanCopyable: typeof import('./src/components/SpanCopyable.vue')['default']
203233
SqlPrettify: typeof import('./src/tools/sql-prettify/sql-prettify.vue')['default']
204234
StringObfuscator: typeof import('./src/tools/string-obfuscator/string-obfuscator.vue')['default']
@@ -210,13 +240,15 @@ declare module '@vue/runtime-core' {
210240
TextToBinary: typeof import('./src/tools/text-to-binary/text-to-binary.vue')['default']
211241
TextToNatoAlphabet: typeof import('./src/tools/text-to-nato-alphabet/text-to-nato-alphabet.vue')['default']
212242
TextToUnicode: typeof import('./src/tools/text-to-unicode/text-to-unicode.vue')['default']
243+
TimezoneConverter: typeof import('./src/tools/timezone-converter/timezone-converter.vue')['default']
213244
TokenDisplay: typeof import('./src/tools/otp-code-generator-and-validator/token-display.vue')['default']
214245
'TokenGenerator.tool': typeof import('./src/tools/token-generator/token-generator.tool.vue')['default']
215246
TomlToJson: typeof import('./src/tools/toml-to-json/toml-to-json.vue')['default']
216247
TomlToYaml: typeof import('./src/tools/toml-to-yaml/toml-to-yaml.vue')['default']
217248
'Tool.layout': typeof import('./src/layouts/tool.layout.vue')['default']
218249
ToolCard: typeof import('./src/components/ToolCard.vue')['default']
219250
UlidGenerator: typeof import('./src/tools/ulid-generator/ulid-generator.vue')['default']
251+
UrlCleaner: typeof import('./src/tools/url-cleaner/url-cleaner.vue')['default']
220252
UrlEncoder: typeof import('./src/tools/url-encoder/url-encoder.vue')['default']
221253
UrlParser: typeof import('./src/tools/url-parser/url-parser.vue')['default']
222254
UserAgentParser: typeof import('./src/tools/user-agent-parser/user-agent-parser.vue')['default']

0 commit comments

Comments
 (0)