gristlabs_grist-core/app/server/lib/ICreate.ts
George Gevoian 2fd8a34ff8 (core) Move Notifier to /ext
Summary:
This makes it possible to configure a SendGrid-based Notifier
instance via a JSON configuration file.

Test Plan: Tested manually.

Reviewers: alexmojaki

Reviewed By: alexmojaki

Subscribers: paulfitz

Differential Revision: https://phab.getgrist.com/D3432
2022-05-18 08:02:32 -07:00

118 lines
4.2 KiB
TypeScript

import {Document} from 'app/gen-server/entity/Document';
import {HomeDBManager} from 'app/gen-server/lib/HomeDBManager';
import {ActiveDoc} from 'app/server/lib/ActiveDoc';
import {DocManager} from 'app/server/lib/DocManager';
import {ExternalStorage} from 'app/server/lib/ExternalStorage';
import {GristServer} from 'app/server/lib/GristServer';
import {IBilling} from 'app/server/lib/IBilling';
import {INotifier} from 'app/server/lib/INotifier';
import {ISandbox, ISandboxCreationOptions} from 'app/server/lib/ISandbox';
import {IShell} from 'app/server/lib/IShell';
import {createSandbox} from 'app/server/lib/NSandbox';
import * as express from 'express';
export interface ICreate {
Billing(dbManager: HomeDBManager, gristConfig: GristServer): IBilling;
Notifier(dbManager: HomeDBManager, gristConfig: GristServer): INotifier;
Shell(): IShell|undefined;
// Create a space to store files externally, for storing either:
// - documents. This store should be versioned, and can be eventually consistent.
// - meta. This store need not be versioned, and can be eventually consistent.
// For test purposes an extra prefix may be supplied. Stores with different prefixes
// should not interfere with each other.
ExternalStorage(purpose: 'doc' | 'meta', testExtraPrefix: string): ExternalStorage | undefined;
ActiveDoc(docManager: DocManager, docName: string, options: ICreateActiveDocOptions): ActiveDoc;
NSandbox(options: ISandboxCreationOptions): ISandbox;
sessionSecret(): string;
// Get configuration information to show at start-up.
configurationOptions(): {[key: string]: any};
// Return a string containing 1 or more HTML tags to insert into the head element of every
// static page.
getExtraHeadHtml?(): string;
}
export interface ICreateActiveDocOptions {
safeMode?: boolean;
docUrl?: string;
doc?: Document;
}
export interface ICreateStorageOptions {
check(): Record<string, string>|undefined;
create(purpose: 'doc'|'meta', extraPrefix: string): ExternalStorage|undefined;
}
export interface ICreateNotifierOptions {
create(dbManager: HomeDBManager, gristConfig: GristServer): INotifier|undefined;
}
export function makeSimpleCreator(opts: {
sessionSecret?: string,
storage?: ICreateStorageOptions[],
activationMiddleware?: (db: HomeDBManager, app: express.Express) => Promise<void>,
notifier?: ICreateNotifierOptions,
}): ICreate {
return {
Billing(db) {
return {
addEndpoints() { /* do nothing */ },
addEventHandlers() { /* do nothing */ },
addWebhooks() { /* do nothing */ },
async addMiddleware(app) {
// add activation middleware, if needed.
return opts?.activationMiddleware?.(db, app);
}
};
},
Notifier(dbManager, gristConfig) {
const {notifier} = opts;
return notifier?.create(dbManager, gristConfig) ?? {
get testPending() { return false; },
deleteUser() { throw new Error('deleteUser unavailable'); },
};
},
Shell() {
return {
moveItemToTrash() { throw new Error('moveToTrash unavailable'); },
showItemInFolder() { throw new Error('showItemInFolder unavailable'); }
};
},
ExternalStorage(purpose, extraPrefix) {
for (const storage of opts.storage || []) {
const config = storage.check();
if (config) { return storage.create(purpose, extraPrefix); }
}
return undefined;
},
ActiveDoc(docManager, docName, options) { return new ActiveDoc(docManager, docName, options); },
NSandbox(options) {
return createSandbox('unsandboxed', options);
},
sessionSecret() {
const secret = process.env.GRIST_SESSION_SECRET || opts.sessionSecret;
if (!secret) {
throw new Error('need GRIST_SESSION_SECRET');
}
return secret;
},
configurationOptions() {
for (const storage of opts.storage || []) {
const config = storage.check();
if (config) { return config; }
}
return {};
},
getExtraHeadHtml() {
let customHeadHtmlSnippet = '';
if (process.env.APP_STATIC_INCLUDE_CUSTOM_CSS === 'true') {
customHeadHtmlSnippet += '<link rel="stylesheet" href="custom.css">';
}
return customHeadHtmlSnippet;
},
};
}