Browse Source

Merge pull request #5031 from nocodb/fix/5026-avoid-sync

fix: avoid synchronous calls on various places
pull/5058/head
Pranav C 2 years ago committed by GitHub
parent
commit
3a64aaa0ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 58
      packages/nocodb/src/lib/Noco.ts
  2. 31
      packages/nocodb/src/lib/db/sql-client/lib/KnexClient.ts
  3. 26
      packages/nocodb/src/lib/db/sql-client/lib/SqlClientFactory.ts
  4. 2
      packages/nocodb/src/lib/db/sql-client/lib/mysql/MysqlClient.ts
  5. 17
      packages/nocodb/src/lib/db/sql-mgr/SqlMgr.ts
  6. 10
      packages/nocodb/src/lib/db/sql-mgr/v2/SqlMgrv2.ts
  7. 6
      packages/nocodb/src/lib/db/sql-mgr/v2/SqlMgrv2Trans.ts
  8. 10
      packages/nocodb/src/lib/db/sql-migrator/lib/KnexMigrator.ts
  9. 10
      packages/nocodb/src/lib/db/sql-migrator/lib/KnexMigratorv2.ts
  10. 2
      packages/nocodb/src/lib/db/sql-migrator/lib/KnexMigratorv2Tans.ts
  11. 34
      packages/nocodb/src/lib/meta/NcMetaMgr.ts
  12. 2
      packages/nocodb/src/lib/meta/api/baseApis.ts
  13. 2
      packages/nocodb/src/lib/meta/api/columnApis.ts
  14. 8
      packages/nocodb/src/lib/meta/api/metaDiffApis.ts
  15. 9
      packages/nocodb/src/lib/meta/api/projectApis.ts
  16. 13
      packages/nocodb/src/lib/meta/api/sync/helpers/job.ts
  17. 4
      packages/nocodb/src/lib/meta/api/tableApis.ts
  18. 4
      packages/nocodb/src/lib/meta/api/utilApis.ts
  19. 2
      packages/nocodb/src/lib/meta/handlers/xcMetaDiff.ts
  20. 3
      packages/nocodb/src/lib/plugins/backblaze/Backblaze.ts
  21. 3
      packages/nocodb/src/lib/plugins/gcs/Gcs.ts
  22. 3
      packages/nocodb/src/lib/plugins/linode/LinodeObjectStorage.ts
  23. 3
      packages/nocodb/src/lib/plugins/mino/Minio.ts
  24. 3
      packages/nocodb/src/lib/plugins/ovhCloud/OvhCloud.ts
  25. 3
      packages/nocodb/src/lib/plugins/s3/S3.ts
  26. 3
      packages/nocodb/src/lib/plugins/scaleway/ScalewayObjectStorage.ts
  27. 3
      packages/nocodb/src/lib/plugins/spaces/Spaces.ts
  28. 3
      packages/nocodb/src/lib/plugins/upcloud/UpoCloud.ts
  29. 3
      packages/nocodb/src/lib/plugins/vultr/Vultr.ts
  30. 49
      packages/nocodb/src/lib/utils/NcConfigFactory.ts
  31. 14
      packages/nocodb/src/lib/utils/common/BaseApiBuilder.ts
  32. 27
      packages/nocodb/src/lib/utils/common/NcConnectionMgr.ts
  33. 2
      packages/nocodb/src/lib/utils/common/NcConnectionMgrv2.ts
  34. 14
      packages/nocodb/src/lib/utils/common/XcProcedure.ts
  35. 6
      packages/nocodb/src/lib/utils/common/handlers/xcMetaDiffSync.ts
  36. 7
      packages/nocodb/src/lib/v1-legacy/NcProjectBuilder.ts
  37. 2
      packages/nocodb/src/lib/v1-legacy/gql/GqlApiBuilder.ts
  38. 2
      packages/nocodb/src/lib/v1-legacy/nc.try.ts
  39. 13
      packages/nocodb/src/lib/v1-legacy/plugins/adapters/storage/Local.ts
  40. 36
      packages/nocodb/src/lib/v1-legacy/rest/RestApiBuilder.ts
  41. 6
      packages/nocodb/src/run/docker.ts
  42. 5
      packages/nocodb/src/run/dockerRunMysql.ts
  43. 5
      packages/nocodb/src/run/dockerRunPG.ts
  44. 5
      packages/nocodb/src/run/dockerRunPG_CyQuick.ts
  45. 30
      packages/nocodb/src/run/testDocker.ts
  46. 2
      packages/nocodb/src/run/try.ts

58
packages/nocodb/src/lib/Noco.ts

@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/ban-types */ /* eslint-disable @typescript-eslint/ban-types */
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { promisify } from 'util';
import * as Sentry from '@sentry/node'; import * as Sentry from '@sentry/node';
import bodyParser from 'body-parser'; import bodyParser from 'body-parser';
@ -114,32 +115,6 @@ export default class Noco {
this.router = express.Router(); this.router = express.Router();
this.projectRouter = express.Router(); this.projectRouter = express.Router();
/* prepare config */
Noco.config = this.config = NcConfigFactory.make();
/******************* setup : start *******************/
this.env = '_noco'; //process.env['NODE_ENV'] || this.config.workingEnv || 'dev';
this.config.workingEnv = this.env;
this.config.type = 'docker';
if (!this.config.toolDir) {
this.config.toolDir = process.cwd();
}
// this.ncToolApi = new NcToolGui(this.config);
// if (server) {
// server.set('view engine', 'ejs');
// }
const NcMetaImpl = process.env.EE ? NcMetaImplEE : NcMetaImplCE;
// const NcMetaMgr = process.env.EE ? NcMetaMgrEE : NcMetaMgrCE;
Noco._ncMeta = new NcMetaImpl(this, this.config);
// this.metaMgr = new NcMetaMgr(this, this.config, Noco._ncMeta);
// this.metaMgrv2 = new NcMetaMgrv2(this, this.config, Noco._ncMeta);
/******************* setup : end *******************/
/******************* prints : start *******************/ /******************* prints : start *******************/
// this.sumTable = new Table({ // this.sumTable = new Table({
// head: ['#DBs', '#Tables', // head: ['#DBs', '#Tables',
@ -169,6 +144,32 @@ export default class Noco {
server?: http.Server, server?: http.Server,
_app?: express.Express _app?: express.Express
) { ) {
/* prepare config */
Noco.config = this.config = await NcConfigFactory.make();
/******************* setup : start *******************/
this.env = '_noco'; //process.env['NODE_ENV'] || this.config.workingEnv || 'dev';
this.config.workingEnv = this.env;
this.config.type = 'docker';
if (!this.config.toolDir) {
this.config.toolDir = process.cwd();
}
// this.ncToolApi = new NcToolGui(this.config);
// if (server) {
// server.set('view engine', 'ejs');
// }
const NcMetaImpl = process.env.EE ? NcMetaImplEE : NcMetaImplCE;
// const NcMetaMgr = process.env.EE ? NcMetaMgrEE : NcMetaMgrCE;
Noco._ncMeta = new NcMetaImpl(this, this.config);
// this.metaMgr = new NcMetaMgr(this, this.config, Noco._ncMeta);
// this.metaMgrv2 = new NcMetaMgrv2(this, this.config, Noco._ncMeta);
/******************* setup : end *******************/
// @ts-ignore // @ts-ignore
const { const {
progressCallback, progressCallback,
@ -180,7 +181,7 @@ export default class Noco {
log('Initializing app'); log('Initializing app');
// create tool directory if missing // create tool directory if missing
mkdirp.sync(this.config.toolDir); await mkdirp(this.config.toolDir);
this.initSentry(); this.initSentry();
NocoCache.init(); NocoCache.init();
@ -278,6 +279,7 @@ export default class Noco {
instance: getInstance, instance: getInstance,
}); });
Tele.emit('evt_app_started', await User.count()); Tele.emit('evt_app_started', await User.count());
console.log(`App started successfully.\nVisit -> ${Noco.dashboardUrl}`);
weAreHiring(); weAreHiring();
return this.router; return this.router;
} }
@ -458,7 +460,7 @@ export default class Noco {
connectionConfig.meta.dbAlias, connectionConfig.meta.dbAlias,
'migrations' 'migrations'
); );
if (!fs.existsSync(migrationFolder)) { if (!await promisify(fs.exists)(migrationFolder)) {
await migrator.init({ await migrator.init({
folder: this.config?.toolDir, folder: this.config?.toolDir,
env: this.env, env: this.env,

31
packages/nocodb/src/lib/db/sql-client/lib/KnexClient.ts

@ -586,27 +586,6 @@ class KnexClient extends SqlClient {
if (connectionConfig.knex) { if (connectionConfig.knex) {
this.sqlClient = connectionConfig.knex; this.sqlClient = connectionConfig.knex;
} else { } else {
// console.log('KnexClient',this.connectionConfig);
if (
this.connectionConfig.connection.ssl &&
typeof this.connectionConfig.connection.ssl === 'object'
) {
if (this.connectionConfig.connection.ssl.caFilePath) {
this.connectionConfig.connection.ssl.ca = fs
.readFileSync(this.connectionConfig.connection.ssl.caFilePath)
.toString();
}
if (this.connectionConfig.connection.ssl.keyFilePath) {
this.connectionConfig.connection.ssl.key = fs
.readFileSync(this.connectionConfig.connection.ssl.keyFilePath)
.toString();
}
if (this.connectionConfig.connection.ssl.certFilePath) {
this.connectionConfig.connection.ssl.cert = fs
.readFileSync(this.connectionConfig.connection.ssl.certFilePath)
.toString();
}
}
const tmpConnectionConfig = const tmpConnectionConfig =
connectionConfig.client === 'sqlite3' connectionConfig.client === 'sqlite3'
? connectionConfig.connection ? connectionConfig.connection
@ -620,10 +599,10 @@ class KnexClient extends SqlClient {
this.evt = new Emit(); this.evt = new Emit();
} }
_validateInput() { async _validateInput() {
try { try {
const packageJson = JSON.parse( const packageJson = JSON.parse(
fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf8') await promisify(fs.readFile)(path.join(process.cwd(), 'package.json'), 'utf8')
); );
return ( return (
packageJson.name === 'nocodb' || 'nocodb' in packageJson.dependencies packageJson.name === 'nocodb' || 'nocodb' in packageJson.dependencies
@ -632,10 +611,10 @@ class KnexClient extends SqlClient {
return true; return true;
} }
validateInput() { async validateInput() {
try { try {
if (!('___ext' in KnexClient)) { if (!('___ext' in KnexClient)) {
KnexClient.___ext = this._validateInput(); KnexClient.___ext = await this._validateInput();
} }
if (!KnexClient.___ext) { if (!KnexClient.___ext) {
Tele.emit('evt', { Tele.emit('evt', {
@ -2838,7 +2817,7 @@ class KnexClient extends SqlClient {
console.log('in knex SeedInit'); console.log('in knex SeedInit');
try { try {
mkdirp.sync(args.seedsFolder); await mkdirp(args.seedsFolder);
} catch (e) { } catch (e) {
log.ppe(e, _func); log.ppe(e, _func);
throw e; throw e;

26
packages/nocodb/src/lib/db/sql-client/lib/SqlClientFactory.ts

@ -9,6 +9,9 @@ import YugabyteClient from './pg/YugabyteClient';
import TidbClient from './mysql/TidbClient'; import TidbClient from './mysql/TidbClient';
import VitessClient from './mysql/VitessClient'; import VitessClient from './mysql/VitessClient';
import fs from 'fs';
import { promisify } from 'util';
export class SqlClientFactory { export class SqlClientFactory {
static create(connectionConfig) { static create(connectionConfig) {
connectionConfig.meta = connectionConfig.meta || {}; connectionConfig.meta = connectionConfig.meta || {};
@ -40,7 +43,28 @@ export class SqlClientFactory {
} }
export default class { export default class {
static create(connectionConfig) { static async create(connectionConfig) {
if (
connectionConfig.connection.ssl &&
typeof connectionConfig.connection.ssl === 'object'
) {
if (connectionConfig.connection.ssl.caFilePath) {
connectionConfig.connection.ssl.ca = await promisify(fs.readFile)(
connectionConfig.connection.ssl.caFilePath
).toString();
}
if (connectionConfig.connection.ssl.keyFilePath) {
connectionConfig.connection.ssl.key = await promisify(fs.readFile)(
connectionConfig.connection.ssl.keyFilePath
).toString();
}
if (connectionConfig.connection.ssl.certFilePath) {
connectionConfig.connection.ssl.cert = await promisify(fs.readFile)(
connectionConfig.connection.ssl.certFilePath
).toString();
}
}
if (Noco.isEE()) { if (Noco.isEE()) {
return SqlClientFactoryEE.create(connectionConfig); return SqlClientFactoryEE.create(connectionConfig);
} }

2
packages/nocodb/src/lib/db/sql-client/lib/mysql/MysqlClient.ts

@ -1930,7 +1930,7 @@ class MysqlClient extends KnexClient {
console.log('in mysql SeedInit'); console.log('in mysql SeedInit');
try { try {
mkdirp.sync(args.seedsFolder); await mkdirp(args.seedsFolder);
const seedSettings = path.join(args.seedsFolder, '__xseeds.json'); const seedSettings = path.join(args.seedsFolder, '__xseeds.json');
await promisify(jsonfile.writeFile)( await promisify(jsonfile.writeFile)(

17
packages/nocodb/src/lib/db/sql-mgr/SqlMgr.ts

@ -1,6 +1,7 @@
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import url from 'url'; import url from 'url';
import { promisify } from 'util';
import fsExtra from 'fs-extra'; import fsExtra from 'fs-extra';
import importFresh from 'import-fresh'; import importFresh from 'import-fresh';
@ -148,7 +149,7 @@ export default class SqlMgr {
// return this._project; // return this._project;
// } // }
public async testConnection(args = {}) { public async testConnection(args = {}) {
const client = SqlClientFactory.create(args); const client = await SqlClientFactory.create(args);
return client.testConnection(); return client.testConnection();
} }
@ -297,9 +298,9 @@ export default class SqlMgr {
const connectionKey = `${env}_${this.currentProjectJson.envs[env].db[i].meta.dbAlias}`; const connectionKey = `${env}_${this.currentProjectJson.envs[env].db[i].meta.dbAlias}`;
this.currentProjectConnections[connectionKey] = this.currentProjectConnections[connectionKey] =
SqlClientFactory.create({ await SqlClientFactory.create({
...connectionConfig, ...connectionConfig,
knex: NcConnectionMgr.get({ knex: await NcConnectionMgr.get({
dbAlias: this.currentProjectJson.envs[env].db[i].meta.dbAlias, dbAlias: this.currentProjectJson.envs[env].db[i].meta.dbAlias,
env: env, env: env,
config: args, config: args,
@ -357,7 +358,7 @@ export default class SqlMgr {
} }
if ('client' in connectionConfig) { if ('client' in connectionConfig) {
const data = SqlClientFactory.create(connectionConfig); const data = await SqlClientFactory.create(connectionConfig);
this.currentProjectConnections[connectionKey] = data; this.currentProjectConnections[connectionKey] = data;
// console.log(data); // console.log(data);
return data; return data;
@ -439,7 +440,7 @@ export default class SqlMgr {
console.log(args); console.log(args);
try { try {
fs.unlinkSync(path.join(this.currentProjectFolder, 'config.xc.json')); await promisify(fs.unlink)(path.join(this.currentProjectFolder, 'config.xc.json'));
args.folder = args.folder || args.project.folder; args.folder = args.folder || args.project.folder;
args.folder = path.dirname(args.folder); args.folder = path.dirname(args.folder);
@ -1098,13 +1099,13 @@ export default class SqlMgr {
public async projectChangeEnv(args) { public async projectChangeEnv(args) {
try { try {
const xcConfig = JSON.parse( const xcConfig = JSON.parse(
fs.readFileSync( await promisify(fs.readFile)(
path.join(this.currentProjectFolder, 'config.xc.json'), path.join(this.currentProjectFolder, 'config.xc.json'),
'utf8' 'utf8'
) )
); );
xcConfig.workingEnv = args.env; xcConfig.workingEnv = args.env;
fs.writeFileSync( await promisify(fs.writeFile)(
path.join(this.currentProjectFolder, 'config.xc.json'), path.join(this.currentProjectFolder, 'config.xc.json'),
JSON.stringify(xcConfig, null, 2) JSON.stringify(xcConfig, null, 2)
); );
@ -1357,7 +1358,7 @@ export default class SqlMgr {
break; break;
case ToolOps.WRITE_FILE: case ToolOps.WRITE_FILE:
console.log('Within WRITE_FILE handler', args); console.log('Within WRITE_FILE handler', args);
result = fs.writeFileSync(args.args.path, args.args.data); result = await promisify(fs.writeFile)(args.args.path, args.args.data);
break; break;
case ToolOps.REST_API_CALL: case ToolOps.REST_API_CALL:

10
packages/nocodb/src/lib/db/sql-mgr/v2/SqlMgrv2.ts

@ -29,11 +29,11 @@ export default class SqlMgrv2 {
return this; return this;
} }
public migrator(_base: Base) { public async migrator(_base: Base) {
return this._migrator; return this._migrator;
} }
public static async testConnection(args = {}) { public static async testConnection(args = {}) {
const client = SqlClientFactory.create(args); const client = await SqlClientFactory.create(args);
return client.testConnection(); return client.testConnection();
} }
@ -52,7 +52,7 @@ export default class SqlMgrv2 {
log.api(`${func}:args:`, base, op, opArgs); log.api(`${func}:args:`, base, op, opArgs);
// create sql client for this operation // create sql client for this operation
const client = this.getSqlClient(base); const client = await this.getSqlClient(base);
// do sql operation // do sql operation
const data = await client[op](opArgs); const data = await client[op](opArgs);
@ -75,7 +75,7 @@ export default class SqlMgrv2 {
log.api(`${func}:args:`, base, op, opArgs); log.api(`${func}:args:`, base, op, opArgs);
// create sql client for this operation // create sql client for this operation
const sqlClient = this.getSqlClient(base); //await this.projectGetSqlClient(args); const sqlClient = await this.getSqlClient(base); //await this.projectGetSqlClient(args);
// do sql operation // do sql operation
const sqlMigrationStatements = await sqlClient[op](opArgs); const sqlMigrationStatements = await sqlClient[op](opArgs);
@ -118,7 +118,7 @@ export default class SqlMgrv2 {
return sqlMigrationStatements; return sqlMigrationStatements;
} }
protected getSqlClient(base: Base) { protected async getSqlClient(base: Base): Promise<any> {
return NcConnectionMgrv2.getSqlClient(base); return NcConnectionMgrv2.getSqlClient(base);
} }
} }

6
packages/nocodb/src/lib/db/sql-mgr/v2/SqlMgrv2Trans.ts

@ -25,10 +25,10 @@ export default class SqlMgrv2Trans extends SqlMgrv2 {
this.base = base; this.base = base;
} }
public migrator() { public async migrator() {
return new KnexMigratorv2Tans( return new KnexMigratorv2Tans(
{ id: this.projectId }, { id: this.projectId },
this.getSqlClient(this.base), await this.getSqlClient(this.base),
this.ncMeta this.ncMeta
); );
} }
@ -52,7 +52,7 @@ export default class SqlMgrv2Trans extends SqlMgrv2 {
} }
} }
protected getSqlClient(base: Base) { protected async getSqlClient(base: Base): Promise<any> {
return NcConnectionMgrv2.getSqlClient(base, this.trx); return NcConnectionMgrv2.getSqlClient(base, this.trx);
} }

10
packages/nocodb/src/lib/db/sql-migrator/lib/KnexMigrator.ts

@ -309,7 +309,7 @@ export default class KnexMigrator extends SqlMigrator {
await this._readProjectJson(projJsonFilePath); await this._readProjectJson(projJsonFilePath);
this.emit('Migrator for project initalised successfully'); this.emit('Migrator for project initalised successfully');
} else if (NcConfigFactory.hasDbUrl()) { } else if (NcConfigFactory.hasDbUrl()) {
this.project = NcConfigFactory.make(); this.project = await NcConfigFactory.make();
} else { } else {
args.type = args.type || 'sqlite'; args.type = args.type || 'sqlite';
@ -381,7 +381,7 @@ export default class KnexMigrator extends SqlMigrator {
async _initDbWithSql(connectionConfig) { async _initDbWithSql(connectionConfig) {
const sqlClient = const sqlClient =
connectionConfig.sqlClient || SqlClientFactory.create(connectionConfig); connectionConfig.sqlClient || await SqlClientFactory.create(connectionConfig);
if (connectionConfig.client === 'oracledb') { if (connectionConfig.client === 'oracledb') {
this.emit( this.emit(
`${connectionConfig.client}: Creating DB if not exists ${connectionConfig.connection.user}` `${connectionConfig.client}: Creating DB if not exists ${connectionConfig.connection.user}`
@ -427,7 +427,7 @@ export default class KnexMigrator extends SqlMigrator {
} }
async _cleanDbWithSql(connectionConfig) { async _cleanDbWithSql(connectionConfig) {
const sqlClient = SqlClientFactory.create(connectionConfig); const sqlClient = await SqlClientFactory.create(connectionConfig);
if (connectionConfig.client === 'oracledb') { if (connectionConfig.client === 'oracledb') {
this.emit(`Dropping DB : ${connectionConfig.connection.user}`); this.emit(`Dropping DB : ${connectionConfig.connection.user}`);
await sqlClient.dropDatabase({ await sqlClient.dropDatabase({
@ -567,7 +567,7 @@ export default class KnexMigrator extends SqlMigrator {
args.dbAlias, args.dbAlias,
args.env args.env
); );
const sqlClient = args.sqlClient || SqlClientFactory.create(connection); const sqlClient = args.sqlClient || await SqlClientFactory.create(connection);
let migrations = await sqlClient.selectAll( let migrations = await sqlClient.selectAll(
sqlClient.getTnPath(connection.meta.tn) sqlClient.getTnPath(connection.meta.tn)
@ -820,7 +820,7 @@ export default class KnexMigrator extends SqlMigrator {
args.dbAlias, args.dbAlias,
args.env args.env
); );
const sqlClient = SqlClientFactory.create(connection); const sqlClient = await SqlClientFactory.create(connection);
const migrations = await sqlClient.selectAll( const migrations = await sqlClient.selectAll(
sqlClient.getTnPath(connection.meta.tn) sqlClient.getTnPath(connection.meta.tn)
); );

10
packages/nocodb/src/lib/db/sql-migrator/lib/KnexMigratorv2.ts

@ -382,7 +382,7 @@ export default class KnexMigratorv2 {
// } // }
async _initDbWithSql(base: Base) { async _initDbWithSql(base: Base) {
const sqlClient = this.getSqlClient(base); const sqlClient = await this.getSqlClient(base);
const connectionConfig = base.getConnectionConfig(); const connectionConfig = base.getConnectionConfig();
if (connectionConfig.client === 'oracledb') { if (connectionConfig.client === 'oracledb') {
this.emit( this.emit(
@ -428,12 +428,12 @@ export default class KnexMigratorv2 {
// } // }
} }
protected getSqlClient(base: Base) { protected async getSqlClient(base: Base): Promise<any> {
return NcConnectionMgrv2.getSqlClient(base); return NcConnectionMgrv2.getSqlClient(base);
} }
async _cleanDbWithSql(connectionConfig) { async _cleanDbWithSql(connectionConfig) {
const sqlClient = SqlClientFactory.create(connectionConfig); const sqlClient = await SqlClientFactory.create(connectionConfig);
if (connectionConfig.client === 'oracledb') { if (connectionConfig.client === 'oracledb') {
this.emit(`Dropping DB : ${connectionConfig.connection.user}`); this.emit(`Dropping DB : ${connectionConfig.connection.user}`);
await sqlClient.dropDatabase({ await sqlClient.dropDatabase({
@ -584,7 +584,7 @@ export default class KnexMigratorv2 {
// args.dbAlias, // args.dbAlias,
// args.env // args.env
// ); // );
const sqlClient = this.getSqlClient(base); const sqlClient = await this.getSqlClient(base);
let migrations = await sqlClient.selectAll( let migrations = await sqlClient.selectAll(
// todo: replace // todo: replace
@ -849,7 +849,7 @@ export default class KnexMigratorv2 {
// args.dbAlias, // args.dbAlias,
// args.env // args.env
// ); // );
const sqlClient = this.getSqlClient(base); // SqlClientFactory.create(connection); const sqlClient = await this.getSqlClient(base); // SqlClientFactory.create(connection);
const migrations = await sqlClient.selectAll( const migrations = await sqlClient.selectAll(
sqlClient.getTnPath('nc_evolutions') sqlClient.getTnPath('nc_evolutions')
); );

2
packages/nocodb/src/lib/db/sql-migrator/lib/KnexMigratorv2Tans.ts

@ -24,7 +24,7 @@ export default class KnexMigratorv2Tans extends KnexMigratorv2 {
protected get metaDb(): XKnex { protected get metaDb(): XKnex {
return this.ncMeta.knex || Noco.ncMeta.knex; return this.ncMeta.knex || Noco.ncMeta.knex;
} }
protected getSqlClient(base: Base) { protected async getSqlClient(base: Base): Promise<any> {
return this.sqlClient || NcConnectionMgrv2.getSqlClient(base); return this.sqlClient || NcConnectionMgrv2.getSqlClient(base);
} }
} }

34
packages/nocodb/src/lib/meta/NcMetaMgr.ts

@ -437,9 +437,9 @@ export default class NcMetaMgr {
await this.xcMetaTablesReset(args); await this.xcMetaTablesReset(args);
for (const tn of META_TABLES[this.config.projectType.toLowerCase()]) { for (const tn of META_TABLES[this.config.projectType.toLowerCase()]) {
if (fs.existsSync(path.join(metaFolder, `${tn}.json`))) { if (await promisify(fs.exists)(path.join(metaFolder, `${tn}.json`))) {
const data = JSON.parse( const data = JSON.parse(
fs.readFileSync(path.join(metaFolder, `${tn}.json`), 'utf8') await promisify(fs.readFile)(path.join(metaFolder, `${tn}.json`), 'utf8')
); );
for (const row of data) { for (const row of data) {
delete row.id; delete row.id;
@ -488,14 +488,14 @@ export default class NcMetaMgr {
}, },
}); });
// delete temporary upload file // delete temporary upload file
fs.unlinkSync(file.path); await promisify(fs.unlink)(file.path);
let projectId = this.getProjectId(args); let projectId = this.getProjectId(args);
if (!projectConfigPath) { if (!projectConfigPath) {
throw new Error('Missing project config file'); throw new Error('Missing project config file');
} }
const projectDetailsJSON: any = fs.readFileSync( const projectDetailsJSON: any = await promisify(fs.readFile)(
path.join(this.config.toolDir, 'uploads', projectConfigPath), path.join(this.config.toolDir, 'uploads', projectConfigPath),
'utf8' 'utf8'
); );
@ -519,7 +519,7 @@ export default class NcMetaMgr {
if (projectConfig?.prefix) { if (projectConfig?.prefix) {
const metaProjConfig = const metaProjConfig =
NcConfigFactory.makeProjectConfigFromConnection( await NcConfigFactory.makeProjectConfigFromConnection(
this.config?.meta?.db, this.config?.meta?.db,
args.args.projectType args.args.projectType
); );
@ -614,11 +614,11 @@ export default class NcMetaMgr {
}, },
}); });
// delete temporary upload file // delete temporary upload file
fs.unlinkSync(file.path); await promisify(fs.unlink)(file.path);
if (projectConfigPath) { if (projectConfigPath) {
// read project config and extract project id // read project config and extract project id
let projectConfig: any = fs.readFileSync( let projectConfig: any = await promisify(fs.readFile)(
path.join(this.config?.toolDir, projectConfigPath), path.join(this.config?.toolDir, projectConfigPath),
'utf8' 'utf8'
); );
@ -702,14 +702,14 @@ export default class NcMetaMgr {
'meta' 'meta'
); );
mkdirp.sync(metaFolder); await mkdirp(metaFolder);
// const client = await this.projectGetSqlClient(args); // const client = await this.projectGetSqlClient(args);
const dbAlias = this.getDbAlias(args); const dbAlias = this.getDbAlias(args);
for (const tn of META_TABLES[this.config.projectType.toLowerCase()]) { for (const tn of META_TABLES[this.config.projectType.toLowerCase()]) {
// const metaData = await client.knex(tn).select(); // const metaData = await client.knex(tn).select();
const metaData = await this.xcMeta.metaList(projectId, dbAlias, tn); const metaData = await this.xcMeta.metaList(projectId, dbAlias, tn);
fs.writeFileSync( await promisify(fs.writeFile)(
path.join(metaFolder, `${tn}.json`), path.join(metaFolder, `${tn}.json`),
JSON.stringify(metaData, null, 2) JSON.stringify(metaData, null, 2)
); );
@ -720,7 +720,7 @@ export default class NcMetaMgr {
true true
); );
projectMetaData.key = this.config?.auth?.jwt?.secret; projectMetaData.key = this.config?.auth?.jwt?.secret;
fs.writeFileSync( await promisify(fs.writeFile)(
path.join(metaFolder, `nc_project.json`), path.join(metaFolder, `nc_project.json`),
JSON.stringify(projectMetaData, null, 2) JSON.stringify(projectMetaData, null, 2)
); );
@ -1551,7 +1551,7 @@ export default class NcMetaMgr {
break; break;
case 'testConnection': case 'testConnection':
result = await SqlClientFactory.create(args.args).testConnection(); result = await (await SqlClientFactory.create(args.args)).testConnection();
break; break;
case 'xcProjectGetConfig': case 'xcProjectGetConfig':
result = await this.xcMeta.projectGetById(this.getProjectId(args)); result = await this.xcMeta.projectGetById(this.getProjectId(args));
@ -1602,7 +1602,7 @@ export default class NcMetaMgr {
break; break;
case 'projectCreateByOneClick': case 'projectCreateByOneClick':
{ {
const config = NcConfigFactory.makeProjectConfigFromUrl( const config = await NcConfigFactory.makeProjectConfigFromUrl(
process.env.NC_DB, process.env.NC_DB,
args.args.projectType args.args.projectType
); );
@ -1635,7 +1635,7 @@ export default class NcMetaMgr {
break; break;
case 'projectCreateByWebWithXCDB': { case 'projectCreateByWebWithXCDB': {
await this.checkIsUserAllowedToCreateProject(req); await this.checkIsUserAllowedToCreateProject(req);
const config = NcConfigFactory.makeProjectConfigFromConnection( const config = await NcConfigFactory.makeProjectConfigFromConnection(
this.config?.meta?.db, this.config?.meta?.db,
args.args.projectType args.args.projectType
); );
@ -2904,7 +2904,7 @@ export default class NcMetaMgr {
} }
} }
protected projectGetSqlClient(args) { protected async projectGetSqlClient(args): Promise<any> {
const builder = this.getBuilder(args); const builder = this.getBuilder(args);
return builder?.getSqlClient(); return builder?.getSqlClient();
} }
@ -3440,7 +3440,7 @@ export default class NcMetaMgr {
} }
// @ts-ignore // @ts-ignore
protected getSqlClient(project_id: string, dbAlias: string) { protected async getSqlClient(project_id: string, dbAlias: string) {
return this.app?.projectBuilders return this.app?.projectBuilders
?.find((pb) => pb?.id === project_id) ?.find((pb) => pb?.id === project_id)
?.apiBuilders?.find((builder) => builder.dbAlias === dbAlias) ?.apiBuilders?.find((builder) => builder.dbAlias === dbAlias)
@ -4250,7 +4250,7 @@ export default class NcMetaMgr {
return { data: { list: columns } }; return { data: { list: columns } };
} }
return this.projectGetSqlClient(args).columnList(args.args); return (await this.projectGetSqlClient(args)).columnList(args.args);
} catch (e) { } catch (e) {
throw e; throw e;
} }
@ -4595,7 +4595,7 @@ export default class NcMetaMgr {
{} {}
); );
const sqlClient = this.projectGetSqlClient(args); const sqlClient = await this.projectGetSqlClient(args);
switch (args.args.type) { switch (args.args.type) {
case 'table': case 'table':

2
packages/nocodb/src/lib/meta/api/baseApis.ts

@ -119,7 +119,7 @@ async function populateMeta(base: Base, project: Project): Promise<any> {
}; };
const t = process.hrtime(); const t = process.hrtime();
const sqlClient = NcConnectionMgrv2.getSqlClient(base); const sqlClient = await NcConnectionMgrv2.getSqlClient(base);
let order = 1; let order = 1;
const models2: { [tableName: string]: Model } = {}; const models2: { [tableName: string]: Model } = {};

2
packages/nocodb/src/lib/meta/api/columnApis.ts

@ -674,7 +674,7 @@ export async function columnAdd(
], ],
}; };
const sqlClient = NcConnectionMgrv2.getSqlClient(base); const sqlClient = await NcConnectionMgrv2.getSqlClient(base);
const sqlMgr = await ProjectMgrv2.getSqlMgr({ id: base.project_id }); const sqlMgr = await ProjectMgrv2.getSqlMgr({ id: base.project_id });
await sqlMgr.sqlOpPlus(base, 'tableUpdate', tableUpdateBody); await sqlMgr.sqlOpPlus(base, 'tableUpdate', tableUpdateBody);

8
packages/nocodb/src/lib/meta/api/metaDiffApis.ts

@ -548,7 +548,7 @@ export async function metaDiff(req, res) {
for (const base of project.bases) { for (const base of project.bases) {
try { try {
// @ts-ignore // @ts-ignore
const sqlClient = NcConnectionMgrv2.getSqlClient(base); const sqlClient = await NcConnectionMgrv2.getSqlClient(base);
changes = changes.concat(await getMetaDiff(sqlClient, project, base)); changes = changes.concat(await getMetaDiff(sqlClient, project, base));
} catch (e) { } catch (e) {
console.log(e); console.log(e);
@ -563,7 +563,7 @@ export async function baseMetaDiff(req, res) {
const base = await Base.get(req.params.baseId); const base = await Base.get(req.params.baseId);
let changes = []; let changes = [];
const sqlClient = NcConnectionMgrv2.getSqlClient(base); const sqlClient = await NcConnectionMgrv2.getSqlClient(base);
changes = await getMetaDiff(sqlClient, project, base); changes = await getMetaDiff(sqlClient, project, base);
res.json(changes); res.json(changes);
@ -575,7 +575,7 @@ export async function metaDiffSync(req, res) {
const virtualColumnInsert: Array<() => Promise<void>> = []; const virtualColumnInsert: Array<() => Promise<void>> = [];
// @ts-ignore // @ts-ignore
const sqlClient = NcConnectionMgrv2.getSqlClient(base); const sqlClient = await NcConnectionMgrv2.getSqlClient(base);
const changes = await getMetaDiff(sqlClient, project, base); const changes = await getMetaDiff(sqlClient, project, base);
/* Get all relations */ /* Get all relations */
@ -778,7 +778,7 @@ export async function baseMetaDiffSync(req, res) {
const virtualColumnInsert: Array<() => Promise<void>> = []; const virtualColumnInsert: Array<() => Promise<void>> = [];
// @ts-ignore // @ts-ignore
const sqlClient = NcConnectionMgrv2.getSqlClient(base); const sqlClient = await NcConnectionMgrv2.getSqlClient(base);
const changes = await getMetaDiff(sqlClient, project, base); const changes = await getMetaDiff(sqlClient, project, base);
/* Get all relations */ /* Get all relations */

9
packages/nocodb/src/lib/meta/api/projectApis.ts

@ -27,6 +27,7 @@ import { extractAndGenerateManyToManyRelations } from './metaDiffApis';
import { metaApiMetrics } from '../helpers/apiMetrics'; import { metaApiMetrics } from '../helpers/apiMetrics';
import { extractPropsAndSanitize } from '../helpers/extractProps'; import { extractPropsAndSanitize } from '../helpers/extractProps';
import NcConfigFactory from '../../utils/NcConfigFactory'; import NcConfigFactory from '../../utils/NcConfigFactory';
import { promisify } from 'util';
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 4); const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 4);
@ -121,8 +122,8 @@ async function projectCreate(req: Request<any, any>, res) {
'1234567890abcdefghijklmnopqrstuvwxyz', '1234567890abcdefghijklmnopqrstuvwxyz',
14 14
); );
if (!fs.existsSync(`${toolDir}/nc_minimal_dbs`)) { if (!await promisify(fs.exists)(`${toolDir}/nc_minimal_dbs`)) {
fs.mkdirSync(`${toolDir}/nc_minimal_dbs`); await promisify(fs.mkdir)(`${toolDir}/nc_minimal_dbs`);
} }
const dbId = nanoidv2(); const dbId = nanoidv2();
const projectTitle = DOMPurify.sanitize(projectBody.title); const projectTitle = DOMPurify.sanitize(projectBody.title);
@ -213,7 +214,7 @@ async function populateMeta(base: Base, project: Project): Promise<any> {
}; };
const t = process.hrtime(); const t = process.hrtime();
const sqlClient = NcConnectionMgrv2.getSqlClient(base); const sqlClient = await NcConnectionMgrv2.getSqlClient(base);
let order = 1; let order = 1;
const models2: { [tableName: string]: Model } = {}; const models2: { [tableName: string]: Model } = {};
@ -467,7 +468,7 @@ export async function projectCost(req, res) {
const project = await Project.getWithInfo(req.params.projectId); const project = await Project.getWithInfo(req.params.projectId);
for (const base of project.bases) { for (const base of project.bases) {
const sqlClient = NcConnectionMgrv2.getSqlClient(base); const sqlClient = await NcConnectionMgrv2.getSqlClient(base);
const userCount = await ProjectUser.getUsersCount(req.query); const userCount = await ProjectUser.getUsersCount(req.query);
const recordCount = (await sqlClient.totalRecords())?.data.TotalRecords; const recordCount = (await sqlClient.totalRecords())?.data.TotalRecords;

13
packages/nocodb/src/lib/meta/api/sync/helpers/job.ts

@ -8,6 +8,7 @@ import { Api } from 'nocodb-sdk';
import Airtable from 'airtable'; import Airtable from 'airtable';
import jsonfile from 'jsonfile'; import jsonfile from 'jsonfile';
import hash from 'object-hash'; import hash from 'object-hash';
import { promisify } from 'util';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc'; import utc from 'dayjs/plugin/utc';
@ -16,6 +17,8 @@ import { importData, importLTARData } from './readAndProcessData';
import EntityMap from './EntityMap'; import EntityMap from './EntityMap';
const writeJsonFileAsync = promisify(jsonfile.writeFile);
dayjs.extend(utc); dayjs.extend(utc);
const selectColors = { const selectColors = {
@ -204,7 +207,7 @@ export default async (
// store copy of airtable schema globally // store copy of airtable schema globally
g_aTblSchema = file.tableSchemas; g_aTblSchema = file.tableSchemas;
if (debugMode) jsonfile.writeFileSync('aTblSchema.json', ft, { spaces: 2 }); if (debugMode) await writeJsonFileAsync('aTblSchema.json', ft, { spaces: 2 });
return file; return file;
} }
@ -216,7 +219,7 @@ export default async (
rtc.fetchAt.count++; rtc.fetchAt.count++;
rtc.fetchAt.time += duration; rtc.fetchAt.time += duration;
if (debugMode) jsonfile.writeFileSync(`${viewId}.json`, ft, { spaces: 2 }); if (debugMode) await writeJsonFileAsync(`${viewId}.json`, ft, { spaces: 2 });
return ft.view; return ft.view;
} }
@ -1917,13 +1920,13 @@ export default async (
logBasic(`:: Axios fetch time: ${rtc.fetchAt.time}`); logBasic(`:: Axios fetch time: ${rtc.fetchAt.time}`);
if (debugMode) { if (debugMode) {
jsonfile.writeFileSync('stats.json', perfStats, { spaces: 2 }); await writeJsonFileAsync('stats.json', perfStats, { spaces: 2 });
const perflog = []; const perflog = [];
for (let i = 0; i < perfStats.length; i++) { for (let i = 0; i < perfStats.length; i++) {
perflog.push(`${perfStats[i].e}, ${perfStats[i].d}`); perflog.push(`${perfStats[i].e}, ${perfStats[i].d}`);
} }
jsonfile.writeFileSync('stats.csv', perflog, { spaces: 2 }); await writeJsonFileAsync('stats.csv', perflog, { spaces: 2 });
jsonfile.writeFileSync('skip.txt', rtc.migrationSkipLog.log, { await writeJsonFileAsync('skip.txt', rtc.migrationSkipLog.log, {
spaces: 2, spaces: 2,
}); });
} }

4
packages/nocodb/src/lib/meta/api/tableApis.ts

@ -148,7 +148,7 @@ export async function tableCreate(req: Request<any, any, TableReqType>, res) {
} }
const sqlMgr = await ProjectMgrv2.getSqlMgr(project); const sqlMgr = await ProjectMgrv2.getSqlMgr(project);
const sqlClient = NcConnectionMgrv2.getSqlClient(base); const sqlClient = await NcConnectionMgrv2.getSqlClient(base);
let tableNameLengthLimit = 255; let tableNameLengthLimit = 255;
const sqlClientType = sqlClient.clientType; const sqlClientType = sqlClient.clientType;
@ -295,7 +295,7 @@ export async function tableUpdate(req: Request<any, any>, res) {
} }
const sqlMgr = await ProjectMgrv2.getSqlMgr(project); const sqlMgr = await ProjectMgrv2.getSqlMgr(project);
const sqlClient = NcConnectionMgrv2.getSqlClient(base); const sqlClient = await NcConnectionMgrv2.getSqlClient(base);
let tableNameLengthLimit = 255; let tableNameLengthLimit = 255;
const sqlClientType = sqlClient.clientType; const sqlClientType = sqlClient.clientType;

4
packages/nocodb/src/lib/meta/api/utilApis.ts

@ -320,8 +320,8 @@ export async function aggregatedMetaInfo(_req: Request, res: Response) {
project.getBases().then(async (bases) => { project.getBases().then(async (bases) => {
return extractResultOrNull( return extractResultOrNull(
await Promise.allSettled( await Promise.allSettled(
bases.map((base) => bases.map(async (base) =>
NcConnectionMgrv2.getSqlClient(base) (await NcConnectionMgrv2.getSqlClient(base))
.totalRecords?.() .totalRecords?.()
?.then((result) => result?.data) ?.then((result) => result?.data)
) )

2
packages/nocodb/src/lib/meta/handlers/xcMetaDiff.ts

@ -42,7 +42,7 @@ export default async function (
const builder = this.getBuilder(args); const builder = this.getBuilder(args);
// @ts-ignore // @ts-ignore
const sqlClient = this.projectGetSqlClient(args); const sqlClient = await this.projectGetSqlClient(args);
// @ts-ignore // @ts-ignore
const tableList = (await sqlClient.tableList())?.data?.list?.filter((t) => { const tableList = (await sqlClient.tableList())?.data?.list?.filter((t) => {

3
packages/nocodb/src/lib/plugins/backblaze/Backblaze.ts

@ -1,4 +1,5 @@
import fs from 'fs'; import fs from 'fs';
import { promisify } from 'util';
import AWS from 'aws-sdk'; import AWS from 'aws-sdk';
import { IStorageAdapterV2, XcFile } from 'nc-plugin'; import { IStorageAdapterV2, XcFile } from 'nc-plugin';
import request from 'request'; import request from 'request';
@ -132,7 +133,7 @@ export default class Backblaze implements IStorageAdapterV2 {
originalname: 'temp.txt', originalname: 'temp.txt',
size: '', size: '',
}); });
fs.unlinkSync(tempFile); await promisify(fs.unlink)(tempFile);
return true; return true;
} catch (e) { } catch (e) {
throw e; throw e;

3
packages/nocodb/src/lib/plugins/gcs/Gcs.ts

@ -1,4 +1,5 @@
import fs from 'fs'; import fs from 'fs';
import { promisify } from 'util';
import { Storage, StorageOptions } from '@google-cloud/storage'; import { Storage, StorageOptions } from '@google-cloud/storage';
import { IStorageAdapterV2, XcFile } from 'nc-plugin'; import { IStorageAdapterV2, XcFile } from 'nc-plugin';
import request from 'request'; import request from 'request';
@ -96,7 +97,7 @@ export default class Gcs implements IStorageAdapterV2 {
originalname: 'temp.txt', originalname: 'temp.txt',
size: '', size: '',
}); });
fs.unlinkSync(tempFile); await promisify(fs.unlink)(tempFile);
return true; return true;
} catch (e) { } catch (e) {
throw e; throw e;

3
packages/nocodb/src/lib/plugins/linode/LinodeObjectStorage.ts

@ -1,4 +1,5 @@
import fs from 'fs'; import fs from 'fs';
import { promisify } from 'util';
import AWS from 'aws-sdk'; import AWS from 'aws-sdk';
import { IStorageAdapterV2, XcFile } from 'nc-plugin'; import { IStorageAdapterV2, XcFile } from 'nc-plugin';
import request from 'request'; import request from 'request';
@ -122,7 +123,7 @@ export default class LinodeObjectStorage implements IStorageAdapterV2 {
originalname: 'temp.txt', originalname: 'temp.txt',
size: '', size: '',
}); });
fs.unlinkSync(tempFile); await promisify(fs.unlink)(tempFile);
return true; return true;
} catch (e) { } catch (e) {
throw e; throw e;

3
packages/nocodb/src/lib/plugins/mino/Minio.ts

@ -1,4 +1,5 @@
import fs from 'fs'; import fs from 'fs';
import { promisify } from 'util';
import { Client as MinioClient } from 'minio'; import { Client as MinioClient } from 'minio';
import { IStorageAdapterV2, XcFile } from 'nc-plugin'; import { IStorageAdapterV2, XcFile } from 'nc-plugin';
import request from 'request'; import request from 'request';
@ -84,7 +85,7 @@ export default class Minio implements IStorageAdapterV2 {
originalname: 'temp.txt', originalname: 'temp.txt',
size: '', size: '',
}); });
fs.unlinkSync(tempFile); await promisify(fs.unlink)(tempFile);
return true; return true;
} catch (e) { } catch (e) {
throw e; throw e;

3
packages/nocodb/src/lib/plugins/ovhCloud/OvhCloud.ts

@ -1,4 +1,5 @@
import fs from 'fs'; import fs from 'fs';
import { promisify } from 'util';
import AWS from 'aws-sdk'; import AWS from 'aws-sdk';
import { IStorageAdapterV2, XcFile } from 'nc-plugin'; import { IStorageAdapterV2, XcFile } from 'nc-plugin';
import request from 'request'; import request from 'request';
@ -122,7 +123,7 @@ export default class OvhCloud implements IStorageAdapterV2 {
originalname: 'temp.txt', originalname: 'temp.txt',
size: '', size: '',
}); });
fs.unlinkSync(tempFile); await promisify(fs.unlink)(tempFile);
return true; return true;
} catch (e) { } catch (e) {
throw e; throw e;

3
packages/nocodb/src/lib/plugins/s3/S3.ts

@ -1,4 +1,5 @@
import fs from 'fs'; import fs from 'fs';
import { promisify } from 'util';
import AWS from 'aws-sdk'; import AWS from 'aws-sdk';
import { IStorageAdapterV2, XcFile } from 'nc-plugin'; import { IStorageAdapterV2, XcFile } from 'nc-plugin';
import request from 'request'; import request from 'request';
@ -125,7 +126,7 @@ export default class S3 implements IStorageAdapterV2 {
originalname: 'temp.txt', originalname: 'temp.txt',
size: '', size: '',
}); });
fs.unlinkSync(tempFile); await promisify(fs.unlink)(tempFile);
return true; return true;
} catch (e) { } catch (e) {
throw e; throw e;

3
packages/nocodb/src/lib/plugins/scaleway/ScalewayObjectStorage.ts

@ -1,4 +1,5 @@
import fs from 'fs'; import fs from 'fs';
import { promisify } from 'util';
import { IStorageAdapterV2, XcFile } from 'nc-plugin'; import { IStorageAdapterV2, XcFile } from 'nc-plugin';
import AWS from 'aws-sdk'; import AWS from 'aws-sdk';
import request from 'request'; import request from 'request';
@ -40,7 +41,7 @@ export default class ScalewayObjectStorage implements IStorageAdapterV2 {
originalname: 'temp.txt', originalname: 'temp.txt',
size: '', size: '',
}); });
fs.unlinkSync(tempFile); await promisify(fs.unlink)(tempFile);
return true; return true;
} catch (e) { } catch (e) {
throw e; throw e;

3
packages/nocodb/src/lib/plugins/spaces/Spaces.ts

@ -1,4 +1,5 @@
import fs from 'fs'; import fs from 'fs';
import { promisify } from 'util';
import AWS from 'aws-sdk'; import AWS from 'aws-sdk';
import { IStorageAdapterV2, XcFile } from 'nc-plugin'; import { IStorageAdapterV2, XcFile } from 'nc-plugin';
import request from 'request'; import request from 'request';
@ -130,7 +131,7 @@ export default class Spaces implements IStorageAdapterV2 {
originalname: 'temp.txt', originalname: 'temp.txt',
size: '', size: '',
}); });
fs.unlinkSync(tempFile); await promisify(fs.unlink)(tempFile);
return true; return true;
} catch (e) { } catch (e) {
throw e; throw e;

3
packages/nocodb/src/lib/plugins/upcloud/UpoCloud.ts

@ -1,4 +1,5 @@
import fs from 'fs'; import fs from 'fs';
import { promisify } from 'util';
import AWS from 'aws-sdk'; import AWS from 'aws-sdk';
import { IStorageAdapterV2, XcFile } from 'nc-plugin'; import { IStorageAdapterV2, XcFile } from 'nc-plugin';
import request from 'request'; import request from 'request';
@ -120,7 +121,7 @@ export default class UpoCloud implements IStorageAdapterV2 {
originalname: 'temp.txt', originalname: 'temp.txt',
size: '', size: '',
}); });
fs.unlinkSync(tempFile); await promisify(fs.unlink)(tempFile);
return true; return true;
} catch (e) { } catch (e) {
throw e; throw e;

3
packages/nocodb/src/lib/plugins/vultr/Vultr.ts

@ -1,4 +1,5 @@
import fs from 'fs'; import fs from 'fs';
import { promisify } from 'util';
import AWS from 'aws-sdk'; import AWS from 'aws-sdk';
import { IStorageAdapterV2, XcFile } from 'nc-plugin'; import { IStorageAdapterV2, XcFile } from 'nc-plugin';
import request from 'request'; import request from 'request';
@ -122,7 +123,7 @@ export default class Vultr implements IStorageAdapterV2 {
originalname: 'temp.txt', originalname: 'temp.txt',
size: '', size: '',
}); });
fs.unlinkSync(tempFile); await promisify(fs.unlink)(tempFile);
return true; return true;
} catch (e) { } catch (e) {
throw e; throw e;

49
packages/nocodb/src/lib/utils/NcConfigFactory.ts

@ -1,6 +1,7 @@
import fs from 'fs'; import fs from 'fs';
import parseDbUrl from 'parse-database-url'; import parseDbUrl from 'parse-database-url';
import { URL } from 'url'; import { URL } from 'url';
import { promisify } from 'util';
import { import {
AuthConfig, AuthConfig,
@ -89,8 +90,8 @@ const knownQueryParams = [
]; ];
export default class NcConfigFactory implements NcConfig { export default class NcConfigFactory implements NcConfig {
public static make(): NcConfig { public static async make(): Promise<NcConfig> {
this.jdbcToXcUrl(); await this.jdbcToXcUrl();
const ncConfig = new NcConfigFactory(); const ncConfig = new NcConfigFactory();
@ -115,17 +116,17 @@ export default class NcConfigFactory implements NcConfig {
} }
if (process.env.NC_DB) { if (process.env.NC_DB) {
ncConfig.meta.db = this.metaUrlToDbConfig(process.env.NC_DB); ncConfig.meta.db = await this.metaUrlToDbConfig(process.env.NC_DB);
} else if (process.env.NC_DB_JSON) { } else if (process.env.NC_DB_JSON) {
ncConfig.meta.db = JSON.parse(process.env.NC_DB_JSON); ncConfig.meta.db = JSON.parse(process.env.NC_DB_JSON);
} else if (process.env.NC_DB_JSON_FILE) { } else if (process.env.NC_DB_JSON_FILE) {
const filePath = process.env.NC_DB_JSON_FILE; const filePath = process.env.NC_DB_JSON_FILE;
if (!fs.existsSync(filePath)) { if (!await promisify(fs.exists)(filePath)) {
throw new Error(`NC_DB_JSON_FILE not found: ${filePath}`); throw new Error(`NC_DB_JSON_FILE not found: ${filePath}`);
} }
const fileContent = fs.readFileSync(filePath, { encoding: 'utf8' }); const fileContent = await promisify(fs.readFile)(filePath, { encoding: 'utf8' });
ncConfig.meta.db = JSON.parse(fileContent); ncConfig.meta.db = JSON.parse(fileContent);
} }
@ -291,7 +292,7 @@ export default class NcConfigFactory implements NcConfig {
.replace(/[ -]/g, '_'); .replace(/[ -]/g, '_');
} }
static metaUrlToDbConfig(urlString) { static async metaUrlToDbConfig(urlString) {
const url = new URL(urlString); const url = new URL(urlString);
let dbConfig; let dbConfig;
@ -378,29 +379,29 @@ export default class NcConfigFactory implements NcConfig {
typeof dbConfig?.connection?.ssl === 'object' typeof dbConfig?.connection?.ssl === 'object'
) { ) {
if (dbConfig.connection.ssl.caFilePath && !dbConfig.connection.ssl.ca) { if (dbConfig.connection.ssl.caFilePath && !dbConfig.connection.ssl.ca) {
dbConfig.connection.ssl.ca = fs dbConfig.connection.ssl.ca = await promisify(fs.readFile)(
.readFileSync(dbConfig.connection.ssl.caFilePath) dbConfig.connection.ssl.caFilePath
.toString(); ).toString();
} }
if (dbConfig.connection.ssl.keyFilePath && !dbConfig.connection.ssl.key) { if (dbConfig.connection.ssl.keyFilePath && !dbConfig.connection.ssl.key) {
dbConfig.connection.ssl.key = fs dbConfig.connection.ssl.key = await promisify(fs.readFile)(
.readFileSync(dbConfig.connection.ssl.keyFilePath) dbConfig.connection.ssl.keyFilePath
.toString(); ).toString();
} }
if ( if (
dbConfig.connection.ssl.certFilePath && dbConfig.connection.ssl.certFilePath &&
!dbConfig.connection.ssl.cert !dbConfig.connection.ssl.cert
) { ) {
dbConfig.connection.ssl.cert = fs dbConfig.connection.ssl.cert = await promisify(fs.readFile)(
.readFileSync(dbConfig.connection.ssl.certFilePath) dbConfig.connection.ssl.certFilePath
.toString(); ).toString();
} }
} }
return dbConfig; return dbConfig;
} }
public static makeProjectConfigFromUrl(url, type?: string): NcConfig { public static async makeProjectConfigFromUrl(url, type?: string): Promise<NcConfig> {
const config = new NcConfigFactory(); const config = new NcConfigFactory();
const dbConfig = this.urlToDbConfig(url, '', config, type); const dbConfig = this.urlToDbConfig(url, '', config, type);
// config.envs[process.env.NODE_ENV || 'dev'].db.push(dbConfig); // config.envs[process.env.NODE_ENV || 'dev'].db.push(dbConfig);
@ -430,7 +431,7 @@ export default class NcConfigFactory implements NcConfig {
} }
if (process.env.NC_DB) { if (process.env.NC_DB) {
config.meta.db = this.metaUrlToDbConfig(process.env.NC_DB); config.meta.db = await this.metaUrlToDbConfig(process.env.NC_DB);
} }
if (process.env.NC_TRY) { if (process.env.NC_TRY) {
@ -482,10 +483,10 @@ export default class NcConfigFactory implements NcConfig {
return config; return config;
} }
public static makeProjectConfigFromConnection( public static async makeProjectConfigFromConnection(
dbConnectionConfig: any, dbConnectionConfig: any,
type?: string type?: string
): NcConfig { ): Promise<NcConfig> {
const config = new NcConfigFactory(); const config = new NcConfigFactory();
let dbConfig = dbConnectionConfig; let dbConfig = dbConnectionConfig;
@ -545,7 +546,7 @@ export default class NcConfigFactory implements NcConfig {
} }
if (process.env.NC_DB) { if (process.env.NC_DB) {
config.meta.db = this.metaUrlToDbConfig(process.env.NC_DB); config.meta.db = await this.metaUrlToDbConfig(process.env.NC_DB);
} }
if (process.env.NC_TRY) { if (process.env.NC_TRY) {
@ -584,7 +585,7 @@ export default class NcConfigFactory implements NcConfig {
public static async metaDbCreateIfNotExist(args: NcConfig) { public static async metaDbCreateIfNotExist(args: NcConfig) {
if (args.meta?.db?.client === 'sqlite3') { if (args.meta?.db?.client === 'sqlite3') {
const metaSqlClient = SqlClientFactory.create({ const metaSqlClient = await SqlClientFactory.create({
...args.meta.db, ...args.meta.db,
connection: args.meta.db, connection: args.meta.db,
}); });
@ -592,7 +593,7 @@ export default class NcConfigFactory implements NcConfig {
database: args.meta.db?.connection?.filename, database: args.meta.db?.connection?.filename,
}); });
} else { } else {
const metaSqlClient = SqlClientFactory.create(args.meta.db); const metaSqlClient = await SqlClientFactory.create(args.meta.db);
await metaSqlClient.createDatabaseIfNotExists(args.meta.db?.connection); await metaSqlClient.createDatabaseIfNotExists(args.meta.db?.connection);
await metaSqlClient.knex.destroy(); await metaSqlClient.knex.destroy();
} }
@ -637,9 +638,9 @@ export default class NcConfigFactory implements NcConfig {
this.envs = { _noco: { db: [] } }; this.envs = { _noco: { db: [] } };
} }
public static jdbcToXcUrl() { public static async jdbcToXcUrl() {
if (process.env.NC_DATABASE_URL_FILE || process.env.DATABASE_URL_FILE) { if (process.env.NC_DATABASE_URL_FILE || process.env.DATABASE_URL_FILE) {
const database_url = fs.readFileSync( const database_url = await promisify(fs.readFile)(
process.env.NC_DATABASE_URL_FILE || process.env.DATABASE_URL_FILE, process.env.NC_DATABASE_URL_FILE || process.env.DATABASE_URL_FILE,
'utf-8' 'utf-8'
); );

14
packages/nocodb/src/lib/utils/common/BaseApiBuilder.ts

@ -187,7 +187,7 @@ export default abstract class BaseApiBuilder<T extends Noco>
return this.connectionConfig?.meta?.dbAlias; return this.connectionConfig?.meta?.dbAlias;
} }
public getSqlClient(): any { public async getSqlClient(): Promise<any> {
return NcConnectionMgr.getSqlClient({ return NcConnectionMgr.getSqlClient({
dbAlias: this.dbAlias, dbAlias: this.dbAlias,
env: this.config.env, env: this.config.env,
@ -1291,8 +1291,8 @@ export default abstract class BaseApiBuilder<T extends Noco>
this.models[viewName] = this.getBaseModel(newMeta); this.models[viewName] = this.getBaseModel(newMeta);
} }
public getDbDriver(): XKnex { public async getDbDriver(): Promise<XKnex> {
this.initDbDriver(); await this.initDbDriver();
return this.dbDriver; return this.dbDriver;
} }
@ -1669,14 +1669,14 @@ export default abstract class BaseApiBuilder<T extends Noco>
await this.cronJob.init(); await this.cronJob.init();
} }
protected initDbDriver(): void { protected async initDbDriver(): Promise<void> {
this.dbDriver = NcConnectionMgr.get({ this.dbDriver = await NcConnectionMgr.get({
dbAlias: this.dbAlias, dbAlias: this.dbAlias,
env: this.config.env, env: this.config.env,
config: this.config, config: this.config,
projectId: this.projectId, projectId: this.projectId,
}); });
this.sqlClient = NcConnectionMgr.getSqlClient({ this.sqlClient = await NcConnectionMgr.getSqlClient({
dbAlias: this.dbAlias, dbAlias: this.dbAlias,
env: this.config.env, env: this.config.env,
config: this.config, config: this.config,
@ -3064,7 +3064,7 @@ export default abstract class BaseApiBuilder<T extends Noco>
); );
const colListRef = {}; const colListRef = {};
const tableList = const tableList =
(await this.getSqlClient()?.tableList())?.data?.list || []; (await (await this.getSqlClient())?.tableList())?.data?.list || [];
colListRef[tableName] = await this.getColumnList(tableName); colListRef[tableName] = await this.getColumnList(tableName);

27
packages/nocodb/src/lib/utils/common/NcConnectionMgr.ts

@ -2,6 +2,7 @@ import SqlClientFactory from '../../db/sql-client/lib/SqlClientFactory';
import { XKnex } from '../../db/sql-data-mapper'; import { XKnex } from '../../db/sql-data-mapper';
import { NcConfig } from '../../../interface/config'; import { NcConfig } from '../../../interface/config';
import fs from 'fs'; import fs from 'fs';
import { promisify } from 'util';
import { Knex } from 'knex'; import { Knex } from 'knex';
import NcMetaIO from '../../meta/NcMetaIO'; import NcMetaIO from '../../meta/NcMetaIO';
@ -43,7 +44,7 @@ export default class NcConnectionMgr {
} }
} }
public static get({ public static async get({
dbAlias = 'db', dbAlias = 'db',
env = '_noco', env = '_noco',
config, config,
@ -53,7 +54,7 @@ export default class NcConnectionMgr {
env: string; env: string;
config: NcConfig; config: NcConfig;
projectId: string; projectId: string;
}): XKnex { }): Promise<XKnex> {
if (this.connectionRefs?.[projectId]?.[env]?.[dbAlias]) { if (this.connectionRefs?.[projectId]?.[env]?.[dbAlias]) {
return this.connectionRefs?.[projectId]?.[env]?.[dbAlias]; return this.connectionRefs?.[projectId]?.[env]?.[dbAlias];
} }
@ -73,25 +74,25 @@ export default class NcConnectionMgr {
connectionConfig.connection.ssl.caFilePath && connectionConfig.connection.ssl.caFilePath &&
!connectionConfig.connection.ssl.ca !connectionConfig.connection.ssl.ca
) { ) {
connectionConfig.connection.ssl.ca = fs connectionConfig.connection.ssl.ca = await promisify(fs.readFile)(
.readFileSync(connectionConfig.connection.ssl.caFilePath) connectionConfig.connection.ssl.caFilePath
.toString(); ).toString();
} }
if ( if (
connectionConfig.connection.ssl.keyFilePath && connectionConfig.connection.ssl.keyFilePath &&
!connectionConfig.connection.ssl.key !connectionConfig.connection.ssl.key
) { ) {
connectionConfig.connection.ssl.key = fs connectionConfig.connection.ssl.key = await promisify(fs.readFile)(
.readFileSync(connectionConfig.connection.ssl.keyFilePath) connectionConfig.connection.ssl.keyFilePath
.toString(); ).toString();
} }
if ( if (
connectionConfig.connection.ssl.certFilePath && connectionConfig.connection.ssl.certFilePath &&
!connectionConfig.connection.ssl.cert !connectionConfig.connection.ssl.cert
) { ) {
connectionConfig.connection.ssl.cert = fs connectionConfig.connection.ssl.cert = await promisify(fs.readFile)(
.readFileSync(connectionConfig.connection.ssl.certFilePath) connectionConfig.connection.ssl.certFilePath
.toString(); ).toString();
} }
} }
@ -138,7 +139,7 @@ export default class NcConnectionMgr {
return config?.envs?.[env]?.db?.find((db) => db?.meta?.dbAlias === dbAlias); return config?.envs?.[env]?.db?.find((db) => db?.meta?.dbAlias === dbAlias);
} }
public static getSqlClient({ public static async getSqlClient({
projectId, projectId,
dbAlias = 'db', dbAlias = 'db',
env = '_noco', env = '_noco',
@ -148,7 +149,7 @@ export default class NcConnectionMgr {
env: string; env: string;
config: NcConfig; config: NcConfig;
projectId: string; projectId: string;
}): any { }): Promise<any> {
const knex = this.get({ const knex = this.get({
dbAlias, dbAlias,
env, env,

2
packages/nocodb/src/lib/utils/common/NcConnectionMgrv2.ts

@ -149,7 +149,7 @@ export default class NcConnectionMgrv2 {
// return config?.envs?.[env]?.db?.find(db => db?.meta?.dbAlias === dbAlias); // return config?.envs?.[env]?.db?.find(db => db?.meta?.dbAlias === dbAlias);
// } // }
public static getSqlClient(base: Base, _knex = null): any { public static async getSqlClient(base: Base, _knex = null): Promise<any> {
const knex = _knex || this.get(base); const knex = _knex || this.get(base);
return SqlClientFactory.create({ return SqlClientFactory.create({
knex, knex,

14
packages/nocodb/src/lib/utils/common/XcProcedure.ts

@ -10,8 +10,8 @@ export default class XcProcedure {
public async callFunction(name: string, args: any[]) { public async callFunction(name: string, args: any[]) {
try { try {
if (this.builder.getDbType() === 'mssql') { if (this.builder.getDbType() === 'mssql') {
const result = await this.builder const result = await (await this.builder
.getDbDriver() .getDbDriver())
.raw( .raw(
`select dbo.??(${new Array(args.length) `select dbo.??(${new Array(args.length)
.fill('?') .fill('?')
@ -20,8 +20,8 @@ export default class XcProcedure {
); );
return result[0]; return result[0];
} else { } else {
const result = await this.builder const result = await (await this.builder
.getDbDriver() .getDbDriver())
.raw( .raw(
`select ??(${new Array(args.length).fill('?').join(',')}) as ??`, `select ??(${new Array(args.length).fill('?').join(',')}) as ??`,
[name, ...args, name] [name, ...args, name]
@ -65,7 +65,7 @@ export default class XcProcedure {
) { ) {
const knexRef = args.reduce( const knexRef = args.reduce(
(knex, val, i) => knex.raw(`SET @var${i}=?`, [val]), (knex, val, i) => knex.raw(`SET @var${i}=?`, [val]),
this.builder.getDbDriver().schema (await this.builder.getDbDriver()).schema
); );
const count = args.length; const count = args.length;
const result = await knexRef.raw( const result = await knexRef.raw(
@ -76,8 +76,8 @@ export default class XcProcedure {
); );
return [result[count][0][0]]; return [result[count][0][0]];
} else if (this.builder.getDbType() === 'pg') { } else if (this.builder.getDbType() === 'pg') {
const result = await this.builder const result = await (await this.builder
.getDbDriver() .getDbDriver())
.raw(`Call ??(${new Array(args.length).fill('?').join(',')})`, [ .raw(`Call ??(${new Array(args.length).fill('?').join(',')})`, [
name, name,
...args, ...args,

6
packages/nocodb/src/lib/utils/common/handlers/xcMetaDiffSync.ts

@ -10,8 +10,8 @@ import { GqlApiBuilder } from '../../../v1-legacy/gql/GqlApiBuilder';
export default async function (this: BaseApiBuilder<any> | any) { export default async function (this: BaseApiBuilder<any> | any) {
const changes: Array<NcMetaDiffType> = await xcMetaDiff.call( const changes: Array<NcMetaDiffType> = await xcMetaDiff.call(
{ {
projectGetSqlClient: () => { projectGetSqlClient: async () => {
return this.getSqlClient(); return await this.getSqlClient();
}, },
getProjectId: () => this.getProjectId(), getProjectId: () => this.getProjectId(),
getDbAlias: () => this.getDbAlias(), getDbAlias: () => this.getDbAlias(),
@ -57,7 +57,7 @@ export default async function (this: BaseApiBuilder<any> | any) {
return true; return true;
}); });
// @ts-ignore // @ts-ignore
const relationList = (await this.getSqlClient().tableList())?.data?.list; const relationList = (await (await this.getSqlClient()).tableList())?.data?.list;
const oldModels = await this.xcMeta.metaList( const oldModels = await this.xcMeta.metaList(
this.getProjectId(), this.getProjectId(),

7
packages/nocodb/src/lib/v1-legacy/NcProjectBuilder.ts

@ -1,5 +1,6 @@
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { promisify } from 'util';
import axios from 'axios'; import axios from 'axios';
import { Router } from 'express'; import { Router } from 'express';
@ -626,7 +627,7 @@ export default class NcProjectBuilder {
i++; i++;
} else if (db.meta?.allSchemas) { } else if (db.meta?.allSchemas) {
/* get all schemas and create APIs for all of them */ /* get all schemas and create APIs for all of them */
const sqlClient = SqlClientFactory.create({ const sqlClient = await SqlClientFactory.create({
...db, ...db,
connection: { ...db.connection, database: undefined }, connection: { ...db.connection, database: undefined },
}); });
@ -697,7 +698,7 @@ export default class NcProjectBuilder {
for (const connectionConfig of dbs) { for (const connectionConfig of dbs) {
try { try {
const sqlClient = NcConnectionMgr.getSqlClient({ const sqlClient = await NcConnectionMgr.getSqlClient({
dbAlias: connectionConfig?.meta?.dbAlias, dbAlias: connectionConfig?.meta?.dbAlias,
env: this.config.env, env: this.config.env,
config: this.config, config: this.config,
@ -718,7 +719,7 @@ export default class NcProjectBuilder {
connectionConfig.meta.dbAlias, connectionConfig.meta.dbAlias,
'migrations' 'migrations'
); );
if (!fs.existsSync(migrationFolder)) { if (!await promisify(fs.exists)(migrationFolder)) {
await migrator.init({ await migrator.init({
folder: this.app.getToolDir(), folder: this.app.getToolDir(),
env: this.appConfig.workingEnv, env: this.appConfig.workingEnv,

2
packages/nocodb/src/lib/v1-legacy/gql/GqlApiBuilder.ts

@ -249,7 +249,7 @@ export class GqlApiBuilder extends BaseApiBuilder<Noco> implements XcMetaMgr {
const t = process.hrtime(); const t = process.hrtime();
this.initDbDriver(); await this.initDbDriver();
// todo: change condition // todo: change condition
if (this.connectionConfig.meta.reset) { if (this.connectionConfig.meta.reset) {

2
packages/nocodb/src/lib/v1-legacy/nc.try.ts

@ -19,7 +19,7 @@ export default async function (dbUrl): Promise<void> {
server.use( server.use(
await app.init({ await app.init({
async afterMetaMigrationInit(): Promise<void> { async afterMetaMigrationInit(): Promise<void> {
const config = NcConfigFactory.makeProjectConfigFromUrl(dbUrl); const config = await NcConfigFactory.makeProjectConfigFromUrl(dbUrl);
await app.ncMeta.projectCreate( await app.ncMeta.projectCreate(
'Dvdrental (Sample SQLite Database)', 'Dvdrental (Sample SQLite Database)',
config, config,

13
packages/nocodb/src/lib/v1-legacy/plugins/adapters/storage/Local.ts

@ -1,5 +1,6 @@
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { promisify } from 'util';
import mkdirp from 'mkdirp'; import mkdirp from 'mkdirp';
@ -14,10 +15,10 @@ export default class Local implements IStorageAdapterV2 {
public async fileCreate(key: string, file: XcFile): Promise<any> { public async fileCreate(key: string, file: XcFile): Promise<any> {
const destPath = path.join(NcConfigFactory.getToolDir(), ...key.split('/')); const destPath = path.join(NcConfigFactory.getToolDir(), ...key.split('/'));
try { try {
mkdirp.sync(path.dirname(destPath)); await mkdirp(path.dirname(destPath));
const data = await fs.readFileSync(file.path); const data = await promisify(fs.readFile)(file.path)
await fs.writeFileSync(destPath, data); await promisify(fs.writeFile)(destPath, data);
fs.unlinkSync(file.path); await promisify(fs.unlink)(file.path);
// await fs.promises.rename(file.path, destPath); // await fs.promises.rename(file.path, destPath);
} catch (e) { } catch (e) {
throw e; throw e;
@ -41,8 +42,8 @@ export default class Local implements IStorageAdapterV2 {
origin: 'https://www.airtable.com/', origin: 'https://www.airtable.com/',
}, },
}) })
.then((response) => { .then(async (response) => {
mkdirp.sync(path.dirname(destPath)); await mkdirp(path.dirname(destPath));
const file = fs.createWriteStream(destPath); const file = fs.createWriteStream(destPath);
// close() is async, call cb after close completes // close() is async, call cb after close completes
file.on('finish', () => { file.on('finish', () => {

36
packages/nocodb/src/lib/v1-legacy/rest/RestApiBuilder.ts

@ -1,5 +1,6 @@
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { promisify } from 'util';
import autoBind from 'auto-bind'; import autoBind from 'auto-bind';
import debug from 'debug'; import debug from 'debug';
@ -86,7 +87,7 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
this.log('loadRoutes'); this.log('loadRoutes');
const t = process.hrtime(); const t = process.hrtime();
this.initDbDriver(); await this.initDbDriver();
// todo: change condition // todo: change condition
if (this.connectionConfig.meta.reset) { if (this.connectionConfig.meta.reset) {
@ -371,7 +372,7 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
}); });
if (tables?.length) { if (tables?.length) {
this.swaggerUpdate({ await this.swaggerUpdate({
addApis: swaggerDoc, addApis: swaggerDoc,
}); });
} else { } else {
@ -995,7 +996,7 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
} }
if (args.tableNames && args.tableNames.length) { if (args.tableNames && args.tableNames.length) {
this.swaggerUpdate({ await this.swaggerUpdate({
addApis: swaggerDoc, addApis: swaggerDoc,
}); });
} else { } else {
@ -1099,7 +1100,7 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
await this.xcTablesRowDelete(tn, extras); await this.xcTablesRowDelete(tn, extras);
delete this.routers[tn]; delete this.routers[tn];
this.swaggerUpdate({ await this.swaggerUpdate({
deleteTags: [tn], deleteTags: [tn],
}); });
} catch (e) { } catch (e) {
@ -1122,7 +1123,7 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
delete this.routers[viewName]; delete this.routers[viewName];
this.swaggerUpdate({ await this.swaggerUpdate({
deleteTags: [viewName], deleteTags: [viewName],
}); });
} catch (e) { } catch (e) {
@ -2367,7 +2368,7 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
this.log(`onFunctionCreate : Update function and procedure routes`); this.log(`onFunctionCreate : Update function and procedure routes`);
this.procedureCtrl.functionsSet(functions); this.procedureCtrl.functionsSet(functions);
this.procedureCtrl.mapRoutes(this.routers.___procedure, this.customRoutes); this.procedureCtrl.mapRoutes(this.routers.___procedure, this.customRoutes);
this.swaggerUpdate({ await this.swaggerUpdate({
addApis: { paths: this.procedureCtrl.getSwaggerObj().paths }, addApis: { paths: this.procedureCtrl.getSwaggerObj().paths },
}); });
} }
@ -2387,7 +2388,7 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
this.routers.___procedure.stack.length this.routers.___procedure.stack.length
); );
this.procedureCtrl.mapRoutes(this.routers.___procedure, this.customRoutes); this.procedureCtrl.mapRoutes(this.routers.___procedure, this.customRoutes);
this.swaggerUpdate({ await this.swaggerUpdate({
addApis: this.procedureCtrl.getSwaggerObj(), addApis: this.procedureCtrl.getSwaggerObj(),
deleteTags: ['Procedures', 'Functions'], deleteTags: ['Procedures', 'Functions'],
}); });
@ -2422,7 +2423,7 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
this.log(`onProcedureCreate : Update function and procedure routes`); this.log(`onProcedureCreate : Update function and procedure routes`);
this.procedureCtrl.proceduresSet(procedures); this.procedureCtrl.proceduresSet(procedures);
this.procedureCtrl.mapRoutes(this.routers.___procedure, this.customRoutes); this.procedureCtrl.mapRoutes(this.routers.___procedure, this.customRoutes);
this.swaggerUpdate({ await this.swaggerUpdate({
addApis: { paths: this.procedureCtrl.getSwaggerObj().paths }, addApis: { paths: this.procedureCtrl.getSwaggerObj().paths },
}); });
} }
@ -2442,7 +2443,7 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
this.routers.___procedure.stack.length this.routers.___procedure.stack.length
); );
this.procedureCtrl.mapRoutes(this.routers.___procedure, this.customRoutes); this.procedureCtrl.mapRoutes(this.routers.___procedure, this.customRoutes);
this.swaggerUpdate({ await this.swaggerUpdate({
addApis: this.procedureCtrl.getSwaggerObj(), addApis: this.procedureCtrl.getSwaggerObj(),
deleteTags: ['Procedures', 'Functions'], deleteTags: ['Procedures', 'Functions'],
}); });
@ -2602,8 +2603,8 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
this.getDbAlias(), this.getDbAlias(),
'swagger' 'swagger'
); );
mkdirp.sync(swaggerFilePath); await mkdirp(swaggerFilePath);
fs.writeFileSync( await promisify(fs.writeFile)(
path.join(swaggerFilePath, 'swagger.json'), path.join(swaggerFilePath, 'swagger.json'),
JSON.stringify(swaggerDoc) JSON.stringify(swaggerDoc)
); );
@ -2648,8 +2649,7 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
scheme, scheme,
scheme === 'http' ? 'https' : 'http', scheme === 'http' ? 'https' : 'http',
]; ];
glob await promisify(glob)(
.sync(
path.join( path.join(
this.app.getToolDir(), this.app.getToolDir(),
'nc', 'nc',
@ -2659,8 +2659,8 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
'swagger.json' 'swagger.json'
) )
) )
.forEach((jsonFile) => { .forEach(async (jsonFile) => {
const swaggerJson = JSON.parse(fs.readFileSync(jsonFile, 'utf8')); const swaggerJson = JSON.parse(await promisify(fs.readFile)(jsonFile, 'utf8'));
swaggerBaseDocument.tags.push(...swaggerJson.tags); swaggerBaseDocument.tags.push(...swaggerJson.tags);
Object.assign(swaggerBaseDocument.paths, swaggerJson.paths); Object.assign(swaggerBaseDocument.paths, swaggerJson.paths);
Object.assign( Object.assign(
@ -2709,7 +2709,7 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
} }
// @ts-ignore // @ts-ignore
private swaggerUpdate(args: { private async swaggerUpdate(args: {
deleteApis?: any; deleteApis?: any;
addApis?: any; addApis?: any;
deleteTags?: string[]; deleteTags?: string[];
@ -2729,7 +2729,7 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
'swagger' 'swagger'
); );
const swaggerJson = JSON.parse( const swaggerJson = JSON.parse(
fs.readFileSync(path.join(swaggerFilePath, 'swagger.json'), 'utf8') await promisify(fs.readFile)(path.join(swaggerFilePath, 'swagger.json'), 'utf8')
); );
/* remove tags, paths and keys */ /* remove tags, paths and keys */
@ -2795,7 +2795,7 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
} }
} }
fs.writeFileSync( await promisify(fs.writeFile)(
path.join(swaggerFilePath, 'swagger.json'), path.join(swaggerFilePath, 'swagger.json'),
JSON.stringify(swaggerJson) JSON.stringify(swaggerJson)
); );

6
packages/nocodb/src/run/docker.ts

@ -18,8 +18,8 @@ server.set('view engine', 'ejs');
process.env[`DEBUG`] = 'xc*'; process.env[`DEBUG`] = 'xc*';
(async () => { (async () => {
const httpServer = server.listen(process.env.PORT || 8080, () => { const httpServer = server.listen(process.env.PORT || 8080, async () => {
console.log(`App started successfully.\nVisit -> ${Noco.dashboardUrl}`); server.use(await Noco.init({}, httpServer, server));
}); });
server.use(await Noco.init({}, httpServer, server));
})().catch((e) => console.log(e)); })().catch((e) => console.log(e));

5
packages/nocodb/src/run/dockerRunMysql.ts

@ -28,8 +28,7 @@ process.env[`NC_DB`] = `mysql2://localhost:3306?u=root&p=password&d=${metaDb}`;
// process.env[`DEBUG`] = 'xc*'; // process.env[`DEBUG`] = 'xc*';
(async () => { (async () => {
const httpServer = server.listen(process.env.PORT || 8080, () => { const httpServer = server.listen(process.env.PORT || 8080, async () => {
console.log(`App started successfully.\nVisit -> ${Noco.dashboardUrl}`); server.use(await Noco.init({}, httpServer, server));
}); });
server.use(await Noco.init({}, httpServer, server));
})().catch((e) => console.log(e)); })().catch((e) => console.log(e));

5
packages/nocodb/src/run/dockerRunPG.ts

@ -28,8 +28,7 @@ process.env[`NC_DB`] = `pg://localhost:5432?u=postgres&p=password&d=${metaDb}`;
// process.env[`DEBUG`] = 'xc*'; // process.env[`DEBUG`] = 'xc*';
(async () => { (async () => {
const httpServer = server.listen(process.env.PORT || 8080, () => { const httpServer = server.listen(process.env.PORT || 8080, async () => {
console.log(`App started successfully.\nVisit -> ${Noco.dashboardUrl}`); server.use(await Noco.init({}, httpServer, server));
}); });
server.use(await Noco.init({}, httpServer, server));
})().catch((e) => console.log(e)); })().catch((e) => console.log(e));

5
packages/nocodb/src/run/dockerRunPG_CyQuick.ts

@ -21,8 +21,7 @@ process.env[
//process.env[`DEBUG`] = 'xc*'; //process.env[`DEBUG`] = 'xc*';
(async () => { (async () => {
const httpServer = server.listen(process.env.PORT || 8080, () => { const httpServer = server.listen(process.env.PORT || 8080, async () => {
console.log(`App started successfully.\nVisit -> ${Noco.dashboardUrl}`); server.use(await Noco.init({}, httpServer, server));
}); });
server.use(await Noco.init({}, httpServer, server));
})().catch((e) => console.log(e)); })().catch((e) => console.log(e));

30
packages/nocodb/src/run/testDocker.ts

@ -21,22 +21,18 @@ server.set('view engine', 'ejs');
process.env[`DEBUG`] = 'xc*'; process.env[`DEBUG`] = 'xc*';
(async () => { (async () => {
const httpServer = server.listen(process.env.PORT || 8080, () => { const httpServer = server.listen(process.env.PORT || 8080, async () => {
console.log(`App started successfully.\nVisit -> ${Noco.dashboardUrl}`); server.use(await Noco.init({}, httpServer, server));
});
server.use(await Noco.init({}, httpServer, server));
// Wait for 0.5 seconds for the server to start
await new Promise((resolve) => setTimeout(resolve, 500));
if (!(await User.getByEmail('user@nocodb.com'))) { if (!(await User.getByEmail('user@nocodb.com'))) {
const response = await axios.post( const response = await axios.post(
`http://localhost:${process.env.PORT || 8080}/api/v1/auth/user/signup`, `http://localhost:${process.env.PORT || 8080}/api/v1/auth/user/signup`,
{ {
email: 'user@nocodb.com', email: 'user@nocodb.com',
password: 'Password123.', password: 'Password123.',
} }
); );
console.log(response.data); console.log(response.data);
} }
});
})().catch((e) => console.log(e)); })().catch((e) => console.log(e));

2
packages/nocodb/src/run/try.ts

@ -20,7 +20,7 @@ process.env.NC_DB = url;
await app.init({ await app.init({
async afterMetaMigrationInit(): Promise<void> { async afterMetaMigrationInit(): Promise<void> {
if (!(await app.ncMeta.projectList())?.length) { if (!(await app.ncMeta.projectList())?.length) {
const config = NcConfigFactory.makeProjectConfigFromUrl(url); const config = await NcConfigFactory.makeProjectConfigFromUrl(url);
const project = await app.ncMeta.projectCreate( const project = await app.ncMeta.projectCreate(
config.title, config.title,
config, config,

Loading…
Cancel
Save