Skip to content

Conversation

@zyf722
Copy link
Contributor

@zyf722 zyf722 commented Sep 15, 2025

What type of PR is this? (check all applicable)

  • ✨ Feature
  • 🐛 Bug Fix
  • 📝 Documentation Update
  • 🎨 Style
  • ♻️ Code Refactor
  • 🔥 Performance Improvements
  • ✅ Test
  • 🤖 Build
  • 🔁 CI
  • 📦 Chore (Release)
  • ⏩ Revert
  • 🌐 Internationalization / Translation

Description

#707 (comment)

This PR uses a new solution to check type-safety for i18n locale ts files (which is used to check languages other than en to keep consistent with en). The main change was to replace the UnAsConst utility type and uses a more direct indexed mapped type to recursively validate the structure.

Related Tickets & Documents

Added tests?

  • 👍 yes
  • 🙅 no, because they aren't needed
  • 🙋 no, because I need help

Added to documentations?

  • 📓 docs (./docs)
  • 📕 storybook (./storybook)
  • 📜 README.md
  • 🙅 no documentation needed

Summary by CodeRabbit

  • Refactor
    • Simplified and reworked i18n type definitions to a structural, nested-friendly approach; no runtime or user-facing changes.
  • Chores
    • Removed an obsolete CI type-check workflow.
    • Deleted a redundant TypeScript config and adjusted project compilation to include i18n locale sources.
    • Removed an unused npm script and cleaned up scripts ordering/formatting.
  • Tests
    • No changes.

@netlify
Copy link

netlify bot commented Sep 15, 2025

Deploy Preview for livecodes ready!

Name Link
🔨 Latest commit a6f5a7a
🔍 Latest deploy log https://app.netlify.com/projects/livecodes/deploys/68c7af490146a800082bc256
😎 Deploy Preview https://deploy-preview-870--livecodes.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link

coderabbitai bot commented Sep 15, 2025

Walkthrough

Deleted Node.js type-check CI workflow and tsconfig.full.json, removed root check-types npm script, included i18n locale sources in tsconfig, and refactored i18n type definitions: removed UnAsConst, rewrote RequireAtLeastOne, added I18nStructure, and updated translation/template typings.

Changes

Cohort / File(s) Summary
CI workflow removal
\.github/workflows/CI-type-checking.yml
Deleted the GitHub Actions workflow that ran Node.js type-checking (checkout, setup-node, npm ci, npm run check-types).
TypeScript config adjustments
tsconfig.full.json, tsconfig.json
Removed tsconfig.full.json. In tsconfig.json removed exclusion of src/livecodes/i18n/locales/**, leaving only **/node_modules/** excluded.
i18n type model refactor
src/livecodes/i18n/models.ts, src/livecodes/i18n/locales/models.ts
Removed UnAsConst; replaced RequireAtLeastOne with a distributive conditional type; added I18nStructure<T> and updated I18nTranslation, I18nLangInfoTranslation, and I18nTranslationTemplate to use structural leaf-string mappings.
NPM scripts update
package.json
Removed the check-types script; i18n-lokalise-json remains as the last scripts entry.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

I thump my paw—types trimmed with care,
Leaves turned into strings, light as air.
CI sleeps, configs rearrange,
Locales now step into the range.
A joyful hop — small, brisk change. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The PR deletes .github/workflows/CI-type-checking.yml, removes the root check-types npm script, and deletes tsconfig.full.json; these CI and project-config changes are not required by the coding objective in [#707] (improving i18n type performance) and therefore appear out-of-scope unless explicitly justified in the PR. Either split CI and config modifications into a separate PR or provide a clear justification and migration plan in this PR; if CI/type-checking is intentionally changed, document the new verification process and include tests/benchmarks before merging.
Linked Issues Check ❓ Inconclusive The code replaces UnAsConst with a structural I18nStructure and simplifies RequireAtLeastOne to a distributive form, which targets the performance objective in [#707], but the PR provides no benchmarks or type-check timing comparisons and includes no tests that prove non-en locales are still validated against en, and the removal of the CI type-check workflow and check-types script further prevents automated verification of the claim. Add before/after type-check timings (e.g., full build:ts), include tests or sample non-en locale validations that demonstrate equivalent type-safety, and reinstate or replace CI steps so the performance and correctness improvements can be verified automatically.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "fix(i18n): optimize i18n types performance" is a concise, single-sentence summary that directly reflects the primary change (i18n type performance optimization) and is clear and specific for a reviewer scanning history.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5bd4181 and a6f5a7a.

📒 Files selected for processing (1)
  • src/livecodes/i18n/locales/models.ts (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: Redirect rules - livecodes
  • GitHub Check: Header rules - livecodes
  • GitHub Check: build
  • GitHub Check: tests (18.x, 5)
  • GitHub Check: tests (18.x, 3)
  • GitHub Check: tests (18.x, 2)
  • GitHub Check: tests (18.x, 1)
  • GitHub Check: build (18.x)
  • GitHub Check: tests (18.x, 4)
  • GitHub Check: Pages changed - livecodes
🔇 Additional comments (5)
src/livecodes/i18n/locales/models.ts (5)

39-39: I18nTranslation alias looks good.


44-44: I18nLangInfoTranslation alias looks good.


8-8: Doc path changed — script verified present.
scripts/vscode-intellisense.js exists.


1-1: Confirmed: RequireAtLeastOne is defined and no circular import from ./locales.
src/livecodes/i18n/models.ts exports RequireAtLeastOne (≈ lines 6–8) and contains no imports from ./locales.


24-24: Template omits arrays; allow arrays of strings.

Current union excludes arrays (e.g., bullet lists). I searched src//locales/ and found no array literals; absence of matches isn't proof — confirm whether locales use arrays; if so, apply:

-export interface I18nTranslationTemplate {
-  [key: string]: I18nAttributes | string | I18nTranslationTemplate;
-}
+export interface I18nTranslationTemplate {
+  [key: string]: I18nAttributes | string | readonly string[] | I18nTranslationTemplate;
+}

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
tsconfig.json (1)

51-53: Locales now type-checked; consider skipLibCheck and align checkJs with include.

Including src/livecodes/i18n/locales/** is likely intended for the new i18n typing. For faster builds, consider skipLibCheck. Also, allowJs: true + checkJs: true won’t have effect with include: ["src/**/*.ts"].

Apply:

   "compilerOptions": {
+    "skipLibCheck": true,
     "rootDir": "src",

If you want JS in type-checks, broaden include:

-  "include": ["src/**/*.ts"],
+  "include": ["src"],

Or disable JS checks to avoid confusion:

-    "checkJs": true,
+    "checkJs": false,

Please confirm intended scope (TS-only vs TS+JS) and measure tsc --noEmit --extendedDiagnostics before/after.

package.json (1)

71-72: Type-check CI guard removed; add a lightweight script to keep an easy gate.

With check-types and the CI workflow removed, ensure another job runs tsc. Add a generic script so workflows can call it.

Apply:

   "scripts": {
@@
-    "i18n-lokalise-json": "node ./scripts/i18n-lokalise-json.mjs"
+    "i18n-lokalise-json": "node ./scripts/i18n-lokalise-json.mjs",
+    "typecheck": "tsc -p tsconfig.json --noEmit"
   },

Then wire npm run typecheck into an existing CI workflow (build/test job).

src/livecodes/i18n/locales/models.ts (1)

5-16: Doc path nit: scripts directory name.

Comment references script/vscode-intellisense.js but repo scripts live under scripts/.

Apply:

- * To add new custom data attributes for HTML intellisense, see `script/vscode-intellisense.js`.
+ * To add new custom data attributes for HTML intellisense, see `scripts/vscode-intellisense.js`.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f46a5c6 and 5bd4181.

📒 Files selected for processing (6)
  • .github/workflows/CI-type-checking.yml (0 hunks)
  • package.json (1 hunks)
  • src/livecodes/i18n/locales/models.ts (2 hunks)
  • src/livecodes/i18n/models.ts (1 hunks)
  • tsconfig.full.json (0 hunks)
  • tsconfig.json (1 hunks)
💤 Files with no reviewable changes (2)
  • .github/workflows/CI-type-checking.yml
  • tsconfig.full.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: build (18.x)
  • GitHub Check: tests (18.x, 4)
  • GitHub Check: tests (18.x, 5)
  • GitHub Check: tests (18.x, 3)
  • GitHub Check: tests (18.x, 1)
  • GitHub Check: tests (18.x, 2)
🔇 Additional comments (4)
src/livecodes/i18n/models.ts (1)

6-12: RequireAtLeastOne looks good and distributive; verify empty-object behavior is desired.

This returns never for keyof T extends never. If T could be {} somewhere, that’ll surface as an error. Confirm that’s intended.

src/livecodes/i18n/locales/models.ts (3)

24-25: Template now allows nested objects — good for structured keys.

This aligns with as const satisfies usage for en. No issues.


44-45: Verify LangInfoTranslation isn't an array or use an array-safe I18nStructure

rg returned no hits for array assignments in src/livecodes/i18n/locales/en/language-info.ts — I couldn't confirm. Check src/livecodes/i18n/locales/models.ts (lines 44–45): if LangInfoTranslation contains arrays, convert them to object maps or switch to the array-safe I18nStructure.


39-40: No arrays found in en translations — typing is safe. Inspected src/livecodes/i18n/locales/en/translation.ts and translation.lokalise.json; no array literals in leaf values were found, so I18nStructure models the translations correctly.

Comment on lines 27 to 34
/**
* Maps a nested object structure to a structure where all leaf nodes are strings.
*
* Use to keep the same structure as the `en` i18n object for other languages.
*/
export type I18nStructure<T> = {
readonly [K in keyof T]: T[K] extends Record<string, any> ? I18nStructure<T[K]> : string;
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Handle arrays in I18nStructure to avoid treating them as objects.

Record<string, any> matches arrays, which would map array methods/indices into the structure. Prefer explicit array handling and avoid any.

Apply:

-export type I18nStructure<T> = {
-    readonly [K in keyof T]: T[K] extends Record<string, any> ? I18nStructure<T[K]> : string;
-};
+export type I18nStructure<T> = {
+  readonly [K in keyof T]:
+    // Preserve arrays as arrays of strings
+    T[K] extends readonly (infer _E)[]
+      ? readonly string[]
+      // Recurse into plain objects
+      : T[K] extends Record<string, unknown>
+        ? I18nStructure<T[K]>
+        : string;
+};
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* Maps a nested object structure to a structure where all leaf nodes are strings.
*
* Use to keep the same structure as the `en` i18n object for other languages.
*/
export type I18nStructure<T> = {
readonly [K in keyof T]: T[K] extends Record<string, any> ? I18nStructure<T[K]> : string;
};
/**
* Maps a nested object structure to a structure where all leaf nodes are strings.
*
* Use to keep the same structure as the `en` i18n object for other languages.
*/
export type I18nStructure<T> = {
readonly [K in keyof T]:
// Preserve arrays as arrays of strings
T[K] extends readonly (infer _E)[]
? readonly string[]
// Recurse into plain objects
: T[K] extends Record<string, unknown>
? I18nStructure<T[K]>
: string;
};
🤖 Prompt for AI Agents
In src/livecodes/i18n/locales/models.ts around lines 27 to 34, the I18nStructure
type currently treats arrays as Record<string, any>, which causes array indices
and methods to be mapped and uses `any`. Change the conditional type to
explicitly detect arrays (T[K] extends Array<infer U> ? I18nStructure<U>[] ...)
before the object check, and replace `any` with `unknown` in the object branch
(T[K] extends Record<string, unknown> ? I18nStructure<T[K]> : string) so arrays
map to arrays of leaf strings/structures and objects use a safe unknown type
instead of any.

@sonarqubecloud
Copy link

@hatemhosny
Copy link
Collaborator

That's very nice.
Thank you @zyf722

@hatemhosny hatemhosny merged commit c8acd7a into live-codes:develop Sep 15, 2025
16 checks passed
@livecodes-ci
Copy link
Contributor

livecodes-ci bot commented Sep 15, 2025

i18n Actions

Source PR has been merged into the default branch.

Maintainers can comment .i18n-update-push to trigger the i18n update workflow and push the changes to Lokalise.

@hatemhosny
Copy link
Collaborator

.i18n-update-push

@livecodes-ci
Copy link
Contributor

livecodes-ci bot commented Sep 15, 2025

i18n Actions: .i18n-update-push

Localization updated and pushed to Lokalise.

Name Description
New Branch for i18n i18n/zyf722/i18next-integration-draft
Last Commit SHA c8acd7a

Maintainers can comment .i18n-update-pull after translation is done to trigger the i18n pull workflow and pull the changes back to Github.

@hatemhosny
Copy link
Collaborator

.i18n-update-pull

@coderabbitai coderabbitai bot mentioned this pull request Oct 18, 2025
19 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

i18n types performance

2 participants