{"id":23763966,"url":"https://github.com/tomashubelbauer/ast-localizer","last_synced_at":"2026-03-22T16:30:21.249Z","repository":{"id":53502872,"uuid":"191155742","full_name":"TomasHubelbauer/ast-localizer","owner":"TomasHubelbauer","description":"An experiment in replacing UI-shown string literals with method calls for looking up localized versions","archived":false,"fork":false,"pushed_at":"2023-01-03T19:28:51.000Z","size":407,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-12-31T22:13:55.840Z","etag":null,"topics":["ast","cra","create-react-app","i18n","internationalization","localization","translation"],"latest_commit_sha":null,"homepage":"https://TomasHubelbauer.github.io/ast-localizer","language":"JavaScript","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/TomasHubelbauer.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}},"created_at":"2019-06-10T11:31:27.000Z","updated_at":"2023-03-07T13:37:57.000Z","dependencies_parsed_at":"2023-02-01T09:16:26.628Z","dependency_job_id":null,"html_url":"https://github.com/TomasHubelbauer/ast-localizer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TomasHubelbauer%2Fast-localizer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TomasHubelbauer%2Fast-localizer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TomasHubelbauer%2Fast-localizer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TomasHubelbauer%2Fast-localizer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TomasHubelbauer","download_url":"https://codeload.github.com/TomasHubelbauer/ast-localizer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239937698,"owners_count":19721484,"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":["ast","cra","create-react-app","i18n","internationalization","localization","translation"],"created_at":"2024-12-31T22:13:58.210Z","updated_at":"2026-03-22T16:30:21.183Z","avatar_url":"https://github.com/TomasHubelbauer.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AST Localizer\r\n\r\nThis is a project where I attempt to see if replacing string literals with their\r\nlocalized versions (or a localizer function invocations) could feasibly be done\r\nby running a `postbuild` step which uses the TypeScript compiler API to pull out\r\nthe string literals and replace/augment them.\r\n\r\n## Running\r\n\r\nI am using Create React App as a stand-in for a real-wold JavaScript project.\r\nThis tool is general and doesn't rely on CRA, it is used merely as an example.\r\n\r\nFirst time around, run `npm install` to make sure the `create-react-app` dev\r\ndependency and the `source-map` and `typescript` dependencies are installed.\r\n\r\n`create-react-app` is used later to scaffold a Create React App application from\r\nthe template and it is installed as a development dependency so that NPX doesn't\r\ninteractively ask for a permission to install it globally.\r\n\r\nTo run, do `npm start` which scaffolds the Create React App application in the\r\n`cra` directory unless it already exists.\r\nNext up, it runs `npm install` followed by `npm run build` in `cra` unless the\r\n`cra/build` directory already exists.\r\nAfter that, it copies `cra/build` into a new directory named `docs`.\r\nFinally, `node .` is ran which runs the main script which can now safely assume\r\na fresh copy of `docs` exists and it can also transform the files in there.\r\n`docs` will be used to host a GitHub Pages demonstration of the result in the\r\nfuture.\r\n\r\n## Features\r\n\r\nScans JavaScript source code (optionally built) and replaces found string\r\nliterals with their corresponding translations based on a translation file.\r\n\r\nLooks up translation based on several key variants to enable easy authoring of\r\nthe translations as well as distinguishing potential conflicts:\r\n\r\n- Translate by text\r\n- Translate by path and text\r\n- Translate by line, char and text\r\n- Leave out leading and trailing white-space if desired - it will be recovered!\r\n\r\n## To-Do\r\n\r\n### Consider turning this into a Babel plugin (TypeScript doesn't have plugins)\r\n\r\nBabel transformations:\r\n- https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md\r\n- https://lihautan.com/step-by-step-guide-for-writing-a-babel-transformation/\r\n\r\nThe TypeScript compiler doesn't have support for custom transformations, only\r\nlanguage service plugins:\r\n\r\nhttps://github.com/microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin\r\n\r\nThese are not useful in my case as the transformation should run as a post-build\r\nstep and not an interactive functionality.\r\n\r\nhttps://github.com/cevek/ttypescript exists but not many people use it or would\r\nswitch to it just for the support of this functionality.\r\n\r\n### Ship this as an NPM library which can be installed and run as a post-step\r\n\r\nPublish this to NPM automatically and make it an executable package so that\r\npeople can run `npx ast-localize` in their `postbuild` script in `package.json`.\r\n\r\n### Implement replacing with a localizer function for runtime switching\r\n\r\nThis will be a bit more complex but still totally doable and it will enable apps\r\nwith runtime language switching with no need for localization logic in the code.\r\n\r\nInstead of replacing a string literal node with another, replace it with either\r\na function call node or maybe even an array access node with the indexer being\r\nthe currently selected language ISO code stored in the local storage.\r\n\r\n### Enable a GitHub Pages static site demo based on the `docs` directory\r\n\r\nThis will demonstrate the translated site and when we have localizer functions\r\neven runtime language switching.\r\n\r\n### Add a GitHub Actions workflow to bump this whenever new CRA versions drop\r\n\r\nThis way the `cra` scaffold will be always current and while that's ignored, the\r\n`docs` output is tracked as it will be used for GitHub Pages so the effects of\r\nCRA changes can be apparent in the contents of this repository and as such it is\r\ndesirable to keep the ouput current with respect to the input.\r\n\r\n## Figure out why both `startMap` and `endMap` always share line and column\r\n\r\nThis is not the case in the original reproduction repo:\r\nhttps://github.com/TomasHubelbauer/babel-sourcemap\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomashubelbauer%2Fast-localizer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomashubelbauer%2Fast-localizer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomashubelbauer%2Fast-localizer/lists"}