Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
ce1d005
Tailwind: canonical class spellings, with a guard test
fadeltd Oct 29, 2026
5d80a0b
tw:fix: group findings without Map.groupBy
fadeltd Oct 29, 2026
479ff3e
ULID test: pin the clock so the case comparison can't flake
fadeltd Oct 29, 2026
92128a6
Scaffold batch-2 tools: registry, core subpaths, dependencies, stubs
fadeltd Oct 29, 2026
4ba29c5
.env Converter: .env ↔ JSON ↔ shell export (B-17)
fadeltd Oct 29, 2026
d3fa469
QR Code: text, URL and Wi-Fi, as SVG or PNG (B-23)
fadeltd Oct 29, 2026
9bbc5ab
String Escaper: escape and unescape for JSON, JS, SQL, shell, regex a…
fadeltd Oct 29, 2026
df54eb2
Lorem Ipsum: generate words, sentences or paragraphs as text, HTML or…
fadeltd Oct 29, 2026
1430f10
Color Converter: hex, RGB, HSL and OKLCH (B-18)
fadeltd Oct 29, 2026
5b57686
Contrast Checker: WCAG ratio and AA/AAA (B-19)
fadeltd Oct 29, 2026
6b52d29
Cron Explainer: plain English and next runs (B-9)
fadeltd Oct 29, 2026
e3a5614
CSV to Table: RFC 4180 parser and virtualised table (B-16)
fadeltd Oct 29, 2026
d4616da
YAML / JSON / TOML: convert between all three (B-11)
fadeltd Oct 29, 2026
23cff0d
SQL Formatter: dialect-aware formatting (B-25)
fadeltd Oct 29, 2026
2810c65
CSS Formatter: pretty-print and minify with Prettier (B-21)
fadeltd Oct 29, 2026
2699427
YAML / JSON / TOML: report an alias with no anchor instead of throwing
fadeltd Oct 29, 2026
fc157aa
Batch-2 tools: READMEs, changelogs, package metadata and bug form
fadeltd Oct 29, 2026
5a04e1f
Merge remote-tracking branch 'origin/main' into feat/tools-batch-2
fadeltd Oct 29, 2026
7afe589
Merge remote-tracking branch 'origin/main' into feat/tools-batch-2
fadeltd Oct 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ body:
- Text to Binary / Hex
- Number Converter
- Unicode Inspector
- YAML / JSON / TOML
- SQL Formatter
- CSS Formatter
- CSV to Table
- .env Converter
- Cron Explainer
- String Escaper
- Color Converter
- Contrast Checker
- QR Code
- Lorem Ipsum
- The site itself (⌘K palette, sidebar, shortcuts, saved state)
validations:
required: true
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
set -euo pipefail
pnpm pack --pack-destination "$RUNNER_TEMP" >/dev/null
LIST=$(tar -tzf "$RUNNER_TEMP"/fadeltd-devtools-core-*.tgz)
for sub in base64 diff hash html-text id-gen json jwt list number random slug text text-bytes text-stats timestamp unicode url; do
for sub in base64 color cron css csv diff env escape hash html-text id-gen json jwt list lorem number qr random slug sql text text-bytes text-stats timestamp unicode url yaml-toml; do
# A here-string, not `echo | grep -q`: grep -q stops reading at the
# first match, and under pipefail the writer's SIGPIPE fails the step.
grep -qx "package/dist/$sub/index.d.ts" <<< "$LIST" || { echo "::error::Missing dist/$sub/index.d.ts"; exit 1; }
Expand Down
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,18 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and

## [Unreleased]

Nothing yet.
### Added
- YAML / JSON / TOML: convert between all three formats in any direction, with the input format detected for you. Every parse error shows its line and column with a caret; YAML follows the 1.2 rules and points out where a 1.1 reader would differ (`no`, `on`, `0755`); YAML-to-YAML keeps comments; anchors and merge keys are expanded; multi-document YAML converts as an array or one document at a time; integers beyond 2^53 stay exact, and a `null` going to TOML is reported with its key path.
- SQL Formatter: format SQL for PostgreSQL, MySQL, MariaDB, SQLite, BigQuery, Snowflake, SQL Server, Oracle PL/SQL, Redshift, Spark, Trino or standard SQL, with keyword case, indent and blank lines between statements. Comments are kept, a query that won't parse shows where it stopped, and Minify squeezes a query onto one line without touching strings, quoted names or comments.
- CSS Formatter: pretty-print CSS, SCSS or Less with Prettier, choosing indent, line width and quote style, or minify plain CSS. Syntax errors show their line and column, and Minify keeps `/*! licence */` comments, the spaces `calc()` needs, and strings and `url(data:…)` values exactly as written.
- CSV to Table: paste CSV, TSV, semicolon- or pipe-separated data and see it as a table you can scroll both ways, with a sticky header, row numbers and a type hint per column. The delimiter is detected for you (European decimal commas included), quoted fields with commas, quotes and line breaks are read correctly, rows with too few or too many cells are listed by line, and the data converts to JSON, a Markdown table, CSV or TSV. Files of 10 MB stay responsive.
- .env Converter: convert between a .env file, JSON, shell `export` lines and Docker's `--env-file` format. Comments, `export`, quotes, `\n` escapes and multiline values like private keys are read the way `dotenv` reads them, and each value is written with the safest quoting for the format you pick. Duplicate keys, nested JSON and keys a shell can't accept are listed by line number instead of silently dropped. Mask values hides values in the preview while you share your screen (Copy still copies the real ones). Nothing you paste is ever saved.
- Cron Explainer: paste a cron expression and read it in plain English, field by field, with its next 10 run times in any time zone. It handles 5- and 6-field cron, month and weekday names and `@daily`-style macros; errors point at the exact field and character, Quartz-only syntax (`?`, `L`, `#`) is called out by name, day-of-month and day-of-week combine with OR as real cron does, daylight-saving changes are handled the way Vixie cron does, and a date that never comes, like `0 0 30 2 *`, is reported as never firing.
- String Escaper: escape and unescape text for JSON strings, JavaScript strings (any quote style), SQL literals (standard or MySQL), shell arguments, regexes and HTML entities. When unescaping fails it says what is wrong, where, and how to fix it, and it warns about things that would surprise you, such as a backslash MySQL would read as an escape.
- Color Converter: paste any CSS color (hex, `rgb()`, `hsl()`, `oklch()` or one of the 148 color names) or use the picker, and get it as hex, RGB, HSL and OKLCH, each with its own Copy button. Bad input is pointed out by position, and an OKLCH color outside sRGB is flagged and shown alongside the nearest sRGB color with the same lightness and hue.
- Contrast Checker: check two colors against WCAG 2 for AA and AAA, normal and large text, and UI components (3:1), with a live preview. The ratio is never rounded up, so a near miss can't look like a pass; a translucent text color is blended over the background first; and when a check fails you get the nearest passing text color, with Copy and Apply.
- QR Code: make a QR code from text, a URL or a Wi-Fi network and download it as SVG or PNG, with your choice of error correction, quiet zone, size and colors, and a live preview. You're warned about non-web links, low-contrast or inverted colors and codes too dense to scan easily, and content too long for any QR code says how many bytes it is and what the limit is. The Wi-Fi password is never saved.
- Lorem Ipsum: generate an exact number of words, sentences or paragraphs of placeholder text as plain text, HTML `<p>` or Markdown, optionally starting with "Lorem ipsum dolor sit amet…", with Regenerate on ⌘⏎.

## [0.11.0] — 2026-10-29

Expand Down
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# devtools.fadeltd.dev

**Free, open-source developer tools that run entirely in your browser.** A JSON formatter, diff checker, base64 encoder/decoder, JWT decoder, timestamp converter, URL encoder, hash and HMAC calculator, UUID, ID and password generator, Unicode inspector, word counter, HTML-to-text extractor and list sorter — with no backend, no accounts, no ads and no tracking.
**Free, open-source developer tools that run entirely in your browser.** A JSON formatter, diff checker, YAML/TOML converter, SQL and CSS formatter, CSV viewer, base64 encoder/decoder, JWT decoder, timestamp and cron tools, URL encoder, string escaper, hash and HMAC calculator, UUID, ID and password generator, color and contrast checker, QR code generator, Unicode inspector, word counter, HTML-to-text extractor and list sorter — with no backend, no accounts, no ads and no tracking.

[![Live](https://img.shields.io/badge/live-devtools.fadeltd.dev-38bdf8)](https://devtools.fadeltd.dev)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
Expand Down Expand Up @@ -41,6 +41,17 @@ Three other things it does that the free sites generally do not:
| **[Text to Binary / Hex](https://devtools.fadeltd.dev/text-bytes)** | UTF-8 text ↔ binary, hex, decimal or octal; `0x` / `\x` prefixes and C-string output; tolerant paste parsing with exact error positions; format auto-detect; invalid UTF-8 located, with a labelled fallback |
| **[Number Converter](https://devtools.fadeltd.dev/number)** | Bases 2–36 with no precision loss, two's complement, byte sizes in SI vs IEC, chmod octal ↔ symbolic with checkboxes |
| **[Unicode Inspector](https://devtools.fadeltd.dev/unicode)** | Every code point with line:column, UTF-8/UTF-16 and category; flags zero-width, bidi (Trojan Source), exotic spaces, tags, lone surrogates; flagged-only view; one-click clean with optional NFC/NFKC |
| **[YAML / JSON / TOML](https://devtools.fadeltd.dev/yaml-toml)** | Convert between YAML, JSON and TOML in any direction with auto-detection; positioned errors with a caret; YAML 1.1 trap notes (`no`, `on`, `0755`); comments kept YAML → YAML; anchors, merge keys and multi-document YAML; exact big integers |
| **[SQL Formatter](https://devtools.fadeltd.dev/sql)** | Twelve dialects, keyword case, indent and statement spacing; comments kept; parse errors with line and column; minify that leaves strings, quoted identifiers and comments untouched |
| **[CSS Formatter](https://devtools.fadeltd.dev/css)** | Prettier for CSS, SCSS and Less with width, indent and quote options; syntax errors with line and column; a careful CSS minifier that keeps `calc()` spacing, licence comments and data URIs intact |
| **[CSV to Table](https://devtools.fadeltd.dev/csv)** | RFC 4180 parsing with quoted newlines, delimiter detection (comma, tab, semicolon, pipe; European decimal commas handled), virtualised table with sticky header and column type hints, ragged-row and unclosed-quote warnings by line, convert to JSON, Markdown, CSV or TSV |
| **[.env Converter](https://devtools.fadeltd.dev/env)** | .env ↔ JSON ↔ shell `export` ↔ docker `--env-file`; dotenv-accurate parsing (quotes, escapes, multiline, inline comments, CRLF); per-value safe quoting; problems reported by line; flatten nested JSON with `__`; mask values for screen sharing; never saved |
| **[Cron Explainer](https://devtools.fadeltd.dev/cron)** | Cron in plain English with a per-field breakdown; next 10 runs in any time zone with DST handled the way Vixie cron does; 6-field seconds, macros, day-of-month/day-of-week OR, Quartz syntax called out by name |
| **[String Escaper](https://devtools.fadeltd.dev/escape)** | Escape and unescape for JSON, JavaScript (`"` `'` or template), SQL (standard `''` or MySQL backslashes), POSIX shell (`'\''` quoting), regex and HTML entities; positioned unescape errors with the fix |
| **[Color Converter](https://devtools.fadeltd.dev/color)** | Hex, RGB, HSL and OKLCH from any CSS color or a picker; all 148 named colors; out-of-sRGB-gamut warning with a chroma-reduced fallback; alpha; positioned errors |
| **[Contrast Checker](https://devtools.fadeltd.dev/contrast)** | WCAG 2 ratio with AA/AAA for normal and large text and 3:1 for UI; live preview; alpha blended over the background; nearest passing text color by OKLCH lightness, with Apply |
| **[QR Code](https://devtools.fadeltd.dev/qr)** | QR codes for text, URLs and Wi-Fi with a chosen error correction level, downloadable as a single-path SVG or a crisp PNG; scan-risk warnings; the Wi-Fi password is never saved |
| **[Lorem Ipsum](https://devtools.fadeltd.dev/lorem)** | Exact counts of words, sentences or paragraphs, optional classic opening, plain text / HTML `<p>` / Markdown output, one-key Regenerate |

Press `⌘K` anywhere to jump to a tool, `⌘1`–`⌘9` for pinned ones, and `?` for the shortcut list. Your last input is restored when you come back.

Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@
"comlink": "4.4.2",
"idb-keyval": "6.3.0",
"lucide-react": "1.47.0",
"prettier": "3.9.10",
"react": "19.3.0",
"react-dom": "19.3.0",
"react-router": "8.4.0"
"react-router": "8.4.0",
"sql-formatter": "15.9.0"
},
"devDependencies": {
"@tailwindcss/node": "4.3.3",
Expand Down
12 changes: 11 additions & 1 deletion packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,17 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and

## [Unreleased]

Nothing yet.
### Added
- `/yaml-toml`: `convert(input, from, to, options)` between JSON, YAML and TOML with `from: 'auto'`, returning errors, warnings and notes with line, column and a caret snippet; never throws. Also `guessFormat` and `stringifyJson` (JSON with exact bigint digits).
- `/sql`: `formatSql` over twelve dialects via `sql-formatter`, with errors as line and column, and a dialect-aware `minifySql` that never touches strings, quoted identifiers or comments. `sql-formatter` is an optional peer dependency, loaded on first use.
- `/css`: `formatCss` for CSS, SCSS and Less via Prettier standalone, with errors as line and column, and a hand-written plain-CSS `minifyCss`. `prettier` is an optional peer dependency, loaded on first use.
- `/csv`: an RFC 4180 parser in linear time that never throws, with positioned issues (unclosed quotes, ragged rows, repeated headers), delimiter sniffing, column type hints, and JSON / Markdown / CSV / TSV writers.
- `/env`: .env ↔ JSON ↔ shell export ↔ docker env-file conversion with dotenv-accurate parsing, per-value safe quoting, positioned issues and JSON flattening.
- `/cron`: 5- and 6-field cron and `@` macros with field-and-position errors, Vixie day-of-month/day-of-week OR, `nextRuns` in any IANA zone with Vixie DST handling and never-fires detection, and `describeCron` (English, via `cronstrue`).
- `/escape`: JSON, JavaScript, SQL (standard/MySQL), POSIX shell, regex and HTML-entity escaping and strict unescaping, with positioned errors.
- `/color`: CSS color parsing (hex, rgb, hsl, oklch, named) with positioned errors; sRGB ↔ HSL ↔ OKLCH via OKLab; gamut detection and chroma clipping; WCAG contrast ratio, verdicts and the nearest passing foreground.
- `/qr`: QR payload builders for text, URLs and Wi-Fi, encoding to a module matrix (via `uqr`), and a single-path SVG.
- `/lorem`: lorem ipsum by exact word, sentence or paragraph count, as text, HTML or Markdown, seedable through any `RandomSource`.

## [0.4.0] — 2026-10-29

Expand Down
38 changes: 37 additions & 1 deletion packages/core/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# @fadeltd/devtools-core

The engines behind [devtools.fadeltd.dev](https://devtools.fadeltd.dev): list pipelines, JSON errors and fixes, diff, base64, prefixed IDs and UUIDs, timestamps, JWT decoding, URL encoding, hashes and HMAC, slugs, text bytes, number bases, Unicode inspection, text statistics and HTML to text.
The engines behind [devtools.fadeltd.dev](https://devtools.fadeltd.dev): list pipelines, JSON errors and fixes, diff, base64, prefixed IDs and UUIDs, timestamps, JWT decoding, URL encoding, hashes and HMAC, slugs, text bytes, number bases, Unicode inspection, YAML/JSON/TOML conversion, SQL and CSS formatting, CSV parsing, .env conversion, cron, string escaping, colors and contrast, QR codes, lorem ipsum, text statistics and HTML to text.

Every export is a pure function: strings and bytes in, data out. No DOM, no network, no storage. It runs the same in Node, in a browser and in a worker, which is how the site itself uses it. Each tool also handles the edge cases that free online tools get wrong:

Expand All @@ -18,6 +18,8 @@ pnpm add @fadeltd/devtools-core

ESM only. Requires Node 22.12+ or a current browser.

`/sql` and `/css` use `sql-formatter` and `prettier`, which are optional peer dependencies so the other subpaths don't install them. Add the one you need: `pnpm add sql-formatter` or `pnpm add prettier`.

## Use

Import from the subpath for the tool you need. Each subpath is independent, so you only pay for what you import.
Expand Down Expand Up @@ -87,6 +89,30 @@ summary('{"key\u200b": 1}').positions[0] // { line: 1, column: 6, hex: 'U+200B',
clean('a\u00a0b\u200bc').text // 'a bc'
```

```js
import { convert } from '@fadeltd/devtools-core/yaml-toml'

convert('country: no\n', 'auto', 'json').notes[0] // { code: 'yaml11-bool', … } — "no" stays a string under YAML 1.2
convert('{"a": null}', 'json', 'toml').errors[0] // { code: 'toml-null', path: '.a', line: 1, column: 2, … }
```

```js
import { describeCron, nextRuns, parseCron } from '@fadeltd/devtools-core/cron'

const r = parseCron('30 2 * * *')
if (r.ok && r.value.kind === 'schedule') {
describeCron(r.value, { use24HourTimeFormat: true }) // { ok: true, text: 'At 02:30' }
nextRuns(r.value, { now: Date.now(), timeZone: 'America/New_York', count: 3 }).runs
}
```

```js
import { formatSql } from '@fadeltd/devtools-core/sql'

await formatSql('select a from t where b = 1', { dialect: 'postgresql', keywordCase: 'upper' })
// { ok: true, output: 'SELECT\n a\nFROM\n t\nWHERE\n b = 1' }
```

| Subpath | What it does |
|---|---|
| `/list` | Sort, natural sort, dedupe, shuffle, case, prefix/suffix, filter, number, wrap, join, split, trim, normalise, set operations, slice; chained with per-step line counts |
Expand All @@ -104,6 +130,16 @@ clean('a\u00a0b\u200bc').text // 'a bc'
| `/text-bytes` | UTF-8 text ↔ binary, hex, decimal or octal, with format auto-detection and invalid-UTF-8 offsets |
| `/number` | BigInt base conversion 2–36 with two's complement, SI/IEC byte sizes, Unix permissions and chmod commands |
| `/unicode` | Per-code-point inspection, invisible/bidi/tag/space flags with names, and an emoji-safe `clean()` |
| `/yaml-toml` | JSON ↔ YAML ↔ TOML with auto-detection, positioned errors, YAML 1.2 with 1.1-gotcha notes, multi-document streams, exact big integers and TOML dates |
| `/sql` | SQL formatting in twelve dialects via `sql-formatter` (optional peer, loaded on first use), errors with line and column, and a dialect-aware minifier |
| `/css` | CSS/SCSS/Less formatting via Prettier standalone (optional peer, loaded on first use), errors with line and column, and a plain-CSS minifier |
| `/csv` | RFC 4180 parsing in linear time with positioned issues, delimiter sniffing, column type hints, and JSON / Markdown / CSV / TSV output |
| `/env` | .env ↔ JSON ↔ shell export ↔ docker env-file: dotenv-accurate parsing, safe quoting, positioned errors, JSON flattening |
| `/cron` | 5- and 6-field cron and `@` macros, Vixie day OR semantics, next runs in any IANA zone with Vixie DST handling, never-fires detection, English via `cronstrue` |
| `/escape` | JSON, JavaScript, SQL (standard/MySQL), POSIX shell, regex and HTML-entity escaping and strict unescaping, with positioned errors |
| `/color` | CSS color parsing with positioned errors; sRGB ↔ HSL ↔ OKLCH; gamut detection and clipping; WCAG contrast and nearest passing foreground |
| `/qr` | QR payloads for text, URLs and Wi-Fi, encoded to a module matrix, plus a single-path SVG |
| `/lorem` | Lorem ipsum by exact word, sentence or paragraph count, as text, HTML or Markdown, seedable |
| `/text` | Line/column offsets and character counts shared by the tools |
| `/random` | Unbiased crypto random source and a seeded PRNG |

Expand Down
Loading
Loading