mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
A set of tweaks to simplify electron packaging (#421)
* Replace `ormconfig.js` with a newer mechanism of configuring TypeORM that can be included in the source code properly. The path to `ormconfig.js` has always been awkward to handle, and eliminating the file makes building different Grist setups a bit simpler. * Remove `electron` package. It is barely used, just for some old remnants of an older attempt at electron packaging. It was used for two types, which I left at `any` for now. More code pruning is no doubt possible here, but I'd rather do it when Electron packaging has solidified. * Add a hook for replacing the login system, and for adding some extra middleware the login system may need. * Add support for some more possible locations of Python, which arise when a standalone version of it is included in the Electron package. This isn't very general purpose, just configurations that I found useful. * Support using grist-core within a yarn workspace - the only tweak needed was webpack related. * Allow an external ID to be optionally associated with documents.
This commit is contained in:
parent
d55e56297e
commit
f7f76fb5e7
@ -103,7 +103,6 @@ COPY --from=sandbox /runsc /usr/bin/runsc
|
||||
|
||||
# Add files needed for running server.
|
||||
ADD package.json /grist/package.json
|
||||
ADD ormconfig.js /grist/ormconfig.js
|
||||
ADD bower_components /grist/bower_components
|
||||
ADD sandbox /grist/sandbox
|
||||
ADD plugins /grist/plugins
|
||||
|
@ -40,7 +40,6 @@ import { getOriginUrl } from 'app/common/urlUtils';
|
||||
import { GristAPI, RPC_GRISTAPI_INTERFACE } from 'app/plugin/GristAPI';
|
||||
import { RenderOptions, RenderTarget } from 'app/plugin/RenderOptions';
|
||||
import { checkers } from 'app/plugin/TypeCheckers';
|
||||
import { IpcMessageEvent } from 'electron';
|
||||
import { IMsgCustom, IMsgRpcCall, Rpc } from 'grain-rpc';
|
||||
import { Disposable } from './dispose';
|
||||
const G = getBrowserGlobals('document', 'window');
|
||||
@ -316,7 +315,7 @@ class WebviewProcess extends ViewProcess {
|
||||
// TODO: find a way for keyboard events to play nice when webviews are non-modal.
|
||||
Mousetrap.setPaused(true);
|
||||
this.autoDisposeCallback(() => Mousetrap.setPaused(false));
|
||||
webview.addEventListener('ipc-message', (event: IpcMessageEvent) => {
|
||||
webview.addEventListener('ipc-message', (event: any /* IpcMessageEvent */) => {
|
||||
// The event object passed to the listener is missing proper documentation. In the examples
|
||||
// listed in https://electronjs.org/docs/api/ipc-main the arguments should be passed to the
|
||||
// listener after the event object, but this is not happening here. Only we know it is a
|
||||
|
@ -14,7 +14,6 @@ import {GristLoadConfig} from 'app/common/gristUrls';
|
||||
import {byteString, safeJsonParse} from 'app/common/gutil';
|
||||
import {FetchUrlOptions, UPLOAD_URL_PATH, UploadResult} from 'app/common/uploads';
|
||||
import {docUrl} from 'app/common/urlUtils';
|
||||
import {OpenDialogOptions} from 'electron';
|
||||
import noop = require('lodash/noop');
|
||||
import trimStart = require('lodash/trimStart');
|
||||
import {basename} from 'path'; // made available by webpack using path-browserify module.
|
||||
@ -69,18 +68,18 @@ function getFileDialogOptions(options: SelectFileOptions): FileDialogOptions {
|
||||
}
|
||||
|
||||
// Helper to convert SelectFileOptions to electron's OpenDialogOptions.
|
||||
function getElectronOptions(options: SelectFileOptions): OpenDialogOptions {
|
||||
const resOptions: OpenDialogOptions = {
|
||||
filters: [],
|
||||
function getElectronOptions(options: SelectFileOptions) /*: OpenDialogOptions */ {
|
||||
const resOptions /*: OpenDialogOptions*/ = {
|
||||
filters: [] as Array<{name: string, extensions: any}>,
|
||||
properties: ['openFile'],
|
||||
};
|
||||
if (options.extensions) {
|
||||
// Electron does not expect leading period.
|
||||
const extensions = options.extensions.map(e => trimStart(e, '.'));
|
||||
resOptions.filters!.push({name: 'Select files', extensions});
|
||||
resOptions.filters.push({name: 'Select files', extensions});
|
||||
}
|
||||
if (options.multiple) {
|
||||
resOptions.properties!.push('multiSelections');
|
||||
resOptions.properties.push('multiSelections');
|
||||
}
|
||||
return resOptions;
|
||||
}
|
||||
|
@ -115,6 +115,8 @@ export interface DocumentOptions {
|
||||
description?: string|null;
|
||||
icon?: string|null;
|
||||
openMode?: OpenDocMode|null;
|
||||
externalId?: string|null; // A slot for storing an externally maintained id.
|
||||
// Not used in grist-core, but handy for Electron app.
|
||||
}
|
||||
|
||||
export interface DocumentProperties extends CommonProperties {
|
||||
|
@ -99,6 +99,9 @@ export class Document extends Resource {
|
||||
if (props.options.icon !== undefined) {
|
||||
this.options.icon = sanitizeIcon(props.options.icon);
|
||||
}
|
||||
if (props.options.externalId !== undefined) {
|
||||
this.options.externalId = props.options.externalId;
|
||||
}
|
||||
// Normalize so that null equates with absence.
|
||||
for (const key of Object.keys(this.options) as Array<keyof DocumentOptions>) {
|
||||
if (this.options[key] === null) {
|
||||
|
@ -36,7 +36,8 @@ import {DocWorkerInfo, IDocWorkerMap} from 'app/server/lib/DocWorkerMap';
|
||||
import {expressWrap, jsonErrorHandler, secureJsonErrorHandler} from 'app/server/lib/expressWrap';
|
||||
import {Hosts, RequestWithOrg} from 'app/server/lib/extractOrg';
|
||||
import {addGoogleAuthEndpoint} from "app/server/lib/GoogleAuth";
|
||||
import {DocTemplate, GristLoginMiddleware, GristServer, RequestWithGrist} from 'app/server/lib/GristServer';
|
||||
import {DocTemplate, GristLoginMiddleware, GristLoginSystem, GristServer,
|
||||
RequestWithGrist} from 'app/server/lib/GristServer';
|
||||
import {initGristSessions, SessionStore} from 'app/server/lib/gristSessions';
|
||||
import {HostedStorageManager} from 'app/server/lib/HostedStorageManager';
|
||||
import {IBilling} from 'app/server/lib/IBilling';
|
||||
@ -157,6 +158,7 @@ export class FlexServer implements GristServer {
|
||||
private _getSignUpRedirectUrl: (req: express.Request, target: URL) => Promise<string>;
|
||||
private _getLogoutRedirectUrl: (req: express.Request, nextUrl: URL) => Promise<string>;
|
||||
private _sendAppPage: (req: express.Request, resp: express.Response, options: ISendAppPageOptions) => Promise<void>;
|
||||
private _getLoginSystem?: () => Promise<GristLoginSystem>;
|
||||
|
||||
constructor(public port: number, public name: string = 'flexServer',
|
||||
public readonly options: FlexServerOptions = {}) {
|
||||
@ -233,6 +235,11 @@ export class FlexServer implements GristServer {
|
||||
});
|
||||
}
|
||||
|
||||
// Allow overridding the login system.
|
||||
public setLoginSystem(loginSystem: () => Promise<GristLoginSystem>) {
|
||||
this._getLoginSystem = loginSystem;
|
||||
}
|
||||
|
||||
public getHost(): string {
|
||||
return `${this.host}:${this.getOwnPort()}`;
|
||||
}
|
||||
@ -481,12 +488,19 @@ export class FlexServer implements GristServer {
|
||||
this.app.use(/^\/help\//, expressWrap(async (req, res) => {
|
||||
res.redirect('https://support.getgrist.com');
|
||||
}));
|
||||
// If there is a directory called "static_ext", serve material from there
|
||||
// as well. This isn't used in grist-core but is handy for extensions such
|
||||
// as an Electron app.
|
||||
const staticExtDir = getAppPathTo(this.appRoot, 'static') + '_ext';
|
||||
const staticExtApp = fse.existsSync(staticExtDir) ?
|
||||
express.static(staticExtDir, options) : null;
|
||||
const staticApp = express.static(getAppPathTo(this.appRoot, 'static'), options);
|
||||
const bowerApp = express.static(getAppPathTo(this.appRoot, 'bower_components'), options);
|
||||
if (process.env.GRIST_LOCALES_DIR) {
|
||||
const locales = express.static(process.env.GRIST_LOCALES_DIR, options);
|
||||
this.app.use("/locales", this.tagChecker.withTag(locales));
|
||||
}
|
||||
if (staticExtApp) { this.app.use(this.tagChecker.withTag(staticExtApp)); }
|
||||
this.app.use(this.tagChecker.withTag(staticApp));
|
||||
this.app.use(this.tagChecker.withTag(bowerApp));
|
||||
}
|
||||
@ -700,7 +714,7 @@ export class FlexServer implements GristServer {
|
||||
this.addOrg();
|
||||
|
||||
// Create the sessionStore and related objects.
|
||||
const {sessions, sessionMiddleware, sessionStore} = initGristSessions(this.instanceRoot, this);
|
||||
const {sessions, sessionMiddleware, sessionStore} = initGristSessions(getUnpackedAppRoot(this.instanceRoot), this);
|
||||
this.app.use(sessionMiddleware);
|
||||
this.app.use(signInStatusMiddleware);
|
||||
|
||||
@ -901,11 +915,16 @@ export class FlexServer implements GristServer {
|
||||
|
||||
// TODO: We could include a third mock provider of login/logout URLs for better tests. Or we
|
||||
// could create a mock SAML identity provider for testing this using the SAML flow.
|
||||
const loginSystem = await (process.env.GRIST_TEST_LOGIN ? getTestLoginSystem() : getLoginSystem());
|
||||
const loginSystem = await (process.env.GRIST_TEST_LOGIN ? getTestLoginSystem() :
|
||||
(this._getLoginSystem?.() || getLoginSystem()));
|
||||
this._loginMiddleware = await loginSystem.getMiddleware(this);
|
||||
this._getLoginRedirectUrl = tbind(this._loginMiddleware.getLoginRedirectUrl, this._loginMiddleware);
|
||||
this._getSignUpRedirectUrl = tbind(this._loginMiddleware.getSignUpRedirectUrl, this._loginMiddleware);
|
||||
this._getLogoutRedirectUrl = tbind(this._loginMiddleware.getLogoutRedirectUrl, this._loginMiddleware);
|
||||
const wildcardMiddleware = this._loginMiddleware.getWildcardMiddleware?.();
|
||||
if (wildcardMiddleware?.length) {
|
||||
this.app.use(wildcardMiddleware);
|
||||
}
|
||||
}
|
||||
|
||||
public addComm() {
|
||||
|
@ -62,6 +62,8 @@ export interface GristLoginMiddleware {
|
||||
getLoginOrSignUpMiddleware?(): express.RequestHandler[];
|
||||
// Optional middleware for the GET /logout route.
|
||||
getLogoutMiddleware?(): express.RequestHandler[];
|
||||
// Optional middleware for all routes.
|
||||
getWildcardMiddleware?(): express.RequestHandler[];
|
||||
// Returns arbitrary string for log.
|
||||
addEndpoints(app: express.Express): Promise<string>;
|
||||
// Optionally, extract profile from request. Result can be a profile,
|
||||
|
@ -40,7 +40,7 @@ export async function getMinimalLoginSystem(): Promise<GristLoginSystem> {
|
||||
};
|
||||
}
|
||||
|
||||
function getDefaultProfile(): UserProfile {
|
||||
export function getDefaultProfile(): UserProfile {
|
||||
return {
|
||||
email: process.env.GRIST_DEFAULT_EMAIL || 'you@example.com',
|
||||
name: 'You',
|
||||
|
@ -5,6 +5,7 @@ import {arrayToString} from 'app/common/arrayToString';
|
||||
import * as marshal from 'app/common/marshal';
|
||||
import {ISandbox, ISandboxCreationOptions, ISandboxCreator} from 'app/server/lib/ISandbox';
|
||||
import log from 'app/server/lib/log';
|
||||
import {getAppRoot, getAppRootFor, getUnpackedAppRoot} from 'app/server/lib/places';
|
||||
import {
|
||||
DirectProcessControl,
|
||||
ISandboxControl,
|
||||
@ -575,7 +576,7 @@ function gvisor(options: ISandboxOptions): SandboxProcess {
|
||||
// Check for local virtual environments created with core's
|
||||
// install:python2 or install:python3 targets. They'll need
|
||||
// some extra sharing to make available in the sandbox.
|
||||
const venv = path.join(process.cwd(),
|
||||
const venv = path.join(getAppRootFor(getAppRoot(), 'sandbox'),
|
||||
pythonVersion === '2' ? 'venv' : 'sandbox_venv3');
|
||||
if (fs.existsSync(venv)) {
|
||||
wrapperArgs.addMount(venv);
|
||||
@ -869,19 +870,24 @@ function findPython(command: string|undefined, preferredVersion?: string) {
|
||||
// TODO: rationalize this, it is a product of haphazard growth.
|
||||
const prefs = preferredVersion === '2' ? ['venv', 'sandbox_venv3'] : ['sandbox_venv3', 'venv'];
|
||||
for (const venv of prefs) {
|
||||
const pythonPath = path.join(process.cwd(), venv, 'bin', 'python');
|
||||
if (fs.existsSync(pythonPath)) {
|
||||
command = pythonPath;
|
||||
break;
|
||||
const base = getUnpackedAppRoot();
|
||||
// Try a battery of possible python executable paths when python is installed
|
||||
// in a standalone directory.
|
||||
// This battery of possibilities comes from Electron packaging, where python
|
||||
// is bundled with Grist. Not all the possibilities are needed (there are
|
||||
// multiple popular python bundles per OS).
|
||||
for (const possiblePath of [['bin', 'python'], ['bin', 'python3'],
|
||||
['Scripts', 'python.exe'], ['python.exe']] as const) {
|
||||
const pythonPath = path.join(base, venv, ...possiblePath);
|
||||
if (fs.existsSync(pythonPath)) {
|
||||
return pythonPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fall back on system python.
|
||||
if (!command) {
|
||||
command = which.sync(preferredVersion === '2' ? 'python2' : 'python3', {nothrow: true})
|
||||
|| which.sync(preferredVersion === '2' ? 'python2.7' : 'python3.9', {nothrow: true})
|
||||
|| which.sync('python');
|
||||
}
|
||||
return command;
|
||||
return which.sync(preferredVersion === '2' ? 'python2' : 'python3', {nothrow: true})
|
||||
|| which.sync(preferredVersion === '2' ? 'python2.7' : 'python3.9', {nothrow: true})
|
||||
|| which.sync('python');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {synchronizeProducts} from 'app/gen-server/entity/Product';
|
||||
import {codeRoot} from 'app/server/lib/places';
|
||||
import {Mutex} from 'async-mutex';
|
||||
import {Connection, createConnection, getConnection} from 'typeorm';
|
||||
import {Connection, createConnection, DataSourceOptions, getConnection} from 'typeorm';
|
||||
|
||||
// Summary of migrations found in database and in code.
|
||||
interface MigrationSummary {
|
||||
@ -61,7 +62,7 @@ export async function getOrCreateConnection(): Promise<Connection> {
|
||||
if (!String(e).match(/ConnectionNotFoundError/)) {
|
||||
throw e;
|
||||
}
|
||||
const connection = await createConnection();
|
||||
const connection = await createConnection(getTypeORMSettings());
|
||||
// When using Sqlite, set a busy timeout of 3s to tolerate a little
|
||||
// interference from connections made by tests. Logging doesn't show
|
||||
// any particularly slow queries, but bad luck is possible.
|
||||
@ -98,3 +99,49 @@ export async function undoLastMigration(connection: Connection) {
|
||||
});
|
||||
if (sqlite) { await connection.query("PRAGMA foreign_keys = ON;"); }
|
||||
}
|
||||
|
||||
// Replace the old janky ormconfig.js file, which was always a source of
|
||||
// pain to use since it wasn't properly integrated into the typescript
|
||||
// project.
|
||||
function getTypeORMSettings(): DataSourceOptions {
|
||||
// If we have a redis server available, tell typeorm. Then any queries built with
|
||||
// .cache() called on them will be cached via redis.
|
||||
// We use a separate environment variable for the moment so that we don't have to
|
||||
// enable this until we really need it.
|
||||
const redisUrl = process.env.TYPEORM_REDIS_URL ? new URL(process.env.TYPEORM_REDIS_URL) : undefined;
|
||||
const cache = redisUrl ? {
|
||||
cache: {
|
||||
type: "redis",
|
||||
options: {
|
||||
host: redisUrl.hostname,
|
||||
port: parseInt(redisUrl.port || "6379", 10)
|
||||
}
|
||||
} as const
|
||||
} : undefined;
|
||||
|
||||
return {
|
||||
"name": process.env.TYPEORM_NAME || "default",
|
||||
"type": (process.env.TYPEORM_TYPE as any) || "sqlite", // officially, TYPEORM_CONNECTION -
|
||||
// but if we use that, this file will never
|
||||
// be read, and we can't configure
|
||||
// caching otherwise.
|
||||
"database": process.env.TYPEORM_DATABASE || "landing.db",
|
||||
"username": process.env.TYPEORM_USERNAME || undefined,
|
||||
"password": process.env.TYPEORM_PASSWORD || undefined,
|
||||
"host": process.env.TYPEORM_HOST || undefined,
|
||||
"port": process.env.TYPEORM_PORT ? parseInt(process.env.TYPEORM_PORT, 10) : undefined,
|
||||
"synchronize": false,
|
||||
"migrationsRun": false,
|
||||
"logging": process.env.TYPEORM_LOGGING === "true",
|
||||
"entities": [
|
||||
`${codeRoot}/app/gen-server/entity/*.js`
|
||||
],
|
||||
"migrations": [
|
||||
`${codeRoot}/app/gen-server/migration/*.js` // migration files don't actually get packaged.
|
||||
],
|
||||
"subscribers": [
|
||||
`${codeRoot}/app/gen-server/subscriber/*.js`
|
||||
],
|
||||
...cache,
|
||||
};
|
||||
}
|
||||
|
@ -9,14 +9,25 @@ import * as path from 'path';
|
||||
*/
|
||||
export const codeRoot = path.dirname(path.dirname(path.dirname(__dirname)));
|
||||
|
||||
let _cachedAppRoot: string|undefined;
|
||||
|
||||
/**
|
||||
* Returns the appRoot, i.e. the directory containing ./sandbox, ./node_modules, ./ormconfig.js,
|
||||
* Returns the appRoot, i.e. the directory containing ./sandbox, ./node_modules,
|
||||
* etc.
|
||||
*/
|
||||
export function getAppRoot(): string {
|
||||
if (_cachedAppRoot) { return _cachedAppRoot; }
|
||||
_cachedAppRoot = getAppRootWithoutCaching();
|
||||
return _cachedAppRoot;
|
||||
}
|
||||
|
||||
// Uncached version of getAppRoot()
|
||||
function getAppRootWithoutCaching(): string {
|
||||
if (process.env.APP_ROOT_PATH) { return process.env.APP_ROOT_PATH; }
|
||||
if (codeRoot.endsWith('/_build/core')) { return path.dirname(path.dirname(codeRoot)); }
|
||||
return codeRoot.endsWith('/_build') ? path.dirname(codeRoot) : codeRoot;
|
||||
if (codeRoot.endsWith('/_build/core') || codeRoot.endsWith('\\_build\\core')) {
|
||||
return path.dirname(path.dirname(codeRoot));
|
||||
}
|
||||
return (codeRoot.endsWith('/_build') || codeRoot.endsWith('\\_build')) ? path.dirname(codeRoot) : codeRoot;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -25,7 +36,14 @@ export function getAppRoot(): string {
|
||||
* which is that .asar file in packaged form, and returns a directory where
|
||||
* remaining files are available on the regular filesystem.
|
||||
*/
|
||||
export function getUnpackedAppRoot(appRoot: string): string {
|
||||
export function getUnpackedAppRoot(appRoot: string = getAppRoot()): string {
|
||||
if (path.basename(appRoot) == 'app.asar') {
|
||||
return path.resolve(path.dirname(appRoot), 'app.asar.unpacked');
|
||||
}
|
||||
if (path.dirname(appRoot).endsWith('app.asar')) {
|
||||
return path.resolve(path.dirname(path.dirname(appRoot)),
|
||||
'app.asar.unpacked', 'core');
|
||||
}
|
||||
return path.resolve(path.dirname(appRoot), path.basename(appRoot, '.asar'));
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
import {FlexServer, FlexServerOptions} from 'app/server/lib/FlexServer';
|
||||
import {GristLoginSystem} from 'app/server/lib/GristServer';
|
||||
import log from 'app/server/lib/log';
|
||||
|
||||
// Allowed server types. We'll start one or a combination based on the value of GRIST_SERVERS
|
||||
@ -36,13 +37,14 @@ interface ServerOptions extends FlexServerOptions {
|
||||
// logToConsole is set to true)
|
||||
externalStorage?: boolean; // If set, documents saved to external storage such as s3 (default is to check environment
|
||||
// variables, which get set in various ways in dev/test entry points)
|
||||
loginSystem?: () => Promise<GristLoginSystem>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a server on the given port, including the functionality specified in serverTypes.
|
||||
*/
|
||||
export async function main(port: number, serverTypes: ServerType[],
|
||||
options: ServerOptions = {logToConsole: true}) {
|
||||
options: ServerOptions = {}) {
|
||||
const includeHome = serverTypes.includes("home");
|
||||
const includeDocs = serverTypes.includes("docs");
|
||||
const includeStatic = serverTypes.includes("static");
|
||||
@ -50,6 +52,10 @@ export async function main(port: number, serverTypes: ServerType[],
|
||||
|
||||
const server = new FlexServer(port, `server(${serverTypes.join(",")})`, options);
|
||||
|
||||
if (options.loginSystem) {
|
||||
server.setLoginSystem(options.loginSystem);
|
||||
}
|
||||
|
||||
server.addCleanup();
|
||||
server.setDirectory();
|
||||
|
||||
@ -58,7 +64,7 @@ export async function main(port: number, serverTypes: ServerType[],
|
||||
server.testAddRouter();
|
||||
}
|
||||
|
||||
if (options.logToConsole) { server.addLogging(); }
|
||||
if (options.logToConsole !== false) { server.addLogging(); }
|
||||
if (options.externalStorage === false) { server.disableExternalStorage(); }
|
||||
await server.loadConfig();
|
||||
|
||||
|
@ -2,10 +2,25 @@
|
||||
|
||||
set -e
|
||||
|
||||
# Use a built-in standalone version of Python if available in a directory
|
||||
# called python. This is used for Electron packaging. The standalone Python
|
||||
# will have extra packages installed, and then be moved to a standard location
|
||||
# (sandbox_venv3).
|
||||
for possible_path in python/bin/python python/bin/python3 \
|
||||
python/Scripts/python.exe python/python.exe; do
|
||||
if [[ -e $possible_path ]]; then
|
||||
echo "found $possible_path"
|
||||
buildtools/prepare_python3.sh $possible_path python
|
||||
# Make sure Python2 sandbox is not around.
|
||||
rm -rf venv
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Use Python3 if available and recent enough, otherwise Python2"
|
||||
if python3 -c 'import sys; assert sys.version_info >= (3,9)' 2> /dev/null; then
|
||||
# Default to python3 if recent enough.
|
||||
buildtools/prepare_python3.sh
|
||||
buildtools/prepare_python3.sh python3
|
||||
# Make sure python2 isn't around.
|
||||
rm -rf venv
|
||||
else
|
||||
|
@ -1,12 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Prepare a Python3 sandbox in the sandbox_venv3 directory.
|
||||
# Optionally, can be called with the command to use for Python,
|
||||
# and the directory of a standalone version of Python to incorporate.
|
||||
|
||||
set -e
|
||||
|
||||
echo "Making Python3 sandbox"
|
||||
if [ ! -e sandbox_venv3 ]; then
|
||||
python3 -m venv sandbox_venv3
|
||||
if [[ -e sandbox_venv3 ]]; then
|
||||
echo "Have Python3 sandbox"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
python="$1"
|
||||
python_dir="$2"
|
||||
if [[ "$python_dir" = "" ]]; then
|
||||
python=python3
|
||||
pip=sandbox_venv3/bin/pip
|
||||
echo "Making Python3 sandbox"
|
||||
$python -m venv sandbox_venv3
|
||||
else
|
||||
pip="$python -m pip"
|
||||
fi
|
||||
|
||||
echo "Updating Python3 packages"
|
||||
sandbox_venv3/bin/pip install --no-deps -r sandbox/requirements3.txt
|
||||
$pip install --no-deps -r sandbox/requirements3.txt
|
||||
|
||||
if [[ ! -e sandbox_venv3 ]]; then
|
||||
echo "Moving $python_dir to sandbox_venv3"
|
||||
mv $python_dir sandbox_venv3
|
||||
fi
|
||||
echo "Python3 packages ready in sandbox_venv3"
|
||||
|
@ -1,5 +1,10 @@
|
||||
const path = require('path');
|
||||
|
||||
// Get path to top-level node_modules if in a yarn workspace.
|
||||
// Otherwise node_modules one level up won't get resolved.
|
||||
// This is used in Electron packaging.
|
||||
const base = path.dirname(path.dirname(require.resolve('grainjs/package.json')));
|
||||
|
||||
module.exports = {
|
||||
target: 'web',
|
||||
entry: {
|
||||
@ -18,7 +23,8 @@ module.exports = {
|
||||
path.resolve('.'),
|
||||
path.resolve('./ext'),
|
||||
path.resolve('./stubs'),
|
||||
path.resolve('./node_modules')
|
||||
path.resolve('./node_modules'),
|
||||
base,
|
||||
],
|
||||
fallback: {
|
||||
'path': require.resolve("path-browserify"),
|
||||
|
@ -2,6 +2,11 @@ const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
|
||||
const { ProvidePlugin } = require('webpack');
|
||||
const path = require('path');
|
||||
|
||||
// Get path to top-level node_modules if in a yarn workspace.
|
||||
// Otherwise node_modules one level up won't get resolved.
|
||||
// This is used in Electron packaging.
|
||||
const base = path.dirname(path.dirname(require.resolve('grainjs/package.json')));
|
||||
|
||||
module.exports = {
|
||||
target: 'web',
|
||||
entry: {
|
||||
@ -39,7 +44,8 @@ module.exports = {
|
||||
path.resolve('.'),
|
||||
path.resolve('./ext'),
|
||||
path.resolve('./stubs'),
|
||||
path.resolve('./node_modules')
|
||||
path.resolve('./node_modules'),
|
||||
base,
|
||||
],
|
||||
fallback: {
|
||||
'path': require.resolve("path-browserify"),
|
||||
|
49
ormconfig.js
49
ormconfig.js
@ -1,49 +0,0 @@
|
||||
// Cache configuration for typeorm does not seem available via ormconfig.env, so
|
||||
// we use ormconfig.js style.
|
||||
|
||||
const {codeRoot} = require('app/server/lib/places');
|
||||
|
||||
module.exports = {
|
||||
"name": process.env.TYPEORM_NAME || "default",
|
||||
"type": process.env.TYPEORM_TYPE || "sqlite", // officially, TYPEORM_CONNECTION -
|
||||
// but if we use that, this file will never
|
||||
// be read, and we can't configure
|
||||
// caching otherwise.
|
||||
"database": process.env.TYPEORM_DATABASE || "landing.db",
|
||||
"username": process.env.TYPEORM_USERNAME || null,
|
||||
"password": process.env.TYPEORM_PASSWORD || null,
|
||||
"host": process.env.TYPEORM_HOST || null,
|
||||
"port": process.env.TYPEORM_PORT || null,
|
||||
"synchronize": false,
|
||||
"migrationsRun": false,
|
||||
"logging": process.env.TYPEORM_LOGGING === "true",
|
||||
"entities": [
|
||||
`${codeRoot}/app/gen-server/entity/*.js`
|
||||
],
|
||||
"migrations": [
|
||||
`${codeRoot}/app/gen-server/migration/*.js` // migration files don't actually get packaged.
|
||||
],
|
||||
"subscribers": [
|
||||
`${codeRoot}/app/gen-server/subscriber/*.js`
|
||||
],
|
||||
"cli": {
|
||||
"entitiesDir": `${codeRoot}/app/gen-server/entity`,
|
||||
"migrationsDir": `${codeRoot}/app/gen-server/migration`,
|
||||
"subscribersDir": `${codeRoot}/app/gen-server/subscriber`
|
||||
}
|
||||
};
|
||||
|
||||
// If we have a redis server available, tell typeorm. Then any queries built with
|
||||
// .cache() called on them will be cached via redis.
|
||||
// We use a separate environment variable for the moment so that we don't have to
|
||||
// enable this until we really need it.
|
||||
if (process.env.TYPEORM_REDIS_URL) {
|
||||
const url = require('url').parse(process.env.TYPEORM_REDIS_URL);
|
||||
module.exports.cache = {
|
||||
type: "redis",
|
||||
options: {
|
||||
host: url.hostname,
|
||||
port: parseInt(url.port || "6379", 10)
|
||||
}
|
||||
};
|
||||
}
|
@ -131,7 +131,6 @@
|
||||
"csv": "4.0.0",
|
||||
"diff-match-patch": "1.0.5",
|
||||
"double-ended-queue": "2.1.0-0",
|
||||
"electron": "19.0.9",
|
||||
"exceljs": "4.2.1",
|
||||
"express": "4.16.4",
|
||||
"file-type": "16.5.4",
|
||||
|
172
yarn.lock
172
yarn.lock
@ -218,22 +218,6 @@
|
||||
resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz"
|
||||
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
|
||||
|
||||
"@electron/get@^1.14.1":
|
||||
version "1.14.1"
|
||||
resolved "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz"
|
||||
integrity sha512-BrZYyL/6m0ZXz/lDxy/nlVhQz+WF+iPS6qXolEU8atw7h6v1aYkjwJZ63m+bJMBTxDE66X+r2tPS4a/8C82sZw==
|
||||
dependencies:
|
||||
debug "^4.1.1"
|
||||
env-paths "^2.2.0"
|
||||
fs-extra "^8.1.0"
|
||||
got "^9.6.0"
|
||||
progress "^2.0.3"
|
||||
semver "^6.2.0"
|
||||
sumchecker "^3.0.1"
|
||||
optionalDependencies:
|
||||
global-agent "^3.0.0"
|
||||
global-tunnel-ng "^2.7.1"
|
||||
|
||||
"@eslint/eslintrc@^1.3.0":
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.4.1.tgz#af58772019a2d271b7e2d4c23ff4ddcba3ccfb3e"
|
||||
@ -831,11 +815,6 @@
|
||||
resolved "https://registry.npmjs.org/@types/node/-/node-14.17.6.tgz"
|
||||
integrity sha512-iBxsxU7eswQDGhlr3AiamBxOssaYxbM+NKXVil8jg9yFXvrfEFbDumLD/2dMTB+zYyg7w+Xjt8yuxfdbUHAtcQ==
|
||||
|
||||
"@types/node@^16.11.26":
|
||||
version "16.11.58"
|
||||
resolved "https://registry.npmjs.org/@types/node/-/node-16.11.58.tgz"
|
||||
integrity sha512-uMVxJ111wpHzkx/vshZFb6Qni3BOMnlWLq7q9jrwej7Yw/KvjsEbpxCCxw+hLKxexFMc8YmpG8J9tnEe/rKsIg==
|
||||
|
||||
"@types/parse5@*":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.npmjs.org/@types/parse5/-/parse5-7.0.0.tgz"
|
||||
@ -1780,11 +1759,6 @@ body-parser@1.18.3:
|
||||
raw-body "2.3.3"
|
||||
type-is "~1.6.16"
|
||||
|
||||
boolean@^3.0.1:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz"
|
||||
integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==
|
||||
|
||||
bootstrap-datepicker@1.9.0:
|
||||
version "1.9.0"
|
||||
resolved "https://registry.npmjs.org/bootstrap-datepicker/-/bootstrap-datepicker-1.9.0.tgz"
|
||||
@ -2539,14 +2513,6 @@ concat-stream@~1.5.0, concat-stream@~1.5.1:
|
||||
readable-stream "~2.0.0"
|
||||
typedarray "~0.0.5"
|
||||
|
||||
config-chain@^1.1.11:
|
||||
version "1.1.13"
|
||||
resolved "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz"
|
||||
integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==
|
||||
dependencies:
|
||||
ini "^1.3.4"
|
||||
proto-list "~1.2.1"
|
||||
|
||||
configstore@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz"
|
||||
@ -2979,11 +2945,6 @@ detect-libc@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd"
|
||||
integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==
|
||||
|
||||
detect-node@^2.0.4:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz"
|
||||
integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
|
||||
|
||||
detective@^4.0.0:
|
||||
version "4.7.1"
|
||||
resolved "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz"
|
||||
@ -3126,15 +3087,6 @@ electron-to-chromium@^1.4.251:
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592"
|
||||
integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==
|
||||
|
||||
electron@19.0.9:
|
||||
version "19.0.9"
|
||||
resolved "https://registry.npmjs.org/electron/-/electron-19.0.9.tgz"
|
||||
integrity sha512-ooEwrv8Y7NSzdhKcl6kPCYecnzcg5nFWuS5ryG+VFH3MMBR8zXh9nW2wLsZrBz6OGUxXrcc5BKBC7dA8C6RhGQ==
|
||||
dependencies:
|
||||
"@electron/get" "^1.14.1"
|
||||
"@types/node" "^16.11.26"
|
||||
extract-zip "^1.0.3"
|
||||
|
||||
elliptic@^6.0.0, elliptic@^6.5.2:
|
||||
version "6.5.4"
|
||||
resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz"
|
||||
@ -3168,7 +3120,7 @@ encode-utf8@^1.0.3:
|
||||
resolved "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz"
|
||||
integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==
|
||||
|
||||
encodeurl@^1.0.2, encodeurl@~1.0.2:
|
||||
encodeurl@~1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz"
|
||||
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
|
||||
@ -3207,7 +3159,7 @@ entities@^4.3.0:
|
||||
|
||||
env-paths@^2.2.0:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz"
|
||||
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
|
||||
integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
|
||||
|
||||
envinfo@^7.7.3:
|
||||
@ -3664,7 +3616,7 @@ extend@^3.0.0, extend@^3.0.2, extend@~3.0.2:
|
||||
resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
|
||||
extract-zip@^1.0.3, extract-zip@^1.6.7:
|
||||
extract-zip@^1.6.7:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz"
|
||||
integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==
|
||||
@ -3921,7 +3873,7 @@ fs-extra@^4.0.2, fs-extra@^4.0.3:
|
||||
jsonfile "^4.0.0"
|
||||
universalify "^0.1.0"
|
||||
|
||||
fs-extra@^8.0.1, fs-extra@^8.1.0:
|
||||
fs-extra@^8.0.1:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz"
|
||||
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
|
||||
@ -4192,18 +4144,6 @@ glob@~3.2.7:
|
||||
inherits "2"
|
||||
minimatch "0.3"
|
||||
|
||||
global-agent@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz"
|
||||
integrity sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==
|
||||
dependencies:
|
||||
boolean "^3.0.1"
|
||||
es6-error "^4.1.1"
|
||||
matcher "^3.0.0"
|
||||
roarr "^2.15.3"
|
||||
semver "^7.3.2"
|
||||
serialize-error "^7.0.1"
|
||||
|
||||
global-dirs@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz"
|
||||
@ -4211,16 +4151,6 @@ global-dirs@^2.0.1:
|
||||
dependencies:
|
||||
ini "^1.3.5"
|
||||
|
||||
global-tunnel-ng@^2.7.1:
|
||||
version "2.7.1"
|
||||
resolved "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz"
|
||||
integrity sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==
|
||||
dependencies:
|
||||
encodeurl "^1.0.2"
|
||||
lodash "^4.17.10"
|
||||
npm-conf "^1.1.3"
|
||||
tunnel "^0.0.6"
|
||||
|
||||
globals@^11.1.0:
|
||||
version "11.12.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
||||
@ -4233,13 +4163,6 @@ globals@^13.15.0, globals@^13.19.0:
|
||||
dependencies:
|
||||
type-fest "^0.20.2"
|
||||
|
||||
globalthis@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz"
|
||||
integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==
|
||||
dependencies:
|
||||
define-properties "^1.1.3"
|
||||
|
||||
globby@^11.1.0:
|
||||
version "11.1.0"
|
||||
resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b"
|
||||
@ -4793,11 +4716,6 @@ inherits@2.0.3:
|
||||
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
|
||||
ini@^1.3.4:
|
||||
version "1.3.8"
|
||||
resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz"
|
||||
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
|
||||
|
||||
ini@^1.3.5, ini@~1.3.0:
|
||||
version "1.3.7"
|
||||
resolved "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz"
|
||||
@ -5331,7 +5249,7 @@ json-stream@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/json-stream/-/json-stream-1.0.0.tgz#1a3854e28d2bbeeab31cc7ddf683d2ddc5652708"
|
||||
integrity sha512-H/ZGY0nIAg3QcOwE1QN/rK/Fa7gJn7Ii5obwp6zyPO4xiPNwpIMjqy2gwjBEGqzkF/vSWEIBQCBuN19hYiL6Qg==
|
||||
|
||||
json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
|
||||
json-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
|
||||
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
||||
@ -5671,7 +5589,7 @@ lodash.uniq@^4.5.0:
|
||||
resolved "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz"
|
||||
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
||||
|
||||
lodash@4.17.21, lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0:
|
||||
lodash@4.17.21, lodash@^4.0.0, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
@ -5753,13 +5671,6 @@ make-fetch-happen@^9.1.0:
|
||||
socks-proxy-agent "^6.0.0"
|
||||
ssri "^8.0.0"
|
||||
|
||||
matcher@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz"
|
||||
integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==
|
||||
dependencies:
|
||||
escape-string-regexp "^4.0.0"
|
||||
|
||||
md5.js@^1.3.4:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz"
|
||||
@ -6334,14 +6245,6 @@ now-and-later@^2.0.0:
|
||||
dependencies:
|
||||
once "^1.3.2"
|
||||
|
||||
npm-conf@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz"
|
||||
integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==
|
||||
dependencies:
|
||||
config-chain "^1.1.11"
|
||||
pify "^3.0.0"
|
||||
|
||||
npm-run-path@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz"
|
||||
@ -6906,11 +6809,6 @@ process@~0.11.0:
|
||||
resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz"
|
||||
integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
|
||||
|
||||
progress@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz"
|
||||
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
|
||||
|
||||
promise-inflight@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
|
||||
@ -6924,11 +6822,6 @@ promise-retry@^2.0.1:
|
||||
err-code "^2.0.2"
|
||||
retry "^0.12.0"
|
||||
|
||||
proto-list@~1.2.1:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz"
|
||||
integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==
|
||||
|
||||
proxy-addr@~2.0.4:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz"
|
||||
@ -7458,18 +7351,6 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
|
||||
hash-base "^3.0.0"
|
||||
inherits "^2.0.1"
|
||||
|
||||
roarr@^2.15.3:
|
||||
version "2.15.4"
|
||||
resolved "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz"
|
||||
integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==
|
||||
dependencies:
|
||||
boolean "^3.0.1"
|
||||
detect-node "^2.0.4"
|
||||
globalthis "^1.0.1"
|
||||
json-stringify-safe "^5.0.1"
|
||||
semver-compare "^1.0.0"
|
||||
sprintf-js "^1.1.2"
|
||||
|
||||
run-parallel@^1.1.9:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
|
||||
@ -7552,11 +7433,6 @@ selenium-webdriver@^4.0.0-alpha.1:
|
||||
tmp "^0.2.1"
|
||||
ws "^7.3.1"
|
||||
|
||||
semver-compare@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz"
|
||||
integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==
|
||||
|
||||
semver-diff@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz"
|
||||
@ -7574,13 +7450,6 @@ semver@^6.0.0, semver@^6.2.0, semver@^6.3.0:
|
||||
resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz"
|
||||
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
|
||||
|
||||
semver@^7.3.2:
|
||||
version "7.3.7"
|
||||
resolved "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz"
|
||||
integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
semver@^7.3.5, semver@^7.3.7:
|
||||
version "7.3.8"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
|
||||
@ -7607,13 +7476,6 @@ send@0.16.2:
|
||||
range-parser "~1.2.0"
|
||||
statuses "~1.4.0"
|
||||
|
||||
serialize-error@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz"
|
||||
integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==
|
||||
dependencies:
|
||||
type-fest "^0.13.1"
|
||||
|
||||
serialize-javascript@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz"
|
||||
@ -7838,11 +7700,6 @@ split2@^4.1.0:
|
||||
resolved "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz"
|
||||
integrity sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==
|
||||
|
||||
sprintf-js@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz"
|
||||
integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz"
|
||||
@ -8096,13 +7953,6 @@ subarg@^1.0.0:
|
||||
dependencies:
|
||||
minimist "^1.1.0"
|
||||
|
||||
sumchecker@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz"
|
||||
integrity sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==
|
||||
dependencies:
|
||||
debug "^4.1.0"
|
||||
|
||||
supports-color@5.4.0:
|
||||
version "5.4.0"
|
||||
resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz"
|
||||
@ -8476,11 +8326,6 @@ tunnel-agent@^0.6.0:
|
||||
dependencies:
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
tunnel@^0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz"
|
||||
integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
|
||||
|
||||
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
||||
version "0.14.5"
|
||||
resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz"
|
||||
@ -8505,11 +8350,6 @@ type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5, type-detect@^4.0.8:
|
||||
resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz"
|
||||
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
|
||||
|
||||
type-fest@^0.13.1:
|
||||
version "0.13.1"
|
||||
resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz"
|
||||
integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
|
||||
|
||||
type-fest@^0.20.2:
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
|
||||
|
Loading…
Reference in New Issue
Block a user