slugen 0.1.1 → 0.1.3
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.
- package/README.md +8 -0
- package/dist/{index.mjs → index.cjs} +6 -3
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +1 -4
- package/dist/index.js.map +1 -1
- package/package.json +29 -28
- package/dist/index.mjs.map +0 -1
- /package/dist/{index.d.mts → index.d.cts} +0 -0
package/README.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# slugen
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/slugen)
|
|
4
|
+
[](https://www.npmjs.com/package/slugen)
|
|
5
|
+
[](https://www.npmjs.com/package/slugen)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
3
11
|
A modern, fast slug generator for JavaScript and TypeScript.
|
|
4
12
|
|
|
5
13
|
Generate URL-friendly slugs, usernames, SEO-friendly links, or safely convert text into clean identifiers.
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
1
3
|
// src/locales.ts
|
|
2
4
|
var locales = {
|
|
3
5
|
de: {
|
|
@@ -165,6 +167,7 @@ function slugen(input, options = {}) {
|
|
|
165
167
|
return text;
|
|
166
168
|
}
|
|
167
169
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
//# sourceMappingURL=index.
|
|
170
|
+
exports.locales = locales;
|
|
171
|
+
exports.slugen = slugen;
|
|
172
|
+
//# sourceMappingURL=index.cjs.map
|
|
173
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/locales.ts","../src/symbols.ts","../src/slugen.ts"],"names":["escapeRegex"],"mappings":"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","file":"index.cjs","sourcesContent":["type LocaleMap = Record<string, string>;\r\n\r\n/**\r\n * Locale definitions\r\n */\r\nexport const locales: Record<string, LocaleMap> = {\r\n de: {\r\n Ä: \"a\",\r\n ä: \"a\",\r\n Ö: \"o\",\r\n ö: \"o\",\r\n Ü: \"u\",\r\n ü: \"u\",\r\n ß: \"ss\",\r\n },\r\n\r\n fr: {\r\n À: \"a\",\r\n Á: \"a\",\r\n Â: \"a\",\r\n Ã: \"a\",\r\n Ä: \"a\",\r\n Å: \"a\",\r\n à: \"a\",\r\n á: \"a\",\r\n â: \"a\",\r\n ã: \"a\",\r\n ä: \"a\",\r\n å: \"a\",\r\n Ç: \"c\",\r\n ç: \"c\",\r\n È: \"e\",\r\n É: \"e\",\r\n Ê: \"e\",\r\n Ë: \"e\",\r\n è: \"e\",\r\n é: \"e\",\r\n ê: \"e\",\r\n ë: \"e\",\r\n Œ: \"oe\",\r\n œ: \"oe\",\r\n },\r\n\r\n es: {\r\n Ñ: \"n\",\r\n ñ: \"n\",\r\n },\r\n\r\n tr: {\r\n İ: \"i\",\r\n I: \"i\",\r\n ı: \"i\",\r\n Ş: \"s\",\r\n ş: \"s\",\r\n Ğ: \"g\",\r\n ğ: \"g\",\r\n Ö: \"o\",\r\n ö: \"o\",\r\n Ü: \"u\",\r\n ü: \"u\",\r\n Ç: \"c\",\r\n ç: \"c\",\r\n },\r\n\r\n pl: {\r\n Ł: \"l\",\r\n ł: \"l\",\r\n Ś: \"s\",\r\n ś: \"s\",\r\n Ż: \"z\",\r\n ż: \"z\",\r\n },\r\n\r\n en: {},\r\n};\r\n\r\n/**\r\n * Cache: localeKey -> { map, regex }\r\n */\r\nconst localeCache = new Map<string, { map: LocaleMap; regex: RegExp }>();\r\n\r\n/**\r\n * Merge multiple locales into a single map\r\n */\r\nfunction mergeLocales(localeKeys: string[]): LocaleMap {\r\n const merged: LocaleMap = {};\r\n\r\n for (const key of localeKeys) {\r\n const locale = locales[key];\r\n if (!locale) continue;\r\n Object.assign(merged, locale);\r\n }\r\n\r\n return merged;\r\n}\r\n\r\n/**\r\n * Apply locale replacements\r\n *\r\n * Supports:\r\n * - 'fr'\r\n * - ['fr', 'de']\r\n */\r\nexport function applyLocale(text: string, locale?: string | string[]): string {\r\n if (!locale) return text;\r\n\r\n const keys = Array.isArray(locale) ? locale : [locale];\r\n const cacheKey = keys.sort().join(\"+\");\r\n\r\n let cached = localeCache.get(cacheKey);\r\n\r\n if (!cached) {\r\n const map = mergeLocales(keys);\r\n\r\n if (Object.keys(map).length === 0) {\r\n localeCache.set(cacheKey, { map, regex: /$^/ });\r\n return text;\r\n }\r\n\r\n const pattern = new RegExp(`[${Object.keys(map).join(\"\")}]`, \"g\");\r\n\r\n cached = { map, regex: pattern };\r\n localeCache.set(cacheKey, cached);\r\n }\r\n\r\n return text.replace(cached.regex, (char) => cached!.map[char] ?? char);\r\n}\r\n","/**\r\n * Common symbols and their slug-friendly replacements\r\n * Policy:\r\n * - semantic symbols => \" word \"\r\n * - separators => \" \"\r\n * - noise => \"\"\r\n */\r\n\r\nexport const symbols: Record<string, string> = {\r\n // Logical / textual (semantic)\r\n \"&\": \" and \",\r\n \"|\": \" or \",\r\n \"@\": \" at \",\r\n \"%\": \" percent \",\r\n \"+\": \" plus \",\r\n \"=\": \" equals \",\r\n\r\n // Currency (semantic)\r\n $: \" dollar \",\r\n \"€\": \" euro \",\r\n \"£\": \" pound \",\r\n \"₺\": \" lira \",\r\n \"¥\": \" yen \",\r\n \"₹\": \" rupee \",\r\n\r\n // Separators\r\n \".\": \" \",\r\n \"/\": \" \",\r\n \"\\\\\": \" \",\r\n _: \" \",\r\n\r\n // Noise (strip)\r\n \"<\": \"\",\r\n \">\": \"\",\r\n \"~\": \"\",\r\n \"^\": \"\",\r\n \"?\": \"\",\r\n \"!\": \"\",\r\n \",\": \"\",\r\n \":\": \"\",\r\n \";\": \"\",\r\n \"'\": \"\",\r\n '\"': \"\",\r\n \"`\": \"\",\r\n \"*\": \"\",\r\n \"#\": \"\",\r\n \"(\": \"\",\r\n \")\": \"\",\r\n \"[\": \"\",\r\n \"]\": \"\",\r\n \"{\": \"\",\r\n \"}\": \"\",\r\n};\r\n\r\n/** Escape regex special chars safely */\r\nconst escapeRegex = (char: string) => char.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n\r\nconst BASE_SYMBOL_REGEX = new RegExp(`[${Object.keys(symbols).map(escapeRegex).join(\"\")}]`, \"g\");\r\n\r\nexport function applySymbols(text: string, custom?: Record<string, string>) {\r\n const map = custom ? { ...symbols, ...custom } : symbols;\r\n const regex = map === symbols ? BASE_SYMBOL_REGEX : new RegExp(`[${Object.keys(map).map(escapeRegex).join(\"\")}]`, \"g\");\r\n\r\n return text.replace(regex, (char) => map[char] ?? \"\");\r\n}\r\n","import { SlugenOptions } from \"./types\";\r\nimport { applyLocale } from \"./locales\";\r\nimport { applySymbols } from \"./symbols\";\r\n\r\nfunction escapeRegex(char: string) {\r\n return char.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n}\r\n\r\nexport function slugen(input: string, options: SlugenOptions = {}): string {\r\n if (!input) return \"\";\r\n\r\n const separator = options.separator ?? \"-\";\r\n const safeSeparator = escapeRegex(separator);\r\n let text = input;\r\n\r\n // Symbols (default true)\r\n if (options.symbols !== false) {\r\n text = applySymbols(text, options.customReplacements);\r\n }\r\n\r\n // Locale\r\n text = applyLocale(text, options.locale);\r\n\r\n // Normalize & remove diacritics\r\n text = text.normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\");\r\n\r\n // Replace non-alphanumeric with separator\r\n text = text.replace(/[^a-zA-Z0-9]+/g, separator);\r\n\r\n // Trim separator (SAFE)\r\n text = text.replace(new RegExp(`^${safeSeparator}+|${safeSeparator}+$`, \"g\"), \"\");\r\n\r\n // Lowercase (default true)\r\n if (options.lowercase !== false) {\r\n text = text.toLowerCase();\r\n }\r\n\r\n return text;\r\n}\r\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
// src/locales.ts
|
|
4
2
|
var locales = {
|
|
5
3
|
de: {
|
|
@@ -167,7 +165,6 @@ function slugen(input, options = {}) {
|
|
|
167
165
|
return text;
|
|
168
166
|
}
|
|
169
167
|
|
|
170
|
-
|
|
171
|
-
exports.slugen = slugen;
|
|
168
|
+
export { locales, slugen };
|
|
172
169
|
//# sourceMappingURL=index.js.map
|
|
173
170
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/locales.ts","../src/symbols.ts","../src/slugen.ts"],"names":["escapeRegex"],"mappings":"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","file":"index.js","sourcesContent":["type LocaleMap = Record<string, string>;\r\n\r\n/**\r\n * Locale definitions\r\n */\r\nexport const locales: Record<string, LocaleMap> = {\r\n de: {\r\n Ä: \"a\",\r\n ä: \"a\",\r\n Ö: \"o\",\r\n ö: \"o\",\r\n Ü: \"u\",\r\n ü: \"u\",\r\n ß: \"ss\",\r\n },\r\n\r\n fr: {\r\n À: \"a\",\r\n Á: \"a\",\r\n Â: \"a\",\r\n Ã: \"a\",\r\n Ä: \"a\",\r\n Å: \"a\",\r\n à: \"a\",\r\n á: \"a\",\r\n â: \"a\",\r\n ã: \"a\",\r\n ä: \"a\",\r\n å: \"a\",\r\n Ç: \"c\",\r\n ç: \"c\",\r\n È: \"e\",\r\n É: \"e\",\r\n Ê: \"e\",\r\n Ë: \"e\",\r\n è: \"e\",\r\n é: \"e\",\r\n ê: \"e\",\r\n ë: \"e\",\r\n Œ: \"oe\",\r\n œ: \"oe\",\r\n },\r\n\r\n es: {\r\n Ñ: \"n\",\r\n ñ: \"n\",\r\n },\r\n\r\n tr: {\r\n İ: \"i\",\r\n I: \"i\",\r\n ı: \"i\",\r\n Ş: \"s\",\r\n ş: \"s\",\r\n Ğ: \"g\",\r\n ğ: \"g\",\r\n Ö: \"o\",\r\n ö: \"o\",\r\n Ü: \"u\",\r\n ü: \"u\",\r\n Ç: \"c\",\r\n ç: \"c\",\r\n },\r\n\r\n pl: {\r\n Ł: \"l\",\r\n ł: \"l\",\r\n Ś: \"s\",\r\n ś: \"s\",\r\n Ż: \"z\",\r\n ż: \"z\",\r\n },\r\n\r\n en: {},\r\n};\r\n\r\n/**\r\n * Cache: localeKey -> { map, regex }\r\n */\r\nconst localeCache = new Map<string, { map: LocaleMap; regex: RegExp }>();\r\n\r\n/**\r\n * Merge multiple locales into a single map\r\n */\r\nfunction mergeLocales(localeKeys: string[]): LocaleMap {\r\n const merged: LocaleMap = {};\r\n\r\n for (const key of localeKeys) {\r\n const locale = locales[key];\r\n if (!locale) continue;\r\n Object.assign(merged, locale);\r\n }\r\n\r\n return merged;\r\n}\r\n\r\n/**\r\n * Apply locale replacements\r\n *\r\n * Supports:\r\n * - 'fr'\r\n * - ['fr', 'de']\r\n */\r\nexport function applyLocale(text: string, locale?: string | string[]): string {\r\n if (!locale) return text;\r\n\r\n const keys = Array.isArray(locale) ? locale : [locale];\r\n const cacheKey = keys.sort().join(\"+\");\r\n\r\n let cached = localeCache.get(cacheKey);\r\n\r\n if (!cached) {\r\n const map = mergeLocales(keys);\r\n\r\n if (Object.keys(map).length === 0) {\r\n localeCache.set(cacheKey, { map, regex: /$^/ });\r\n return text;\r\n }\r\n\r\n const pattern = new RegExp(`[${Object.keys(map).join(\"\")}]`, \"g\");\r\n\r\n cached = { map, regex: pattern };\r\n localeCache.set(cacheKey, cached);\r\n }\r\n\r\n return text.replace(cached.regex, (char) => cached!.map[char] ?? char);\r\n}\r\n","/**\r\n * Common symbols and their slug-friendly replacements\r\n * Policy:\r\n * - semantic symbols => \" word \"\r\n * - separators => \" \"\r\n * - noise => \"\"\r\n */\r\n\r\nexport const symbols: Record<string, string> = {\r\n // Logical / textual (semantic)\r\n \"&\": \" and \",\r\n \"|\": \" or \",\r\n \"@\": \" at \",\r\n \"%\": \" percent \",\r\n \"+\": \" plus \",\r\n \"=\": \" equals \",\r\n\r\n // Currency (semantic)\r\n $: \" dollar \",\r\n \"€\": \" euro \",\r\n \"£\": \" pound \",\r\n \"₺\": \" lira \",\r\n \"¥\": \" yen \",\r\n \"₹\": \" rupee \",\r\n\r\n // Separators\r\n \".\": \" \",\r\n \"/\": \" \",\r\n \"\\\\\": \" \",\r\n _: \" \",\r\n\r\n // Noise (strip)\r\n \"<\": \"\",\r\n \">\": \"\",\r\n \"~\": \"\",\r\n \"^\": \"\",\r\n \"?\": \"\",\r\n \"!\": \"\",\r\n \",\": \"\",\r\n \":\": \"\",\r\n \";\": \"\",\r\n \"'\": \"\",\r\n '\"': \"\",\r\n \"`\": \"\",\r\n \"*\": \"\",\r\n \"#\": \"\",\r\n \"(\": \"\",\r\n \")\": \"\",\r\n \"[\": \"\",\r\n \"]\": \"\",\r\n \"{\": \"\",\r\n \"}\": \"\",\r\n};\r\n\r\n/** Escape regex special chars safely */\r\nconst escapeRegex = (char: string) => char.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n\r\nconst BASE_SYMBOL_REGEX = new RegExp(`[${Object.keys(symbols).map(escapeRegex).join(\"\")}]`, \"g\");\r\n\r\nexport function applySymbols(text: string, custom?: Record<string, string>) {\r\n const map = custom ? { ...symbols, ...custom } : symbols;\r\n const regex = map === symbols ? BASE_SYMBOL_REGEX : new RegExp(`[${Object.keys(map).map(escapeRegex).join(\"\")}]`, \"g\");\r\n\r\n return text.replace(regex, (char) => map[char] ?? \"\");\r\n}\r\n","import { SlugenOptions } from \"./types\";\r\nimport { applyLocale } from \"./locales\";\r\nimport { applySymbols } from \"./symbols\";\r\n\r\nfunction escapeRegex(char: string) {\r\n return char.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n}\r\n\r\nexport function slugen(input: string, options: SlugenOptions = {}): string {\r\n if (!input) return \"\";\r\n\r\n const separator = options.separator ?? \"-\";\r\n const safeSeparator = escapeRegex(separator);\r\n let text = input;\r\n\r\n // Symbols (default true)\r\n if (options.symbols !== false) {\r\n text = applySymbols(text, options.customReplacements);\r\n }\r\n\r\n // Locale\r\n text = applyLocale(text, options.locale);\r\n\r\n // Normalize & remove diacritics\r\n text = text.normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\");\r\n\r\n // Replace non-alphanumeric with separator\r\n text = text.replace(/[^a-zA-Z0-9]+/g, separator);\r\n\r\n // Trim separator (SAFE)\r\n text = text.replace(new RegExp(`^${safeSeparator}+|${safeSeparator}+$`, \"g\"), \"\");\r\n\r\n // Lowercase (default true)\r\n if (options.lowercase !== false) {\r\n text = text.toLowerCase();\r\n }\r\n\r\n return text;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/locales.ts","../src/symbols.ts","../src/slugen.ts"],"names":["escapeRegex"],"mappings":"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","file":"index.js","sourcesContent":["type LocaleMap = Record<string, string>;\r\n\r\n/**\r\n * Locale definitions\r\n */\r\nexport const locales: Record<string, LocaleMap> = {\r\n de: {\r\n Ä: \"a\",\r\n ä: \"a\",\r\n Ö: \"o\",\r\n ö: \"o\",\r\n Ü: \"u\",\r\n ü: \"u\",\r\n ß: \"ss\",\r\n },\r\n\r\n fr: {\r\n À: \"a\",\r\n Á: \"a\",\r\n Â: \"a\",\r\n Ã: \"a\",\r\n Ä: \"a\",\r\n Å: \"a\",\r\n à: \"a\",\r\n á: \"a\",\r\n â: \"a\",\r\n ã: \"a\",\r\n ä: \"a\",\r\n å: \"a\",\r\n Ç: \"c\",\r\n ç: \"c\",\r\n È: \"e\",\r\n É: \"e\",\r\n Ê: \"e\",\r\n Ë: \"e\",\r\n è: \"e\",\r\n é: \"e\",\r\n ê: \"e\",\r\n ë: \"e\",\r\n Œ: \"oe\",\r\n œ: \"oe\",\r\n },\r\n\r\n es: {\r\n Ñ: \"n\",\r\n ñ: \"n\",\r\n },\r\n\r\n tr: {\r\n İ: \"i\",\r\n I: \"i\",\r\n ı: \"i\",\r\n Ş: \"s\",\r\n ş: \"s\",\r\n Ğ: \"g\",\r\n ğ: \"g\",\r\n Ö: \"o\",\r\n ö: \"o\",\r\n Ü: \"u\",\r\n ü: \"u\",\r\n Ç: \"c\",\r\n ç: \"c\",\r\n },\r\n\r\n pl: {\r\n Ł: \"l\",\r\n ł: \"l\",\r\n Ś: \"s\",\r\n ś: \"s\",\r\n Ż: \"z\",\r\n ż: \"z\",\r\n },\r\n\r\n en: {},\r\n};\r\n\r\n/**\r\n * Cache: localeKey -> { map, regex }\r\n */\r\nconst localeCache = new Map<string, { map: LocaleMap; regex: RegExp }>();\r\n\r\n/**\r\n * Merge multiple locales into a single map\r\n */\r\nfunction mergeLocales(localeKeys: string[]): LocaleMap {\r\n const merged: LocaleMap = {};\r\n\r\n for (const key of localeKeys) {\r\n const locale = locales[key];\r\n if (!locale) continue;\r\n Object.assign(merged, locale);\r\n }\r\n\r\n return merged;\r\n}\r\n\r\n/**\r\n * Apply locale replacements\r\n *\r\n * Supports:\r\n * - 'fr'\r\n * - ['fr', 'de']\r\n */\r\nexport function applyLocale(text: string, locale?: string | string[]): string {\r\n if (!locale) return text;\r\n\r\n const keys = Array.isArray(locale) ? locale : [locale];\r\n const cacheKey = keys.sort().join(\"+\");\r\n\r\n let cached = localeCache.get(cacheKey);\r\n\r\n if (!cached) {\r\n const map = mergeLocales(keys);\r\n\r\n if (Object.keys(map).length === 0) {\r\n localeCache.set(cacheKey, { map, regex: /$^/ });\r\n return text;\r\n }\r\n\r\n const pattern = new RegExp(`[${Object.keys(map).join(\"\")}]`, \"g\");\r\n\r\n cached = { map, regex: pattern };\r\n localeCache.set(cacheKey, cached);\r\n }\r\n\r\n return text.replace(cached.regex, (char) => cached!.map[char] ?? char);\r\n}\r\n","/**\r\n * Common symbols and their slug-friendly replacements\r\n * Policy:\r\n * - semantic symbols => \" word \"\r\n * - separators => \" \"\r\n * - noise => \"\"\r\n */\r\n\r\nexport const symbols: Record<string, string> = {\r\n // Logical / textual (semantic)\r\n \"&\": \" and \",\r\n \"|\": \" or \",\r\n \"@\": \" at \",\r\n \"%\": \" percent \",\r\n \"+\": \" plus \",\r\n \"=\": \" equals \",\r\n\r\n // Currency (semantic)\r\n $: \" dollar \",\r\n \"€\": \" euro \",\r\n \"£\": \" pound \",\r\n \"₺\": \" lira \",\r\n \"¥\": \" yen \",\r\n \"₹\": \" rupee \",\r\n\r\n // Separators\r\n \".\": \" \",\r\n \"/\": \" \",\r\n \"\\\\\": \" \",\r\n _: \" \",\r\n\r\n // Noise (strip)\r\n \"<\": \"\",\r\n \">\": \"\",\r\n \"~\": \"\",\r\n \"^\": \"\",\r\n \"?\": \"\",\r\n \"!\": \"\",\r\n \",\": \"\",\r\n \":\": \"\",\r\n \";\": \"\",\r\n \"'\": \"\",\r\n '\"': \"\",\r\n \"`\": \"\",\r\n \"*\": \"\",\r\n \"#\": \"\",\r\n \"(\": \"\",\r\n \")\": \"\",\r\n \"[\": \"\",\r\n \"]\": \"\",\r\n \"{\": \"\",\r\n \"}\": \"\",\r\n};\r\n\r\n/** Escape regex special chars safely */\r\nconst escapeRegex = (char: string) => char.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n\r\nconst BASE_SYMBOL_REGEX = new RegExp(`[${Object.keys(symbols).map(escapeRegex).join(\"\")}]`, \"g\");\r\n\r\nexport function applySymbols(text: string, custom?: Record<string, string>) {\r\n const map = custom ? { ...symbols, ...custom } : symbols;\r\n const regex = map === symbols ? BASE_SYMBOL_REGEX : new RegExp(`[${Object.keys(map).map(escapeRegex).join(\"\")}]`, \"g\");\r\n\r\n return text.replace(regex, (char) => map[char] ?? \"\");\r\n}\r\n","import { SlugenOptions } from \"./types\";\r\nimport { applyLocale } from \"./locales\";\r\nimport { applySymbols } from \"./symbols\";\r\n\r\nfunction escapeRegex(char: string) {\r\n return char.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n}\r\n\r\nexport function slugen(input: string, options: SlugenOptions = {}): string {\r\n if (!input) return \"\";\r\n\r\n const separator = options.separator ?? \"-\";\r\n const safeSeparator = escapeRegex(separator);\r\n let text = input;\r\n\r\n // Symbols (default true)\r\n if (options.symbols !== false) {\r\n text = applySymbols(text, options.customReplacements);\r\n }\r\n\r\n // Locale\r\n text = applyLocale(text, options.locale);\r\n\r\n // Normalize & remove diacritics\r\n text = text.normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\");\r\n\r\n // Replace non-alphanumeric with separator\r\n text = text.replace(/[^a-zA-Z0-9]+/g, separator);\r\n\r\n // Trim separator (SAFE)\r\n text = text.replace(new RegExp(`^${safeSeparator}+|${safeSeparator}+$`, \"g\"), \"\");\r\n\r\n // Lowercase (default true)\r\n if (options.lowercase !== false) {\r\n text = text.toLowerCase();\r\n }\r\n\r\n return text;\r\n}\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slugen",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "Generate URL-friendly slugs, usernames, SEO-friendly links, or safely convert text into clean identifiers",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "tsup",
|
|
8
|
+
"dev": "tsup --watch",
|
|
9
|
+
"typecheck": "tsc --noEmit",
|
|
10
|
+
"test": "vitest tests/slugen.spec.ts --run",
|
|
11
|
+
"bench": "vitest tests/bench.spec.ts --run"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"tsup": "^8.5.1",
|
|
15
|
+
"typescript": "^5.9.3",
|
|
16
|
+
"vitest": "^4.0.16"
|
|
17
|
+
},
|
|
18
18
|
"main": "./dist/index.cjs",
|
|
19
19
|
"module": "./dist/index.js",
|
|
20
20
|
"types": "./dist/index.d.ts",
|
|
@@ -29,23 +29,24 @@
|
|
|
29
29
|
"dist"
|
|
30
30
|
],
|
|
31
31
|
"sideEffects": false,
|
|
32
|
+
"keywords": [
|
|
33
|
+
"slug",
|
|
34
|
+
"slug-generator",
|
|
35
|
+
"url-slug",
|
|
36
|
+
"permalink",
|
|
37
|
+
"seo",
|
|
38
|
+
"url",
|
|
39
|
+
"identifier",
|
|
40
|
+
"string-normalization",
|
|
41
|
+
"multilingual",
|
|
42
|
+
"i18n",
|
|
43
|
+
"typescript"
|
|
44
|
+
],
|
|
32
45
|
"homepage": "https://github.com/kabledev/slugen",
|
|
33
46
|
"repository": {
|
|
34
47
|
"type": "git",
|
|
35
48
|
"url": "git+https://github.com/kabledev/slugen.git"
|
|
36
49
|
},
|
|
37
50
|
"author": "Kable",
|
|
38
|
-
"license": "MIT"
|
|
39
|
-
"scripts": {
|
|
40
|
-
"build": "tsup",
|
|
41
|
-
"dev": "tsup --watch",
|
|
42
|
-
"typecheck": "tsc --noEmit",
|
|
43
|
-
"test": "vitest tests/slugen.spec.ts --run",
|
|
44
|
-
"bench": "vitest tests/bench.spec.ts --run"
|
|
45
|
-
},
|
|
46
|
-
"devDependencies": {
|
|
47
|
-
"tsup": "^8.5.1",
|
|
48
|
-
"typescript": "^5.9.3",
|
|
49
|
-
"vitest": "^4.0.16"
|
|
50
|
-
}
|
|
51
|
+
"license": "MIT"
|
|
51
52
|
}
|
package/dist/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/locales.ts","../src/symbols.ts","../src/slugen.ts"],"names":["escapeRegex"],"mappings":"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","file":"index.mjs","sourcesContent":["type LocaleMap = Record<string, string>;\r\n\r\n/**\r\n * Locale definitions\r\n */\r\nexport const locales: Record<string, LocaleMap> = {\r\n de: {\r\n Ä: \"a\",\r\n ä: \"a\",\r\n Ö: \"o\",\r\n ö: \"o\",\r\n Ü: \"u\",\r\n ü: \"u\",\r\n ß: \"ss\",\r\n },\r\n\r\n fr: {\r\n À: \"a\",\r\n Á: \"a\",\r\n Â: \"a\",\r\n Ã: \"a\",\r\n Ä: \"a\",\r\n Å: \"a\",\r\n à: \"a\",\r\n á: \"a\",\r\n â: \"a\",\r\n ã: \"a\",\r\n ä: \"a\",\r\n å: \"a\",\r\n Ç: \"c\",\r\n ç: \"c\",\r\n È: \"e\",\r\n É: \"e\",\r\n Ê: \"e\",\r\n Ë: \"e\",\r\n è: \"e\",\r\n é: \"e\",\r\n ê: \"e\",\r\n ë: \"e\",\r\n Œ: \"oe\",\r\n œ: \"oe\",\r\n },\r\n\r\n es: {\r\n Ñ: \"n\",\r\n ñ: \"n\",\r\n },\r\n\r\n tr: {\r\n İ: \"i\",\r\n I: \"i\",\r\n ı: \"i\",\r\n Ş: \"s\",\r\n ş: \"s\",\r\n Ğ: \"g\",\r\n ğ: \"g\",\r\n Ö: \"o\",\r\n ö: \"o\",\r\n Ü: \"u\",\r\n ü: \"u\",\r\n Ç: \"c\",\r\n ç: \"c\",\r\n },\r\n\r\n pl: {\r\n Ł: \"l\",\r\n ł: \"l\",\r\n Ś: \"s\",\r\n ś: \"s\",\r\n Ż: \"z\",\r\n ż: \"z\",\r\n },\r\n\r\n en: {},\r\n};\r\n\r\n/**\r\n * Cache: localeKey -> { map, regex }\r\n */\r\nconst localeCache = new Map<string, { map: LocaleMap; regex: RegExp }>();\r\n\r\n/**\r\n * Merge multiple locales into a single map\r\n */\r\nfunction mergeLocales(localeKeys: string[]): LocaleMap {\r\n const merged: LocaleMap = {};\r\n\r\n for (const key of localeKeys) {\r\n const locale = locales[key];\r\n if (!locale) continue;\r\n Object.assign(merged, locale);\r\n }\r\n\r\n return merged;\r\n}\r\n\r\n/**\r\n * Apply locale replacements\r\n *\r\n * Supports:\r\n * - 'fr'\r\n * - ['fr', 'de']\r\n */\r\nexport function applyLocale(text: string, locale?: string | string[]): string {\r\n if (!locale) return text;\r\n\r\n const keys = Array.isArray(locale) ? locale : [locale];\r\n const cacheKey = keys.sort().join(\"+\");\r\n\r\n let cached = localeCache.get(cacheKey);\r\n\r\n if (!cached) {\r\n const map = mergeLocales(keys);\r\n\r\n if (Object.keys(map).length === 0) {\r\n localeCache.set(cacheKey, { map, regex: /$^/ });\r\n return text;\r\n }\r\n\r\n const pattern = new RegExp(`[${Object.keys(map).join(\"\")}]`, \"g\");\r\n\r\n cached = { map, regex: pattern };\r\n localeCache.set(cacheKey, cached);\r\n }\r\n\r\n return text.replace(cached.regex, (char) => cached!.map[char] ?? char);\r\n}\r\n","/**\r\n * Common symbols and their slug-friendly replacements\r\n * Policy:\r\n * - semantic symbols => \" word \"\r\n * - separators => \" \"\r\n * - noise => \"\"\r\n */\r\n\r\nexport const symbols: Record<string, string> = {\r\n // Logical / textual (semantic)\r\n \"&\": \" and \",\r\n \"|\": \" or \",\r\n \"@\": \" at \",\r\n \"%\": \" percent \",\r\n \"+\": \" plus \",\r\n \"=\": \" equals \",\r\n\r\n // Currency (semantic)\r\n $: \" dollar \",\r\n \"€\": \" euro \",\r\n \"£\": \" pound \",\r\n \"₺\": \" lira \",\r\n \"¥\": \" yen \",\r\n \"₹\": \" rupee \",\r\n\r\n // Separators\r\n \".\": \" \",\r\n \"/\": \" \",\r\n \"\\\\\": \" \",\r\n _: \" \",\r\n\r\n // Noise (strip)\r\n \"<\": \"\",\r\n \">\": \"\",\r\n \"~\": \"\",\r\n \"^\": \"\",\r\n \"?\": \"\",\r\n \"!\": \"\",\r\n \",\": \"\",\r\n \":\": \"\",\r\n \";\": \"\",\r\n \"'\": \"\",\r\n '\"': \"\",\r\n \"`\": \"\",\r\n \"*\": \"\",\r\n \"#\": \"\",\r\n \"(\": \"\",\r\n \")\": \"\",\r\n \"[\": \"\",\r\n \"]\": \"\",\r\n \"{\": \"\",\r\n \"}\": \"\",\r\n};\r\n\r\n/** Escape regex special chars safely */\r\nconst escapeRegex = (char: string) => char.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n\r\nconst BASE_SYMBOL_REGEX = new RegExp(`[${Object.keys(symbols).map(escapeRegex).join(\"\")}]`, \"g\");\r\n\r\nexport function applySymbols(text: string, custom?: Record<string, string>) {\r\n const map = custom ? { ...symbols, ...custom } : symbols;\r\n const regex = map === symbols ? BASE_SYMBOL_REGEX : new RegExp(`[${Object.keys(map).map(escapeRegex).join(\"\")}]`, \"g\");\r\n\r\n return text.replace(regex, (char) => map[char] ?? \"\");\r\n}\r\n","import { SlugenOptions } from \"./types\";\r\nimport { applyLocale } from \"./locales\";\r\nimport { applySymbols } from \"./symbols\";\r\n\r\nfunction escapeRegex(char: string) {\r\n return char.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n}\r\n\r\nexport function slugen(input: string, options: SlugenOptions = {}): string {\r\n if (!input) return \"\";\r\n\r\n const separator = options.separator ?? \"-\";\r\n const safeSeparator = escapeRegex(separator);\r\n let text = input;\r\n\r\n // Symbols (default true)\r\n if (options.symbols !== false) {\r\n text = applySymbols(text, options.customReplacements);\r\n }\r\n\r\n // Locale\r\n text = applyLocale(text, options.locale);\r\n\r\n // Normalize & remove diacritics\r\n text = text.normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\");\r\n\r\n // Replace non-alphanumeric with separator\r\n text = text.replace(/[^a-zA-Z0-9]+/g, separator);\r\n\r\n // Trim separator (SAFE)\r\n text = text.replace(new RegExp(`^${safeSeparator}+|${safeSeparator}+$`, \"g\"), \"\");\r\n\r\n // Lowercase (default true)\r\n if (options.lowercase !== false) {\r\n text = text.toLowerCase();\r\n }\r\n\r\n return text;\r\n}\r\n"]}
|
|
File without changes
|