Skip to content

Commit 8817d9c

Browse files
woonmayerRomanHotsiy
authored andcommitted
fix: use original tag name when slugified one is not valid (#553)
* use original tag name when slugified one is not valid * use wrapper function when using slugify
1 parent 76906eb commit 8817d9c

File tree

4 files changed

+33
-6
lines changed

4 files changed

+33
-6
lines changed

src/services/MarkdownRenderer.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import * as marked from 'marked';
2-
import slugify from 'slugify';
32

4-
import { highlight, html2Str } from '../utils';
3+
import { highlight, html2Str, safeSlugify } from '../utils';
54
import { AppStore } from './AppStore';
65
import { SECTION_ATTR } from './MenuStore';
76

@@ -56,7 +55,7 @@ export class MarkdownRenderer {
5655
parentId?: string,
5756
): MarkdownHeading {
5857
const item = {
59-
id: parentId ? `${parentId}/${slugify(name)}` : `section/${slugify(name)}`,
58+
id: parentId ? `${parentId}/${safeSlugify(name)}` : `section/${safeSlugify(name)}`,
6059
name,
6160
items: [],
6261
};

src/services/models/Group.model.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { action, observable } from 'mobx';
2-
import slugify from 'slugify';
32

43
import { OpenAPIExternalDocumentation, OpenAPITag } from '../../types';
4+
import { safeSlugify } from '../../utils';
55
import { MarkdownHeading } from '../MarkdownRenderer';
66
import { ContentItemModel } from '../MenuBuilder';
77
import { IMenuItem, MenuItemGroupType } from '../MenuStore';
@@ -32,7 +32,7 @@ export class GroupModel implements IMenuItem {
3232
parent?: GroupModel,
3333
) {
3434
// markdown headings already have ids calculated as they are needed for heading anchors
35-
this.id = (tagOrGroup as MarkdownHeading).id || type + '/' + slugify(tagOrGroup.name);
35+
this.id = (tagOrGroup as MarkdownHeading).id || type + '/' + safeSlugify(tagOrGroup.name);
3636
this.type = type;
3737
this.name = tagOrGroup['x-displayName'] || tagOrGroup.name;
3838
this.description = tagOrGroup.description || '';

src/utils/__tests__/helpers.test.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { mapWithLast, appendToMdHeading, mergeObjects } from '../helpers';
1+
import slugify from 'slugify';
2+
import { mapWithLast, appendToMdHeading, mergeObjects, safeSlugify } from '../helpers';
23

34
describe('Utils', () => {
45
describe('helpers', () => {
@@ -39,6 +40,16 @@ describe('Utils', () => {
3940
expect(val).toEqual('# Authentication\n\n<test>');
4041
});
4142

43+
test('slugifyIfAvailable returns original value when cannot slugify the value', () => {
44+
const willBeSlugifed = safeSlugify('some string')
45+
expect(willBeSlugifed).toEqual('some-string');
46+
47+
const cannotBeSlugified = '가나다라 마바사'
48+
// if slugify() fixes this issue, safeSlugify should be removed and replaced with original one.
49+
expect(slugify(cannotBeSlugified)).toEqual('');
50+
expect(safeSlugify(cannotBeSlugified)).toEqual('가나다라-마바사');
51+
})
52+
4253
describe('mergeObjects', () => {
4354
test('should merge Objects and all nested Ones', () => {
4455
const obj1 = { a: { a1: 'A1' }, c: 'C', d: {} };

src/utils/helpers.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import slugify from 'slugify';
2+
13
/**
24
* Maps over array passing `isLast` bool to iterator as the second arguemnt
35
*/
@@ -116,3 +118,18 @@ const isObject = (item: any): boolean => {
116118
const isMergebleObject = (item): boolean => {
117119
return isObject(item) && !Array.isArray(item);
118120
};
121+
122+
/**
123+
* slugify() returns empty string when failed to slugify.
124+
* so try to return minimun slugified-string with failed one which keeps original value
125+
* the regex codes are referenced with https://gist.github.com/mathewbyrne/1280286
126+
*/
127+
export function safeSlugify(value: string): string {
128+
return slugify(value) ||
129+
value.toString().toLowerCase()
130+
.replace(/\s+/g, '-') // Replace spaces with -
131+
.replace(/&/g, '-and-') // Replace & with 'and'
132+
.replace(/\--+/g, '-') // Replace multiple - with single -
133+
.replace(/^-+/, '') // Trim - from start of text
134+
.replace(/-+$/, ''); // Trim - from end of text
135+
}

0 commit comments

Comments
 (0)