Skip to content

Commit

Permalink
feat: add client internal query params (#349)
Browse files Browse the repository at this point in the history
* feat: add client internal headers

* refactor: use query params instead of headers

* test: remove unused tsdocs

* Revert "test: remove unused tsdocs"

This reverts commit d2cf531.

* refactor: inject query parameters directly

* Update test/buildQueryURL.test.ts

Co-authored-by: Angelo Ashmore <[email protected]>

* Update test/client-buildQueryURL.test.ts

Co-authored-by: Angelo Ashmore <[email protected]>

---------

Co-authored-by: lihbr <[email protected]>
Co-authored-by: Angelo Ashmore <[email protected]>
  • Loading branch information
3 people authored Sep 17, 2024
1 parent 601edd5 commit 938d711
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 16 deletions.
19 changes: 19 additions & 0 deletions src/buildQueryURL.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
import { castArray } from "./lib/castArray"
import { devMsg } from "./lib/devMsg"

import { version } from "../package.json"

/**
* The query parameter used to indicate if the client is in development mode to
* the API.
*/
const PRISMIC_DEV_PARAM = "x-d"

/**
* The query parameter used to indicate the version of the client to the API.
*/
const PRISMIC_CLIENT_VERSION_PARAM = "x-c"

/**
* Create a union of the given object's values, and optionally specify which
* keys to get the values from.
Expand Down Expand Up @@ -374,5 +387,11 @@ export const buildQueryURL = (
}
}

url.searchParams.set(PRISMIC_CLIENT_VERSION_PARAM, `js-${version}`)

if (process.env.NODE_ENV === "development") {
url.searchParams.set(PRISMIC_DEV_PARAM, "1")
}

return url.toString()
}
55 changes: 39 additions & 16 deletions test/buildQueryURL.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { expect, it, vi } from "vitest"

import { version } from "../package.json"

import * as prismic from "../src"

const endpoint = prismic.getRepositoryEndpoint("qwerty")
const xClientVersionParam = `&x-c=js-${version}`

it("includes ref", () => {
expect(prismic.buildQueryURL(endpoint, { ref: "ref" })).toBe(
"https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref",
`https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref${xClientVersionParam}`,
)
})

Expand All @@ -19,7 +22,7 @@ it("supports single filter", () => {
}),
),
).toBe(
"https://qwerty.cdn.prismic.io/api/v2/documents/search?q=[[has(my.document.title)]]&ref=ref",
`https://qwerty.cdn.prismic.io/api/v2/documents/search?q=[[has(my.document.title)]]&ref=ref${xClientVersionParam}`,
)

// TODO: Remove when we remove support for deprecated `predicates` argument.
Expand All @@ -31,7 +34,7 @@ it("supports single filter", () => {
}),
),
).toBe(
"https://qwerty.cdn.prismic.io/api/v2/documents/search?q=[[has(my.document.title)]]&ref=ref",
`https://qwerty.cdn.prismic.io/api/v2/documents/search?q=[[has(my.document.title)]]&ref=ref${xClientVersionParam}`,
)
})

Expand All @@ -47,7 +50,7 @@ it("supports multiple filters", () => {
}),
),
).toBe(
"https://qwerty.cdn.prismic.io/api/v2/documents/search?q=[[has(my.document.title)]]&q=[[has(my.document.subtitle)]]&ref=ref",
`https://qwerty.cdn.prismic.io/api/v2/documents/search?q=[[has(my.document.title)]]&q=[[has(my.document.subtitle)]]&ref=ref${xClientVersionParam}`,
)

// TODO: Remove when we remove support for deprecated `predicates` argument.
Expand All @@ -62,7 +65,7 @@ it("supports multiple filters", () => {
}),
),
).toBe(
"https://qwerty.cdn.prismic.io/api/v2/documents/search?q=[[has(my.document.title)]]&q=[[has(my.document.subtitle)]]&ref=ref",
`https://qwerty.cdn.prismic.io/api/v2/documents/search?q=[[has(my.document.title)]]&q=[[has(my.document.subtitle)]]&ref=ref${xClientVersionParam}`,
)
})

Expand All @@ -85,7 +88,7 @@ it("supports params", () => {
}),
),
).toBe(
"https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&access_token=accessToken&pageSize=1&page=1&after=after&fetch=fetch&fetchLinks=fetchLinks&graphQuery=graphQuery&lang=lang&orderings=[orderings]&routes=routes&brokenRoute=brokenRoute",
`https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&access_token=accessToken&pageSize=1&page=1&after=after&fetch=fetch&fetchLinks=fetchLinks&graphQuery=graphQuery&lang=lang&orderings=[orderings]&routes=routes&brokenRoute=brokenRoute${xClientVersionParam}`,
)
})

Expand All @@ -105,7 +108,9 @@ it("ignores nullish params", () => {
orderings: undefined,
}),
),
).toBe("https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref")
).toBe(
`https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref${xClientVersionParam}`,
)
})

it("supports array fetch param", () => {
Expand All @@ -117,7 +122,7 @@ it("supports array fetch param", () => {
}),
),
).toBe(
"https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&fetch=title,subtitle",
`https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&fetch=title,subtitle${xClientVersionParam}`,
)
})

Expand All @@ -130,7 +135,7 @@ it("supports array fetchLinks param", () => {
}),
),
).toBe(
"https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&fetchLinks=page.link,page.second_link",
`https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&fetchLinks=page.link,page.second_link${xClientVersionParam}`,
)
})

Expand All @@ -144,7 +149,7 @@ it("supports empty orderings param", () => {
}),
),
).toBe(
"https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&orderings=[]",
`https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&orderings=[]${xClientVersionParam}`,
)

expect(
Expand All @@ -155,7 +160,7 @@ it("supports empty orderings param", () => {
}),
),
).toBe(
"https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&orderings=[]",
`https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&orderings=[]${xClientVersionParam}`,
)
})

Expand All @@ -169,7 +174,7 @@ it("supports array orderings param", () => {
}),
),
).toBe(
"https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&orderings=[page.title,page.subtitle]",
`https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&orderings=[page.title,page.subtitle]${xClientVersionParam}`,
)
})

Expand All @@ -183,7 +188,7 @@ it("supports setting direction of ordering param", () => {
}),
),
).toBe(
"https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&orderings=[page.title,page.subtitle]",
`https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&orderings=[page.title,page.subtitle]${xClientVersionParam}`,
)

expect(
Expand All @@ -198,7 +203,7 @@ it("supports setting direction of ordering param", () => {
}),
),
).toBe(
"https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&orderings=[page.title+desc,page.subtitle+desc]",
`https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&orderings=[page.title+desc,page.subtitle+desc]${xClientVersionParam}`,
)
})

Expand All @@ -219,7 +224,7 @@ it("supports single item routes param", () => {
).toBe(
`https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&routes=[${JSON.stringify(
route,
)}]`,
)}]${xClientVersionParam}`,
)
})

Expand Down Expand Up @@ -247,10 +252,28 @@ it("supports array routes param", () => {
).toBe(
`https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref&routes=${JSON.stringify(
routes,
)}`,
)}${xClientVersionParam}`,
)
})

it("forwards `x-c` param in production", () => {
expect(prismic.buildQueryURL(endpoint, { ref: "ref" })).toBe(
`https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref${xClientVersionParam}`,
)
})

it("forwards `x-c` and `x-d` param in development", () => {
const originalEnv = { ...process.env }

process.env.NODE_ENV = "development"

expect(prismic.buildQueryURL(endpoint, { ref: "ref" })).toBe(
`https://qwerty.cdn.prismic.io/api/v2/documents/search?ref=ref${xClientVersionParam}&x-d=1`,
)

process.env = originalEnv
})

it("warns if NODE_ENV is development and a string is provided to `orderings`", () => {
const originalEnv = { ...process.env }

Expand Down
23 changes: 23 additions & 0 deletions test/client-buildQueryURL.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ import { createTestClient } from "./__testutils__/createClient"
import { getMasterRef } from "./__testutils__/getMasterRef"
import { mockPrismicRestAPIV2 } from "./__testutils__/mockPrismicRestAPIV2"

import { version } from "../package.json"

import type * as prismic from "../src"

const xClientVersion = `js-${version}`

it("builds a query URL using the master ref", async (ctx) => {
const repositoryResponse = ctx.mock.api.repository()
const ref = getMasterRef(repositoryResponse)
Expand All @@ -21,6 +25,7 @@ it("builds a query URL using the master ref", async (ctx) => {

const expectedSearchParams = new URLSearchParams({
ref,
"x-c": xClientVersion,
})
url.searchParams.delete("integrationFieldsRef")
url.searchParams.sort()
Expand All @@ -31,6 +36,21 @@ it("builds a query URL using the master ref", async (ctx) => {
expect(url.searchParams.toString()).toBe(expectedSearchParams.toString())
})

it("includes the `x-d` param in development", async (ctx) => {
const originalEnv = { ...process.env }
process.env.NODE_ENV = "development"

mockPrismicRestAPIV2({ ctx })

const client = createTestClient()
const res = await client.buildQueryURL()
const url = new URL(res)

expect(url.searchParams.get("x-d")).toBe("1")

process.env = originalEnv
})

it("includes params if provided", async (ctx) => {
const params: prismic.BuildQueryURLArgs = {
accessToken: "custom-accessToken",
Expand All @@ -49,6 +69,7 @@ it("includes params if provided", async (ctx) => {
lang: params.lang?.toString() ?? "",
// TODO: Remove when Authorization header support works in browsers with CORS.
access_token: params.accessToken ?? "",
"x-c": xClientVersion,
})

url.searchParams.delete("integrationFieldsRef")
Expand Down Expand Up @@ -78,6 +99,7 @@ it("includes default params if provided", async (ctx) => {
lang: clientConfig.defaultParams?.lang?.toString() ?? "",
// TODO: Remove when Authorization header support works in browsers with CORS.
access_token: clientConfig.accessToken ?? "",
"x-c": xClientVersion,
})

url.searchParams.delete("integrationFieldsRef")
Expand Down Expand Up @@ -111,6 +133,7 @@ it("merges params and default params if provided", async (ctx) => {
page: clientConfig.defaultParams?.page?.toString() ?? "",
// TODO: Remove when Authorization header support works in browsers with CORS.
access_token: clientConfig.accessToken ?? "",
"x-c": xClientVersion,
})

url.searchParams.delete("integrationFieldsRef")
Expand Down

0 comments on commit 938d711

Please sign in to comment.