Skip to content
This repository has been archived by the owner on Jan 21, 2022. It is now read-only.

feat: provide a singleton Clerk instance as the the default export, a… #8

Merged
merged 2 commits into from
Feb 1, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
232 changes: 176 additions & 56 deletions README.md

Large diffs are not rendered by default.

104 changes: 63 additions & 41 deletions src/Clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,18 @@ import { SMSMessage } from './resources/SMSMessage';
import { User } from './resources/User';
import { Verification } from './resources/Verification';

const defaultApiVersion = 'v1';
const defaultServerApiUrl = 'https://api.clerk.dev';
const defaultApiKey = process.env.CLERK_API_KEY || '';
const defaultApiVersion = process.env.CLERK_API_VERSION || 'v1';
const defaultServerApiUrl =
process.env.CLERK_API_URL || 'https://api.clerk.dev';

export default class Clerk {
apiKey: string;
serverApiUrl: string = defaultServerApiUrl;
apiVersion: string = defaultApiVersion;
httpOptions: object = {};
restClient: RestClient;
private _restClient: RestClient;

// singleton instance
static _instance: Clerk;

// TODO we may not need to instantiate these any more if they keep no state
// private api instances
private _clientApi?: ClientApi;
private _emailApi?: EmailApi;
Expand All @@ -48,69 +50,89 @@ export default class Clerk {
public static User = User;
public static Verification = Verification;

constructor(
apiKey: string,
{
serverApiUrl = defaultServerApiUrl,
apiVersion = defaultApiVersion,
httpOptions = {},
}: {
serverApiUrl?: string;
apiVersion?: string;
httpOptions?: object;
} = {}
) {
this.apiKey = apiKey;
this.apiVersion = apiVersion;
this.httpOptions = httpOptions || {};

if (serverApiUrl) {
this.serverApiUrl = serverApiUrl;
constructor({
apiKey = defaultApiKey,
serverApiUrl = defaultServerApiUrl,
apiVersion = defaultApiVersion,
httpOptions = {},
}: {
apiKey?: string;
serverApiUrl?: string;
apiVersion?: string;
httpOptions?: object;
} = {}) {
this._restClient = new RestClient(
apiKey,
serverApiUrl,
apiVersion,
httpOptions
);
}

// For use as singleton, always returns the same instance
static getInstance() {
if (!this._instance) {
this._instance = new Clerk();
}

this.restClient = new RestClient(
this.apiKey,
this.serverApiUrl,
this.apiVersion,
this.httpOptions
);
return this._instance;
}

// Setters for the embedded rest client

set apiKey(value: string) {
this._restClient.apiKey = value;
}

get clientApi(): ClientApi {
set serverApiUrl(value: string) {
this._restClient.serverApiUrl = value;
}

set apiVersion(value: string) {
this._restClient.apiVersion = value;
}

set httpOptions(value: object) {
this._restClient.httpOptions = value;
}

// Lazy sub-api getters

get clients(): ClientApi {
if (!this._clientApi) {
this._clientApi = new ClientApi(this.restClient);
this._clientApi = new ClientApi(this._restClient);
}

return this._clientApi;
}

get emailApi(): EmailApi {
get emails(): EmailApi {
if (!this._emailApi) {
this._emailApi = new EmailApi(this.restClient);
this._emailApi = new EmailApi(this._restClient);
}

return this._emailApi;
}

get sessionApi(): SessionApi {
get sessions(): SessionApi {
if (!this._sessionApi) {
this._sessionApi = new SessionApi(this.restClient);
this._sessionApi = new SessionApi(this._restClient);
}

return this._sessionApi;
}

get smsMessageApi(): SMSMessageApi {
get smsMessages(): SMSMessageApi {
if (!this._smsMessageApi) {
this._smsMessageApi = new SMSMessageApi(this.restClient);
this._smsMessageApi = new SMSMessageApi(this._restClient);
}

return this._smsMessageApi;
}

get userApi(): UserApi {
get users(): UserApi {
if (!this._userApi) {
this._userApi = new UserApi(this.restClient);
this._userApi = new UserApi(this._restClient);
}

return this._userApi;
Expand Down
4 changes: 2 additions & 2 deletions src/apis/AbstractApi.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { RestClient } from '../utils/RestClient';

export abstract class AbstractApi {
restClient: RestClient;
protected _restClient: RestClient;

constructor(restClient: RestClient) {
this.restClient = restClient;
this._restClient = restClient;
}
}
6 changes: 3 additions & 3 deletions src/apis/ClientApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@ import { Client } from '../resources/Client';

export class ClientApi extends AbstractApi {
public async getClientList(): Promise<Array<Client>> {
return this.restClient.makeRequest({
return this._restClient.makeRequest({
method: 'get',
path: '/clients',
});
}

public async getClient(clientId: string): Promise<Client> {
return this.restClient.makeRequest({
return this._restClient.makeRequest({
method: 'get',
path: `/clients/${clientId}`,
});
}

public verifyClient(token: string): Promise<Client> {
return this.restClient.makeRequest({
return this._restClient.makeRequest({
method: 'post',
path: '/clients/verify',
bodyParams: { token },
Expand Down
2 changes: 1 addition & 1 deletion src/apis/EmailApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type EmailParams = {

export class EmailApi extends AbstractApi {
public async createEmail(params: EmailParams): Promise<Email> {
return this.restClient.makeRequest({
return this._restClient.makeRequest({
method: 'post',
path: '/emails',
bodyParams: params,
Expand Down
2 changes: 1 addition & 1 deletion src/apis/SMSMessageApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type SMSParams = {

export class SMSMessageApi extends AbstractApi {
public async createSMSMessage(params: SMSParams): Promise<SMSMessage> {
return this.restClient.makeRequest({
return this._restClient.makeRequest({
method: 'post',
path: '/sms_messages',
bodyParams: params,
Expand Down
8 changes: 4 additions & 4 deletions src/apis/SessionApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ export class SessionApi extends AbstractApi {
public async getSessionList(
queryParams: QueryParams
): Promise<Array<Session>> {
return this.restClient.makeRequest({
return this._restClient.makeRequest({
method: 'get',
path: '/sessions',
queryParams: queryParams,
});
}

public async getSession(sessionId: string): Promise<Session> {
return this.restClient.makeRequest({
return this._restClient.makeRequest({
method: 'get',
path: `/sessions/${sessionId}`,
});
}

public async revokeSession(sessionId: string): Promise<Session> {
return this.restClient.makeRequest({
return this._restClient.makeRequest({
method: 'post',
path: `/sessions/${sessionId}/revoke`,
});
Expand All @@ -35,7 +35,7 @@ export class SessionApi extends AbstractApi {
sessionId: string,
token: string
): Promise<Session> {
return this.restClient.makeRequest({
return this._restClient.makeRequest({
method: 'post',
path: `/sessions/${sessionId}/verify`,
bodyParams: { token },
Expand Down
8 changes: 4 additions & 4 deletions src/apis/UserApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ interface UserParams {

export class UserApi extends AbstractApi {
public async getUserList(): Promise<Array<User>> {
return this.restClient.makeRequest({
return this._restClient.makeRequest({
method: 'get',
path: '/users',
});
}

public async getUser(userId: string): Promise<User> {
return this.restClient.makeRequest({
return this._restClient.makeRequest({
method: 'get',
path: `/users/${userId}`,
});
Expand All @@ -29,15 +29,15 @@ export class UserApi extends AbstractApi {
userId: string,
params: UserParams = {}
): Promise<User> {
return this.restClient.makeRequest({
return this._restClient.makeRequest({
method: 'patch',
path: `/users/${userId}`,
bodyParams: params,
});
}

public async deleteUser(userId: string): Promise<User> {
return this.restClient.makeRequest({
return this._restClient.makeRequest({
method: 'delete',
path: `/users/${userId}`,
});
Expand Down
13 changes: 7 additions & 6 deletions src/examples/express/server.mjs
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import express from 'express';
import { ExpressAuthMiddleware } from '@clerk/clerk-sdk-node';
import dotenv from 'dotenv';
// Usage:
// node --require dotenv/config server.mjs

dotenv.config();
import express from 'express';
import clerk, { ClerkExpressMiddleware } from '@clerk/clerk-sdk-node';

const apiKey = process.env.CLERK_API_KEY;
const serverApiUrl = process.env.CLERK_API_URL;
const port = process.env.PORT;

function onError(error) {
console.log(error);
}

clerk.serverApiUrl = serverApiUrl;

var app = express();

app.use(ExpressAuthMiddleware(apiKey, { serverApiUrl, onError }));
app.use(ClerkExpressMiddleware({ clerk, onError }));

app.get('/', (req, res) => {
res.json(req.session);
Expand Down
16 changes: 8 additions & 8 deletions src/examples/express/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
# yarn lockfile v1


"@clerk/clerk-sdk-node@file:../../..":
version "0.0.2"
dependencies:
"@types/cookies" "^0.7.6"
cookies "^0.8.0"
got "^11.8.1"
snakecase-keys "^3.2.1"

"@sindresorhus/is@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.0.tgz#2ff674e9611b45b528896d820d3d7a812de2f0e4"
Expand Down Expand Up @@ -172,14 +180,6 @@ cacheable-request@^7.0.1:
normalize-url "^4.1.0"
responselike "^2.0.0"

"clerk-sdk-node@file:../../..":
version "0.0.4"
dependencies:
"@types/cookies" "^0.7.6"
cookies "^0.8.0"
got "^11.8.1"
snakecase-keys "^3.2.1"

clone-response@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
Expand Down
4 changes: 2 additions & 2 deletions src/examples/next/pages/api/require-session.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const { requireSession } = require('@clerk/clerk-sdk-node');
import clerk, { requireSession } from '@clerk/clerk-sdk-node';

function handler(req, res) {
console.log('Session required');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yourtallness Can we fix or surpress these Github actions linting suggestions? They kind of get in the way during the PR review

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#truedat, will look into it

res.statusCode = 200;
res.json(req.session || { empty: true });
}

export default requireSession(handler, { serverApiUrl: process.env.CLERK_API_URL, onError: error => console.log(error) });
export default requireSession(handler, { clerk, onError: error => console.log(error) });
4 changes: 2 additions & 2 deletions src/examples/next/pages/api/with-session.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const { withSession } = require('@clerk/clerk-sdk-node');
import clerk, { withSession } from '@clerk/clerk-sdk-node';

function handler(req, res) {
console.log('Session optional');
res.statusCode = 200;
res.json(req.session || { empty: true });
}

export default withSession(handler, { serverApiUrl: process.env.CLERK_API_URL, onError: error => console.log(error) });
export default withSession(handler, { clerk, onError: error => console.log(error) });
19 changes: 9 additions & 10 deletions src/examples/node/client.mjs
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
import Clerk from '@clerk/clerk-sdk-node';
import dotenv from 'dotenv';
// Usage:
// node --require dotenv/config client.mjs

dotenv.config();
import { setClerkServerApiUrl, clients } from '@clerk/clerk-sdk-node';

const serverApiUrl = process.env.CLERK_API_URL;
const apiKey = process.env.CLERK_API_KEY;
const clientId = process.env.CLIENT_ID;
const sessionToken = process.env.SESSION_TOKEN;

const clerk = new Clerk.default(apiKey, { serverApiUrl });
setClerkServerApiUrl(serverApiUrl);

console.log('Get client list');
let clients = await clerk.clientApi.getClientList();
console.log(clients);
let clientList = await clients.getClientList();
console.log(clientList);

console.log('Get single client');
let client = await clerk.clientApi.getClient(clientId);
let client = await clients.getClient(clientId);
console.log(client);

console.log('Verify client');
let verifiedClient = await clerk.clientApi.verifyClient(sessionToken);
let verifiedClient = await clients.verifyClient(sessionToken);
console.log(verifiedClient);

try {
console.log('Get single client for invalid clientId');
let invalidClient = await clerk.clientApi.getClient('foobar');
let invalidClient = await clients.getClient('foobar');
console.log(invalidClient);
} catch (error) {
console.log(error);
Expand Down
Loading