@verifyhash/slugify-lite 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +112 -0
  3. package/index.js +0 -0
  4. package/package.json +36 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 <OWNER-NAME PLACEHOLDER>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # slugify-lite
2
+
3
+ A tiny, **zero-dependency, zero-network** Node.js library that turns an arbitrary
4
+ string into a clean URL slug: `"Héllo, World!"` → `"hello-world"`. One CommonJS
5
+ file (`index.js`), no install step, no I/O, no runtime `require` of anything —
6
+ drop it into any project and `require` it.
7
+
8
+ ## Who it's for
9
+
10
+ JavaScript/Node developers who need slugs for URLs, filenames, anchor IDs, or
11
+ database keys and want a **small, auditable, single-file** helper instead of
12
+ pulling in a larger dependency graph. It covers the everyday Western-European
13
+ case (accented Latin letters like `é`, `ü`, `ñ`, `ß`, `ø`, `æ`) with a pinned,
14
+ in-repo character map — no lookup tables downloaded at runtime, no transitive
15
+ packages. If you already reach for [`slugify`](https://www.npmjs.com/package/slugify)
16
+ or [`@sindresorhus/slugify`](https://www.npmjs.com/package/@sindresorhus/slugify)
17
+ but want zero deps and full control over the map, this is that.
18
+
19
+ ## Install / use
20
+
21
+ No install — copy `index.js`, or `require` it directly:
22
+
23
+ ```js
24
+ const slugify = require('./index.js');
25
+
26
+ slugify('Héllo, World!'); // 'hello-world'
27
+ slugify('Crème brûlée'); // 'creme-brulee'
28
+ slugify('Straße'); // 'strasse' (ß -> ss)
29
+
30
+ // custom separator
31
+ slugify('Hello World', { separator: '_' }); // 'hello_world'
32
+
33
+ // preserve case
34
+ slugify('CamelCase API', { lowercase: false }); // 'CamelCase-API'
35
+
36
+ // truncate to a max length on a WORD boundary (never mid-word)
37
+ slugify('The quick brown fox', { maxLength: 15 }); // 'the-quick-brown'
38
+ slugify('The quick brown fox', { maxLength: 13 }); // 'the-quick'
39
+
40
+ // custom replacements, merged OVER the built-in map (raw-char match)
41
+ slugify('100% cotton & wool', {
42
+ replacements: { '%': ' percent ', '&': ' and ' }
43
+ }); // '100-percent-cotton-and-wool'
44
+ ```
45
+
46
+ ## API
47
+
48
+ ### `slugify(input, options?) → string`
49
+
50
+ `input` is coerced with `String()`; `null`/`undefined` return `''`.
51
+
52
+ | option | type | default | meaning |
53
+ | -------------- | --------- | ------- | ----------------------------------------------------------------------------------------- |
54
+ | `separator` | `string` | `'-'` | Character(s) used to join words. May be multi-character or `''`; matched literally. |
55
+ | `lowercase` | `boolean` | `true` | Lowercase the result. Set `false` to preserve case (transliteration still happens). |
56
+ | `maxLength` | `number` | — | Max output length. Truncated on a **word boundary** — never mid-word, never a trailing separator. |
57
+ | `replacements` | `object` | — | Single-char → string map, merged **over** the built-in map. Matched against the raw character (before lowercasing). |
58
+
59
+ Pipeline, in order: (1) transliterate each character (custom `replacements`
60
+ win over the built-in map, then the built-in map, else the char passes through);
61
+ (2) lowercase unless `lowercase: false`; (3) collapse every run of non-ASCII-
62
+ alphanumeric characters (`[^A-Za-z0-9]+`) to a single separator, which strips
63
+ punctuation, whitespace, and any unmapped characters; (4) trim leading/trailing
64
+ separators; (5) if `maxLength` is set, keep whole words while the running slug
65
+ (words joined by `separator`) stays `<= maxLength`.
66
+
67
+ The module also exposes `slugify.slugify`, `slugify.default` (both the same
68
+ function), and `slugify.charMap` — a **frozen** copy of the built-in map for
69
+ inspection.
70
+
71
+ ## Limits (please read — this is the honest part)
72
+
73
+ - **It only romanizes what the built-in map covers.** The map is a small,
74
+ hand-maintained table of common accented/Latin-1 and a few Latin-Extended
75
+ characters (roughly `à á â ã ä å ā ă ą æ ç ć č ð è é ê ë ē ę ě ñ ń ň ø ō œ ß
76
+ þ ù ú û ü ū ů ý ÿ ž …` plus their uppercase forms). It is **not**
77
+ Unicode-complete and does **not** do context-aware romanization.
78
+ - **Non-Latin scripts are stripped, not transliterated.** Cyrillic (`Москва`),
79
+ Greek, Arabic, Hebrew, Hangul, and CJK (`日本語`) are **not** in the map, so
80
+ step 3 removes them. `slugify('日本語 test')` → `'test'`, and
81
+ `slugify('日本語')` → `''`. If you need Chinese→pinyin, Cyrillic→Latin, or
82
+ Greek→Latin romanization, use a dedicated transliteration library — that is
83
+ deliberately out of scope here.
84
+ - **Emoji and symbols are dropped** unless you supply a `replacements` entry
85
+ for them (e.g. `{ '&': ' and ' }`).
86
+ - **`maxLength` never splits a word.** If the very first word is longer than
87
+ `maxLength`, the result is `''` (there is no whole word that fits). It counts
88
+ the separator length between words, but does not hyphenate or ellipsize.
89
+ - **Custom `replacements` match the raw character**, before lowercasing — so to
90
+ override `ø` supply the lowercase key `'ø'`; an uppercase `'Ø'` in the input
91
+ is handled by the built-in uppercase map entry unless you add `'Ø'` yourself.
92
+ - **No collision avoidance / uniqueness.** Two different inputs can slug to the
93
+ same string (`'Café!'` and `'café'` both → `'cafe'`). If you need unique
94
+ slugs, dedupe at the call site.
95
+
96
+ ## Running the tests
97
+
98
+ One command, Node's built-in `assert` only — no test runner, no dependencies:
99
+
100
+ ```sh
101
+ node test/index.test.js
102
+ ```
103
+
104
+ It prints `slugify-lite: all N tests passed.` and exits `0` on success. The
105
+ suite covers accented→ASCII transliteration (including `ß→ss`, `æ→ae`),
106
+ punctuation/whitespace collapsing, custom separators, non-Latin/CJK/emoji
107
+ passthrough behavior, `maxLength` word-boundary truncation, custom replacement
108
+ overrides, empty/whitespace-only input, and leading/trailing separator trimming.
109
+
110
+ ## License
111
+
112
+ MIT — see `LICENSE`.
package/index.js ADDED
Binary file
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@verifyhash/slugify-lite",
3
+ "version": "0.1.0",
4
+ "description": "Zero-dependency, zero-network string-to-URL-slug library for Node.js: Latin-1/accent transliteration via a pinned in-repo map, custom separator, word-boundary maxLength truncation, and custom replacement overrides.",
5
+ "keywords": [
6
+ "slug",
7
+ "slugify",
8
+ "url",
9
+ "transliterate",
10
+ "ascii",
11
+ "seo",
12
+ "zero-dependency"
13
+ ],
14
+ "main": "index.js",
15
+ "scripts": {
16
+ "test": "node test/index.test.js"
17
+ },
18
+ "license": "MIT",
19
+ "files": [
20
+ "index.js",
21
+ "README.md",
22
+ "LICENSE"
23
+ ],
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/verifyhash/libs.git",
30
+ "directory": "slugify-lite"
31
+ },
32
+ "homepage": "https://github.com/verifyhash/libs/tree/main/slugify-lite#readme",
33
+ "bugs": {
34
+ "url": "https://github.com/verifyhash/libs/issues"
35
+ }
36
+ }