osm-community-index
Version:
An index of community resources for OpenStreetMap
11 lines • 10.8 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../lib/simplify.ts", "../../lib/resolve_strings.ts"],
"sourcesContent": [
"import diacritics from 'diacritics';\n\n/**\n * Simplifies a string by removing spaces, punctuation, and diacritics,\n * replacing `&` with `and`, and lowercasing the result.\n * Useful for generating normalized keys that can be compared across languages and scripts.\n *\n * For punctuation ranges see https://stackoverflow.com/a/21224179\n *\n * @param str - The input string to simplify\n * @returns A normalized, lowercase string with all whitespace, punctuation, and diacritics removed.\n * Returns an empty string if the input is not a string.\n */\nexport function simplify(str?: string): string {\n if (typeof str !== 'string') return '';\n\n return diacritics.remove(\n str\n .replace(/&/g, 'and')\n .replace(/(İ|i̇)/ig, 'i') // see name-suggestion-index#5017, #8261\n .replace(/[\\s\\-=_!\"#%'*{},.\\/:;?\\(\\)\\[\\]@\\\\$\\^*+<>«»~`’\\u00a1\\u00a7\\u00b6\\u00b7\\u00bf\\u037e\\u0387\\u055a-\\u055f\\u0589\\u05c0\\u05c3\\u05c6\\u05f3\\u05f4\\u0609\\u060a\\u060c\\u060d\\u061b\\u061e\\u061f\\u066a-\\u066d\\u06d4\\u0700-\\u070d\\u07f7-\\u07f9\\u0830-\\u083e\\u085e\\u0964\\u0965\\u0970\\u0af0\\u0df4\\u0e4f\\u0e5a\\u0e5b\\u0f04-\\u0f12\\u0f14\\u0f85\\u0fd0-\\u0fd4\\u0fd9\\u0fda\\u104a-\\u104f\\u10fb\\u1360-\\u1368\\u166d\\u166e\\u16eb-\\u16ed\\u1735\\u1736\\u17d4-\\u17d6\\u17d8-\\u17da\\u1800-\\u1805\\u1807-\\u180a\\u1944\\u1945\\u1a1e\\u1a1f\\u1aa0-\\u1aa6\\u1aa8-\\u1aad\\u1b5a-\\u1b60\\u1bfc-\\u1bff\\u1c3b-\\u1c3f\\u1c7e\\u1c7f\\u1cc0-\\u1cc7\\u1cd3\\u2000-\\u206f\\u2cf9-\\u2cfc\\u2cfe\\u2cff\\u2d70\\u2e00-\\u2e7f\\u3001-\\u3003\\u303d\\u30fb\\ua4fe\\ua4ff\\ua60d-\\ua60f\\ua673\\ua67e\\ua6f2-\\ua6f7\\ua874-\\ua877\\ua8ce\\ua8cf\\ua8f8-\\ua8fa\\ua92e\\ua92f\\ua95f\\ua9c1-\\ua9cd\\ua9de\\ua9df\\uaa5c-\\uaa5f\\uaade\\uaadf\\uaaf0\\uaaf1\\uabeb\\ufe10-\\ufe16\\ufe19\\ufe30\\ufe45\\ufe46\\ufe49-\\ufe4c\\ufe50-\\ufe52\\ufe54-\\ufe57\\ufe5f-\\ufe61\\ufe68\\ufe6a\\ufe6b\\ufeff\\uff01-\\uff03\\uff05-\\uff07\\uff0a\\uff0c\\uff0e\\uff0f\\uff1a\\uff1b\\uff1f\\uff20\\uff3c\\uff61\\uff64\\uff65]+/g,'')\n .toLowerCase()\n );\n}\n",
"import { simplify } from './simplify.ts';\n\nexport interface ItemStrings {\n community: string;\n communityID: string;\n name: string;\n description: string;\n extendedDescription: string;\n signupUrl: string;\n url: string;\n};\n\nexport interface Item {\n id: string;\n type: string;\n account?: string | undefined | null;\n strings: Partial<ItemStrings>;\n};\n\nexport type Defaults = Record<string, Partial<ItemStrings>>;\n\nexport interface ResolvedStrings {\n name: string | undefined;\n url: string | undefined;\n signupUrl: string | undefined;\n description: string | undefined;\n extendedDescription: string | undefined;\n nameHTML: string | undefined;\n urlHTML: string | undefined;\n signupUrlHTML: string | undefined;\n descriptionHTML: string | undefined;\n extendedDescriptionHTML: string | undefined;\n};\n\nexport type LocalizerFn = (a: string) => string;\n\n\n//\n// `resolveStrings`\n// Resolves the text strings for a given community index item\n//\n// Arguments\n// `item`: Object containing the community index item\n// `defaults`: Object containing the community index default strings\n// `localizerFn?`: optional function we will call to do the localization.\n// This function should be like the iD `t()` function that\n// accepts a `stringID` and returns a localized string\n//\n// Returns\n// An Object containing all the resolved strings:\n// {\n// name: 'talk-ru Mailing List',\n// url: 'https://lists.openstreetmap.org/listinfo/talk-ru',\n// signupUrl: 'https://example.url/signup',\n// description: 'A one line description',\n// extendedDescription: 'Extended description',\n// nameHTML: '<a href=\"the url\">the name</a>',\n// urlHTML: '<a href=\"the url\">the url</a>',\n// signupUrlHTML: '<a href=\"the signupUrl\">the signupUrl</a>',\n// descriptionHTML: the description, with urls and signupUrls linkified,\n// extendedDescriptionHTML: the extendedDescription with urls and signupUrls linkified\n// }\n//\nexport function resolveStrings(item: Item, defaults: Defaults, localizerFn?: LocalizerFn): ResolvedStrings {\n const itemStrings = Object.assign({}, item.strings); // shallow clone\n const defaultStrings = Object.assign({}, defaults[item.type]); // shallow clone\n const anyToken = new RegExp(/(\\{\\w+\\})/, 'gi');\n\n // Pre-localize the item and default strings\n if (localizerFn) {\n if (itemStrings.community) {\n const communityID = simplify(itemStrings.community);\n itemStrings.community = localizerFn(`_communities.${communityID}`);\n }\n for (const prop of ['name', 'description', 'extendedDescription'] as const) {\n if (defaultStrings[prop]) defaultStrings[prop] = localizerFn(`_defaults.${item.type}.${prop}`);\n if (itemStrings[prop]) itemStrings[prop] = localizerFn(`${item.id}.${prop}`);\n }\n }\n\n const replacements: {\n account: string | undefined | null;\n community: string | undefined | null;\n signupUrl: string | undefined | null;\n url: string | undefined | null;\n } = {\n account: item.account,\n community: itemStrings.community,\n signupUrl: itemStrings.signupUrl,\n url: itemStrings.url\n };\n\n // Resolve URLs first (which may refer to {account})\n if (!replacements.signupUrl) { replacements.signupUrl = resolve(itemStrings.signupUrl || defaultStrings.signupUrl); }\n if (!replacements.url) { replacements.url = resolve(itemStrings.url || defaultStrings.url); }\n\n const resolved = {\n name: resolve(itemStrings.name || defaultStrings.name),\n url: resolve(itemStrings.url || defaultStrings.url),\n signupUrl: resolve(itemStrings.signupUrl || defaultStrings.signupUrl),\n description: resolve(itemStrings.description || defaultStrings.description),\n extendedDescription: resolve(itemStrings.extendedDescription || defaultStrings.extendedDescription)\n } as ResolvedStrings;\n\n // Generate linkified strings\n resolved.nameHTML = linkify(resolved.url, resolved.name);\n resolved.urlHTML = linkify(resolved.url);\n resolved.signupUrlHTML = linkify(resolved.signupUrl);\n resolved.descriptionHTML = resolve((itemStrings.description || defaultStrings.description), true);\n resolved.extendedDescriptionHTML = resolve((itemStrings.extendedDescription || defaultStrings.extendedDescription), true);\n\n return resolved;\n\n\n function resolve(s?: string, addLinks?: boolean): string | undefined {\n if (!s) return undefined;\n let result = s;\n\n for (const key in replacements) {\n const token = `{${key}}`;\n const regex = new RegExp(token, 'g');\n if (regex.test(result)) {\n let replacement = replacements[key as keyof typeof replacements];\n if (!replacement) {\n throw new Error(`Cannot resolve token: ${token}`);\n } else {\n if (addLinks && (key === 'signupUrl' || key === 'url')) {\n replacement = linkify(replacement) ?? replacement;\n }\n result = result.replace(regex, replacement);\n }\n }\n }\n\n // There shouldn't be any leftover tokens in a resolved string\n const leftovers = result.match(anyToken);\n if (leftovers) {\n throw new Error(`Cannot resolve tokens: ${leftovers}`);\n }\n\n // Linkify subreddits like `/r/openstreetmap`\n // https://github.com/osmlab/osm-community-index/issues/82\n // https://github.com/openstreetmap/iD/issues/4997\n if (addLinks && resolved.url && item.type === 'reddit') {\n result = result.replace(/(\\/r\\/\\w+\\/*)/i, match => linkify(resolved.url, match) as string);\n }\n\n return result;\n }\n\n function linkify(url?: string, text?: string): string | undefined {\n if (!url) return undefined;\n text = text || url;\n return `<a target=\"_blank\" href=\"${url}\">${text}</a>`;\n }\n}\n"
],
"mappings": "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",
"debugId": "52CB7309EF2FBB8E64756E2164756E21",
"names": []
}