forked from martinandert/inflected
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add facility for caching and prepopulating a cache
- Loading branch information
Showing
10 changed files
with
145 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,27 @@ | ||
import { inflections } from "./Inflector"; | ||
|
||
export function applyInflections(word: string, rules: [RegExp | string, string][]) { | ||
let result = "" + word, | ||
rule, | ||
regex, | ||
replacement; | ||
let result = word; | ||
const inflector = inflections(); | ||
|
||
if (result.length === 0) { | ||
return result; | ||
} else { | ||
const match = result.toLowerCase().match(/\b\w+$/); | ||
} | ||
|
||
if (match && inflector.uncountables.indexOf(match[0]) > -1) { | ||
return result; | ||
} else { | ||
for (let i = 0, ii = rules.length; i < ii; i++) { | ||
rule = rules[i]; | ||
const match = result.toLowerCase().match(/\b\w+$/); | ||
|
||
regex = rule[0]; | ||
replacement = rule[1]; | ||
if (match && inflector.uncountables.indexOf(match[0]) > -1) { | ||
return result; | ||
} else { | ||
for (const rule of rules) { | ||
const [regex, replacement] = rule; | ||
|
||
if (result.match(regex)) { | ||
result = result.replace(regex, replacement); | ||
break; | ||
} | ||
if (result.match(regex)) { | ||
result = result.replace(regex, replacement); | ||
break; | ||
} | ||
|
||
return result; | ||
} | ||
|
||
return result; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/** Wrap a given function in a cache that is off by default */ | ||
export const cacheable = <T extends (...args: any[]) => any>( | ||
fn: T, | ||
getCacheKey: (...args: Parameters<T>) => string = ((str: string) => str) as unknown as (...args: Parameters<T>) => string | ||
) => { | ||
const cache = new Map<string, ReturnType<T>>(); | ||
|
||
const cachedFn = Object.assign( | ||
function (this: unknown, ...args: Parameters<T>): ReturnType<T> { | ||
return cache.get(getCacheKey(...args)) ?? fn.call(this, ...args); | ||
}, | ||
{ | ||
cache, | ||
populate: (...args: Parameters<T>) => { | ||
cache.set(getCacheKey(...args), fn(...args)); | ||
}, | ||
} | ||
); | ||
|
||
return cachedFn as T & { cache: Map<string, ReturnType<T>>; populate: (...args: Parameters<T>) => void }; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
import { cacheable } from "./cache"; | ||
import { camelize } from "./camelize"; | ||
import { singularize } from "./singularize"; | ||
|
||
export function classify(tableName: string) { | ||
return camelize(singularize(tableName.replace(/.*\./g, ""))); | ||
} | ||
export const classify = cacheable((tableName: string) => camelize(singularize(tableName.replace(/.*\./g, "")))); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
import { cacheable } from "./cache"; | ||
import { underscore } from "./underscore"; | ||
|
||
export function constantify(word: string) { | ||
return underscore(word) | ||
.toUpperCase() | ||
.replace(/\s+/g, "_"); | ||
} | ||
export const constantify = cacheable((word: string) => { | ||
return underscore(word).toUpperCase().replace(/\s+/g, "_"); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,43 @@ | ||
import { inflections } from "./Inflector"; | ||
import { cacheable } from "./cache"; | ||
export const humanize = cacheable( | ||
(lowerCaseAndUnderscoredWord: string, options?: { capitalize?: boolean }) => { | ||
let result = "" + lowerCaseAndUnderscoredWord; | ||
const inflector = inflections(); | ||
const humans = inflector.humans; | ||
let human, rule, replacement; | ||
|
||
options = options || {}; | ||
|
||
if (options.capitalize === null || options.capitalize === undefined) { | ||
options.capitalize = true; | ||
} | ||
|
||
export function humanize(lowerCaseAndUnderscoredWord: string, options?: { capitalize?: boolean }) { | ||
let result = "" + lowerCaseAndUnderscoredWord; | ||
const inflector = inflections(); | ||
const humans = inflector.humans; | ||
let human, rule, replacement; | ||
|
||
options = options || {}; | ||
|
||
if (options.capitalize === null || options.capitalize === undefined) { | ||
options.capitalize = true; | ||
} | ||
|
||
for (let i = 0, ii = humans.length; i < ii; i++) { | ||
human = humans[i]; | ||
rule = human[0]; | ||
replacement = human[1]; | ||
for (let i = 0, ii = humans.length; i < ii; i++) { | ||
human = humans[i]; | ||
rule = human[0]; | ||
replacement = human[1]; | ||
|
||
if (rule instanceof RegExp ? rule.test(result) : result.indexOf(rule) > -1) { | ||
result = result.replace(rule, replacement); | ||
break; | ||
if (rule instanceof RegExp ? rule.test(result) : result.indexOf(rule) > -1) { | ||
result = result.replace(rule, replacement); | ||
break; | ||
} | ||
} | ||
} | ||
|
||
result = result.replace(/_id$/, ""); | ||
result = result.replace(/_/g, " "); | ||
result = result.replace(/_id$/, ""); | ||
result = result.replace(/_/g, " "); | ||
|
||
result = result.replace(/([a-z\d]*)/gi, function (match) { | ||
return inflector.lowerToAcronyms[match] || match.toLowerCase(); | ||
}); | ||
|
||
if (options.capitalize) { | ||
result = result.replace(/^\w/, function (match) { | ||
return match.toUpperCase(); | ||
result = result.replace(/([a-z\d]*)/gi, function (match) { | ||
return inflector.lowerToAcronyms[match] || match.toLowerCase(); | ||
}); | ||
} | ||
|
||
return result; | ||
} | ||
if (options.capitalize) { | ||
result = result.replace(/^\w/, function (match) { | ||
return match.toUpperCase(); | ||
}); | ||
} | ||
|
||
return result; | ||
}, | ||
(lowerCaseAndUnderscoredWord, options) => `${lowerCaseAndUnderscoredWord}-${options?.capitalize}` | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,36 @@ | ||
import { cacheable } from "./cache"; | ||
import { transliterate } from "./Transliterator"; | ||
|
||
export function parameterize(string: string, options: { locale?: string; separator?: string | null; preserveCase?: boolean } = {}) { | ||
if (options.separator === undefined) { | ||
options.separator = "-"; | ||
} | ||
export const parameterize = cacheable( | ||
(string: string, options: { locale?: string; separator?: string | null; preserveCase?: boolean } = {}) => { | ||
if (options.separator === undefined) { | ||
options.separator = "-"; | ||
} | ||
|
||
if (options.separator === null) { | ||
options.separator = ""; | ||
} | ||
if (options.separator === null) { | ||
options.separator = ""; | ||
} | ||
|
||
// replace accented chars with their ascii equivalents | ||
let result = transliterate(string, { locale: options.locale }); | ||
// replace accented chars with their ascii equivalents | ||
let result = transliterate(string, { locale: options.locale }); | ||
|
||
result = result.replace(/[^a-z0-9\-_]+/gi, options.separator); | ||
result = result.replace(/[^a-z0-9\-_]+/gi, options.separator); | ||
|
||
if (options.separator.length) { | ||
const separatorRegex = new RegExp(options.separator); | ||
if (options.separator.length) { | ||
const separatorRegex = new RegExp(options.separator); | ||
|
||
// no more than one of the separator in a row | ||
result = result.replace(new RegExp(separatorRegex.source + "{2,}"), options.separator); | ||
// no more than one of the separator in a row | ||
result = result.replace(new RegExp(separatorRegex.source + "{2,}"), options.separator); | ||
|
||
// remove leading/trailing separator | ||
result = result.replace(new RegExp("^" + separatorRegex.source + "|" + separatorRegex.source + "$", "i"), ""); | ||
} | ||
// remove leading/trailing separator | ||
result = result.replace(new RegExp("^" + separatorRegex.source + "|" + separatorRegex.source + "$", "i"), ""); | ||
} | ||
|
||
if (options.preserveCase) { | ||
return result; | ||
} | ||
if (options.preserveCase) { | ||
return result; | ||
} | ||
|
||
return result.toLowerCase(); | ||
} | ||
return result.toLowerCase(); | ||
}, | ||
(string, options) => `${string}-${options?.locale}-${options?.separator}-${options?.preserveCase}` | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
import { applyInflections } from "./applyInflections"; | ||
import { cacheable } from "./cache"; | ||
import { inflections } from "./Inflector"; | ||
|
||
export function pluralize(word: string, locale = "en") { | ||
return applyInflections(word, inflections(locale).plurals); | ||
} | ||
export const pluralize = cacheable( | ||
(word: string, locale = "en") => applyInflections(word, inflections(locale).plurals), | ||
(word, locale) => `${word}-${locale}` | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
import { applyInflections } from "./applyInflections"; | ||
import { cacheable } from "./cache"; | ||
import { inflections } from "./Inflector"; | ||
|
||
export function singularize(word: string, locale = "en") { | ||
return applyInflections(word, inflections(locale).singulars); | ||
} | ||
export const singularize = cacheable( | ||
(word: string, locale = "en") => applyInflections(word, inflections(locale).singulars), | ||
(word, locale) => `${word}-${locale}` | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters