Skip to content

Added multi language version support#27

Closed
ArkeBcacy wants to merge 29 commits intomainfrom
feature/multi-locale-support
Closed

Added multi language version support#27
ArkeBcacy wants to merge 29 commits intomainfrom
feature/multi-locale-support

Conversation

@ArkeBcacy
Copy link
Copy Markdown

Added support for serialization/de-serialization of locale versions of entries

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds support for serializing and deserializing locale-specific versions of entries in Contentstack. The implementation allows entries to be stored either as single files (for backward compatibility) or as multiple locale-specific files with the naming pattern entry.locale.yaml.

Changes:

  • Added new API functions to export and fetch locale-specific entry data
  • Modified entry import/export logic to handle multiple locale versions
  • Updated filesystem indexing to recognize both single-locale and multi-locale file patterns
  • Implemented backward compatibility by supporting simple filename format for single-locale entries

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 18 comments.

Show a summary per file
File Description
cli/src/cs/entries/exportEntryLocale.ts New function to export entry data for a specific locale
cli/src/cs/entries/getEntryLocales.ts New function to fetch available locales for an entry
cli/src/cs/entries/getEntryLocales.test.ts Tests for locale info structure and filename patterns
cli/src/schema/entries/lib/loadEntryLocales.ts New function to load all locale versions of an entry from filesystem
cli/src/schema/entries/lib/loadEntryLocales.test.ts Basic tests for loadEntryLocales function
cli/src/schema/entries/toFilesystem.ts Modified export logic to write locale-specific files
cli/src/schema/entries/toContentstack.ts Modified import logic to handle locale-specific files
cli/src/schema/entries/lib/buildCreator.ts Updated entry creation to import all locale versions
cli/src/schema/entries/indexAllFsEntries.ts Updated indexing to recognize multi-locale file patterns
cli/src/cs/entries/import.ts Added locale parameter to import function
cli/src/cs/entries/lib/importCreate.ts Added locale parameter to API call
cli/src/cs/entries/lib/importOverwrite.ts Added locale parameter to API call
test/integration/workflow/lib/loadEntry.ts Updated test helper to support locale-specific file loading

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 14 comments.

Copy link
Copy Markdown
Contributor

@altearius altearius left a comment

Choose a reason for hiding this comment

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

Partial review only, I looked over it, but I have some questions about the functionality before I do a full review.

In the file system, what is the intended structure for handling locale-specific versions of entries?

How will this handle backwards compatibility with projects that have already serialized content?

How does this handle serialization of non-localizable fields on locale-specific versions of entries?

How does this handle references between entries / assets?

What happens during a push if we attempt to push a localized version of an entry for which the fallback entry does not yet exist? Is it possible for such a situation to occur?

The management API has endpoints related to localization: Localize an Entry, Update a Localized Entry, Unlocalize an Entry. Are these being used? If they aren't being used, can we add some documentation (under /doc or /doc/lessons-learned) that describes why not?

My reading of the documentation is that, when working with localized entries, the order in which we manage locales is important. We should work with the default language first, then work with every language that uses the default language as a fallback, then work with languages that use those as fallbacks, and so on. Is that being done? If not, what happens when this order is violated?

What happens when we delete an entry that has localized versions? Are the localized versions automatically deleted?

How are localized assets handled?

* const pattern = new RegExp(`^${escapeRegex(filename)}\\.yaml$`, 'u');
* // Creates pattern: /^My\.Entry\.Title\.yaml$/u
*/
export default function escapeRegex(str: string): string {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should already exist, is RegExp.escape not working?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/escape

Also, why is this needed at all?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Regarding RegExp.escape:
RegExp.escape is a Stage 3 TC39 proposal but is not yet available in Node.js 22. It's not part of the JavaScript standard yet. Once it reaches Stage 4 and is implemented in Node.js, you could replace this custom implementation.

Why is this needed?
The function is used in 3 locations to escape filenames when creating regex patterns for matching entry locale files:

loadEntryLocales.ts:73 - Creates pattern like /^My.Entry.Title.([^.]+).yaml$/ to match locale variants
toFilesystem.ts:135 - Creates pattern to match entry files with any locale
loadEntry.ts:24 - Used in tests
Without escaping, a filename like My.Entry.Title would have . treated as "any character" in the regex instead of literal dots, causing incorrect matches.

Recommendation:
Keep the custom implementation for now since RegExp.escape isn't available yet. When Node.js supports it (likely Node.js 24+), you can replace this with the native implementation.

// If simple format doesn't exist, try finding locale-specific file
try {
const files = await readdir(entriesDir);
// eslint-disable-next-line @typescript-eslint/no-unsafe-call -- escapeRegex is properly typed as (string) => string
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This line generates a lint error for me:

$ yarn lint

/home/cnielsen/projects/beacon/test/integration/workflow/lib/loadEntry.ts
  23:4  warning  Unused eslint-disable directive (no problems were reported from '@typescript-eslint/no-unsafe-call')

✖ 1 problem (0 errors, 1 warning)
  0 errors and 1 warning potentially fixable with the `--fix` option.

CI/CD should be reporting this, and it isn't -- but that's an unrelated issue with CI/CD.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I'm not seeing this pop up as an error locally when running yarn lint.

@ArkeBcacy
Copy link
Copy Markdown
Author

Partial review only, I looked over it, but I have some questions about the functionality before I do a full review.

In the file system, what is the intended structure for handling locale-specific versions of entries?

How will this handle backwards compatibility with projects that have already serialized content?

How does this handle serialization of non-localizable fields on locale-specific versions of entries?

How does this handle references between entries / assets?

What happens during a push if we attempt to push a localized version of an entry for which the fallback entry does not yet exist? Is it possible for such a situation to occur?

The management API has endpoints related to localization: Localize an Entry, Update a Localized Entry, Unlocalize an Entry. Are these being used? If they aren't being used, can we add some documentation (under /doc or /doc/lessons-learned) that describes why not?

My reading of the documentation is that, when working with localized entries, the order in which we manage locales is important. We should work with the default language first, then work with every language that uses the default language as a fallback, then work with languages that use those as fallbacks, and so on. Is that being done? If not, what happens when this order is violated?

What happens when we delete an entry that has localized versions? Are the localized versions automatically deleted?

How are localized assets handled?

Added /doc/lessons-learned/multi-language-support.md to outline the answers to the questions.

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.

3 participants