(core) Update dependencies

Summary:
Changes the minimum version of Node to 18, and updates the Docker images and GitHub workflows to build Grist with Node 18.

Also updates various dependencies and scripts to support building running tests with arm64 builds of Node.

Test Plan: Existing tests.

Reviewers: paulfitz

Reviewed By: paulfitz

Differential Revision: https://phab.getgrist.com/D3968
This commit is contained in:
George Gevoian
2023-10-11 17:03:02 -04:00
parent 519f2f4fb6
commit 0cadb93d25
45 changed files with 4049 additions and 907 deletions

View File

@@ -628,6 +628,8 @@ export class CustomSectionConfig extends Disposable {
protected async _getWidgets() {
const api = this._gristDoc.app.topAppModel.api;
const widgets = await api.getWidgets();
if (this.isDisposed()) { return; }
// Request for rest of the widgets.
if (this._canSelect) {
// From the start we will provide single widget definition

View File

@@ -243,6 +243,15 @@ async function getMappingsIfChanged(data: any): Promise<WidgetColumnMap|null> {
return _mappingsCache ? JSON.parse(JSON.stringify(_mappingsCache)) : null;
}
/**
* Used by tests to wait for all pending requests to settle.
*
* TODO: currently only waits for requests for mappings.
*/
export async function testWaitForPendingRequests() {
return await _activeRefreshReq;
}
/**
* Renames columns in the result using columns mapping configuration passed in ready method.
* Returns null if not all required columns were mapped or not widget doesn't support

View File

@@ -68,7 +68,6 @@ import {addUploadRoute} from 'app/server/lib/uploads';
import {buildWidgetRepository, IWidgetRepository} from 'app/server/lib/WidgetRepository';
import {setupLocale} from 'app/server/localization';
import axios from 'axios';
import * as bodyParser from 'body-parser';
import * as cookie from 'cookie';
import express from 'express';
import * as fse from 'fs-extra';
@@ -789,7 +788,7 @@ export class FlexServer implements GristServer {
public addJsonSupport() {
if (this._check('json')) { return; }
this.app.use(bodyParser.json({limit: '1mb'})); // Increase from the default 100kb
this.app.use(express.json({limit: '1mb'})); // Increase from the default 100kb
}
public addSessions() {

View File

@@ -737,6 +737,10 @@ function gvisor(options: ISandboxOptions): SandboxProcess {
wrapperArgs.push(process.env.GRIST_CHECKPOINT!);
}
const child = spawn(command, [...wrapperArgs.get(), `python${pythonVersion}`, '--', ...pythonArgs]);
if (!child.pid) {
throw new Error(`failed to spawn python${pythonVersion}`);
}
// For gvisor under ptrace, main work is done by a traced process identifiable as
// being labeled "exe" and having a parent also labeled "exe".
const recognizeTracedProcess = (p: ProcessInfo) => {

View File

@@ -52,7 +52,6 @@
*
*/
import * as bodyParser from 'body-parser';
import * as express from 'express';
import * as fse from 'fs-extra';
import * as saml2 from 'saml2-js';
@@ -161,7 +160,7 @@ export class SamlConfig {
}));
// Assert endpoint for when the login completes as POST.
app.post("/saml/assert", bodyParser.urlencoded({extended: true}), expressWrap(async (req, res, next) => {
app.post("/saml/assert", express.urlencoded({extended: true}), expressWrap(async (req, res, next) => {
const relayState: string = req.body.RelayState;
if (!relayState) { throw new Error('Login or logout failed to complete'); }
const permitStore = this._gristServer.getExternalPermitStore();

View File

@@ -30,12 +30,16 @@ export interface ISandboxControl {
* Control a single process directly. A thin wrapper around the Throttle class.
*/
export class DirectProcessControl implements ISandboxControl {
private _pid: number;
private _throttle?: Throttle;
constructor(private _process: childProcess.ChildProcess, logMeta?: log.ILogMeta) {
if (!_process.pid) { throw new Error(`process identifier (PID) is undefined`); }
this._pid = _process.pid;
if (process.env.GRIST_THROTTLE_CPU) {
this._throttle = new Throttle({
pid: _process.pid,
pid: this._pid,
logMeta: {...logMeta, pid: _process.pid},
});
}
@@ -55,7 +59,7 @@ export class DirectProcessControl implements ISandboxControl {
}
public async getUsage() {
const memory = (await pidusage(this._process.pid)).memory;
const memory = (await pidusage(this._pid)).memory;
return { memory };
}
}

View File

@@ -2,10 +2,16 @@ import {RequestWithLogin} from 'app/server/lib/Authorizer';
import log from 'app/server/lib/log';
import * as express from 'express';
export type AsyncRequestHandler = (
req: express.Request,
res: express.Response,
next: express.NextFunction
) => any | Promise<any>;
/**
* Wrapper for async express endpoints to catch errors and forward them to the error handler.
*/
export function expressWrap(callback: express.RequestHandler): express.RequestHandler {
export function expressWrap(callback: AsyncRequestHandler): express.RequestHandler {
return async (req, res, next) => {
try {
await callback(req, res, next);