slugen 0.1.2 → 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 CHANGED
@@ -1,8 +1,11 @@
1
1
  # slugen
2
2
 
3
- ![NPM Downloads](https://img.shields.io/npm/v/slugen)
4
- ![NPM Last Update](https://img.shields.io/npm/last-update/slugen)
5
- ![NPM Downloads](https://img.shields.io/npm/dw/slugen)
3
+ [![NPM Downloads](https://img.shields.io/npm/v/slugen)](https://www.npmjs.com/package/slugen)
4
+ [![NPM Last Update](https://img.shields.io/npm/last-update/slugen)](https://www.npmjs.com/package/slugen)
5
+ [![NPM Downloads](https://img.shields.io/npm/dw/slugen)](https://www.npmjs.com/package/slugen)
6
+
7
+
8
+
6
9
 
7
10
 
8
11
  A modern, fast slug generator for JavaScript and TypeScript.
@@ -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
- export { locales, slugen };
169
- //# sourceMappingURL=index.mjs.map
170
- //# sourceMappingURL=index.mjs.map
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
- exports.locales = locales;
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":";;;AAKO,IAAM,OAAA,GAAqC;AAAA,EAChD,EAAA,EAAI;AAAA,IACF,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG;AAAA,GACL;AAAA,EAEA,EAAA,EAAI;AAAA,IACF,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,IAAA;AAAA,IACH,MAAA,EAAG;AAAA,GACL;AAAA,EAEA,EAAA,EAAI;AAAA,IACF,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG;AAAA,GACL;AAAA,EAEA,EAAA,EAAI;AAAA,IACF,MAAA,EAAG,GAAA;AAAA,IACH,CAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG;AAAA,GACL;AAAA,EAEA,EAAA,EAAI;AAAA,IACF,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG,GAAA;AAAA,IACH,MAAA,EAAG;AAAA,GACL;AAAA,EAEA,IAAI;AACN;AAKA,IAAM,WAAA,uBAAkB,GAAA,EAA+C;AAKvE,SAAS,aAAa,UAAA,EAAiC;AACrD,EAAA,MAAM,SAAoB,EAAC;AAE3B,EAAA,KAAA,MAAW,OAAO,UAAA,EAAY;AAC5B,IAAA,MAAM,MAAA,GAAS,QAAQ,GAAG,CAAA;AAC1B,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,MAAA,CAAO,MAAA,CAAO,QAAQ,MAAM,CAAA;AAAA,EAC9B;AAEA,EAAA,OAAO,MAAA;AACT;AASO,SAAS,WAAA,CAAY,MAAc,MAAA,EAAoC;AAC5E,EAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AAEpB,EAAA,MAAM,OAAO,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,GAAI,MAAA,GAAS,CAAC,MAAM,CAAA;AACrD,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,IAAA,EAAK,CAAE,KAAK,GAAG,CAAA;AAErC,EAAA,IAAI,MAAA,GAAS,WAAA,CAAY,GAAA,CAAI,QAAQ,CAAA;AAErC,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,GAAA,GAAM,aAAa,IAAI,CAAA;AAE7B,IAAA,IAAI,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,CAAE,WAAW,CAAA,EAAG;AACjC,MAAA,WAAA,CAAY,IAAI,QAAA,EAAU,EAAE,GAAA,EAAK,KAAA,EAAO,MAAM,CAAA;AAC9C,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,OAAA,GAAU,IAAI,MAAA,CAAO,CAAA,CAAA,EAAI,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,CAAC,CAAA,CAAA,CAAA,EAAK,GAAG,CAAA;AAEhE,IAAA,MAAA,GAAS,EAAE,GAAA,EAAK,KAAA,EAAO,OAAA,EAAQ;AAC/B,IAAA,WAAA,CAAY,GAAA,CAAI,UAAU,MAAM,CAAA;AAAA,EAClC;AAEA,EAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,KAAA,EAAO,CAAC,SAAS,MAAA,CAAQ,GAAA,CAAI,IAAI,CAAA,IAAK,IAAI,CAAA;AACvE;;;ACtHO,IAAM,OAAA,GAAkC;AAAA;AAAA,EAE7C,GAAA,EAAK,OAAA;AAAA,EACL,GAAA,EAAK,MAAA;AAAA,EACL,GAAA,EAAK,MAAA;AAAA,EACL,GAAA,EAAK,WAAA;AAAA,EACL,GAAA,EAAK,QAAA;AAAA,EACL,GAAA,EAAK,UAAA;AAAA;AAAA,EAGL,CAAA,EAAG,UAAA;AAAA,EACH,QAAA,EAAK,QAAA;AAAA,EACL,MAAA,EAAK,SAAA;AAAA,EACL,QAAA,EAAK,QAAA;AAAA,EACL,MAAA,EAAK,OAAA;AAAA,EACL,QAAA,EAAK,SAAA;AAAA;AAAA,EAGL,GAAA,EAAK,GAAA;AAAA,EACL,GAAA,EAAK,GAAA;AAAA,EACL,IAAA,EAAM,GAAA;AAAA,EACN,CAAA,EAAG,GAAA;AAAA;AAAA,EAGH,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK,EAAA;AAAA,EACL,GAAA,EAAK;AACP,CAAA;AAGA,IAAM,cAAc,CAAC,IAAA,KAAiB,IAAA,CAAK,OAAA,CAAQ,uBAAuB,MAAM,CAAA;AAEhF,IAAM,iBAAA,GAAoB,IAAI,MAAA,CAAO,CAAA,CAAA,EAAI,OAAO,IAAA,CAAK,OAAO,CAAA,CAAE,GAAA,CAAI,WAAW,CAAA,CAAE,IAAA,CAAK,EAAE,CAAC,KAAK,GAAG,CAAA;AAExF,SAAS,YAAA,CAAa,MAAc,MAAA,EAAiC;AAC1E,EAAA,MAAM,MAAM,MAAA,GAAS,EAAE,GAAG,OAAA,EAAS,GAAG,QAAO,GAAI,OAAA;AACjD,EAAA,MAAM,QAAQ,GAAA,KAAQ,OAAA,GAAU,oBAAoB,IAAI,MAAA,CAAO,IAAI,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,CAAE,IAAI,WAAW,CAAA,CAAE,KAAK,EAAE,CAAC,KAAK,GAAG,CAAA;AAErH,EAAA,OAAO,IAAA,CAAK,QAAQ,KAAA,EAAO,CAAC,SAAS,GAAA,CAAI,IAAI,KAAK,EAAE,CAAA;AACtD;;;AC5DA,SAASA,aAAY,IAAA,EAAc;AACjC,EAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,qBAAA,EAAuB,MAAM,CAAA;AACnD;AAEO,SAAS,MAAA,CAAO,KAAA,EAAe,OAAA,GAAyB,EAAC,EAAW;AACzE,EAAA,IAAI,CAAC,OAAO,OAAO,EAAA;AAEnB,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,GAAA;AACvC,EAAA,MAAM,aAAA,GAAgBA,aAAY,SAAS,CAAA;AAC3C,EAAA,IAAI,IAAA,GAAO,KAAA;AAGX,EAAA,IAAI,OAAA,CAAQ,YAAY,KAAA,EAAO;AAC7B,IAAA,IAAA,GAAO,YAAA,CAAa,IAAA,EAAM,OAAA,CAAQ,kBAAkB,CAAA;AAAA,EACtD;AAGA,EAAA,IAAA,GAAO,WAAA,CAAY,IAAA,EAAM,OAAA,CAAQ,MAAM,CAAA;AAGvC,EAAA,IAAA,GAAO,KAAK,SAAA,CAAU,KAAK,CAAA,CAAE,OAAA,CAAQ,oBAAoB,EAAE,CAAA;AAG3D,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,gBAAA,EAAkB,SAAS,CAAA;AAG/C,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,IAAI,MAAA,CAAO,CAAA,CAAA,EAAI,aAAa,CAAA,EAAA,EAAK,aAAa,CAAA,EAAA,CAAA,EAAM,GAAG,CAAA,EAAG,EAAE,CAAA;AAGhF,EAAA,IAAI,OAAA,CAAQ,cAAc,KAAA,EAAO;AAC/B,IAAA,IAAA,GAAO,KAAK,WAAA,EAAY;AAAA,EAC1B;AAEA,EAAA,OAAO,IAAA;AACT","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,7 +1,8 @@
1
1
  {
2
2
  "name": "slugen",
3
- "version": "0.1.2",
4
- "description": "Modern and lightweight slug generator for URLs, permalinks, and identifiers with multi-language support",
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",
5
6
  "scripts": {
6
7
  "build": "tsup",
7
8
  "dev": "tsup --watch",
@@ -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