(core) updates from grist-core

This commit is contained in:
Paul Fitzpatrick
2023-12-01 08:14:12 -05:00
29 changed files with 163 additions and 89 deletions

View File

@@ -212,6 +212,6 @@ export function attachAppEndpoint(options: AttachOptions): void {
// The * is a wildcard in express 4, rather than a regex symbol.
// See https://expressjs.com/en/guide/routing.html
app.get('/doc/:urlId([^/]+):remainder(*)', ...docMiddleware, docHandler);
app.get('/:urlId([^/]{12,})/:slug([^/]+):remainder(*)',
app.get('/:urlId([^/]{12,})(/:slug([^/]+):remainder(*))?',
...docMiddleware, docHandler);
}

View File

@@ -1998,8 +1998,13 @@ export class FlexServer implements GristServer {
// Only used as {userRoot}/plugins as a place for plugins in addition to {appRoot}/plugins
const userRoot = path.resolve(process.env.GRIST_USER_ROOT || getAppPathTo(this.appRoot, '.grist'));
this.info.push(['userRoot', userRoot]);
const pluginManager = new PluginManager(this.appRoot, userRoot);
// Some custom widgets may be included as an npm package called @gristlabs/grist-widget.
const bundledRoot = isAffirmative(process.env.GRIST_SKIP_BUNDLED_WIDGETS) ? undefined : path.join(
getAppPathTo(this.appRoot, 'node_modules'),
'@gristlabs', 'grist-widget', 'dist'
);
this.info.push(['bundledRoot', bundledRoot]);
const pluginManager = new PluginManager(this.appRoot, userRoot, bundledRoot);
// `initialize()` is asynchronous and reads plugins manifests; if PluginManager is used before it
// finishes, it will act as if there are no plugins.
// ^ I think this comment was here to justify calling initialize without waiting for

View File

@@ -46,7 +46,8 @@ function servePluginContent(req: express.Request, res: express.Response,
req.get('X-From-Plugin-WebView') === "true" ||
mimeTypes.lookup(path.extname(pluginPath)) === "application/javascript") {
const dirs = pluginManager.dirs();
const contentRoot = pluginKind === "installed" ? dirs.installed : dirs.builtIn;
const contentRoot = pluginKind === "installed" ? dirs.installed :
(pluginKind === "builtIn" ? dirs.builtIn : dirs.bundled);
// Note that pluginPath may not be safe, but `sendFile` with the "root" option restricts
// relative paths to be within the root folder (see the 3rd party library unit-test:
// https://github.com/pillarjs/send/blob/3daa901cf731b86187e4449fa2c52f971e0b3dbc/test/send.js#L1363)

View File

@@ -14,9 +14,14 @@ export interface PluginDirectories {
*/
readonly builtIn?: string;
/**
* Directory where user installed plugins are localted.
* Directory where user installed plugins are located.
*/
readonly installed?: string;
/**
* Yet another option, for plugins that are included
* during a build but not part of the codebase itself.
*/
readonly bundled?: string;
}
/**
@@ -44,10 +49,12 @@ export class PluginManager {
* @param {string} userRoot: path to user's grist directory; `null` is allowed, to only uses built in plugins.
*
*/
public constructor(public appRoot?: string, userRoot?: string) {
public constructor(public appRoot?: string, userRoot?: string,
public bundledRoot?: string) {
this._dirs = {
installed: userRoot ? path.join(userRoot, 'plugins') : undefined,
builtIn: appRoot ? getAppPathTo(appRoot, 'plugins') : undefined
builtIn: appRoot ? getAppPathTo(appRoot, 'plugins') : undefined,
bundled: bundledRoot ? getAppPathTo(bundledRoot, 'plugins') : undefined,
};
}
@@ -91,6 +98,11 @@ export class PluginManager {
this._entries.push(...await scanDirectory(this._dirs.builtIn, "builtIn"));
}
// Load bundled plugins
if (this._dirs.bundled) {
this._entries.push(...await scanDirectory(this._dirs.bundled, "bundled"));
}
if (!process.env.GRIST_EXPERIMENTAL_PLUGINS ||
process.env.GRIST_EXPERIMENTAL_PLUGINS === '0') {
// Remove experimental plugins
@@ -130,7 +142,7 @@ export class PluginManager {
}
async function scanDirectory(dir: string, kind: "installed"|"builtIn"): Promise<DirectoryScanEntry[]> {
async function scanDirectory(dir: string, kind: "installed"|"builtIn"|"bundled"): Promise<DirectoryScanEntry[]> {
const plugins: DirectoryScanEntry[] = [];
let listDir;

View File

@@ -187,7 +187,7 @@ export class Telemetry implements ITelemetry {
public addPages(app: express.Application, middleware: express.RequestHandler[]) {
if (this._deploymentType === 'core') {
app.get('/support-grist', ...middleware, expressWrap(async (req, resp) => {
app.get('/support', ...middleware, expressWrap(async (req, resp) => {
return this._gristServer.sendAppPage(req, resp,
{path: 'app.html', status: 200, config: {}});
}));

View File

@@ -142,6 +142,7 @@ export function getTypeORMSettings(): DataSourceOptions {
"subscribers": [
`${codeRoot}/app/gen-server/subscriber/*.js`
],
...JSON.parse(process.env.TYPEORM_EXTRA || "{}"),
...cache,
};
}