(core) updates from grist-core

This commit is contained in:
Paul Fitzpatrick
2023-09-18 15:04:08 -04:00
12 changed files with 751 additions and 85 deletions

View File

@@ -504,6 +504,11 @@ export class RightPanel extends Disposable {
const srcSec = use(tgtSec.linkSrcSection); //might be the empty section
const srcCol = use(tgtSec.linkSrcCol);
const srcColId = use(use(tgtSec.linkSrcCol).colId); // if srcCol is the empty col, colId will be undefined
if (srcSec.isDisposed()) { // can happen when deleting srcSection with rightpanel open
return cssLinkInfoPanel("");
}
//const tgtColId = use(use(tgtSec.linkTargetCol).colId);
const srcTable = use(srcSec.table);
const tgtTable = use(tgtSec.table);
@@ -616,6 +621,11 @@ export class RightPanel extends Disposable {
// but the fact that it's all observables makes that trickier to do correctly, so let's leave it here
const srcSec = use(activeSection.linkSrcSection); //might be the empty section
const tgtSec = activeSection;
if (srcSec.isDisposed()) { // can happen when deleting srcSection with rightpanel open
return cssRow("");
}
const srcCol = use(activeSection.linkSrcCol); // might be the empty column
const tgtCol = use(activeSection.linkTargetCol);
// columns might be the empty column

View File

@@ -1046,6 +1046,11 @@ export function buildTelemetryEventChecker(telemetryLevel: TelemetryLevel) {
`but received a value of type ${typeof value}`
);
}
if (typeof value === 'string' && !hasTimezone(value)) {
throw new Error(
`Telemetry metadata ${key} of event ${event} has an ambiguous date string`
);
}
} else if (dataType !== typeof value) {
throw new Error(
`Telemetry metadata ${key} of event ${event} expected a value of type ${dataType} ` +
@@ -1056,4 +1061,11 @@ export function buildTelemetryEventChecker(telemetryLevel: TelemetryLevel) {
};
}
// Check that datetime looks like it has a timezone in it. If not,
// that could be a problem for whatever ingests the data.
function hasTimezone(isoDateString: string) {
// Use a regular expression to check for a timezone offset or 'Z'
return /([+-]\d{2}:\d{2}|Z)$/.test(isoDateString);
}
export type TelemetryEventChecker = (event: TelemetryEvent, metadata?: TelemetryMetadata) => void;

View File

@@ -13,6 +13,7 @@ import log from 'app/server/lib/log';
import { IPermitStore } from 'app/server/lib/Permit';
import { optStringParam, stringParam } from 'app/server/lib/requestUtils';
import * as express from 'express';
import moment from 'moment';
import fetch from 'node-fetch';
import * as Fetch from 'node-fetch';
import { EntityManager } from 'typeorm';
@@ -185,8 +186,8 @@ export class Housekeeper {
numDocs: Number(summary.num_docs),
numWorkspaces: Number(summary.num_workspaces),
numMembers: Number(summary.num_members),
lastActivity: summary.last_activity,
earliestDocCreatedAt: summary.earliest_doc_created_at,
lastActivity: normalizedDateTimeString(summary.last_activity),
earliestDocCreatedAt: normalizedDateTimeString(summary.earliest_doc_created_at),
},
full: {
stripePlanId: summary.stripe_plan_id,
@@ -398,3 +399,29 @@ export class Housekeeper {
});
}
}
/**
* Output an ISO8601 format datetime string, with timezone.
* Any string fed in without timezone is expected to be in UTC.
*
* When connected to postgres, dates will be extracted as Date objects,
* with timezone information. The normalization done here is not
* really needed in this case.
*
* Timestamps in SQLite are stored as UTC, and read as strings
* (without timezone information). The normalization here is
* pretty important in this case.
*/
function normalizedDateTimeString(dateTime: any): string {
if (!dateTime) { return dateTime; }
if (dateTime instanceof Date) {
return moment(dateTime).toISOString();
}
if (typeof dateTime === 'string') {
// When SQLite returns a string, it will be in UTC.
// Need to make sure it actually have timezone info in it
// (will not by default).
return moment.utc(dateTime).toISOString();
}
throw new Error(`normalizedDateTimeString cannot handle ${dateTime}`);
}