lokalise / shared-ts-libs

Shared TypeScript libraries
Apache License 2.0
2 stars 1 forks source link

Buffer is not available in the browser #59

Open oskarski opened 7 months ago

oskarski commented 7 months ago

The decodeCursor() may be invoked within the browser and it fails, since the Buffer is not available. I've stumbled upon this issue, while passing schema for request query params based on GET_CONTENT_MANAGER_PAGINATION_SCHEMA

sendGet(authorizedApiClient(token), {
        path: `...`,
        queryParams: query,
        responseBodySchema: GET_CONTENT_MANAGER_RESPONSE_SCHEMA,
                queryParamsSchema: GET_CONTENT_MANAGER_QUERY_SCHEMA, // <- This is based on `GET_CONTENT_MANAGER_PAGINATION_SCHEMA` and fails before request is being sent  
    })

Buffer usage: https://github.com/lokalise/shared-ts-libs/blob/db67b57b5b370b9fac397cc0972101da27807b25/packages/app/api-common/src/cursorCodec.ts#L21C19-L21C25

Error screenshot from browser:

image
kibertoad commented 7 months ago

@oskarski ~Should we replace buffer usage with base64 encoding, maybe?~ we are already using it for base64 encoding 😂

kibertoad commented 7 months ago

Would something like this work? (this is a refined version of a ChatGPT proposal)

function toBase64UrlWithReplaceAll(object) {
  // Convert the object to a JSON string
  const jsonString = JSON.stringify(object);

  // Encode the JSON string into an Uint8Array using TextEncoder
  const encoder = new TextEncoder();
  const encodedData = encoder.encode(jsonString);

  // Convert the Uint8Array to a base64 string
  const base64 = btoa(String.fromCharCode.apply(null, encodedData));

  // Convert base64 to base64url by replacing '+' with '-' and '/' with '_'
  let base64url = base64.replaceAll('+', '-').replaceAll('/', '_');

  // Remove any '=' padding
  base64url = base64url.replaceAll('=', '');

  return base64url;
}

// Example usage
const object = { hello: 'world' };
const base64url = toBase64UrlWithReplaceAll(object);
console.log(base64url);
oskarski commented 7 months ago

Hmm, and can't it be simplified to something like this?

const encodeToBase64 = (data: any): string => btoa(JSON.stringify(data))

const decodeFromBase64 = <T = unknown>(encodedData: string): T => JSON.parse(atob(encodedData))
kibertoad commented 7 months ago

@oskarski Would that provide sufficient amount of escaping?

oskarski commented 7 months ago

I haven't used much these functions, but as far as I know it should be enough. Also proper tests should catch and cover escaping edge cases