Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release #226

Merged
merged 3 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"no-prototype-builtins": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-extra-semi": "off",
"semi": [2, "never"]
"semi": [2, "never"],
"no-control-regex": 0
}
}
61 changes: 42 additions & 19 deletions src/__tests__/path_validation.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as fs from 'fs'
import {
ILLEGAL_CHAR_REGEX,
replaceIllegalChars,
ILLEGAL_CHAR_REGEX_FILE,
replaceIllegalCharsFile,
replaceIllegalCharsFolder,
REPLACEMENT_CHAR,
} from '../util'

const expectedManualIllegalChars: string[] = [
'/',
const expectedManualIllegalCharsInFolderName: string[] = [
'\\',
'?',
'*',
Expand All @@ -19,59 +19,82 @@ const expectedManualIllegalChars: string[] = [
'\u001F',
]

// Adding forward slash too which is not allowed in file names
const expectedManualIllegalChars =
expectedManualIllegalCharsInFolderName.concat(['/'])

// ZERO WIDTH JOINER and SOFT HYPHEN
const expectedInvisibleChars: string[] = ['­', '‍']

describe('replaceIllegalChars() removes all expected characters', () => {
describe('replaceIllegalCharsFolder() does not replace forward slash', () => {
test('Forward slash is not replaced', () => {
const input = 'this/that'
const output = replaceIllegalCharsFolder(input)
expect(output).toEqual(input)
})
})

describe('replaceIllegalCharsFolder() removes all expected characters', () => {
test.each(expectedManualIllegalCharsInFolderName)(
'Illegal character "%s" is removed',
(character) => {
const input = `this${character}string`
const output = replaceIllegalCharsFolder(input)
expect(output).not.toContain(character)
},
)
})

describe('replaceIllegalCharsFile() removes all expected characters', () => {
test.each(expectedManualIllegalChars)(
'Illegal character "%s" is removed',
(character) => {
const input = `this${character}string`
const output = replaceIllegalChars(input)
const output = replaceIllegalCharsFile(input)
expect(output).not.toContain(character)
},
)
})

describe('replaceIllegalChars() function replaces illegal characters with replacement char', () => {
describe('replaceIllegalCharsFile() function replaces illegal characters with replacement char', () => {
test.each(expectedManualIllegalChars)(
"Illegal character '%s' is replaced",
(char) => {
const input = `this${char}string`
const expectedOutput = `this${REPLACEMENT_CHAR}string`
const output = replaceIllegalChars(input)
const output = replaceIllegalCharsFile(input)
expect(output).toEqual(expectedOutput)
},
)
})

describe('replaceIllegalChars() function does not modify string without illegal characters', () => {
describe('replaceIllegalCharsFile() function does not modify string without illegal characters', () => {
test.each(['this_is_a_valid_string', 'this is a valid string'])(
"String '%s' is not modified",
(input) => {
const output = replaceIllegalChars(input)
const output = replaceIllegalCharsFile(input)
expect(output).toEqual(input)
},
)
})

describe('replaceIllegalChars() function handles empty string', () => {
describe('replaceIllegalCharsFile() function handles empty string', () => {
test('Empty string is not modified', () => {
const input = ''
const output = replaceIllegalChars(input)
const output = replaceIllegalCharsFile(input)
expect(output).toEqual(input)
})
})

describe('replaceIllegalChars() function replaces all occurrences of illegal characters', () => {
describe('replaceIllegalCharsFile() function replaces all occurrences of illegal characters', () => {
test.each(expectedManualIllegalChars)(
"Illegal character '%s' is replaced",
(char) => {
const input = `${char}foo${char}bar`
const expectedOutput = `${REPLACEMENT_CHAR}foo${REPLACEMENT_CHAR}bar`
const output = replaceIllegalChars(input)
const output = replaceIllegalCharsFile(input)
expect(output).toEqual(expectedOutput)
expect(output.match(ILLEGAL_CHAR_REGEX)).toBeNull()
expect(output.match(ILLEGAL_CHAR_REGEX_FILE)).toBeNull()
},
)
})
Expand All @@ -82,7 +105,7 @@ describe('file system behavior with non-alphanumeric characters not in the illeg
(_, i) => String.fromCharCode(i + 32),
)
.filter((char) => !/^[a-zA-Z0-9]+$/.test(char))
.map(replaceIllegalChars)
.map(replaceIllegalCharsFile)

test.each(nonAlphanumericCharactersWithoutIllegal)(
"File system allows creation of file with character '%s'",
Expand All @@ -101,15 +124,15 @@ describe('file system behavior with non-alphanumeric characters not in the illeg
)
})

describe('replaceIllegalChars() function removes all occurrences of invisible characters', () => {
describe('replaceIllegalCharsFile() function removes all occurrences of invisible characters', () => {
test.each(expectedInvisibleChars)(
"Invisible character '%s' is replaced",
(char) => {
const input = `${char}foo${char}bar`
const expectedOutput = 'foobar'
const output = replaceIllegalChars(input)
const output = replaceIllegalCharsFile(input)
expect(output).toEqual(expectedOutput)
expect(output.match(ILLEGAL_CHAR_REGEX)).toBeNull()
expect(output.match(ILLEGAL_CHAR_REGEX_FILE)).toBeNull()
},
)
})
7 changes: 4 additions & 3 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import {
parseDateTime,
parseFrontMatterFromContent,
removeFrontMatterFromContent,
replaceIllegalChars,
replaceIllegalCharsFile,
replaceIllegalCharsFolder,
setOrUpdateHighlightColors,
} from './util'
import { OmnivoreSettingTab } from './settingsTab'
Expand Down Expand Up @@ -247,7 +248,7 @@ export default class OmnivorePlugin extends Plugin {
)

for (const item of items) {
const folderName = replaceIllegalChars(
const folderName = replaceIllegalCharsFolder(
normalizePath(render(item, folder, this.settings.folderDateFormat)),
)
const omnivoreFolder =
Expand All @@ -274,7 +275,7 @@ export default class OmnivorePlugin extends Plugin {
fileAttachment,
)
// use the custom filename
const customFilename = replaceIllegalChars(
const customFilename = replaceIllegalCharsFile(
renderFilename(item, filename, this.settings.filenameDateFormat),
)
const pageName = `${folderName}/${customFilename}.md`
Expand Down
15 changes: 12 additions & 3 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
// On Unix-like systems / is reserved and <>:"/\|?* as well as non-printable characters \u0000-\u001F on Windows
// credit: https://github.com/sindresorhus/filename-reserved-regex
// eslint-disable-next-line no-control-regex
export const ILLEGAL_CHAR_REGEX = /[<>:"/\\|?*\u0000-\u001F]/g
export const ILLEGAL_CHAR_REGEX_FILE = /[<>:"/\\|?*\u0000-\u001F]/g
export const ILLEGAL_CHAR_REGEX_FOLDER = /[<>:"\\|?*\u0000-\u001F]/g

export interface HighlightPoint {
left: number
Expand Down Expand Up @@ -103,8 +104,16 @@
)
}

export const replaceIllegalChars = (str: string): string => {
return removeInvisibleChars(str.replace(ILLEGAL_CHAR_REGEX, REPLACEMENT_CHAR))
export const replaceIllegalCharsFile = (str: string): string => {
return removeInvisibleChars(
str.replace(ILLEGAL_CHAR_REGEX_FILE, REPLACEMENT_CHAR),
)
}

export const replaceIllegalCharsFolder = (str: string): string => {
return removeInvisibleChars(
str.replace(ILLEGAL_CHAR_REGEX_FOLDER, REPLACEMENT_CHAR),
)
}

export function formatDate(date: string, format: string): string {
Expand Down Expand Up @@ -181,7 +190,7 @@
}

export const findFrontMatterIndex = (
frontMatter: any[],

Check warning on line 193 in src/util.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 18.x)

Unexpected any. Specify a different type

Check warning on line 193 in src/util.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 193 in src/util.ts

View workflow job for this annotation

GitHub Actions / build (macos-latest, 18.x)

Unexpected any. Specify a different type

Check warning on line 193 in src/util.ts

View workflow job for this annotation

GitHub Actions / build (macos-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 193 in src/util.ts

View workflow job for this annotation

GitHub Actions / build (windows-latest, 18.x)

Unexpected any. Specify a different type

Check warning on line 193 in src/util.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 18.x)

Unexpected any. Specify a different type

Check warning on line 193 in src/util.ts

View workflow job for this annotation

GitHub Actions / build (windows-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 193 in src/util.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 193 in src/util.ts

View workflow job for this annotation

GitHub Actions / build (macos-latest, 18.x)

Unexpected any. Specify a different type

Check warning on line 193 in src/util.ts

View workflow job for this annotation

GitHub Actions / build (macos-latest, 20.x)

Unexpected any. Specify a different type

Check warning on line 193 in src/util.ts

View workflow job for this annotation

GitHub Actions / build (windows-latest, 18.x)

Unexpected any. Specify a different type

Check warning on line 193 in src/util.ts

View workflow job for this annotation

GitHub Actions / build (windows-latest, 20.x)

Unexpected any. Specify a different type
id: string,
): number => {
// find index of front matter with matching id
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"isolatedModules": true,
"strictNullChecks": true,
"esModuleInterop": true,
"lib": ["ES2021","ES2021.String", "DOM"]
"lib": ["ES2021", "ES2021.String", "DOM"]
},
"include": ["src/**/*.ts"]
}
Loading