mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
Don't initialize database on file require (#6003)
This commit is contained in:
@@ -4,6 +4,8 @@ import installDatabase from '../../../database/seeds/run';
|
||||
import env from '../../../env';
|
||||
import logger from '../../../logger';
|
||||
import { getSchema } from '../../../utils/get-schema';
|
||||
import { RolesService, UsersService, SettingsService } from '../../../services';
|
||||
import getDatabase, { isInstalled, hasDatabaseConnection } from '../../../database';
|
||||
|
||||
export default async function bootstrap(): Promise<void> {
|
||||
logger.info('Initializing bootstrap...');
|
||||
@@ -13,10 +15,7 @@ export default async function bootstrap(): Promise<void> {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const { isInstalled, default: database } = require('../../../database');
|
||||
const { RolesService } = require('../../../services/roles');
|
||||
const { UsersService } = require('../../../services/users');
|
||||
const { SettingsService } = require('../../../services/settings');
|
||||
const database = getDatabase();
|
||||
|
||||
if ((await isInstalled()) === false) {
|
||||
logger.info('Installing Directus system tables...');
|
||||
@@ -66,8 +65,6 @@ export default async function bootstrap(): Promise<void> {
|
||||
}
|
||||
|
||||
async function isDatabaseAvailable() {
|
||||
const { hasDatabaseConnection } = require('../../../database');
|
||||
|
||||
const tries = 5;
|
||||
const secondsBetweenTries = 5;
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import getDatabase from '../../../database';
|
||||
|
||||
export default async function count(collection: string): Promise<void> {
|
||||
const database = require('../../../database/index').default;
|
||||
const database = getDatabase();
|
||||
|
||||
if (!collection) {
|
||||
console.error('Collection is required');
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Knex } from 'knex';
|
||||
import runMigrations from '../../../database/migrations/run';
|
||||
import installSeeds from '../../../database/seeds/run';
|
||||
import getDatabase from '../../../database';
|
||||
|
||||
export default async function start(): Promise<void> {
|
||||
const database = require('../../../database/index').default as Knex;
|
||||
const database = getDatabase();
|
||||
|
||||
try {
|
||||
await installSeeds(database);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import run from '../../../database/migrations/run';
|
||||
import getDatabase from '../../../database';
|
||||
|
||||
export default async function migrate(direction: 'latest' | 'up' | 'down'): Promise<void> {
|
||||
const database = require('../../../database').default;
|
||||
const database = getDatabase();
|
||||
|
||||
try {
|
||||
console.log('✨ Running migrations...');
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { getSchema } from '../../../utils/get-schema';
|
||||
import { RolesService } from '../../../services';
|
||||
import getDatabase from '../../../database';
|
||||
|
||||
export default async function rolesCreate({ role: name, admin }: { role: string; admin: boolean }): Promise<void> {
|
||||
const { default: database } = require('../../../database/index');
|
||||
const { RolesService } = require('../../../services/roles');
|
||||
const database = getDatabase();
|
||||
|
||||
if (!name) {
|
||||
console.error('Name is required');
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { getSchema } from '../../../utils/get-schema';
|
||||
import { UsersService } from '../../../services';
|
||||
import getDatabase from '../../../database';
|
||||
|
||||
export default async function usersCreate({
|
||||
email,
|
||||
@@ -9,8 +11,7 @@ export default async function usersCreate({
|
||||
password?: string;
|
||||
role?: string;
|
||||
}): Promise<void> {
|
||||
const { default: database } = require('../../../database/index');
|
||||
const { UsersService } = require('../../../services/users');
|
||||
const database = getDatabase();
|
||||
|
||||
if (!email || !password || !role) {
|
||||
console.error('Email, password, role are required');
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import argon2 from 'argon2';
|
||||
import { getSchema } from '../../../utils/get-schema';
|
||||
import { UsersService } from '../../../services';
|
||||
import getDatabase from '../../../database';
|
||||
|
||||
export default async function usersPasswd({ email, password }: { email?: string; password?: string }): Promise<void> {
|
||||
const { default: database } = require('../../../database/index');
|
||||
const { UsersService } = require('../../../services/users');
|
||||
const database = getDatabase();
|
||||
|
||||
if (!email || !password) {
|
||||
console.error('Email and password are required');
|
||||
|
||||
@@ -4,7 +4,7 @@ import { pick } from 'lodash';
|
||||
import ms from 'ms';
|
||||
import validate from 'uuid-validate';
|
||||
import { ASSET_TRANSFORM_QUERY_KEYS, SYSTEM_ASSET_ALLOW_LIST } from '../constants';
|
||||
import database from '../database';
|
||||
import getDatabase from '../database';
|
||||
import env from '../env';
|
||||
import { ForbiddenException, InvalidQueryException, RangeNotSatisfiableException } from '../exceptions';
|
||||
import useCollection from '../middleware/use-collection';
|
||||
@@ -32,11 +32,11 @@ router.get(
|
||||
* This is a little annoying. Postgres will error out if you're trying to search in `where`
|
||||
* with a wrong type. In case of directus_files where id is a uuid, we'll have to verify the
|
||||
* validity of the uuid ahead of time.
|
||||
* @todo move this to a validation middleware function
|
||||
*/
|
||||
const isValidUUID = validate(id, 4);
|
||||
if (isValidUUID === false) throw new ForbiddenException();
|
||||
|
||||
const database = getDatabase();
|
||||
const file = await database.select('id', 'storage', 'filename_disk').from('directus_files').where({ id }).first();
|
||||
if (!file) throw new ForbiddenException();
|
||||
|
||||
@@ -51,6 +51,7 @@ router.get(
|
||||
const payloadService = new PayloadService('directus_settings', { schema: req.schema });
|
||||
const defaults = { storage_asset_presets: [], storage_asset_transform: 'all' };
|
||||
|
||||
const database = getDatabase();
|
||||
const savedAssetSettings = await database
|
||||
.select('storage_asset_presets', 'storage_asset_transform')
|
||||
.from('directus_settings')
|
||||
|
||||
@@ -1,76 +1,98 @@
|
||||
import SchemaInspector from '@directus/schema';
|
||||
import dotenv from 'dotenv';
|
||||
import { knex, Knex } from 'knex';
|
||||
import path from 'path';
|
||||
import { performance } from 'perf_hooks';
|
||||
import env from '../env';
|
||||
import logger from '../logger';
|
||||
import { getConfigFromEnv } from '../utils/get-config-from-env';
|
||||
import { validateEnv } from '../utils/validate-env';
|
||||
|
||||
dotenv.config({ path: path.resolve(__dirname, '../../', '.env') });
|
||||
let database: Knex | null = null;
|
||||
let inspector: ReturnType<typeof SchemaInspector> | null = null;
|
||||
|
||||
const connectionConfig: Record<string, any> = getConfigFromEnv('DB_', [
|
||||
'DB_CLIENT',
|
||||
'DB_SEARCH_PATH',
|
||||
'DB_CONNECTION_STRING',
|
||||
'DB_POOL',
|
||||
]);
|
||||
|
||||
const poolConfig = getConfigFromEnv('DB_POOL');
|
||||
|
||||
const requiredKeys = ['DB_CLIENT'];
|
||||
|
||||
if (env.DB_CLIENT && env.DB_CLIENT === 'sqlite3') {
|
||||
requiredKeys.push('DB_FILENAME');
|
||||
} else if (env.DB_CLIENT && env.DB_CLIENT === 'oracledb') {
|
||||
requiredKeys.push('DB_USER', 'DB_PASSWORD', 'DB_CONNECT_STRING');
|
||||
} else {
|
||||
if (env.DB_CLIENT === 'pg') {
|
||||
if (!env.DB_CONNECTION_STRING) {
|
||||
requiredKeys.push('DB_HOST', 'DB_PORT', 'DB_DATABASE', 'DB_USER');
|
||||
}
|
||||
} else {
|
||||
requiredKeys.push('DB_HOST', 'DB_PORT', 'DB_DATABASE', 'DB_USER', 'DB_PASSWORD');
|
||||
export default function getDatabase() {
|
||||
if (database) {
|
||||
return database;
|
||||
}
|
||||
}
|
||||
|
||||
validateEnv(requiredKeys);
|
||||
const connectionConfig: Record<string, any> = getConfigFromEnv('DB_', [
|
||||
'DB_CLIENT',
|
||||
'DB_SEARCH_PATH',
|
||||
'DB_CONNECTION_STRING',
|
||||
'DB_POOL',
|
||||
]);
|
||||
|
||||
const knexConfig: Knex.Config = {
|
||||
client: env.DB_CLIENT,
|
||||
searchPath: env.DB_SEARCH_PATH,
|
||||
connection: env.DB_CONNECTION_STRING || connectionConfig,
|
||||
log: {
|
||||
warn: (msg) => logger.warn(msg),
|
||||
error: (msg) => logger.error(msg),
|
||||
deprecate: (msg) => logger.info(msg),
|
||||
debug: (msg) => logger.debug(msg),
|
||||
},
|
||||
pool: poolConfig,
|
||||
};
|
||||
const poolConfig = getConfigFromEnv('DB_POOL');
|
||||
|
||||
if (env.DB_CLIENT === 'sqlite3') {
|
||||
knexConfig.useNullAsDefault = true;
|
||||
poolConfig.afterCreate = (conn: any, cb: any) => {
|
||||
conn.run('PRAGMA foreign_keys = ON', cb);
|
||||
const requiredEnvVars = ['DB_CLIENT'];
|
||||
|
||||
if (env.DB_CLIENT && env.DB_CLIENT === 'sqlite3') {
|
||||
requiredEnvVars.push('DB_FILENAME');
|
||||
} else if (env.DB_CLIENT && env.DB_CLIENT === 'oracledb') {
|
||||
requiredEnvVars.push('DB_USER', 'DB_PASSWORD', 'DB_CONNECT_STRING');
|
||||
} else {
|
||||
if (env.DB_CLIENT === 'pg') {
|
||||
if (!env.DB_CONNECTION_STRING) {
|
||||
requiredEnvVars.push('DB_HOST', 'DB_PORT', 'DB_DATABASE', 'DB_USER');
|
||||
}
|
||||
} else {
|
||||
requiredEnvVars.push('DB_HOST', 'DB_PORT', 'DB_DATABASE', 'DB_USER', 'DB_PASSWORD');
|
||||
}
|
||||
}
|
||||
|
||||
validateEnv(requiredEnvVars);
|
||||
|
||||
const knexConfig: Knex.Config = {
|
||||
client: env.DB_CLIENT,
|
||||
searchPath: env.DB_SEARCH_PATH,
|
||||
connection: env.DB_CONNECTION_STRING || connectionConfig,
|
||||
log: {
|
||||
warn: (msg) => logger.warn(msg),
|
||||
error: (msg) => logger.error(msg),
|
||||
deprecate: (msg) => logger.info(msg),
|
||||
debug: (msg) => logger.debug(msg),
|
||||
},
|
||||
pool: poolConfig,
|
||||
};
|
||||
|
||||
if (env.DB_CLIENT === 'sqlite3') {
|
||||
knexConfig.useNullAsDefault = true;
|
||||
poolConfig.afterCreate = (conn: any, cb: any) => {
|
||||
conn.run('PRAGMA foreign_keys = ON', cb);
|
||||
};
|
||||
}
|
||||
|
||||
database = knex(knexConfig);
|
||||
|
||||
const times: Record<string, number> = {};
|
||||
|
||||
database
|
||||
.on('query', (queryInfo) => {
|
||||
times[queryInfo.__knexUid] = performance.now();
|
||||
})
|
||||
.on('query-response', (response, queryInfo) => {
|
||||
const delta = performance.now() - times[queryInfo.__knexUid];
|
||||
logger.trace(`[${delta.toFixed(3)}ms] ${queryInfo.sql} [${queryInfo.bindings.join(', ')}]`);
|
||||
delete times[queryInfo.__knexUid];
|
||||
});
|
||||
|
||||
return database;
|
||||
}
|
||||
|
||||
const database = knex(knexConfig);
|
||||
export function getSchemaInspector() {
|
||||
if (inspector) {
|
||||
return inspector;
|
||||
}
|
||||
|
||||
const times: Record<string, number> = {};
|
||||
const database = getDatabase();
|
||||
|
||||
database
|
||||
.on('query', (queryInfo) => {
|
||||
times[queryInfo.__knexUid] = performance.now();
|
||||
})
|
||||
.on('query-response', (response, queryInfo) => {
|
||||
const delta = performance.now() - times[queryInfo.__knexUid];
|
||||
logger.trace(`[${delta.toFixed(3)}ms] ${queryInfo.sql} [${queryInfo.bindings.join(', ')}]`);
|
||||
});
|
||||
inspector = SchemaInspector(database);
|
||||
|
||||
return inspector;
|
||||
}
|
||||
|
||||
export async function hasDatabaseConnection(): Promise<boolean> {
|
||||
const database = getDatabase();
|
||||
|
||||
try {
|
||||
if (env.DB_CLIENT === 'oracledb') {
|
||||
await database.raw('select 1 from DUAL');
|
||||
@@ -93,13 +115,11 @@ export async function validateDBConnection(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
export const schemaInspector = SchemaInspector(database);
|
||||
|
||||
export async function isInstalled(): Promise<boolean> {
|
||||
const inspector = getSchemaInspector();
|
||||
|
||||
// The existence of a directus_collections table alone isn't a "proper" check to see if everything
|
||||
// is installed correctly of course, but it's safe enough to assume that this collection only
|
||||
// exists when using the installer CLI.
|
||||
return await schemaInspector.hasTable('directus_collections');
|
||||
return await inspector.hasTable('directus_collections');
|
||||
}
|
||||
|
||||
export default database;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Knex } from 'knex';
|
||||
import SchemaInspector from 'knex-schema-inspector';
|
||||
import { schemaInspector } from '..';
|
||||
import logger from '../../logger';
|
||||
import { RelationMeta } from '../../types';
|
||||
|
||||
@@ -22,8 +21,8 @@ export async function up(knex: Knex): Promise<void> {
|
||||
for (const constraint of constraintsToAdd) {
|
||||
if (!constraint.one_collection) continue;
|
||||
|
||||
const currentPrimaryKeyField = await schemaInspector.primary(constraint.many_collection);
|
||||
const relatedPrimaryKeyField = await schemaInspector.primary(constraint.one_collection);
|
||||
const currentPrimaryKeyField = await inspector.primary(constraint.many_collection);
|
||||
const relatedPrimaryKeyField = await inspector.primary(constraint.one_collection);
|
||||
if (!currentPrimaryKeyField || !relatedPrimaryKeyField) continue;
|
||||
|
||||
const rowsWithIllegalFKValues = await knex
|
||||
@@ -67,8 +66,8 @@ export async function up(knex: Knex): Promise<void> {
|
||||
// to `unsigned`, but defaults `.integer()` to `int`. This means that created m2o fields
|
||||
// have the wrong type. This step will force the m2o `int` field into `unsigned`, but only
|
||||
// if both types are integers, and only if we go from `int` to `int unsigned`.
|
||||
const columnInfo = await schemaInspector.columnInfo(constraint.many_collection, constraint.many_field);
|
||||
const relatedColumnInfo = await schemaInspector.columnInfo(constraint.one_collection!, relatedPrimaryKeyField);
|
||||
const columnInfo = await inspector.columnInfo(constraint.many_collection, constraint.many_field);
|
||||
const relatedColumnInfo = await inspector.columnInfo(constraint.one_collection!, relatedPrimaryKeyField);
|
||||
|
||||
try {
|
||||
await knex.schema.alterTable(constraint.many_collection, (table) => {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Item, Query, SchemaOverview } from '../types';
|
||||
import { AST, FieldNode, NestedCollectionNode } from '../types/ast';
|
||||
import applyQuery from '../utils/apply-query';
|
||||
import { toArray } from '../utils/to-array';
|
||||
import database from './index';
|
||||
import getDatabase from './index';
|
||||
|
||||
type RunASTOptions = {
|
||||
/**
|
||||
@@ -39,7 +39,7 @@ export default async function runAST(
|
||||
): Promise<null | Item | Item[]> {
|
||||
const ast = cloneDeep(originalAST);
|
||||
|
||||
const knex = options?.knex || database;
|
||||
const knex = options?.knex || getDatabase();
|
||||
|
||||
if (ast.type === 'm2a') {
|
||||
const results: { [collection: string]: null | Item | Item[] } = {};
|
||||
|
||||
@@ -92,6 +92,22 @@ env = processValues(env);
|
||||
|
||||
export default env;
|
||||
|
||||
/**
|
||||
* When changes have been made during runtime, like in the CLI, we can refresh the env object with
|
||||
* the newly created variables
|
||||
*/
|
||||
export function refreshEnv() {
|
||||
env = {
|
||||
...defaults,
|
||||
...getEnv(),
|
||||
...process.env,
|
||||
};
|
||||
|
||||
process.env = env;
|
||||
|
||||
env = processValues(env);
|
||||
}
|
||||
|
||||
function getEnv() {
|
||||
const configPath = path.resolve(process.env.CONFIG_PATH || defaults.CONFIG_PATH);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import database from '../../../database';
|
||||
import getDatabase from '../../../database';
|
||||
import { ContainsNullValuesException } from '../contains-null-values';
|
||||
import { InvalidForeignKeyException } from '../invalid-foreign-key';
|
||||
import { NotNullViolationException } from '../not-null-violation';
|
||||
@@ -56,6 +56,8 @@ async function uniqueViolation(error: MSSQLError) {
|
||||
|
||||
const keyName = quoteMatches[1];
|
||||
|
||||
const database = getDatabase();
|
||||
|
||||
const constraintUsage = await database
|
||||
.select('*')
|
||||
.from('INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import database from '../../database';
|
||||
import getDatabase from '../../database';
|
||||
import { extractError as mssql } from './dialects/mssql';
|
||||
import { extractError as mysql } from './dialects/mysql';
|
||||
import { extractError as oracle } from './dialects/oracle';
|
||||
@@ -16,6 +16,8 @@ import { SQLError } from './dialects/types';
|
||||
* - Value Too Long
|
||||
*/
|
||||
export async function translateDatabaseError(error: SQLError): Promise<any> {
|
||||
const database = getDatabase();
|
||||
|
||||
switch (database.client.constructor.name) {
|
||||
case 'Client_MySQL':
|
||||
return mysql(error);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import express, { Router } from 'express';
|
||||
import { ensureDir } from 'fs-extra';
|
||||
import path from 'path';
|
||||
import database from './database';
|
||||
import getDatabase from './database';
|
||||
import emitter from './emitter';
|
||||
import env from './env';
|
||||
import * as exceptions from './exceptions';
|
||||
@@ -93,7 +93,7 @@ function registerHooks(hooks: string[]) {
|
||||
}
|
||||
}
|
||||
|
||||
const events = register({ services, exceptions, env, database, getSchema });
|
||||
const events = register({ services, exceptions, env, database: getDatabase(), getSchema });
|
||||
for (const [event, handler] of Object.entries(events)) {
|
||||
emitter.on(event, handler);
|
||||
}
|
||||
@@ -126,6 +126,6 @@ function registerEndpoints(endpoints: string[], router: Router) {
|
||||
const scopedRouter = express.Router();
|
||||
router.use(`/${endpoint}/`, scopedRouter);
|
||||
|
||||
register(scopedRouter, { services, exceptions, env, database, getSchema });
|
||||
register(scopedRouter, { services, exceptions, env, database: getDatabase(), getSchema });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { RequestHandler } from 'express';
|
||||
import jwt, { JsonWebTokenError, TokenExpiredError } from 'jsonwebtoken';
|
||||
import database from '../database';
|
||||
import getDatabase from '../database';
|
||||
import env from '../env';
|
||||
import { InvalidCredentialsException } from '../exceptions';
|
||||
import asyncHandler from '../utils/async-handler';
|
||||
@@ -21,6 +21,8 @@ const authenticate: RequestHandler = asyncHandler(async (req, res, next) => {
|
||||
|
||||
if (!req.token) return next();
|
||||
|
||||
const database = getDatabase();
|
||||
|
||||
if (isJWT(req.token)) {
|
||||
let payload: { id: string };
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { RequestHandler } from 'express';
|
||||
import database from '../database';
|
||||
import getDatabase from '../database';
|
||||
import { InvalidIPException } from '../exceptions';
|
||||
import asyncHandler from '../utils/async-handler';
|
||||
|
||||
export const checkIP: RequestHandler = asyncHandler(async (req, res, next) => {
|
||||
const database = getDatabase();
|
||||
|
||||
const role = await database
|
||||
.select('ip_access')
|
||||
.from('directus_roles')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import expressSession, { Store } from 'express-session';
|
||||
import env from '../env';
|
||||
import { getConfigFromEnv } from '../utils/get-config-from-env';
|
||||
import database from '../database';
|
||||
import getDatabase from '../database';
|
||||
let store: Store | undefined = undefined;
|
||||
|
||||
if (env.SESSION_STORE === 'redis') {
|
||||
@@ -20,7 +20,7 @@ if (env.SESSION_STORE === 'memcache') {
|
||||
if (env.SESSION_STORE === 'database') {
|
||||
const KnexSessionStore = require('connect-session-knex')(expressSession);
|
||||
store = new KnexSessionStore({
|
||||
knex: database,
|
||||
knex: getDatabase(),
|
||||
tablename: 'oauth_sessions', // optional. Defaults to 'sessions'
|
||||
});
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { once } from 'lodash';
|
||||
import qs from 'qs';
|
||||
import url from 'url';
|
||||
import createApp from './app';
|
||||
import database from './database';
|
||||
import getDatabase from './database';
|
||||
import { emitAsyncSafe } from './emitter';
|
||||
import logger from './logger';
|
||||
|
||||
@@ -94,6 +94,7 @@ export default async function createServer(): Promise<http.Server> {
|
||||
}
|
||||
|
||||
async function onSignal() {
|
||||
const database = getDatabase();
|
||||
await database.destroy();
|
||||
logger.info('Database connections destroyed');
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Range, StatResponse } from '@directus/drive';
|
||||
import { Knex } from 'knex';
|
||||
import path from 'path';
|
||||
import sharp, { ResizeOptions } from 'sharp';
|
||||
import database from '../database';
|
||||
import getDatabase from '../database';
|
||||
import { RangeNotSatisfiableException, IllegalAssetTransformation } from '../exceptions';
|
||||
import storage from '../storage';
|
||||
import { AbstractServiceOptions, Accountability, Transformation } from '../types';
|
||||
@@ -23,7 +23,7 @@ export class AssetsService {
|
||||
authorizationService: AuthorizationService;
|
||||
|
||||
constructor(options: AbstractServiceOptions) {
|
||||
this.knex = options.knex || database;
|
||||
this.knex = options.knex || getDatabase();
|
||||
this.accountability = options.accountability || null;
|
||||
this.authorizationService = new AuthorizationService(options);
|
||||
}
|
||||
@@ -44,7 +44,7 @@ export class AssetsService {
|
||||
await this.authorizationService.checkAccess('read', 'directus_files', id);
|
||||
}
|
||||
|
||||
const file = (await database.select('*').from('directus_files').where({ id }).first()) as File;
|
||||
const file = (await this.knex.select('*').from('directus_files').where({ id }).first()) as File;
|
||||
|
||||
if (range) {
|
||||
if (range.start >= file.filesize || (range.end && range.end >= file.filesize)) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Knex } from 'knex';
|
||||
import ms from 'ms';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { authenticator } from 'otplib';
|
||||
import database from '../database';
|
||||
import getDatabase from '../database';
|
||||
import emitter, { emitAsyncSafe } from '../emitter';
|
||||
import env from '../env';
|
||||
import {
|
||||
@@ -37,7 +37,7 @@ export class AuthenticationService {
|
||||
schema: SchemaOverview;
|
||||
|
||||
constructor(options: AbstractServiceOptions) {
|
||||
this.knex = options.knex || database;
|
||||
this.knex = options.knex || getDatabase();
|
||||
this.accountability = options.accountability || null;
|
||||
this.activityService = new ActivityService({ knex: this.knex, schema: options.schema });
|
||||
this.schema = options.schema;
|
||||
@@ -59,7 +59,7 @@ export class AuthenticationService {
|
||||
|
||||
const { email, password, ip, userAgent, otp } = options;
|
||||
|
||||
let user = await database
|
||||
let user = await this.knex
|
||||
.select('id', 'password', 'role', 'tfa_secret', 'status')
|
||||
.from('directus_users')
|
||||
.whereRaw('LOWER(??) = ?', ['email', email.toLowerCase()])
|
||||
@@ -114,7 +114,7 @@ export class AuthenticationService {
|
||||
try {
|
||||
await loginAttemptsLimiter.consume(user.id);
|
||||
} catch (err) {
|
||||
await database('directus_users').update({ status: 'suspended' }).where({ id: user.id });
|
||||
await this.knex('directus_users').update({ status: 'suspended' }).where({ id: user.id });
|
||||
user.status = 'suspended';
|
||||
|
||||
// This means that new attempts after the user has been re-activated will be accepted
|
||||
@@ -164,7 +164,7 @@ export class AuthenticationService {
|
||||
const refreshToken = nanoid(64);
|
||||
const refreshTokenExpiration = new Date(Date.now() + ms(env.REFRESH_TOKEN_TTL as string));
|
||||
|
||||
await database('directus_sessions').insert({
|
||||
await this.knex('directus_sessions').insert({
|
||||
token: refreshToken,
|
||||
user: user.id,
|
||||
expires: refreshTokenExpiration,
|
||||
@@ -172,7 +172,7 @@ export class AuthenticationService {
|
||||
user_agent: userAgent,
|
||||
});
|
||||
|
||||
await database('directus_sessions').delete().where('expires', '<', new Date());
|
||||
await this.knex('directus_sessions').delete().where('expires', '<', new Date());
|
||||
|
||||
if (this.accountability) {
|
||||
await this.activityService.createOne({
|
||||
@@ -204,7 +204,7 @@ export class AuthenticationService {
|
||||
throw new InvalidCredentialsException();
|
||||
}
|
||||
|
||||
const record = await database
|
||||
const record = await this.knex
|
||||
.select<Session & { email: string; id: string }>(
|
||||
'directus_sessions.*',
|
||||
'directus_users.email',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Knex } from 'knex';
|
||||
import { cloneDeep, flatten, merge, uniq, uniqWith } from 'lodash';
|
||||
import database from '../database';
|
||||
import getDatabase from '../database';
|
||||
import { FailedValidationException, ForbiddenException } from '../exceptions';
|
||||
import {
|
||||
AbstractServiceOptions,
|
||||
@@ -28,7 +28,7 @@ export class AuthorizationService {
|
||||
schema: SchemaOverview;
|
||||
|
||||
constructor(options: AbstractServiceOptions) {
|
||||
this.knex = options.knex || database;
|
||||
this.knex = options.knex || getDatabase();
|
||||
this.accountability = options.accountability || null;
|
||||
this.schema = options.schema;
|
||||
this.payloadService = new PayloadService('directus_permissions', {
|
||||
|
||||
@@ -2,7 +2,7 @@ import SchemaInspector from '@directus/schema';
|
||||
import { Knex } from 'knex';
|
||||
import cache from '../cache';
|
||||
import { ALIAS_TYPES } from '../constants';
|
||||
import database, { schemaInspector } from '../database';
|
||||
import getDatabase, { getSchemaInspector } from '../database';
|
||||
import { systemCollectionRows } from '../database/system-data/collections';
|
||||
import env from '../env';
|
||||
import { ForbiddenException, InvalidPayloadException } from '../exceptions';
|
||||
@@ -27,13 +27,13 @@ export type RawCollection = {
|
||||
export class CollectionsService {
|
||||
knex: Knex;
|
||||
accountability: Accountability | null;
|
||||
schemaInspector: typeof schemaInspector;
|
||||
schemaInspector: ReturnType<typeof SchemaInspector>;
|
||||
schema: SchemaOverview;
|
||||
|
||||
constructor(options: AbstractServiceOptions) {
|
||||
this.knex = options.knex || database;
|
||||
this.knex = options.knex || getDatabase();
|
||||
this.accountability = options.accountability || null;
|
||||
this.schemaInspector = options.knex ? SchemaInspector(options.knex) : schemaInspector;
|
||||
this.schemaInspector = options.knex ? SchemaInspector(options.knex) : getSchemaInspector();
|
||||
this.schema = options.schema;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Knex } from 'knex';
|
||||
import { Column } from 'knex-schema-inspector/dist/types/column';
|
||||
import cache from '../cache';
|
||||
import { ALIAS_TYPES } from '../constants';
|
||||
import database, { schemaInspector } from '../database';
|
||||
import getDatabase, { getSchemaInspector } from '../database';
|
||||
import { systemFieldRows } from '../database/system-data/fields/';
|
||||
import emitter, { emitAsyncSafe } from '../emitter';
|
||||
import env from '../env';
|
||||
@@ -26,12 +26,12 @@ export class FieldsService {
|
||||
accountability: Accountability | null;
|
||||
itemsService: ItemsService;
|
||||
payloadService: PayloadService;
|
||||
schemaInspector: typeof schemaInspector;
|
||||
schemaInspector: ReturnType<typeof SchemaInspector>;
|
||||
schema: SchemaOverview;
|
||||
|
||||
constructor(options: AbstractServiceOptions) {
|
||||
this.knex = options.knex || database;
|
||||
this.schemaInspector = options.knex ? SchemaInspector(options.knex) : schemaInspector;
|
||||
this.knex = options.knex || getDatabase();
|
||||
this.schemaInspector = options.knex ? SchemaInspector(options.knex) : getSchemaInspector();
|
||||
this.accountability = options.accountability || null;
|
||||
this.itemsService = new ItemsService('directus_fields', options);
|
||||
this.payloadService = new PayloadService('directus_fields', options);
|
||||
|
||||
@@ -44,7 +44,7 @@ import {
|
||||
import { Knex } from 'knex';
|
||||
import { flatten, get, mapKeys, merge, set, uniq } from 'lodash';
|
||||
import ms from 'ms';
|
||||
import database from '../database';
|
||||
import getDatabase from '../database';
|
||||
import env from '../env';
|
||||
import { BaseException, GraphQLValidationException, InvalidPayloadException } from '../exceptions';
|
||||
import { listExtensions } from '../extensions';
|
||||
@@ -115,7 +115,7 @@ export class GraphQLService {
|
||||
|
||||
constructor(options: AbstractServiceOptions & { scope: 'items' | 'system' }) {
|
||||
this.accountability = options?.accountability || null;
|
||||
this.knex = options?.knex || database;
|
||||
this.knex = options?.knex || getDatabase();
|
||||
this.schema = options.schema;
|
||||
this.scope = options.scope;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Knex } from 'knex';
|
||||
import database from '../database';
|
||||
import getDatabase from '../database';
|
||||
import { AbstractServiceOptions, Accountability, SchemaOverview } from '../types';
|
||||
import { ForbiddenException, InvalidPayloadException } from '../exceptions';
|
||||
import StreamArray from 'stream-json/streamers/StreamArray';
|
||||
@@ -15,7 +15,7 @@ export class ImportService {
|
||||
schema: SchemaOverview;
|
||||
|
||||
constructor(options: AbstractServiceOptions) {
|
||||
this.knex = options.knex || database;
|
||||
this.knex = options.knex || getDatabase();
|
||||
this.accountability = options.accountability || null;
|
||||
this.schema = options.schema;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Knex } from 'knex';
|
||||
import { clone, cloneDeep, merge, pick, without } from 'lodash';
|
||||
import cache from '../cache';
|
||||
import database from '../database';
|
||||
import getDatabase from '../database';
|
||||
import runAST from '../database/run-ast';
|
||||
import emitter, { emitAsyncSafe } from '../emitter';
|
||||
import env from '../env';
|
||||
@@ -55,7 +55,7 @@ export class ItemsService<Item extends AnyItem = AnyItem> implements AbstractSer
|
||||
|
||||
constructor(collection: string, options: AbstractServiceOptions) {
|
||||
this.collection = collection;
|
||||
this.knex = options.knex || database;
|
||||
this.knex = options.knex || getDatabase();
|
||||
this.accountability = options.accountability || null;
|
||||
this.eventScope = this.collection.startsWith('directus_') ? this.collection.substring(9) : 'items';
|
||||
this.schema = options.schema;
|
||||
@@ -204,7 +204,7 @@ export class ItemsService<Item extends AnyItem = AnyItem> implements AbstractSer
|
||||
schema: this.schema,
|
||||
// This hook is called async. If we would pass the transaction here, the hook can be
|
||||
// called after the transaction is done #5460
|
||||
database: database,
|
||||
database: getDatabase(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -516,7 +516,7 @@ export class ItemsService<Item extends AnyItem = AnyItem> implements AbstractSer
|
||||
schema: this.schema,
|
||||
// This hook is called async. If we would pass the transaction here, the hook can be
|
||||
// called after the transaction is done #5460
|
||||
database: database,
|
||||
database: getDatabase(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -665,7 +665,7 @@ export class ItemsService<Item extends AnyItem = AnyItem> implements AbstractSer
|
||||
schema: this.schema,
|
||||
// This hook is called async. If we would pass the transaction here, the hook can be
|
||||
// called after the transaction is done #5460
|
||||
database: database,
|
||||
database: getDatabase(),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import fse from 'fs-extra';
|
||||
import { Knex } from 'knex';
|
||||
import { Liquid } from 'liquidjs';
|
||||
import path from 'path';
|
||||
import database from '../../database';
|
||||
import getDatabase from '../../database';
|
||||
import env from '../../env';
|
||||
import { InvalidPayloadException } from '../../exceptions';
|
||||
import logger from '../../logger';
|
||||
@@ -30,7 +30,7 @@ export class MailService {
|
||||
constructor(opts: AbstractServiceOptions) {
|
||||
this.schema = opts.schema;
|
||||
this.accountability = opts.accountability || null;
|
||||
this.knex = opts?.knex || database;
|
||||
this.knex = opts?.knex || getDatabase();
|
||||
}
|
||||
|
||||
async send(options: EmailOptions): Promise<void> {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Knex } from 'knex';
|
||||
import database from '../database';
|
||||
import getDatabase from '../database';
|
||||
import { ForbiddenException } from '../exceptions';
|
||||
import { AbstractServiceOptions, Accountability, SchemaOverview } from '../types';
|
||||
import { Query } from '../types/query';
|
||||
@@ -12,7 +12,7 @@ export class MetaService {
|
||||
schema: SchemaOverview;
|
||||
|
||||
constructor(options: AbstractServiceOptions) {
|
||||
this.knex = options.knex || database;
|
||||
this.knex = options.knex || getDatabase();
|
||||
this.accountability = options.accountability || null;
|
||||
this.schema = options.schema;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import Joi from 'joi';
|
||||
import { Knex } from 'knex';
|
||||
import { clone, cloneDeep, isObject, isPlainObject } from 'lodash';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import database from '../database';
|
||||
import getDatabase from '../database';
|
||||
import { ForbiddenException, InvalidPayloadException } from '../exceptions';
|
||||
import { AbstractServiceOptions, Accountability, Item, PrimaryKey, Query, SchemaOverview } from '../types';
|
||||
import { toArray } from '../utils/to-array';
|
||||
@@ -43,7 +43,7 @@ export class PayloadService {
|
||||
|
||||
constructor(collection: string, options: AbstractServiceOptions) {
|
||||
this.accountability = options.accountability || null;
|
||||
this.knex = options.knex || database;
|
||||
this.knex = options.knex || getDatabase();
|
||||
this.collection = collection;
|
||||
this.schema = options.schema;
|
||||
|
||||
|
||||
@@ -7,20 +7,20 @@ import { ItemsService, QueryOptions } from './items';
|
||||
import { PermissionsService } from './permissions';
|
||||
import SchemaInspector from '@directus/schema';
|
||||
import { ForeignKey } from 'knex-schema-inspector/dist/types/foreign-key';
|
||||
import database, { schemaInspector } from '../database';
|
||||
import getDatabase, { getSchemaInspector } from '../database';
|
||||
|
||||
export class RelationsService {
|
||||
knex: Knex;
|
||||
permissionsService: PermissionsService;
|
||||
schemaInspector: typeof schemaInspector;
|
||||
schemaInspector: ReturnType<typeof SchemaInspector>;
|
||||
accountability: Accountability | null;
|
||||
schema: SchemaOverview;
|
||||
relationsItemService: ItemsService<RelationMeta>;
|
||||
|
||||
constructor(options: AbstractServiceOptions) {
|
||||
this.knex = options.knex || database;
|
||||
this.knex = options.knex || getDatabase();
|
||||
this.permissionsService = new PermissionsService(options);
|
||||
this.schemaInspector = options.knex ? SchemaInspector(options.knex) : schemaInspector;
|
||||
this.schemaInspector = options.knex ? SchemaInspector(options.knex) : getSchemaInspector();
|
||||
this.schema = options.schema;
|
||||
this.accountability = options.accountability || null;
|
||||
this.relationsItemService = new ItemsService('directus_relations', {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { performance } from 'perf_hooks';
|
||||
// @ts-ignore
|
||||
import { version } from '../../package.json';
|
||||
import cache from '../cache';
|
||||
import database, { hasDatabaseConnection } from '../database';
|
||||
import getDatabase, { hasDatabaseConnection } from '../database';
|
||||
import env from '../env';
|
||||
import logger from '../logger';
|
||||
import { rateLimiter } from '../middleware/rate-limiter';
|
||||
@@ -24,7 +24,7 @@ export class ServerService {
|
||||
schema: SchemaOverview;
|
||||
|
||||
constructor(options: AbstractServiceOptions) {
|
||||
this.knex = options.knex || database;
|
||||
this.knex = options.knex || getDatabase();
|
||||
this.accountability = options.accountability || null;
|
||||
this.schema = options.schema;
|
||||
this.settingsService = new SettingsService({ knex: this.knex, schema: this.schema });
|
||||
@@ -129,6 +129,7 @@ export class ServerService {
|
||||
}
|
||||
|
||||
async function testDatabase(): Promise<Record<string, HealthCheck[]>> {
|
||||
const database = getDatabase();
|
||||
const client = env.DB_CLIENT;
|
||||
|
||||
const checks: Record<string, HealthCheck[]> = {};
|
||||
|
||||
@@ -5,7 +5,7 @@ import { cloneDeep, mergeWith } from 'lodash';
|
||||
import { OpenAPIObject, OperationObject, PathItemObject, SchemaObject, TagObject } from 'openapi3-ts';
|
||||
// @ts-ignore
|
||||
import { version } from '../../package.json';
|
||||
import database from '../database';
|
||||
import getDatabase from '../database';
|
||||
import env from '../env';
|
||||
import {
|
||||
AbstractServiceOptions,
|
||||
@@ -37,7 +37,7 @@ export class SpecificationService {
|
||||
|
||||
constructor(options: AbstractServiceOptions) {
|
||||
this.accountability = options.accountability || null;
|
||||
this.knex = options.knex || database;
|
||||
this.knex = options.knex || getDatabase();
|
||||
this.schema = options.schema;
|
||||
|
||||
this.fieldsService = new FieldsService(options);
|
||||
@@ -80,7 +80,7 @@ class OASSpecsService implements SpecificationSubService {
|
||||
}
|
||||
) {
|
||||
this.accountability = options.accountability || null;
|
||||
this.knex = options.knex || database;
|
||||
this.knex = options.knex || getDatabase();
|
||||
this.schema = options.schema;
|
||||
|
||||
this.fieldsService = fieldsService;
|
||||
@@ -541,7 +541,7 @@ class GraphQLSpecsService implements SpecificationSubService {
|
||||
|
||||
constructor(options: AbstractServiceOptions) {
|
||||
this.accountability = options.accountability || null;
|
||||
this.knex = options.knex || database;
|
||||
this.knex = options.knex || getDatabase();
|
||||
this.schema = options.schema;
|
||||
|
||||
this.items = new GraphQLService({ ...options, scope: 'items' });
|
||||
|
||||
@@ -3,7 +3,7 @@ import jwt from 'jsonwebtoken';
|
||||
import { Knex } from 'knex';
|
||||
import { clone } from 'lodash';
|
||||
import cache from '../cache';
|
||||
import database from '../database';
|
||||
import getDatabase from '../database';
|
||||
import env from '../env';
|
||||
import {
|
||||
FailedValidationException,
|
||||
@@ -29,7 +29,7 @@ export class UsersService extends ItemsService {
|
||||
constructor(options: AbstractServiceOptions) {
|
||||
super('directus_users', options);
|
||||
|
||||
this.knex = options.knex || database;
|
||||
this.knex = options.knex || getDatabase();
|
||||
this.accountability = options.accountability || null;
|
||||
this.service = new ItemsService('directus_users', options);
|
||||
this.schema = options.schema;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Knex } from 'knex';
|
||||
import database from '../database';
|
||||
import getDatabase from '../database';
|
||||
import { systemCollectionRows } from '../database/system-data/collections';
|
||||
import { ForbiddenException, InvalidPayloadException } from '../exceptions';
|
||||
import { AbstractServiceOptions, Accountability, PrimaryKey, SchemaOverview } from '../types';
|
||||
@@ -10,7 +10,7 @@ export class UtilsService {
|
||||
schema: SchemaOverview;
|
||||
|
||||
constructor(options: AbstractServiceOptions) {
|
||||
this.knex = options.knex || database;
|
||||
this.knex = options.knex || getDatabase();
|
||||
this.accountability = options.accountability || null;
|
||||
this.schema = options.schema;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { LocalFileSystemStorage, Storage, StorageManager, StorageManagerConfig } from '@directus/drive';
|
||||
import { AzureBlobWebServicesStorage } from '@directus/drive-azure';
|
||||
import { GoogleCloudStorage } from '@directus/drive-gcs';
|
||||
/** @todo dynamically load these storage adapters */
|
||||
import { AmazonWebServicesS3Storage } from '@directus/drive-s3';
|
||||
import env from './env';
|
||||
import { getConfigFromEnv } from './utils/get-config-from-env';
|
||||
|
||||
@@ -11,13 +11,14 @@ import { toArray } from '../utils/to-array';
|
||||
import getDefaultValue from './get-default-value';
|
||||
import getLocalType from './get-local-type';
|
||||
import { mergePermissions } from './merge-permissions';
|
||||
import getDatabase from '../database';
|
||||
|
||||
export async function getSchema(options?: {
|
||||
accountability?: Accountability;
|
||||
database?: Knex;
|
||||
}): Promise<SchemaOverview> {
|
||||
// Allows for use in the CLI
|
||||
const database = options?.database || (require('../database').default as Knex);
|
||||
const database = options?.database || getDatabase();
|
||||
const schemaInspector = SchemaInspector(database);
|
||||
|
||||
const result: SchemaOverview = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import axios from 'axios';
|
||||
import { ListenerFn } from 'eventemitter2';
|
||||
import database from './database';
|
||||
import getDatabase from './database';
|
||||
import emitter from './emitter';
|
||||
import logger from './logger';
|
||||
import { Webhook } from './types';
|
||||
@@ -10,6 +10,8 @@ let registered: { event: string; handler: ListenerFn }[] = [];
|
||||
export async function register(): Promise<void> {
|
||||
unregister();
|
||||
|
||||
const database = getDatabase();
|
||||
|
||||
const webhooks = await database.select<Webhook[]>('*').from('directus_webhooks').where({ status: 'active' });
|
||||
|
||||
for (const webhook of webhooks) {
|
||||
|
||||
27
package-lock.json
generated
27
package-lock.json
generated
@@ -13076,6 +13076,7 @@
|
||||
"version": "0.0.9",
|
||||
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
|
||||
"integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"inherits": "~2.0.0"
|
||||
@@ -21174,6 +21175,7 @@
|
||||
"version": "1.0.12",
|
||||
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
|
||||
"integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
@@ -21189,6 +21191,7 @@
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.5"
|
||||
@@ -21201,6 +21204,7 @@
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
@@ -41963,6 +41967,7 @@
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.5"
|
||||
@@ -41975,6 +41980,7 @@
|
||||
"version": "3.8.0",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
|
||||
"integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"fstream": "^1.0.0",
|
||||
@@ -42001,6 +42007,7 @@
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
|
||||
"integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"abbrev": "1"
|
||||
@@ -42013,6 +42020,7 @@
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
@@ -42025,6 +42033,7 @@
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
|
||||
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver"
|
||||
@@ -42034,6 +42043,7 @@
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
|
||||
"integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"block-stream": "*",
|
||||
@@ -42045,6 +42055,7 @@
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
@@ -61062,6 +61073,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@oclif/command/-/command-1.8.0.tgz",
|
||||
"integrity": "sha512-5vwpq6kbvwkQwKqAoOU3L72GZ3Ta8RRrewKj9OJRolx28KLJJ8Dg9Rf7obRwt5jQA9bkYd8gqzMTrI7H3xLfaw==",
|
||||
"requires": {
|
||||
"@oclif/config": "^1.15.1",
|
||||
"@oclif/errors": "^1.3.3",
|
||||
"@oclif/parser": "^3.8.3",
|
||||
"@oclif/plugin-help": "^3",
|
||||
@@ -63209,6 +63221,7 @@
|
||||
"integrity": "sha512-pM7CR3yXB6L8Gfn6EmX7FLNE3+V/15I3o33GkSNsWvgsMp6HVGXKkXgojrcfUUauyL1LZOdvTmu4enU2RePGHw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/core": "^7.11.0",
|
||||
"@babel/helper-compilation-targets": "^7.9.6",
|
||||
"@babel/helper-module-imports": "^7.8.3",
|
||||
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
||||
@@ -63221,6 +63234,7 @@
|
||||
"@vue/babel-plugin-jsx": "^1.0.3",
|
||||
"@vue/babel-preset-jsx": "^1.2.4",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.3",
|
||||
"core-js": "^3.6.5",
|
||||
"core-js-compat": "^3.6.5",
|
||||
"semver": "^6.1.0"
|
||||
},
|
||||
@@ -67288,6 +67302,7 @@
|
||||
"version": "0.0.9",
|
||||
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
|
||||
"integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"inherits": "~2.0.0"
|
||||
@@ -71015,7 +71030,7 @@
|
||||
"keyv": "^4.0.3",
|
||||
"keyv-memcache": "^1.2.5",
|
||||
"knex": "^0.95.6",
|
||||
"knex-schema-inspector": "1.5.6",
|
||||
"knex-schema-inspector": "^1.5.6",
|
||||
"liquidjs": "^9.25.0",
|
||||
"lodash": "^4.17.21",
|
||||
"macos-release": "^2.4.1",
|
||||
@@ -74027,6 +74042,7 @@
|
||||
"version": "1.0.12",
|
||||
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
|
||||
"integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
@@ -74039,6 +74055,7 @@
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
@@ -74048,6 +74065,7 @@
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.3"
|
||||
@@ -90635,6 +90653,7 @@
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
@@ -90644,6 +90663,7 @@
|
||||
"version": "3.8.0",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
|
||||
"integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"fstream": "^1.0.0",
|
||||
@@ -90664,6 +90684,7 @@
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
|
||||
"integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"abbrev": "1"
|
||||
@@ -90673,6 +90694,7 @@
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.3"
|
||||
@@ -90682,12 +90704,14 @@
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
|
||||
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"tar": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
|
||||
"integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"block-stream": "*",
|
||||
@@ -90699,6 +90723,7 @@
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
|
||||
Reference in New Issue
Block a user