Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@scalar/helpers

Package Overview
Dependencies
Maintainers
8
Versions
47
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@scalar/helpers - npm Package Compare versions

Comparing version
0.5.4
to
0.5.5
+19
dist/string/slugger.d.ts
import { type SlugifyOptions } from './slugify.js';
/**
* Creates a stateful slug generator that tracks previously seen slugs and
* appends an incrementing numeric suffix to avoid collisions, mirroring the
* behaviour of `github-slugger`.
*
* @example
* const { slug, reset } = createSlugger()
* slug('Hello World') // 'hello-world'
* slug('Hello World') // 'hello-world-1'
* slug('Hello World') // 'hello-world-2'
* reset() // Clears the seen slugs
* slug('Hello World') // 'hello-world'
*/
export declare const slugger: (options?: SlugifyOptions) => {
slug(v: string): string;
reset(): void;
};
//# sourceMappingURL=slugger.d.ts.map
{"version":3,"file":"slugger.d.ts","sourceRoot":"","sources":["../../src/string/slugger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAW,MAAM,WAAW,CAAA;AAExD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,OAAO,GAAI,UAAS,cAAmB;YAIxC,MAAM,GAAG,MAAM;;CAkB1B,CAAA"}
import { slugify } from './slugify.js';
/**
* Creates a stateful slug generator that tracks previously seen slugs and
* appends an incrementing numeric suffix to avoid collisions, mirroring the
* behaviour of `github-slugger`.
*
* @example
* const { slug, reset } = createSlugger()
* slug('Hello World') // 'hello-world'
* slug('Hello World') // 'hello-world-1'
* slug('Hello World') // 'hello-world-2'
* reset() // Clears the seen slugs
* slug('Hello World') // 'hello-world'
*/
export const slugger = (options = {}) => {
const seen = new Map();
return {
slug(v) {
const base = slugify(v, options);
const count = seen.get(base);
if (count === undefined) {
seen.set(base, 0);
return base;
}
const next = count + 1;
seen.set(base, next);
return `${base}-${next}`;
},
reset() {
seen.clear();
},
};
};
export type SlugifyOptions = {
/**
* A string of extra characters to allow through the non-word filter.
* Each character in the string is treated literally.
* @example '.' // keeps dots: "v1.2.3" → "v1.2.3"
* @example '.@' // keeps dots and at-signs
*/
allowedSpecialChars?: string;
/**
* When `true`, the result is preserved as-is (i.e. case is preserved). By default we lowercase the string.
* @default false
* @example slugify('MyAPI', { preserveCase: true }) // 'MyAPI'
*/
preserveCase?: boolean;
};
/**
* Normalizes and slugifies a string.
*
* By default the result is lowercased, limited to 255 characters, and stripped
* of everything that is not a Unicode letter, mark, number, hyphen, or space
* (spaces and hyphens are then collapsed into a single hyphen).
*
* Pass {@link SlugifyOptions} to adjust this behaviour.
*
* | Option | Type | Default | Description |
* |----------------------|------------|---------|----------------------------------------------------------------------------------------------|
* | `allowedSpecialChars`| `string` | `""` | Extra characters that should survive the non-word filter (e.g. `"."` keeps dots so `"v1.2"` → `"v1.2"` instead of `"v12"`). |
* | `preserveCase` | `boolean` | `false` | When `true`, the case is preserved. By default we lowercase the string |
*/
export declare const slugify: (v: string, options?: SlugifyOptions) => string;
//# sourceMappingURL=slugify.d.ts.map
{"version":3,"file":"slugify.d.ts","sourceRoot":"","sources":["../../src/string/slugify.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,cAAc,GAAG;IAC3B;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,OAAO,GAAI,GAAG,MAAM,EAAE,UAAS,cAAmB,WA2B9D,CAAA"}
const RE_NON_WORD = /[^\p{L}\p{M}\p{N}\s_-]/gu;
const RE_SPACES = /[\s_-]+/g;
const RE_TRIM_HYPHENS = /^-+|-+$/g;
/** Cache of compiled non-word regexes keyed by their `allowedSpecialChars` string. */
const reNonWordCache = new Map();
/**
* Normalizes and slugifies a string.
*
* By default the result is lowercased, limited to 255 characters, and stripped
* of everything that is not a Unicode letter, mark, number, hyphen, or space
* (spaces and hyphens are then collapsed into a single hyphen).
*
* Pass {@link SlugifyOptions} to adjust this behaviour.
*
* | Option | Type | Default | Description |
* |----------------------|------------|---------|----------------------------------------------------------------------------------------------|
* | `allowedSpecialChars`| `string` | `""` | Extra characters that should survive the non-word filter (e.g. `"."` keeps dots so `"v1.2"` → `"v1.2"` instead of `"v12"`). |
* | `preserveCase` | `boolean` | `false` | When `true`, the case is preserved. By default we lowercase the string |
*/
export const slugify = (v, options = {}) => {
const { allowedSpecialChars = '', preserveCase = false } = options;
// Compile the non-word regex once and cache it for future use.
const reNonWord = (() => {
if (allowedSpecialChars.length === 0) {
return RE_NON_WORD;
}
const cached = reNonWordCache.get(allowedSpecialChars);
if (cached) {
return cached;
}
// Escape user-provided characters so they are treated literally inside the character class.
const escaped = allowedSpecialChars.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
const reNonWordWithAllowedSpecialChars = new RegExp(`[^\\p{L}\\p{M}\\p{N}\\s_\\-${escaped}]`, 'gu');
reNonWordCache.set(allowedSpecialChars, reNonWordWithAllowedSpecialChars);
return reNonWordWithAllowedSpecialChars;
})();
// Normalize before filtering so equivalent Unicode forms produce the same slug.
const normalized = v.slice(0, 255).trim().normalize('NFC');
const result = preserveCase ? normalized : normalized.toLowerCase();
return result.replace(reNonWord, '').replace(RE_SPACES, '-').replace(RE_TRIM_HYPHENS, '');
};
+6
-0
# @scalar/helpers
## 0.5.5
### Patch Changes
- [#9023](https://github.com/scalar/scalar/pull/9023): chore: use homemade slugger
## 0.5.4

@@ -4,0 +10,0 @@

+2
-1

@@ -17,3 +17,3 @@ {

],
"version": "0.5.4",
"version": "0.5.5",
"engines": {

@@ -130,4 +130,5 @@ "node": ">=22"

"test": "vitest --run",
"test:watch": "vitest",
"types:check": "tsc --noEmit"
}
}