Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating a singleton instance of Contentful #5

Merged
merged 10 commits into from
Feb 15, 2024

Conversation

bounteous17
Copy link
Contributor

Description

  • Being able to instance a client and retrieve content from Contentful
  • Next PR would implement a generic output format after parsing CMS retrieved data no matter which provider is (Contentful, Strapim etc ...)

Related Issue

Motivation and Context

How Has This Been Tested?

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Copy link

socket-security bot commented Feb 14, 2024

👍 Dependency issues cleared. Learn more about Socket for GitHub ↗︎

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

Ignoring: npm/[email protected], npm/[email protected]

View full report↗︎

Next steps

Take a deeper look at the dependency

Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support [AT] socket [DOT] dev.

Remove the package

If you happen to install a dependency that Socket reports as Known Malware you should immediately remove it and select a different dependency. For other alert types, you may may wish to investigate alternative packages or consider if there are other ways to mitigate the specific risk posed by the dependency.

Mark a package as acceptable risk

To ignore an alert, reply with a comment starting with @SocketSecurity ignore followed by a space separated list of ecosystem/package-name@version specifiers. e.g. @SocketSecurity ignore npm/[email protected] or ignore all packages with @SocketSecurity ignore-all

Copy link
Member

@matyasjay matyasjay left a comment

Choose a reason for hiding this comment

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

Looks good to me so far! One thing I would add is the type infers from generics instead explicit any.

I'm thinking of something like:

 public async getEntry<T = Record<string, unknown>>(entryId: string) {
    return await this.getEntryHarmonized<T>(
      () => this.getClientInstance().getEntry<T>(entryId),
      // The following might not even needed if we can infer `T` from the return type
      ({ fields }: { fields: T }) => ({ data: fields }),
    );
  }

This requires typed client instances. The above example is a high level abstraction of what actually needed here. For now, I'd say we can merge this as is.

Copy link
Contributor

@inigomarquinez inigomarquinez left a comment

Choose a reason for hiding this comment

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

I really like your approach, @bounteous17

I've just added a small suggestion about the tests, but we can do it in a future PR if you want.

__tests__/e2e/cms/contentful.test.ts Show resolved Hide resolved
@inigomarquinez
Copy link
Contributor

@UlisesGascon , perhaps your feedback is useful here related to the alerts reported by socket.dev related to some dependencies running post-install scripts.

@UlisesGascon UlisesGascon self-requested a review February 14, 2024 12:25
@UlisesGascon
Copy link
Collaborator

@UlisesGascon , perhaps your feedback is useful here related to the alerts reported by socket.dev related to some dependencies running post-install scripts.

I reviewed the comment from the socket.dev bot, and here are my fast conclusions on the topic:

Regarding [email protected]

Seems like [email protected] is using the postinstall script to run patch-package@^8.0.0:

{
   "postinstall": "patch-package",
}

Seems like this might not be necessary to run as it will only solve broken dependencies:

patch-package lets app authors instantly make and keep fixes to npm dependencies. It's a vital band-aid for those of us living on the bleeding edge. patch-package

Resources

Regarding [email protected]

Seems like [email protected] is using the postinstall script to run a [js file].

{
  "postinstall": "node postinstall"
}
File Content

The file published can be found at npm, see as /spawn-sync/postinstall.js. Please don't use Github to source the file as it might defer from the final code published.

'use strict';

function onError(err) {
try {
  var str = '' + (err ? (err.stack || err.message || err) : 'null');
  require('fs').writeFileSync(__dirname + '/error.log', str);
} catch (ex) {
}
}
try {
var fs = require('fs');
var cp = require('child_process');
var REQUIRES_UPDATE = false;
var pkg = JSON.parse(fs.readFileSync(__dirname + '/package.json', 'utf8'));
if (cp.spawnSync || __dirname.indexOf('node_modules') === -1) {
  if(pkg.dependencies['try-thread-sleep']){
    delete pkg.dependencies['try-thread-sleep'];
    REQUIRES_UPDATE = true;
  }
} else {
  if(!pkg.dependencies['try-thread-sleep']){
    pkg.dependencies['try-thread-sleep'] = "^1.0.0";
    REQUIRES_UPDATE = true;
    console.log('Installing native dependencies (this may take up to a minute)');
  }
}
if (REQUIRES_UPDATE && __dirname.indexOf('node_modules') !== -1) {
  fs.writeFileSync(__dirname + '/package.json', JSON.stringify(pkg, null, '  '));
  cp.exec((process.env.npm_execpath ? ('"' + process.argv[0] + '" "' + process.env.npm_execpath + '"') : 'npm') +
          ' install --production', {
    cwd: __dirname
  }, function (err) {
    if (err) onError(err);
    process.exit(0);
  });
  setTimeout(function () {
    process.exit(0);
  }, 60000);
}
} catch (ex) {
onError(ex);
}

This script seems to be a workaround for environments where child_process.spawnSync is not available. It adds or removes the try-thread-sleep dependency based on the environment and updates the dependencies accordingly. This was introduced as subdependency by [email protected]

/agnostic-cms-harmonizer
└─┬ [email protected]
  └─┬ [email protected]
    └─┬ [email protected]
      └─┬ [email protected]
        └── [email protected]

Based on the official documentation. child_process.spawnSync was added to Node in v0.11.12 (10y ago). As this is a fallback the execution is not require.

Resources

Conclusion

Overall, both postscripts does not seem malicious or with known vulnerabilities (AFIK), but I will suggest to install them using --ignore-scripts flag in npm. But as this is a library that will be distributed, I am not sure if the end users will take care of this or not.

Copy link
Collaborator

@UlisesGascon UlisesGascon left a comment

Choose a reason for hiding this comment

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

I only reviewed the dependencies and I left a comment with my analysis.

@UlisesGascon
Copy link
Collaborator

@SocketSecurity ignore npm/[email protected]
@SocketSecurity ignore npm/[email protected]

Copy link
Collaborator

@UlisesGascon UlisesGascon left a comment

Choose a reason for hiding this comment

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

Not sure why, but I just realized that the package-lock.json is different on my machine.

Steps to reproduce:

  • (Optional) delete the node_modules
  • nvm use. In my case node v20.11.0 (npm v10.2.4)
  • npm i

And here is the discrepancy:
Screenshot 2024-02-14 at 14 11 26

@inigomarquinez
Copy link
Contributor

Conclusion

Overall, both postscripts does not seem malicious or with known vulnerabilities (AFIK), but I will suggest to install them using --ignore-scripts flag in npm. But as this is a library that will be distributed, I am not sure if the end users will take care of this or not.

Thank you so much @UlisesGascon !

@matyasjay
Copy link
Member

Conclusion

Overall, both postscripts does not seem malicious or with known vulnerabilities (AFIK), but I will suggest to install them using --ignore-scripts flag in npm. But as this is a library that will be distributed, I am not sure if the end users will take care of this or not.

Hi @UlisesGascon, thanks for your time and valuable info! One thing here: --ignore-scripts might be not optimal but as I mentioned to @inigomarquinez internally, running CI with --no-optional flag would be sufficient to ignore the dependency since contentful-cli defined as optional.

@matyasjay
Copy link
Member

matyasjay commented Feb 14, 2024

Not sure why, but I just realized that the package-lock.json is different on my machine.

Steps to reproduce:

  • (Optional) delete the node_modules
  • nvm use. In my case node v20.11.0 (npm v10.2.4)
  • npm i

And here is the discrepancy: Screenshot 2024-02-14 at 14 11 26

This is the result of you are running raw npm i. However in CI, optional deps should be ignored hence no contentful-cli in the lock file. You can repro by running the install with --no-optional flag. Not sure how to resolve this tho.
Probably the best to explicitly flag, that it is the user's responsibility to have the CLI installed instead having it listed.

@bounteous17
Copy link
Contributor Author

Looks good to me so far! One thing I would add is the type infers from generics instead explicit any.

I'm thinking of something like:

 public async getEntry<T = Record<string, unknown>>(entryId: string) {
    return await this.getEntryHarmonized<T>(
      () => this.getClientInstance().getEntry<T>(entryId),
      // The following might not even needed if we can infer `T` from the return type
      ({ fields }: { fields: T }) => ({ data: fields }),
    );
  }

This requires typed client instances. The above example is a high level abstraction of what actually needed here. For now, I'd say we can merge this as is.

@matyasjay @inigomarquinez we would implement the abstract type for the different providers instance on another PR. For the moment let's leave it as an any

@bounteous17
Copy link
Contributor Author

Not sure why, but I just realized that the package-lock.json is different on my machine.

Steps to reproduce:

  • (Optional) delete the node_modules
  • nvm use. In my case node v20.11.0 (npm v10.2.4)
  • npm i

And here is the discrepancy: Screenshot 2024-02-14 at 14 11 26

@UlisesGascon At the beginning contentful-cli was part of the dependencies until I realized that it should be part of optionalDependencies, that's the fix: 1cf9820

@bounteous17 bounteous17 merged commit 12159d0 into main Feb 15, 2024
2 checks passed
@bounteous17 bounteous17 deleted the CROS-48-create-a-singleton-instance branch February 15, 2024 08:21
@inigomarquinez
Copy link
Contributor

@all-contributors please add @bounteous17 for code,test,doc
@all-contributors please add @matyasjay for review
@all-contributors please add @UlisesGascon for review

@inigomarquinez
Copy link
Contributor

@all-contributors please add @UlisesGascon for review

Copy link
Contributor

@inigomarquinez

This project's configuration file has malformed JSON: .all-contributorsrc. Error:: Unexpected token ] in JSON at position 940

@inigomarquinez
Copy link
Contributor

@all-contributors please add @UlisesGascon for review

Copy link
Contributor

@inigomarquinez

I've put up a pull request to add @UlisesGascon! 🎉

Copy link
Contributor

@inigomarquinez

I've put up a pull request to add @bounteous17! 🎉

I've put up a pull request to add @matyasjay! 🎉

We had trouble processing your request. Please try again later.

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.

4 participants