Skip to content

Commit

Permalink
feat(server): use init vs blocking fetch
Browse files Browse the repository at this point in the history
  • Loading branch information
jrea committed Apr 3, 2024
1 parent 8d5c5cb commit 19d150d
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 75 deletions.
8 changes: 4 additions & 4 deletions packages/server/src/Server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ describe('server', () => {
user: 'username',
password: 'password',
};
const server = Nile(config);
const server = new Nile(config);
expect(server.config.db).toEqual({
host: 'db.thenile.dev',
port: 5432,
Expand All @@ -24,7 +24,7 @@ describe('server', () => {
user: 'username',
password: 'password',
};
const nile = Nile(config);
const nile = new Nile(config);
nile.tenantId = 'tenantId';
nile.userId = 'userId';
for (const api in nile.api) {
Expand All @@ -39,7 +39,7 @@ describe('server', () => {
user: 'username',
password: 'password',
};
const nile = Nile(config);
const nile = new Nile(config);

const another = nile.getInstance({
databaseId: 'somethingelse?!',
Expand Down Expand Up @@ -68,7 +68,7 @@ describe('server', () => {
user: 'username',
password: 'password',
};
const nile = Nile(config);
const nile = new Nile(config);

const another = nile.getInstance({
databaseId: 'somethingelse?!',
Expand Down
40 changes: 21 additions & 19 deletions packages/server/src/Server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,15 @@ type Api = {
tenants: Tenants;
};

const init = (config: Config): [Api] => {
const init = (config: Config): Api => {
const auth = new Auth(config);
const users = new Users(config);
const tenants = new Tenants(config);
return [
{
auth,
users,
tenants,
},
];
return {
auth,
users,
tenants,
};
};

class Server {
Expand All @@ -35,10 +33,9 @@ class Server {
private servers: Map<string, Server>;

constructor(config?: ServerConfig) {
this.config = new Config(config as ServerConfig, true);
this.config = new Config(config as ServerConfig);
this.servers = new Map();
const [api] = init(this.config);
this.api = api;
this.api = init(this.config);
this.manager = new DbManager(this.config);

watchTenantId((tenantId) => {
Expand All @@ -55,7 +52,17 @@ class Server {
}

setConfig(cfg: Config) {
this.config = new Config(cfg, false);
this.config = new Config(cfg);
}

async init(cfg?: Config) {
const updatedConfig = await this.config.configure({
...this.config,
...cfg,
});
this.setConfig(updatedConfig);
this.manager = new DbManager(this.config);
this.api = init(updatedConfig);
}

set databaseId(val: string | void) {
Expand Down Expand Up @@ -134,7 +141,7 @@ class Server {

if (existing) {
// be sure the config is up to date
const updatedConfig = new Config(_config, false);
const updatedConfig = new Config(_config);
existing.setConfig(updatedConfig);
// propagage special config items
existing.tenantId = updatedConfig.tenantId;
Expand All @@ -149,9 +156,4 @@ class Server {
}
}

// export default Server;
export default function Nile(config?: ServerConfig) {
const server = new Server(config);
// server.setConfig(new Config(config as ServerConfig, false));
return server;
}
export default Server;
1 change: 1 addition & 0 deletions packages/server/src/auth/auth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const baseConfig = [
'loginSSOUrl',
'signUp',
'updateProvider',
'configure',
'user',
'password',
];
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 @@ -3,6 +3,7 @@ import { Pool } from 'pg';
import { Config } from '../utils/Config';
import { watchEvictPool } from '../utils/Event';
import Logger from '../utils/Logger';
import { ServerConfig } from '../types';

import NileDatabase from './NileInstance';

Expand All @@ -21,7 +22,7 @@ export default class DBManager {
}
return 'base';
}
constructor(config: Config) {
constructor(config: ServerConfig) {
const { info } = Logger(config, '[DBManager]');
this.connections = new Map();
// add the base one, so you can at least query
Expand All @@ -35,7 +36,7 @@ export default class DBManager {
});
}

getConnection(config: Config): Pool {
getConnection(config: ServerConfig): Pool {
const { info } = Logger(config, '[DBManager]');
const id = this.makeId(config.tenantId, config.userId);
const existing = this.connections.get(id);
Expand Down
1 change: 0 additions & 1 deletion packages/server/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { default as Server } from './Server';

module.exports = Server;
export default Server;
1 change: 1 addition & 0 deletions packages/server/src/tenants/tenants.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const baseConfig = [
'databaseId',
'databaseName',
'user',
'configure',
'password',
];
const config = {
Expand Down
1 change: 1 addition & 0 deletions packages/server/src/users/users.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const baseConfig = [
'me',
'databaseName',
'debug',
'configure',
'updateUser',
'user',
'password',
Expand Down
105 changes: 58 additions & 47 deletions packages/server/src/utils/Config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,31 +83,75 @@ export class Config {
this._userId = value;
}

constructor(config: ServerConfig, allowPhoneHome?: boolean) {
const { info, error } = Logger(config, '[config]');

constructor(config: ServerConfig) {
const envVarConfig: EnvConfig = {
config,
};
if (allowPhoneHome) {
envVarConfig.logger = '[config]';
}
this.databaseId = getDatbaseId(envVarConfig) as string;
this.user = getUsername(envVarConfig) as string;
this.password = getPassword(envVarConfig) as string;
this.databaseName = getDatabaseName(envVarConfig) as string;
this._tenantId = getTenantId(envVarConfig);
this.debug = Boolean(config?.debug);
this._userId = config?.userId;

let basePath = getBasePath(envVarConfig);
const basePath = getBasePath(envVarConfig);
const host = getDbHost(envVarConfig);
const port = getDbPort(envVarConfig);

this.api = new ApiConfig({
basePath,
cookieKey: config?.api?.cookieKey ?? 'token',
token: getToken({ config }),
});
this.db = {
user: this.user,
password: this.password,
host,
port,
database: this.databaseName,
...(typeof config?.db === 'object' ? config.db : {}),
};
}

configure = async (config: ServerConfig): Promise<Config> => {
const { info, error } = Logger(config, '[init]');
const envVarConfig: EnvConfig = {
config,
};
let basePath = getBasePath(envVarConfig);
let host = getDbHost(envVarConfig);
const port = getDbPort(envVarConfig);

this._userId = config?.userId;

if (allowPhoneHome && (!host || !this.databaseName || !this.databaseId)) {
const database = getInfo(config);
const databaseName = getDatabaseName({ config, logger: 'getInfo' });
const url = new URL(`${basePath}/databases/configure`);
if (databaseName) {
url.searchParams.set('databaseName', databaseName);
}
info(url.href);
const res = syncFetch(url, {
headers: {
Authorization: `Bearer ${getInfoBearer({ config })}`,
},
});
let database: Database;
const possibleError = res.clone();
try {
const json: Database = res.json();
if (res.status === 404) {
info('is the configured databaseName correct?');
}
if (json.status && json.status !== 'READY') {
database = { message: 'Database is not ready yet' } as Database;
} else {
database = json;
}
} catch (e) {
const message = possibleError.text();
error(message);
database = { message } as Database;
}
if (!host || !this.databaseName || !this.databaseId) {
info('[fetched database]', database);
if (process.env.NODE_ENV !== 'TEST') {
if ('message' in database) {
Expand All @@ -132,7 +176,6 @@ export class Config {
}
}
}

this.api = new ApiConfig({
basePath,
cookieKey: config?.api?.cookieKey ?? 'token',
Expand All @@ -146,39 +189,7 @@ export class Config {
database: this.databaseName,
...(typeof config?.db === 'object' ? config.db : {}),
};
if (allowPhoneHome) {
info(this);
}
}
}

function getInfo(config: ServerConfig): Database {
const basePath = getBasePath({ config });
const databaseName = getDatabaseName({ config, logger: 'getInfo' });
const url = new URL(`${basePath}/databases/configure`);
if (databaseName) {
url.searchParams.set('databaseName', databaseName);
}
const { info, error } = Logger(config, '[getInfo]');
info(url.href);
const res = syncFetch(url, {
headers: {
Authorization: `Bearer ${getInfoBearer({ config })}`,
},
});
const possibleError = res.clone();
try {
const json: Database = res.json();
if (res.status === 404) {
info('is the configured databaseName correct?');
}
if (json.status && json.status !== 'READY') {
return { message: 'Database is not ready yet' } as Database;
}
return json;
} catch (e) {
const message = possibleError.text();
error(message);
return { message } as Database;
}
info('[config set]', this);
return this;
};
}
6 changes: 4 additions & 2 deletions packages/server/test/integration/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ const config: ServerConfig = {

describe.skip('api integration', () => {
it('does a bunch of api calls', async () => {
const nile = Server(config);
const nile = new Server(config);
await nile.init();
const loginResp = await nile.api.auth.login({
email: String(process.env.EMAIL),
password: String(process.env.PASSWORD),
Expand Down Expand Up @@ -57,7 +58,8 @@ describe.skip('api integration', () => {

describe.skip('db integration', () => {
it('queries', async () => {
const nile = Server(config);
const nile = new Server(config);
await nile.init();
const res = await nile.db.query('select * from tenants');
expect(res.rowCount).toBeGreaterThan(0);
});
Expand Down

0 comments on commit 19d150d

Please sign in to comment.