GithubHelp home page GithubHelp logo

thompsonsj / payload-crowdin-sync Goto Github PK

View Code? Open in Web Editor NEW
6.0 6.0 4.0 4.85 MB

Upload and sync localized fields from the default locale to Crowdin.

TypeScript 99.53% JavaScript 0.47%
payload-plugin

payload-crowdin-sync's People

Contributors

andrii-bodnar avatar ccapndave avatar github-actions[bot] avatar thompsonsj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

payload-crowdin-sync's Issues

Handle directories/files deleted on Crowdin

If a collection directory is deleted on Crowdin, and a corresponding CrowdinArticleDirectories collection document exists for that directory, the following line will cause an error:

directoryId: crowdinPayloadCollectionDirectory['originalId'] as number,

Error: Invalid directory id given. Directory doesn't exists
    at handleHttpClientError (/<project-dir>/node_modules/@crowdin/crowdin-api-client/out/core/index.js:79:15)
    at /<project-dir>/node_modules/@crowdin/crowdin-api-client/out/core/index.js:250:29
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

Handle this type of scenario. Might be worth doing this once the plugin has been refactored to only use nock rather than a mock API.

Better Crowdin file/folder names: use collection labels and `useAsTitle` if available

Follow the Payload CMS logic here.

  • Collection labels can be used to provide a folder name in Crowdin. Currently we convert the slug to words.
  • useAsTitle can be used for 'document' folder names in Crowdin. Currently we look for either a title or name field.

title: global
? toWords(collectionSlug)
: document.title || document.name, // no tests for this Crowdin metadata, but makes it easier for translators
}

https://payloadcms.com/docs/configuration/collections

Improve error handling/reporting

The bug fixed in #89 was difficult to detect because await calls can fail without any error feedback. try catch blocks have been introduced. Often, a console.log is added before throwing an exception - this seems to be the only way to get feedback on await calls.

Any Payload functions that can replace `getLocalizedFields`?

getLocalizedFields is fairly complicated. Over time, support is added for multiple Payload field types such as group, array, blocks ...etc.

Because we are writing our own logic for this, bugs can creep in that are hard to detect! For example, consider what might happen if fields are added that get detected as localized when they shouldn't be - #64.

On the one hand, it makes sense to have our own function - we need to be involved in the recursion to control:

  • which fields are sent to fields.json;
  • which fields create their own html files; and
  • which fields are excluded.

However, https://github.com/payloadcms/payload should be studied to see if there is any logic that can be used to make this functionality more maintainable/reliable.

Can't sync from Crowdin to Payload

Hi! I've got data syncing from Payload to Crowdin, but I don't seem to be able to get it to sync back again.

I've tried http://localhost:3000/api/crowdin-translations/<id>/review as described in the README, and I've also tried http://localhost:3000/api/crowdin-article-directories/<id>/review (from looking at the code, this seems to be the slug).

However whatever I do I get a 404.

Any advice appreciated!

Delete behaviour

fields.json (for text fields) will be refreshed as long as all fields are not removed. Happy with this for now.

However, files for richText fields won't be deleted automatically once they are removed from Payload CMS. This could cause a situation where old translations are left in CrowdIn, and this could get worse over time.

Add integration tests

From the README:

Notes on the current test suite

Integration tests are not ideal: they break a lot of best practice when writing tests. However, they are effective, and this is the reason they are included.

They use the Payload CMS REST API to perform operations on the test server.

The advantages of this approach are that the setup is as similar as possible to production. The test server runs with almost exactly the same configuration as production.

However, there are many disadvantages. Tests should be refactored. The reason for not doing this so far is that it has been difficult to set up preferred alternatives - I experienced a lot of complaints from Babel, Payload, TypeScript, Jest. In particular, the get-port dependency from Payload CMS caused a lot of issues because it uses a require import. This occured when trying to initiate Payload for tests directly. Having said that, Payload CMS tests run fine so maybe further work is needed to emulate that test setup.

Integration tests do not tear down data. This is an unfortunate side effect of running a seperate test server. However, the benefit is that the databse can be inspected after the test is run. Manually deleting the policies, crowdin-files, crowdin-article-directories and crowdin-collection-directories folders is possible, and Payload CMS will recreate those collections once the tests are re-run.

CrowdIn API responses are mocked. Configuration in server.ts detects when this test database is running and provides a mock CrowdIn API service that returns sample data. This is another unfortunate side effect of the test setup - best practice dictates that API responses should never be mocked. See notes on this approach below.

Preferred alternatives:

  • Set up integration tasks in a similar way to payloadcms/payload | GitHub, which uses specific configs and init functions to start Payload within tests and be able to access the payload object within them.
  • Use services/dependency injection in a similar way to how its achieved in finkinfridom/payload-cloudinary-plugin | GitHub in order to write tests on hooks/functions directly and mock any API calls/libraries as needed.

Textarea support needed to support payloadcms/plugin-seo

https://github.com/payloadcms/plugin-seo adds localized: true to SEO collection/global fields as expected.

e.g. for a collection with localized fields, the following is included in the fields array:

{
    "name": "meta",
    "label": "SEO",
    "type": "group",
    "fields": [
      {
        "name": "overview",
        "label": "Overview",
        "type": "ui",
        "admin": {
          "components": {}
        }
      },
      {
        "name": "title",
        "type": "text",
        "localized": true,
        "admin": {
          "components": {}
        }
      },
      {
        "name": "description",
        "type": "textarea",
        "localized": true,
        "admin": {
          "components": {}
        }
      },
      {
        "name": "preview",
        "label": "Preview",
        "type": "ui",
        "admin": {
          "components": {}
        }
      }
    ]
  }

At present, textarea is not a supported field. As a result, getLocalizedFields won't pick this up:

{
    "name": "meta",
    "label": "SEO",
    "type": "group",
    "fields": [
      {
        "name": "title",
        "type": "text",
        "localized": true,
        "admin": {
          "components": {}
        }
      }
    ]
  }

Add textarea support. It should be added anyway, but this is prioritized in order to support SEO fields.

Invalid json file possible

A createFile error can occur and cause problems in the following scenario:

It is caused by localized fields being detected in a group - but they are all empty.

{
  "meta": {}
}

Invalid directory id given. Directory doesn't exists

This error appears fairly frequently. It seems that some entities do not get a crowdin article directory associated with them. There are many scenarios that can cause this situation. e.g.:

  • articles are created when the plugin is disabled (e.g. locally)
  • there's an error when creating an article that prevents afterChange from running?
  • article directory is deleted as part of the plugin logic.

TDD this bug out!



[2023-10-12T14:45:38] | (payload): Error: Invalid directory id given. Directory doesn't exists
-- | --
[2023-10-12T14:45:38] | at handleHttpClientError (/workspace/node_modules/@crowdin/crowdin-api-client/out/core/index.js:67:15)
[2023-10-12T14:45:38] | at /workspace/node_modules/@crowdin/crowdin-api-client/out/core/index.js:235:29
[2023-10-12T14:45:38] | at runMicrotasks (<anonymous>)
[2023-10-12T14:45:38] | at processTicksAndRejections (node:internal/process/task_queues:96:5)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.