@empyria/name 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.
Files changed (2) hide show
  1. package/lib/Name.js +54 -0
  2. package/package.json +1 -1
package/lib/Name.js CHANGED
@@ -99,4 +99,58 @@ export function findTitle(_title) {
99
99
  return TITLE_LIST.find((t) => transliterate(t).toUpperCase() === title)
100
100
  }
101
101
 
102
+ /**
103
+ * Base fold: transliterate to ASCII, collapse any run of whitespace to a single space, trim.
104
+ * @param {unknown} value
105
+ * @returns {string}
106
+ */
107
+ export function fold(value) {
108
+ return transliterate(String(value ?? ''))
109
+ .replace(/\s+/g, ' ')
110
+ .trim()
111
+ }
112
+
113
+ /**
114
+ * Compact identifier key — transliterated, alphanumerics only, upper-case. Format-agnostic:
115
+ * `idKey('5299 00 T8BM49') === idKey('529900t8bm49')`, `idKey('DE 123.456.789') === 'DE123456789'`.
116
+ * Empty string for empty/nullish input (callers skip those).
117
+ * @param {unknown} value
118
+ * @returns {string}
119
+ */
120
+ export function idKey(value) {
121
+ return fold(value)
122
+ .toUpperCase()
123
+ .replace(/[^A-Z0-9]/g, '')
124
+ }
125
+
126
+ /**
127
+ * Free-text name form for external full-text engines (BAILII, CourtListener, opencaselaw) —
128
+ * transliterated, lower-case, single-spaced, tokens intact so their tokenisers still work.
129
+ * @param {unknown} value
130
+ * @returns {string}
131
+ */
132
+ export function nameText(value) {
133
+ return fold(value).toLowerCase()
134
+ }
135
+
136
+ /**
137
+ * Order-, case-, punctuation-, script-invariant name fingerprint: transliterate, upper-case,
138
+ * split on whitespace, strip non-alphanumerics per token, drop honorifics and 1-char tokens,
139
+ * dedupe, sort. `nameFp('Dr. Steve Charles') === nameFp('charles, steve') === 'CHARLES STEVE'`.
140
+ *
141
+ * Best-effort for organisations — legal-form / "&" vs "and" differences aren't reconciled here
142
+ * (`nameFp('J.P. Morgan & Co') !== nameFp('JPMorgan and Co')`); the `:Ident` exact match and the
143
+ * raw-name text search are the reliable paths for companies.
144
+ * @param {unknown} value
145
+ * @returns {string}
146
+ */
147
+ export function nameFp(value) {
148
+ const tokens = fold(value)
149
+ .toUpperCase()
150
+ .split(' ')
151
+ .map((token) => token.replace(/[^A-Z0-9]/g, ''))
152
+ .filter((token) => token.length > 1 && !TITLES.has(token))
153
+ return [...new Set(tokens)].sort().join(' ')
154
+ }
155
+
102
156
  export { transliterate, slugify, TRANS, capitalise, shortify }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empyria/name",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Name and title manipulation library for Empyria",
5
5
  "license": "MIT",
6
6
  "author": "Imre Fazekas <imre.fazekas@icloud.com>",