Skip to content

Commit

Permalink
fix(server): fixes for v3
Browse files Browse the repository at this point in the history
  • Loading branch information
jrea committed Aug 26, 2024
1 parent 52ad537 commit ea360e6
Show file tree
Hide file tree
Showing 11 changed files with 129 additions and 92 deletions.
38 changes: 38 additions & 0 deletions packages/server/src/Api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Handlers from './api/handlers';
import { Routes } from './api/types';
import { appRoutes } from './api/utils/routes/defaultRoutes';
import serverAuth from './auth';
import Tenants from './tenants';
import Users from './users';
import { Config } from './utils/Config';

export class Api {
config: Config;
users: Users;
tenants: Tenants;
routes: Routes;
handlers: {
GET: (req: Request) => Promise<void | Response>;
POST: (req: Request) => Promise<void | Response>;
DELETE: (req: Request) => Promise<void | Response>;
PUT: (req: Request) => Promise<void | Response>;
};
constructor(config: Config) {
this.config = config;
this.users = new Users(config);
this.tenants = new Tenants(config);
this.routes = {
...appRoutes(config?.routePrefix),
...config?.routes,
};
this.handlers = Handlers(this.routes, config);
}

set headers(headers: Headers) {
this.users = new Users(this.config, headers);
this.tenants = new Tenants(this.config, headers);
}
async login(payload: { email: string; password: string }) {
this.headers = await serverAuth(this.config, this.handlers)(payload);
}
}
46 changes: 6 additions & 40 deletions packages/server/src/Server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,10 @@ import { Pool } from 'pg';

import { ServerConfig } from './types';
import { Config } from './utils/Config';
import Users from './users';
import Tenants from './tenants';
import { watchTenantId, watchToken, watchUserId } from './utils/Event';
import DbManager from './db';
import { getServerId, makeServerId } from './utils/Server';
import serverAuth from './auth';
import { appRoutes } from './api/utils/routes/defaultRoutes';
import Handlers from './api/handlers';
import { Routes } from './api/types';

class Api {
config: Config;
users: Users;
tenants: Tenants;
routes: Routes;
handlers: {
GET: (req: Request) => Promise<void | Response>;
POST: (req: Request) => Promise<void | Response>;
DELETE: (req: Request) => Promise<void | Response>;
PUT: (req: Request) => Promise<void | Response>;
};
constructor(config: Config) {
this.config = config;
this.users = new Users(config);
this.tenants = new Tenants(config);
this.routes = {
...appRoutes(config?.routePrefix),
...config?.routes,
};
this.handlers = Handlers(this.routes, config);
}

set headers(headers: Headers) {
this.users = new Users(this.config, headers);
this.tenants = new Tenants(this.config, headers);
}
async login(payload: { email: string; password: string }) {
this.headers = await serverAuth(this.config, this.handlers)(payload);
}
}
import { Api } from './Api';

export class Server {
config: Config;
Expand Down Expand Up @@ -136,7 +100,6 @@ export class Server {
}
}
get db(): Pool {
// only need to interact with the knex object
return this.manager.getConnection(this.config);
}

Expand Down Expand Up @@ -167,8 +130,11 @@ export class Server {
return existing;
}

this.servers.set(serverId, new Server(_config));
return this.servers.get(serverId) as unknown as Server;
const newServer = new Server(_config);

this.servers.set(serverId, newServer);

return newServer;
}
}

Expand Down
5 changes: 3 additions & 2 deletions packages/server/src/db/DBManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Logger from '../utils/Logger';
import { ServerConfig } from '../types';

import NileDatabase from './NileInstance';
import { isUUID } from './isUUID';

export default class DBManager {
connections: Map<string, NileDatabase>;
Expand All @@ -15,10 +16,10 @@ export default class DBManager {
tenantId?: string | undefined | null,
userId?: string | undefined | null
) {
if (tenantId && userId) {
if (isUUID(tenantId) && isUUID(userId)) {
return `${tenantId}:${userId}`;
}
if (tenantId) {
if (isUUID(tenantId)) {
return `${tenantId}`;
}
return 'base';
Expand Down
9 changes: 5 additions & 4 deletions packages/server/src/db/NileInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AfterCreate } from '../types';
import Logger from '../utils/Logger';

import { createProxyForPool } from './PoolProxy';
import { isUUID } from './isUUID';

class NileDatabase {
pool: Pool;
Expand Down Expand Up @@ -95,9 +96,9 @@ function makeAfterCreate(config: Config): AfterCreate {
done(error, conn);
});

if (config.tenantId) {
if (isUUID(config.tenantId)) {
const query = [`SET nile.tenant_id = '${config.tenantId}'`];
if (config.userId) {
if (isUUID(config.userId)) {
if (!config.tenantId) {
warn('A user id cannot be set in context without a tenant id');
}
Expand All @@ -106,10 +107,10 @@ function makeAfterCreate(config: Config): AfterCreate {

// in this example we use pg driver's connection API
conn.query(query.join(';'), function (err: Error) {
if (config.tenantId) {
if (query.length === 1) {
info('[tenant id]', config.tenantId);
}
if (config.userId) {
if (query.length === 2) {
info('[user id]', config.userId);
}
done(err, conn);
Expand Down
8 changes: 8 additions & 0 deletions packages/server/src/db/isUUID.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function isUUID(value: string | null | undefined) {
if (!value) {
return false;
}
const regex =
/^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
return regex.test(value);
}
33 changes: 24 additions & 9 deletions packages/server/src/tenants/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Config } from '../utils/Config';
import Requester, { NileRequest, NileResponse } from '../utils/Requester';
import Requester, { NileRequest } from '../utils/Requester';

export interface Tenant {
id: string;
Expand Down Expand Up @@ -34,30 +34,45 @@ export default class Tenants extends Config {
}

createTenant = async (
req: NileRequest<{ name: string }>,
req: NileRequest<{ name: string }> | Headers | string,
init?: RequestInit
): NileResponse<Tenant> => {
): Promise<Tenant | Response> => {
let _req;
if (typeof req === 'string') {
_req = new Request(`${this.api.basePath}${this.tenantsUrl}`, {
body: JSON.stringify({ name: req }),
method: 'POST',
});
} else {
_req = req;
}
const _requester = new Requester(this);
const _init = this.handleHeaders(init);
return _requester.post(req, this.tenantsUrl, _init);
return _requester.post(_req, this.tenantsUrl, _init);
};

getTenant = async (
req: NileRequest<void>,
req: NileRequest<{ id: string }> | Headers | string | void,
init?: RequestInit
): NileResponse<Tenant> => {
): Promise<Tenant | Response> => {
if (typeof req === 'string') {
this.tenantId = req;
}
const _requester = new Requester(this);
const _init = this.handleHeaders(init);
return _requester.get(req, this.tenantUrl, _init);
return _requester.get<Tenant>(req, this.tenantUrl, _init);
};

get tenantListUrl() {
return `/users/${this.userId ?? '{userId}'}/tenants`;
}

listTenants = async (req: NileRequest<void>, init?: RequestInit) => {
listTenants = async (
req: NileRequest<void> | Headers,
init?: RequestInit
): Promise<Tenant[] | Response> => {
const _requester = new Requester(this);
const _init = this.handleHeaders(init);
return _requester.get(req, this.tenantListUrl, _init);
return _requester.get<Tenant[]>(req, this.tenantListUrl, _init);
};
}
16 changes: 8 additions & 8 deletions packages/server/src/users/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Config } from '../utils/Config';
import Requester, { NileRequest, NileResponse } from '../utils/Requester';
import Requester, { NileRequest } from '../utils/Requester';

export interface CreateBasicUserRequest {
email: string;
Expand Down Expand Up @@ -65,7 +65,7 @@ export default class Users extends Config {
createUser = async (
req: NileRequest<CreateBasicUserRequest>,
init?: RequestInit
): NileResponse<LoginUserResponse> => {
): Promise<User | Response> => {
const _requester = new Requester(this);

const _init = this.handleHeaders(init);
Expand All @@ -76,7 +76,7 @@ export default class Users extends Config {
userId: string,
req: NileRequest<User>,
init?: RequestInit
): NileResponse<User> => {
): Promise<User | Response> => {
const _requester = new Requester(this);
const _init = this.handleHeaders(init);
return await _requester.put(req, `${this.usersUrl}/${userId}`, _init);
Expand All @@ -85,7 +85,7 @@ export default class Users extends Config {
listUsers = async (
req: NileRequest<void> | Headers,
init?: RequestInit
): NileResponse<User[]> => {
): Promise<User[] | Response> => {
const _requester = new Requester(this);
const _init = this.handleHeaders(init);
return await _requester.get(req, this.tenantUsersUrl, _init);
Expand All @@ -94,7 +94,7 @@ export default class Users extends Config {
linkUser = async (
req: NileRequest<{ id: string }> | Headers,
init?: RequestInit
): NileResponse<User[]> => {
): Promise<User | Response> => {
const _requester = new Requester(this);
const _init = this.handleHeaders(init);
return await _requester.put(req, this.tenantUsersUrl, _init);
Expand Down Expand Up @@ -122,7 +122,7 @@ export default class Users extends Config {
unlinkUser = async (
req: NileRequest<{ id: string }> | Headers,
init?: RequestInit
): NileResponse<User[]> => {
): Promise<User[] | Response> => {
const _requester = new Requester(this);
const userId = await this.getUserId(req);
const _init = this.handleHeaders(init);
Expand All @@ -138,9 +138,9 @@ export default class Users extends Config {
}

me = async (
req: NileRequest<void>,
req: NileRequest<void> | Headers,
init?: RequestInit
): NileResponse<User> => {
): Promise<User | Response> => {
const _requester = new Requester(this);
const _init = this.handleHeaders(init);
return await _requester.get(req, this.meUrl, _init);
Expand Down
50 changes: 33 additions & 17 deletions packages/server/src/utils/Requester/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default class Requester<T> extends Config {
}

/**
* three optios here
* three options here
* 1) pass in headers for a server side request
* 2) pass in the payload that matches the api
* 3) pass in the request object sent by a browser
Expand Down Expand Up @@ -96,35 +96,51 @@ export default class Requester<T> extends Config {
return await this.rawRequest(method, url, _init, body);
}

post = async (
async post<R = JSON>(
req: T | Headers,
url: string,
init?: RequestInit
): Promise<Response> => {
return await this.request('POST', url, req, init);
};
): Promise<Response | R> {
const response = await this.request('POST', url, req, init);
if (response && response.status >= 200 && response.status < 300) {
return response.json();
}
return response;
}

get = async (
async get<R = JSON>(
req: T | Headers,
url: string,
init?: RequestInit
): Promise<Response> => {
return await this.request('GET', url, req, init);
};
): Promise<Response | R> {
const response = await this.request('GET', url, req, init);
if (response && response.status >= 200 && response.status < 300) {
return response.json();
}
return response;
}

put = async (
async put<R = JSON>(
req: T | Headers,
url: string,
init?: RequestInit
): Promise<Response> => {
return await this.request('PUT', url, req, init);
};
): Promise<Response | R> {
const response = await this.request('PUT', url, req, init);
if (response && response.status >= 200 && response.status < 300) {
return response.json();
}
return response;
}

delete = async (
async delete<R = JSON>(
req: T | Headers,
url: string,
init?: RequestInit
): Promise<Response> => {
return await this.request('DELETE', url, req, init);
};
): Promise<Response | R> {
const response = await this.request('DELETE', url, req, init);
if (response && response.status >= 200 && response.status < 300) {
return response.json();
}
return response;
}
}
2 changes: 1 addition & 1 deletion packages/server/src/utils/Requester/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,4 @@ export interface APIError {
statusCode: number;
}

export type NileResponse<T> = Promise<NResponse<T & APIError>>;
export type NileResponse<T> = Promise<T | NResponse<T & APIError>>;
2 changes: 1 addition & 1 deletion packages/server/src/utils/Server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ export const getServerId = (config: ServerConfig) => {
return makeServerId(cfg);
};
export const makeServerId = (config: Config) => {
return Buffer.from(JSON.stringify(config), 'base64').toString();
return Buffer.from(JSON.stringify(config), 'utf8').toString('base64');
};
Loading

0 comments on commit ea360e6

Please sign in to comment.