{"id":16974614,"url":"https://github.com/alttiri/string-magic","last_synced_at":"2026-02-26T09:49:08.876Z","repository":{"id":247166129,"uuid":"825174494","full_name":"AlttiRi/string-magic","owner":"AlttiRi","description":"It's not a magic string, it's a string magic.","archived":false,"fork":false,"pushed_at":"2025-06-18T14:38:53.000Z","size":45,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-05T10:03:28.980Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://npmjs.com/package/@alttiri/string-magic","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AlttiRi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-07T02:38:32.000Z","updated_at":"2025-06-18T14:38:57.000Z","dependencies_parsed_at":"2024-11-28T05:02:13.488Z","dependency_job_id":null,"html_url":"https://github.com/AlttiRi/string-magic","commit_stats":null,"previous_names":["alttiri/string-magic"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/AlttiRi/string-magic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlttiRi%2Fstring-magic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlttiRi%2Fstring-magic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlttiRi%2Fstring-magic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlttiRi%2Fstring-magic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AlttiRi","download_url":"https://codeload.github.com/AlttiRi/string-magic/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlttiRi%2Fstring-magic/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266229376,"owners_count":23896250,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-14T01:07:15.825Z","updated_at":"2026-02-26T09:49:03.832Z","avatar_url":"https://github.com/AlttiRi.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [string-magic](https://github.com/AlttiRi/string-magic)\n\n~~ It's not a magic string, it's a string magic. ~~\n\nSome util \"StringRule\"-driven functions do some string transformations.\n\nI think, this lib will be mostly for my personal use, so the readme is short.\n\n---\n\nThere are two string cleaners — `TitleCleaner` and `UrlCleaner`.\n\nThe first one is to clean sites' titles from a boilerplate text like `\"on Twitter\"`,\nthe second one is to clean URLs (to remove search params and do some other things like removing site's redirects).\n\nYou describe rules as a string array, then apply them on a string is associated with some URL.\n\n---\n\n## TitleCleaner\n\n```ts\nconst tcRules: TCRuleStrings = [\n    \"site:artstation.com\",\n      \"trim-start:: ArtStation - \",\n    \"site:deviantart.com\",\n      \"trim-end:: on DeviantArt\",\n];\nconst titleCleaner = TitleCleaner.fromRuleStrings(tcRules);\n\ntitleCleaner.clean(\n    \"https://www.artstation.com/artwork/o0Yxm\",\n    \"ArtStation - Overwatch Preorder Widowmaker Noire\"\n);\n//  \"Overwatch Preorder Widowmaker Noire\"\n```\n\n## UrlCleaner\n```ts\nconst ucRules: UCRuleStrings = [\n    \"site:youtube.com\",\n      \"trim-search-params:feature t si list\",\n    \"site:t.umblr.com\",\n      \"filter-start:https://t.umblr.com/redirect\",\n      \"search-param:z\",\n      \"recursive\",\n    \"site:deviantart.com\",\n      \"trim-start:https://www.deviantart.com/users/outgoing?\",\n      \"decode-url\",\n      \"recursive\",\n];\nconst urlCleaner = UrlCleaner.fromRuleStrings(ucRules);\n\nurlCleaner.clean(\"https://t.umblr.com/redirect?z=http%3A%2F%2Fgfycat.com%2FRedFatCat\u0026m=1\");\n// \"https://gfycat.com/RedFatCat\"\n\nurlCleaner.clean(\"http://www.youtube.com/watch?feature=player_embedded\u0026v=z_HWtzUHm6s\");\n// \"http://www.youtube.com/watch?v=z_HWtzUHm6s\"\n\nurlCleaner.clean(\"https://www.deviantart.com/users/outgoing?https://t.umblr.com/redirect?z=https%3A%2F%2Ftwitter.com%2FSpaceX%2Fstatus%2F1798792222743122164\");\n// \"https://twitter.com/SpaceX/status/1798792222743122164\"\n\n```\n\n---\n\nSee tests for more examples.\n\n- [TitleCleaner](https://github.com/AlttiRi/string-magic/tree/master/test/title-cleaner)\n- [UrlCleaner](https://github.com/AlttiRi/string-magic/tree/master/test/url-cleaner)\n\n---\n\n## *.d.ts\n\n```ts\ndeclare const TypeArray_TCCommands: readonly [\"trim-start\", \"trim-end\", \"trim-start-end\"];\ndeclare const TypeArray_TCCommands_SD: readonly [\"trim-regex\"];\nexport type TCCommandString = typeof TypeArray_TCCommands[number];\nexport type TCCommandString_SD = typeof TypeArray_TCCommands_SD[number];\nexport type TCRuleString = `${TCCommandString | TCCommandString_SD | \"sites\" | \"site\"}:${string}`;\nexport type TCRuleStrings = TCRuleString[];\nexport type TCRule = {\n    command: TCCommandString;\n    data: string[];\n} | {\n    command: TCCommandString_SD;\n    data: string;\n};\nexport type TCRuleRecords = Record\u003cstring, Array\u003cTCRule\u003e\u003e;\nexport type TCCompiledRules = {\n    ruleRecords: TCRuleRecords;\n    ruleRecordsWC: TCRuleRecords | null;\n};\nexport declare function isTCRuleStringArray(array: string[]): array is TCRuleStrings;\nexport declare const knownCommands: Set\u003cstring\u003e;\nexport declare const knownCommands_SD: Set\u003cstring\u003e;\nexport declare class TitleCleaner {\n    private readonly ruleRecords;\n    private readonly ruleRecordsWC;\n    private constructor();\n    static fromRuleStrings(rule_strings: TCRuleStrings): TitleCleaner;\n    static fromRuleRecords(rules: TCCompiledRules): TitleCleaner;\n    static compileRuleStrings(rule_strings: TCRuleStrings): TCCompiledRules;\n    private getRules;\n    clean(url: string, title: string): string;\n    private applyRule;\n    private static parseRuleString;\n}\n\ndeclare const TypeArray_UCRuleCommands: readonly [\"https\", \"decode-url\", \"recursive\", \"atob\"];\ntype UCCommandString = typeof TypeArray_UCRuleCommands[number];\ndeclare const TypeArray_UCRuleDataCommands: readonly [\"filter-start\", \"trim-start\", \"prepend\", \"trim-regex\", \"trim-search-param\", \"search-param\"];\ntype UCDataCommandString = typeof TypeArray_UCRuleDataCommands[number];\ndeclare const TypeArray_UCRuleMDataCommands: readonly [\"trim-search-params\"];\ntype UCMDataCommandString = typeof TypeArray_UCRuleMDataCommands[number];\ntype UCAnyDataCommandString = UCDataCommandString | UCMDataCommandString;\ntype UCRuleCommandString = UCCommandString;\ntype UCRuleDataCommandString = `site:${string}` | `sites:${string}` | `${UCAnyDataCommandString}:${string}`;\nexport type UCRuleString = UCRuleCommandString | UCRuleDataCommandString;\nexport type UCRuleStrings = UCRuleString[];\ntype UCRule = {\n    command: UCCommandString;\n};\ntype UCDataRule = {\n    command: UCDataCommandString;\n    data: string;\n};\ntype UCMDataRule = {\n    command: UCMDataCommandString;\n    data: string | string[];\n};\ntype UCAnyDataRule = UCDataRule | UCMDataRule;\ntype UCAnyRule = UCRule | UCAnyDataRule;\nexport type UCRuleRecords = Record\u003cstring, Array\u003cUCAnyRule\u003e\u003e;\nexport type UCCompiledRules = {\n    ruleRecords: UCRuleRecords;\n    ruleRecordsWC: UCRuleRecords | null;\n};\nexport declare function isUCRuleStringArray(array: string[]): array is UCRuleStrings;\nexport declare class UrlCleaner {\n    private readonly ruleRecords;\n    private readonly ruleRecordsWC;\n    private constructor();\n    static fromRuleStrings(rule_strings: UCRuleStrings): UrlCleaner;\n    static fromRuleRecords(rules: UCCompiledRules): UrlCleaner;\n    static compileRuleStrings(rule_strings: UCRuleStrings): UCCompiledRules;\n    private getRules;\n    clean(url: string): string;\n    private static parseRuleString;\n}\n\nexport declare function isPlainObjectEmpty(obj: object): boolean;\nexport declare function noWWW(hostname: string): string;\nexport declare function getHostname(url: string): string;\nexport declare function getHostnameWithURL(url: string): string;\n/** Find dot positions in a string. */\nexport declare function findDots(str: string): number[];\n/**\n * @example\n * getParentSubHosts(\"localhost\")    -\u003e []\n * getParentSubHosts(\"example.com\")  -\u003e []\n * getParentSubHosts(\"qwerty.example.com\")      -\u003e [ \"example.com\" ]\n * getParentSubHosts(\"test.qwerty.example.com\") -\u003e [ \"example.com\", \"qwerty.example.com\" ]\n */\nexport declare function getParentSubHosts(hostname: string): string[];\n/**\n * # Hostname rule matching\n *\n * Simple and performance oriented implementation with simplified WildCards support.\n * Only one (the first) hostname match's rules are applied.\n *\n * - \"example.com\"\n *  1. look for \"example.com\" rules, if none then do nothing (since, there are only 2 hostname parts).\n *\n *  - \"www.example.com\"\n *  1. look for \"example.com\" rules, if none then\n *  2. look for \"*.example.com\" rules.\n *\n *  - \"qwerty.example.com\"\n *  1. look for \"qwerty.example.com\", if none then\n *  2. look for \"*.example.com\".\n *\n *  - \"more.qwerty.example.com\"\n *  1. look for \"more.qwerty.example.com\", if none then\n *  2. look for \"*.example.com\", if none then\n *  3. look for \"*.qwerty.example.com\".\n */\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falttiri%2Fstring-magic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falttiri%2Fstring-magic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falttiri%2Fstring-magic/lists"}