webflow / js-webflow-api

Node.js SDK for the Webflow Data API
https://www.npmjs.com/package/webflow-api
286 stars 93 forks source link

Allow CORS mode to be optional #60

Closed jakemwood closed 1 year ago

jakemwood commented 1 year ago

Hello! We are trying to use the Webflow API with Cloudflare Workers. Unfortunately, their fetch API does not allow the usage of cors mode. This seems to make sense, since there shouldn't be any cross-origin issues in a Node.JS environment, as there is no origin. However, I have added an optional parameter to the Webflow constructor (useCors) to ask if the user would like to use CORS or not. It defaults to true to make this a non-breaking change. I've also updated the TypeScript definition to match.

johnagan commented 1 year ago

Thanks @jakemwood! I'm aligned with getting a fix for you. Made a suggestion on approach - let me know your thoughts.

johnagan commented 1 year ago

You're welcome to pushback on this, but my recommendation is to make a PR to override fetch options rather than focusing on disabling cors.

Client Code

so I'd imagine something like this:

const options = {
  mode: undefined,   // this is your use-case, but likely an edge case
  headers: {
    "User-Agent": "My Awesome Webflow App"    // a more likely use-case for this feature
  }
};

const webflow = new Webflow({ token: 'api-token', options });

Changes to SDK

Possibly add something like this to line 55.

constructor({ endpoint = DEFAULT_ENDPOINT, token, version = "1.0.0", options = {} } = {}) {
  if (!token) throw buildRequiredArgError("token");

  this.responseWrapper = new ResponseWrapper(this);

  this.endpoint = endpoint;
  this.token = token;

   // Enable header overrides
  this.headers = Object.assign({
    Accept: "application/json",
    Authorization: `Bearer ${token}`,
    "accept-version": version,
    "Content-Type": "application/json"
  }, options.headers);

  this.authenticatedFetch = (method, path, data, query) => {
    const queryString =
      query && !isObjectEmpty(query) ? `?${qs.stringify(query)}` : "";

    const uri = `${this.endpoint}${path}${queryString}`;
    const opts = {
      method,
      mode: "cors",
      ...options,
      headers, // set headers after blanket override
    };

    if (data) {
      opts.body = JSON.stringify(data);
    }

    return fetch(uri, opts).then(responseHandler);
  };
}

I'm winging it on coding in comments here, but let me know what you think about this approach!