Skip to content

Commit

Permalink
🐛 Fix base64 encoding in browser
Browse files Browse the repository at this point in the history
  • Loading branch information
NatoBoram committed Sep 18, 2024
1 parent c462822 commit 22e3c8e
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 30 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ pnpm i @coderabbitai/bitbucket
### Cloud

```ts
import { createBitbucketCloudClient } from "@coderabbitai/bitbucket"
import { createBitbucketCloudClient, toBase64 } from "@coderabbitai/bitbucket"
import {
BITBUCKET_CLOUD_APP_PASSWORD,
BITBUCKET_CLOUD_URL,
BITBUCKET_CLOUD_USERNAME,
} from "./env.js"

const basic = Buffer.from(
const basic = toBase64(
BITBUCKET_CLOUD_USERNAME + ":" + BITBUCKET_CLOUD_APP_PASSWORD,
).toString("base64")
)

export const cloud = createBitbucketCloudClient({
baseUrl: BITBUCKET_CLOUD_URL,
export const client = createBitbucketCloudClient({
baseUrl: BITBUCKET_CLOUD_URL.toString(),
headers: { Accept: "application/json", Authorization: `Basic ${basic}` },
})
```
Expand Down
12 changes: 12 additions & 0 deletions src/base64.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { test } from "vitest"
import { fromBase64, toBase64 } from "./base64.js"

test("toBase64", ({ expect }) => {
const based = toBase64("Copyright © 2024 CodeRabbit")
expect(based).toBe("Q29weXJpZ2h0IMKpIDIwMjQgQ29kZVJhYmJpdA==")
})

test("fromBase64", ({ expect }) => {
const debased = fromBase64("Q29weXJpZ2h0IMKpIDIwMjQgQ29kZVJhYmJpdA==")
expect(debased).toBe("Copyright © 2024 CodeRabbit")
})
11 changes: 11 additions & 0 deletions src/base64.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export function toBase64(input: string): string {
const bytes = new TextEncoder().encode(input)
const string = String.fromCodePoint(...bytes)
return btoa(string)
}

export function fromBase64(base64: string): Buffer | Uint8Array | string {
const string = atob(base64)
const bytes = Uint8Array.from(string, v => v.codePointAt(0) ?? 0)
return new TextDecoder().decode(bytes)
}
12 changes: 11 additions & 1 deletion src/cloud/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import createClient, { type Client, type ClientOptions } from "openapi-fetch"
import type { Client, ClientOptions } from "openapi-fetch"
import createClient from "openapi-fetch"
import type { paths } from "./openapi/index.js"

/**
* Creates an `openapi-fetch` client using {@link createClient}.
*
* @example
* export client = createBitbucketCloudClient({
* baseUrl: "https://api.bitbucket.org/2.0",
* headers: { Accept: "application/json", Authorization: `Basic ${basic}` },
* })
*/
export const createBitbucketCloudClient: (
clientOptions?: ClientOptions,
) => Client<paths, "application/json"> = createClient<paths, "application/json">
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./base64.js"
export * from "./cloud/index.js"
export * from "./server/index.js"
12 changes: 12 additions & 0 deletions src/server/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@ import type { Client, ClientOptions } from "openapi-fetch"
import createClient from "openapi-fetch"
import type { paths } from "./openapi/index.js"

/**
* Creates an `openapi-fetch` client using {@link createClient}.
*
* @example
* export const client = createBitbucketServerClient({
* baseUrl: "https://example.org/rest",
* headers: {
* Accept: "application/json",
* Authorization: `Bearer ${BITBUCKET_SERVER_TOKEN}`,
* },
* })
*/
export const createBitbucketServerClient: (
clientOptions?: ClientOptions,
) => Client<paths, "application/json"> = createClient<paths, "application/json">
17 changes: 7 additions & 10 deletions tests/cloud/client.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import type { Client } from "openapi-fetch"
import type { paths } from "../../src/cloud/openapi/openapi-typescript.js"
import { createBitbucketCloudClient } from "../../src/index.js"
import { createBitbucketCloudClient, toBase64 } from "../../src/index.js"
import {
BITBUCKET_CLOUD_APP_PASSWORD,
BITBUCKET_CLOUD_URL,
BITBUCKET_CLOUD_USERNAME,
} from "../env.js"

const basic = Buffer.from(
const basic = toBase64(
BITBUCKET_CLOUD_USERNAME + ":" + BITBUCKET_CLOUD_APP_PASSWORD,
).toString("base64")
)

export const cloud: Client<paths, "application/json"> =
createBitbucketCloudClient({
baseUrl: BITBUCKET_CLOUD_URL,
headers: { Accept: "application/json", Authorization: `Basic ${basic}` },
})
export const cloud = createBitbucketCloudClient({
baseUrl: BITBUCKET_CLOUD_URL.toString(),
headers: { Accept: "application/json", Authorization: `Basic ${basic}` },
})
15 changes: 11 additions & 4 deletions tests/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ function envString(key: string) {
return value
}

function envUrl(key: string) {
const str = envString(key)
try {
return new URL(str)
} catch (error) {
throw new Error(`$${key} is not a URL: ${str}`, { cause: error })
}
}

export function isNodeEnv(value: unknown): value is NodeEnv {
return Object.values<unknown>(nodeEnvs).includes(value)
}
Expand Down Expand Up @@ -72,12 +81,10 @@ const nodeEnvs = {
test: "test",
} as const
const parsed = loadEnv()

export const BITBUCKET_CLOUD_URL = envString("BITBUCKET_CLOUD_URL")
export const BITBUCKET_CLOUD_URL = envUrl("BITBUCKET_CLOUD_URL")
export const BITBUCKET_CLOUD_USERNAME = envString("BITBUCKET_CLOUD_USERNAME")
export const BITBUCKET_CLOUD_APP_PASSWORD = envString(
"BITBUCKET_CLOUD_APP_PASSWORD",
)

export const BITBUCKET_SERVER_URL = envString("BITBUCKET_SERVER_URL")
export const BITBUCKET_SERVER_URL = envUrl("BITBUCKET_SERVER_URL")
export const BITBUCKET_SERVER_TOKEN = envString("BITBUCKET_SERVER_TOKEN")
17 changes: 7 additions & 10 deletions tests/server/client.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import type { Client } from "openapi-fetch"
import { createBitbucketServerClient } from "../../src/index.js"
import type { paths } from "../../src/server/openapi/openapi-typescript.js"
import { BITBUCKET_SERVER_TOKEN, BITBUCKET_SERVER_URL } from "../env.js"

export const server: Client<paths, "application/json"> =
createBitbucketServerClient({
baseUrl: BITBUCKET_SERVER_URL,
headers: {
Accept: "application/json",
Authorization: `Bearer ${BITBUCKET_SERVER_TOKEN}`,
},
})
export const server = createBitbucketServerClient({
baseUrl: BITBUCKET_SERVER_URL.toString(),
headers: {
Accept: "application/json",
Authorization: `Bearer ${BITBUCKET_SERVER_TOKEN}`,
},
})

0 comments on commit 22e3c8e

Please # to comment.