Skip to content

Commit

Permalink
feat: add getSessionStore api (#633)
Browse files Browse the repository at this point in the history
  • Loading branch information
chentsulin authored Jan 17, 2020
1 parent 562661c commit dbaf4d2
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 69 deletions.
74 changes: 74 additions & 0 deletions packages/bottender/src/__tests__/getSessionStore.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import getBottenderConfig from '../shared/getBottenderConfig';
import getSessionStore from '../getSessionStore';
import { SessionDriver } from '../types';

jest.mock('../shared/getBottenderConfig');

const getBottenderConfigMocked = getBottenderConfig as jest.MockedFunction<
typeof getBottenderConfig
>;

it('should get MemorySessionStore by default', () => {
getBottenderConfigMocked.mockReturnValueOnce({});
expect(getSessionStore().constructor.name).toEqual('MemorySessionStore');
});

it('should get MemorySessionStore when assigning memory as driver', () => {
getBottenderConfigMocked.mockReturnValueOnce({
session: {
driver: SessionDriver.Memory,
stores: {
memory: {
maxSize: 500,
},
},
},
});
expect(getSessionStore().constructor.name).toEqual('MemorySessionStore');
});

it('should get FileSessionStore when assigning file as driver', () => {
getBottenderConfigMocked.mockReturnValueOnce({
session: {
driver: SessionDriver.File,
stores: {
file: {
dirname: '.sessions',
},
},
},
});
expect(getSessionStore().constructor.name).toEqual('FileSessionStore');
});

it('should get MongoSessionStore when assigning mongo as driver', () => {
getBottenderConfigMocked.mockReturnValueOnce({
session: {
driver: SessionDriver.Mongo,
stores: {
mongo: {
url: 'mongodb://localhost:27017',
collectionName: 'sessions',
},
},
},
});
expect(getSessionStore().constructor.name).toEqual('MongoSessionStore');
});

it('should get RedisSessionStore when assigning redis as driver', () => {
getBottenderConfigMocked.mockReturnValueOnce({
session: {
driver: SessionDriver.Redis,
stores: {
redis: {
port: 6379,
host: '127.0.0.1',
password: 'auth',
db: 0,
},
},
},
});
expect(getSessionStore().constructor.name).toEqual('RedisSessionStore');
});
4 changes: 4 additions & 0 deletions packages/bottender/src/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ describe('core', () => {
expect(core.createServer).toBeDefined();
});

it('export getSessionStore', () => {
expect(core.getSessionStore).toBeDefined();
});

it('export chain', () => {
expect(core.chain).toBeDefined();
});
Expand Down
64 changes: 64 additions & 0 deletions packages/bottender/src/getSessionStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import warning from 'warning';

import getBottenderConfig from './shared/getBottenderConfig';

function getSessionStore() {
const bottenderConfig = getBottenderConfig();

const { session } = bottenderConfig;

const sessionDriver = (session && session.driver) || 'memory';

const storesConfig = (session && session.stores) || {};

switch (sessionDriver) {
case 'memory': {
const MemorySessionStore = require('./session/MemorySessionStore')
.default;

return new MemorySessionStore(
storesConfig.memory || {},
session && session.expiresIn
);
}
case 'file': {
const FileSessionStore = require('./session/FileSessionStore').default;

return new FileSessionStore(
storesConfig.file || {},
session && session.expiresIn
);
}
case 'mongo': {
const MongoSessionStore = require('./session/MongoSessionStore').default;

return new MongoSessionStore(
storesConfig.mongo || {},
session && session.expiresIn
);
}
case 'redis': {
const RedisSessionStore = require('./session/RedisSessionStore').default;

return new RedisSessionStore(
storesConfig.redis || {},
session && session.expiresIn
);
}
default: {
warning(
false,
`Received unknown driver: ${sessionDriver}, so fallback it to \`memory\` driver.`
);
const MemorySessionStore = require('./session/MemorySessionStore')
.default;

return new MemorySessionStore(
storesConfig.memory || {},
session && session.expiresIn
);
}
}
}

export default getSessionStore;
1 change: 1 addition & 0 deletions packages/bottender/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export { bottender };
/* Core */
export { default as Bot } from './bot/Bot';
export { default as Context } from './context/Context';
export { default as getSessionStore } from './getSessionStore';

/* Action */
export { default as chain } from './chain';
Expand Down
31 changes: 3 additions & 28 deletions packages/bottender/src/initializeServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import SlackBot from './slack/SlackBot';
import TelegramBot from './telegram/TelegramBot';
import ViberBot from './viber/ViberBot';
import getBottenderConfig from './shared/getBottenderConfig';
import getSessionStore from './getSessionStore';
import { Action, BottenderConfig, Channel, Plugin } from './types';

const BOT_MAP = {
Expand All @@ -30,35 +31,9 @@ function initializeServer({
} = {}): express.Application | void {
const bottenderConfig = getBottenderConfig();

const { initialState, plugins, session, channels } = merge(
bottenderConfig,
config
);

// session
const sessionDriver = (session && session.driver) || 'memory';
let SessionStore;
switch (sessionDriver) {
case 'file':
SessionStore = require('./session/FileSessionStore').default;
break;
case 'mongo':
SessionStore = require('./session/MongoSessionStore').default;
break;
case 'redis':
SessionStore = require('./session/RedisSessionStore').default;
break;
default:
SessionStore = require('./session/MemorySessionStore').default;
}

const sessionDriverConfig =
((session && session.stores) || {})[sessionDriver] || {};
const { initialState, plugins, channels } = merge(bottenderConfig, config);

const sessionStore = new SessionStore(
sessionDriverConfig,
session && session.expiresIn
);
const sessionStore = getSessionStore();

// TODO: refine handler entry, improve error message and hint
// eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
Expand Down
41 changes: 4 additions & 37 deletions packages/bottender/src/server/Server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,14 @@ import { pascalcase } from 'messaging-api-common';

import Bot from '../bot/Bot';
import getBottenderConfig from '../shared/getBottenderConfig';
import {
Action,
BottenderConfig,
Plugin,
SessionConfig,
SessionDriver,
} from '../types';
import getSessionStore from '../getSessionStore';
import { Action, BottenderConfig, Plugin } from '../types';

export type ServerOptions = {
useConsole?: boolean;
dev?: boolean;
};

function createSessionStore(
sessionConfig: SessionConfig = { driver: SessionDriver.Memory, stores: {} }
) {
const sessionDriver = (sessionConfig && sessionConfig.driver) || 'memory';
let SessionStore;
switch (sessionDriver) {
case 'file':
SessionStore = require('../session/FileSessionStore').default;
break;
case 'mongo':
SessionStore = require('../session/MongoSessionStore').default;
break;
case 'redis':
SessionStore = require('../session/RedisSessionStore').default;
break;
default:
SessionStore = require('../session/MemorySessionStore').default;
}

const sessionDriverConfig =
((sessionConfig && sessionConfig.stores) || {})[sessionDriver] || {};

return new SessionStore(
sessionDriverConfig,
sessionConfig && sessionConfig.expiresIn
);
}

class Server {
_channelBots: { webhookPath: string; bot: Bot<any, any, any> }[] = [];

Expand All @@ -73,11 +40,11 @@ class Server {
public async prepare(): Promise<void> {
const bottenderConfig = getBottenderConfig();

const { initialState, plugins, session, channels } = merge(
const { initialState, plugins, channels } = merge(
bottenderConfig /* , config */
) as BottenderConfig;

const sessionStore = createSessionStore(session);
const sessionStore = getSessionStore();

// TODO: refine handler entry, improve error message and hint
// eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
Expand Down
4 changes: 2 additions & 2 deletions packages/bottender/src/session/MongoSessionStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import SessionStore from './SessionStore';
type MongoOption =
| string
| {
url: string;
url?: string;
collectionName?: string;
};

Expand All @@ -27,7 +27,7 @@ export default class MongoSessionStore implements SessionStore {
this._url = options;
this._collectionName = 'sessions';
} else {
this._url = options.url;
this._url = options.url || 'mongodb://localhost:27017';
this._collectionName = options.collectionName || 'sessions';
}
this._expiresIn = expiresIn || 0;
Expand Down
4 changes: 2 additions & 2 deletions packages/bottender/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ export type SessionConfig = {
port?: number;
host?: string;
password?: string;
db: number;
db?: number;
};
mongo?: {
url: string;
url?: string;
collectionName?: string;
};
};
Expand Down

0 comments on commit dbaf4d2

Please sign in to comment.