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

feat: support providing a repository name to createClient() in place of an API endpoint #224

Merged
merged 2 commits into from
Feb 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ The official JavaScript + TypeScript client library for [Prismic][prismic].
import * as prismic from "@prismicio/client";

// Create a client
const endpoint = prismic.getRepositoryEndpoint("my-repository");
const client = prismic.createClient(endpoint);
const client = prismic.createClient("my-repository");

// Then query for your content
const blogPosts = await client.getAllByType("blog_post");
Expand Down
3 changes: 1 addition & 2 deletions examples/custom-caching/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ import * as prismic from "@prismicio/client";
import fetch from "node-fetch";
import QuickLRU from "quick-lru";

const endpoint = prismic.getRepositoryEndpoint("qwerty");
const cache = new QuickLRU({
maxSize: 1000, // 1000 entries
});

const client = prismic.createClient(endpoint, {
const client = prismic.createClient("qwerty", {
fetch: async (url, options) => {
// The cache key contains the requested URL and headers
const key = JSON.stringify({ url, options });
Expand Down
4 changes: 1 addition & 3 deletions examples/custom-timeout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ import fetch, { AbortError } from "node-fetch";
// version >=14.17.0, or are not in a node environment, remove this line.
import { AbortController } from "abort-controller";

const endpoint = prismic.getRepositoryEndpoint("qwerty");

// A global timeout can be implemented like the following. This timeout will
// apply to all network requests made by the client.
const client = prismic.createClient(endpoint, {
const client = prismic.createClient("qwerty", {
fetch: async (url, options) => {
// Create an AbortController. This will be used to cancel the
// `fetch()` request if it does not resolve within the given
Expand Down
3 changes: 1 addition & 2 deletions examples/multiple-languages/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import * as prismic from "@prismicio/client";
import fetch from "node-fetch";

const endpoint = prismic.getRepositoryEndpoint("qwerty");
const client = prismic.createClient(endpoint, {
const client = prismic.createClient("qwerty", {
fetch,
// A default language can be set here. If a `lang` option is not set, your
// repository's default language will be used.
Expand Down
3 changes: 1 addition & 2 deletions examples/releases/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import * as prismic from "@prismicio/client";
import fetch from "node-fetch";

const endpoint = prismic.getRepositoryEndpoint("qwerty");
const client = prismic.createClient(endpoint, {
const client = prismic.createClient("qwerty", {
fetch,
});

Expand Down
3 changes: 1 addition & 2 deletions examples/server-usage/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import * as prismic from "@prismicio/client";
import fetch from "node-fetch";

const endpoint = prismic.getRepositoryEndpoint("qwerty");
const client = prismic.createClient(endpoint, {
const client = prismic.createClient("qwerty", {
// Here, we provide a way for the client to make network requests.
// `node-fetch` is a Node.js fetch-compatible package.
fetch,
Expand Down
3 changes: 1 addition & 2 deletions examples/using-refs/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import * as prismic from "@prismicio/client";
import fetch from "node-fetch";

const endpoint = prismic.getRepositoryEndpoint("qwerty");
const client = prismic.createClient(endpoint, {
const client = prismic.createClient("qwerty", {
fetch,
});

Expand Down
3 changes: 1 addition & 2 deletions examples/with-express/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ import fetch from "node-fetch";
import express from "express";
import QuickLRU from "quick-lru";

const endpoint = prismic.getRepositoryEndpoint("qwerty");
const cache = new QuickLRU({
maxSize: 1000, // 1000 entries
});

const client = prismic.createClient(endpoint, {
const client = prismic.createClient("qwerty", {
fetch: async (url, options) => {
// The cache key contains the requested URL and headers
const key = JSON.stringify({ url, options });
Expand Down
3 changes: 1 addition & 2 deletions examples/with-typescript/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ type PrismicDocumentBlogPost = prismicT.PrismicDocument<
>;

const main = async () => {
const endpoint = prismic.getRepositoryEndpoint("qwerty");
const client = prismic.createClient(endpoint, { fetch });
const client = prismic.createClient("qwerty", { fetch });

// We can pass a type to client methods that return documents.
// Here, we tell `client.getByUID` that the document type will be a `PrismicDocumentPage`.
Expand Down
47 changes: 32 additions & 15 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { NotFoundError } from "./NotFoundError";
import { ParsingError } from "./ParsingError";
import { PrismicError } from "./PrismicError";
import { buildQueryURL, BuildQueryURLArgs } from "./buildQueryURL";
import { getRepositoryEndpoint } from "./getRepositoryEndpoint";
import { isRepositoryEndpoint } from "./isRepositoryEndpoint";
import { predicate } from "./predicate";

/**
Expand Down Expand Up @@ -237,8 +239,18 @@ const someTagsPredicate = (tags: string | string[]): string =>
/**
* Creates a Prismic client that can be used to query a repository.
*
* @param endpoint - The Prismic REST API V2 endpoint for the repository (use
* `prismic.getRepositoryEndpoint` for the default endpoint).
* @example
*
* ```ts
* // With a repository name.
* createClient("qwerty");
*
* // Or with a full Prismic Rest API V2 endpoint.
* createClient("https://qwerty.cdn.prismic.io/api/v2");
* ```
*
* @param repositoryNameOrEndpoint - The Prismic repository name or full Rest
* API V2 endpoint for the repository.
* @param options - Configuration that determines how content will be queried
* from the Prismic repository.
*
Expand Down Expand Up @@ -319,26 +331,31 @@ export class Client {
* such as Node.js, the `fetch` option must be provided as part of the
* `options` parameter.
*
* @param endpoint - The Prismic REST API V2 endpoint for the repository (use
* `prismic.getRepositoryEndpoint` to get the default endpoint).
* @param repositoryNameOrEndpoint - The Prismic repository name or full Rest
* API V2 endpoint for the repository.
* @param options - Configuration that determines how content will be queried
* from the Prismic repository.
*
* @returns A client that can query content from the repository.
*/
constructor(endpoint: string, options: ClientConfig = {}) {
if (
process.env.NODE_ENV === "development" &&
/\.prismic\.io\/(?!api\/v2\/?)/.test(endpoint)
) {
throw new PrismicError(
"@prismicio/client only supports Prismic Rest API V2. Please use the getRepositoryEndpoint helper to generate a valid Rest API V2 endpoint URL.",
undefined,
undefined,
);
constructor(repositoryNameOrEndpoint: string, options: ClientConfig = {}) {
if (isRepositoryEndpoint(repositoryNameOrEndpoint)) {
if (
process.env.NODE_ENV === "development" &&
/\.prismic\.io\/(?!api\/v2\/?)/.test(repositoryNameOrEndpoint)
) {
throw new PrismicError(
"@prismicio/client only supports Prismic Rest API V2. Please provide only the repository name to the first createClient() parameter or use the getRepositoryEndpoint() helper to generate a valid Rest API V2 endpoint URL.",
undefined,
undefined,
);
}

this.endpoint = repositoryNameOrEndpoint;
} else {
this.endpoint = getRepositoryEndpoint(repositoryNameOrEndpoint);
}

this.endpoint = endpoint;
this.accessToken = options.accessToken;
this.routes = options.routes;
this.defaultParams = options.defaultParams;
Expand Down
53 changes: 52 additions & 1 deletion test/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,29 @@ test.before(() => server.listen({ onUnhandledRequest: "error" }));
test.after(() => server.close());

test.serial("createClient creates a Client", (t) => {
const client = prismic.createClient("qwerty", {
fetch: sinon.stub(),
});

t.true(client instanceof prismic.Client);
});

test.serial("creates a client with a repository name", (t) => {
const repositoryName = "qwerty";
const client = prismic.createClient(repositoryName, {
fetch: sinon.stub(),
});

t.is(client.endpoint, prismic.getRepositoryEndpoint(repositoryName));
});

test.serial("creates a client with a Rest API V2 endpoint", (t) => {
const endpoint = prismic.getRepositoryEndpoint("qwerty");
const client = prismic.createClient(endpoint, {
fetch: sinon.stub(),
});

t.true(client instanceof prismic.Client);
t.is(client.endpoint, endpoint);
});

test.serial("client has correct default state", (t) => {
Expand All @@ -47,6 +64,40 @@ test.serial("client has correct default state", (t) => {
t.is(client.defaultParams, options.defaultParams);
});

test.serial(
"constructor throws if an invalid repository name is provided",
(t) => {
t.throws(
() => {
prismic.createClient("invalid repository name", {
fetch: sinon.stub(),
});
},
{
instanceOf: prismic.PrismicError,
message: /an invalid Prismic repository name was given/i,
},
);
},
);

test.serial(
"constructor throws if an invalid repository endpoint is provided",
(t) => {
t.throws(
() => {
prismic.createClient("https://invalid url.cdn.prismic.io/api/v2", {
fetch: sinon.stub(),
});
},
{
instanceOf: prismic.PrismicError,
message: /an invalid Prismic repository name was given/i,
},
);
},
);

test.serial("constructor throws if fetch is unavailable", (t) => {
const endpoint = prismic.getRepositoryEndpoint("qwerty");

Expand Down