mirror of https://github.com/nocodb/nocodb
Pranav C
2 years ago
17 changed files with 688 additions and 146 deletions
@ -0,0 +1,59 @@ |
|||||||
|
// // Project CRUD
|
||||||
|
import { Request, Response } from 'express'; |
||||||
|
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; |
||||||
|
import catchError from '../meta/helpers/catchError'; |
||||||
|
import { utilService } from '../services'; |
||||||
|
|
||||||
|
export async function testConnection(req: Request, res: Response) { |
||||||
|
res.json(await utilService.testConnection({ body: req.body })); |
||||||
|
} |
||||||
|
|
||||||
|
export async function appInfo(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await utilService.appInfo({ |
||||||
|
req: { |
||||||
|
ncSiteUrl: (req as any).ncSiteUrl, |
||||||
|
}, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function versionInfo(_req: Request, res: Response) { |
||||||
|
res.json(await utilService.versionInfo()); |
||||||
|
} |
||||||
|
|
||||||
|
export async function appHealth(_: Request, res: Response) { |
||||||
|
res.json(await utilService.appHealth()); |
||||||
|
} |
||||||
|
|
||||||
|
export async function axiosRequestMake(req: Request, res: Response) { |
||||||
|
res.json(await utilService.axiosRequestMake({ body: req.body })); |
||||||
|
} |
||||||
|
|
||||||
|
export async function aggregatedMetaInfo(_req: Request, res: Response) { |
||||||
|
res.json(await utilService.aggregatedMetaInfo()); |
||||||
|
} |
||||||
|
|
||||||
|
export async function urlToDbConfig(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await utilService.urlToDbConfig({ |
||||||
|
body: req.body, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export default (router) => { |
||||||
|
router.post( |
||||||
|
'/api/v1/db/meta/connection/test', |
||||||
|
ncMetaAclMw(testConnection, 'testConnection') |
||||||
|
); |
||||||
|
router.get('/api/v1/db/meta/nocodb/info', catchError(appInfo)); |
||||||
|
router.post('/api/v1/db/meta/axiosRequestMake', catchError(axiosRequestMake)); |
||||||
|
router.get('/api/v1/version', catchError(versionInfo)); |
||||||
|
router.get('/api/v1/health', catchError(appHealth)); |
||||||
|
router.post('/api/v1/url_to_config', catchError(urlToDbConfig)); |
||||||
|
router.get( |
||||||
|
'/api/v1/aggregated-meta-info', |
||||||
|
ncMetaAclMw(aggregatedMetaInfo, 'aggregatedMetaInfo') |
||||||
|
); |
||||||
|
}; |
@ -0,0 +1,13 @@ |
|||||||
|
import { FormViewColumn } from '../models'; |
||||||
|
import { Tele } from 'nc-help'; |
||||||
|
export async function columnUpdate(param: { |
||||||
|
formViewColumnId: string; |
||||||
|
// todo: replace with FormColumnReq
|
||||||
|
formViewColumn: FormViewColumn; |
||||||
|
}) { |
||||||
|
Tele.emit('evt', { evt_type: 'formViewColumn:updated' }); |
||||||
|
return await FormViewColumn.update( |
||||||
|
param.formViewColumnId, |
||||||
|
param.formViewColumn |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
import { Tele } from 'nc-help'; |
||||||
|
import { FormReqType, ViewTypes } from 'nocodb-sdk'; |
||||||
|
import { FormView, View } from '../models'; |
||||||
|
|
||||||
|
export async function formViewGet(param: { formViewId: string }) { |
||||||
|
const formViewData = await FormView.getWithInfo(param.formViewId); |
||||||
|
return formViewData; |
||||||
|
} |
||||||
|
|
||||||
|
export async function formViewCreate(param: { |
||||||
|
tableId: string; |
||||||
|
body: FormReqType; |
||||||
|
}) { |
||||||
|
Tele.emit('evt', { evt_type: 'vtable:created', show_as: 'form' }); |
||||||
|
const view = await View.insert({ |
||||||
|
...param.body, |
||||||
|
// todo: sanitize
|
||||||
|
fk_model_id: param.tableId, |
||||||
|
type: ViewTypes.FORM, |
||||||
|
}); |
||||||
|
return view; |
||||||
|
} |
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
export async function formViewUpdate(param: { |
||||||
|
formViewId: string; |
||||||
|
body: FormReqType; |
||||||
|
}) { |
||||||
|
Tele.emit('evt', { evt_type: 'view:updated', type: 'grid' }); |
||||||
|
await FormView.update(param.formViewId, param.body); |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
import { Request, Response, Router } from 'express'; |
||||||
|
import { GalleryReqType, GalleryType, ViewTypes } from 'nocodb-sdk'; |
||||||
|
import View from '../models/View'; |
||||||
|
import GalleryView from '../models/GalleryView'; |
||||||
|
import { Tele } from 'nc-help'; |
||||||
|
|
||||||
|
export async function galleryViewGet(param: { galleryViewId: string }) { |
||||||
|
return await GalleryView.get(param.galleryViewId); |
||||||
|
} |
||||||
|
|
||||||
|
export async function galleryViewCreate(param: { |
||||||
|
tableId: string; |
||||||
|
gallery: GalleryReqType; |
||||||
|
}) { |
||||||
|
Tele.emit('evt', { evt_type: 'vtable:created', show_as: 'gallery' }); |
||||||
|
const view = await View.insert({ |
||||||
|
...param.gallery, |
||||||
|
// todo: sanitize
|
||||||
|
fk_model_id: param.tableId, |
||||||
|
type: ViewTypes.GALLERY, |
||||||
|
}); |
||||||
|
return view; |
||||||
|
} |
||||||
|
|
||||||
|
export async function galleryViewUpdate(param: { |
||||||
|
galleryViewId: string; |
||||||
|
gallery: GalleryReqType; |
||||||
|
}) { |
||||||
|
Tele.emit('evt', { evt_type: 'view:updated', type: 'gallery' }); |
||||||
|
await GalleryView.update(param.galleryViewId, param.gallery); |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
import { Tele } from 'nc-help'; |
||||||
|
import { GridReqType, ViewTypes } from 'nocodb-sdk'; |
||||||
|
import { View } from '../models'; |
||||||
|
import { GridView } from '../models'; |
||||||
|
|
||||||
|
export async function gridViewCreate(param: { |
||||||
|
tableId: string; |
||||||
|
grid: GridReqType; |
||||||
|
}) { |
||||||
|
const view = await View.insert({ |
||||||
|
...param.grid, |
||||||
|
// todo: sanitize
|
||||||
|
fk_model_id: param.tableId, |
||||||
|
type: ViewTypes.GRID, |
||||||
|
}); |
||||||
|
Tele.emit('evt', { evt_type: 'vtable:created', show_as: 'grid' }); |
||||||
|
return view; |
||||||
|
} |
||||||
|
|
||||||
|
export async function gridViewUpdate(param: { |
||||||
|
viewId: string; |
||||||
|
grid: GridReqType; |
||||||
|
}) { |
||||||
|
Tele.emit('evt', { evt_type: 'view:updated', type: 'grid' }); |
||||||
|
return await GridView.update(param.viewId, param.grid); |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
import { KanbanReqType, ViewTypes } from 'nocodb-sdk'; |
||||||
|
import { KanbanView, View } from '../models'; |
||||||
|
import { Tele } from 'nc-help'; |
||||||
|
|
||||||
|
export async function kanbanViewGet(param: { kanbanViewId: string }) { |
||||||
|
return await KanbanView.get(param.kanbanViewId); |
||||||
|
} |
||||||
|
|
||||||
|
export async function kanbanViewCreate(param: { |
||||||
|
tableId: string; |
||||||
|
kanban: KanbanReqType; |
||||||
|
}) { |
||||||
|
Tele.emit('evt', { evt_type: 'vtable:created', show_as: 'kanban' }); |
||||||
|
const view = await View.insert({ |
||||||
|
...param.kanban, |
||||||
|
// todo: sanitize
|
||||||
|
fk_model_id: param.tableId, |
||||||
|
type: ViewTypes.KANBAN, |
||||||
|
}); |
||||||
|
return view; |
||||||
|
} |
||||||
|
|
||||||
|
export async function kanbanViewUpdate(param: { |
||||||
|
kanbanViewId: string; |
||||||
|
kanban: KanbanReqType; |
||||||
|
}) { |
||||||
|
Tele.emit('evt', { evt_type: 'view:updated', type: 'kanban' }); |
||||||
|
return await KanbanView.update(param.kanbanViewId, param.kanban); |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
import { Tele } from 'nc-help'; |
||||||
|
import { Plugin } from '../models' |
||||||
|
import { PluginTestReqType, PluginType } from 'nocodb-sdk' |
||||||
|
import NcPluginMgrv2 from '../meta/helpers/NcPluginMgrv2'; |
||||||
|
|
||||||
|
export async function pluginList() { |
||||||
|
return await Plugin.list() |
||||||
|
} |
||||||
|
|
||||||
|
export async function pluginTest(param:{body: PluginTestReqType}) { |
||||||
|
Tele.emit('evt', { evt_type: 'plugin:tested' }); |
||||||
|
return await NcPluginMgrv2.test(param.body) |
||||||
|
} |
||||||
|
|
||||||
|
export async function pluginRead(param: { pluginId: string }) { |
||||||
|
return await Plugin.get(param.pluginId) |
||||||
|
} |
||||||
|
export async function pluginUpdate( |
||||||
|
param: { pluginId: string; plugin: PluginType } |
||||||
|
) { |
||||||
|
const plugin = await Plugin.update(param.pluginId, param.plugin); |
||||||
|
Tele.emit('evt', { |
||||||
|
evt_type: plugin.active ? 'plugin:installed' : 'plugin:uninstalled', |
||||||
|
title: plugin.title, |
||||||
|
}); |
||||||
|
return plugin |
||||||
|
} |
||||||
|
export async function isPluginActive(param: { pluginTitle: string }) { |
||||||
|
return await Plugin.isPluginActive(param.pluginTitle) |
||||||
|
} |
@ -0,0 +1,381 @@ |
|||||||
|
import { compareVersions, validate } from 'compare-versions'; |
||||||
|
|
||||||
|
import { ViewTypes } from 'nocodb-sdk'; |
||||||
|
import { Project } from '../models'; |
||||||
|
import { NcError } from '../meta/helpers/catchError'; |
||||||
|
import Noco from '../Noco'; |
||||||
|
import NcConnectionMgrv2 from '../utils/common/NcConnectionMgrv2'; |
||||||
|
import { MetaTable } from '../utils/globals'; |
||||||
|
import { packageVersion } from '../utils/packageVersion'; |
||||||
|
import SqlMgrv2 from '../db/sql-mgr/v2/SqlMgrv2'; |
||||||
|
import NcConfigFactory, { |
||||||
|
defaultConnectionConfig, |
||||||
|
} from '../utils/NcConfigFactory'; |
||||||
|
import { User } from '../models'; |
||||||
|
import axios from 'axios'; |
||||||
|
import { NC_ATTACHMENT_FIELD_SIZE } from '../constants'; |
||||||
|
|
||||||
|
const versionCache = { |
||||||
|
releaseVersion: null, |
||||||
|
lastFetched: null, |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export async function testConnection(param:{body: any}) { |
||||||
|
return await SqlMgrv2.testConnection(param.body); |
||||||
|
} |
||||||
|
|
||||||
|
export async function appInfo(param: { req: { ncSiteUrl: string } }) { |
||||||
|
const projectHasAdmin = !(await User.isFirst()); |
||||||
|
const result = { |
||||||
|
authType: 'jwt', |
||||||
|
projectHasAdmin, |
||||||
|
firstUser: !projectHasAdmin, |
||||||
|
type: 'rest', |
||||||
|
env: process.env.NODE_ENV, |
||||||
|
googleAuthEnabled: !!( |
||||||
|
process.env.NC_GOOGLE_CLIENT_ID && process.env.NC_GOOGLE_CLIENT_SECRET |
||||||
|
), |
||||||
|
githubAuthEnabled: !!( |
||||||
|
process.env.NC_GITHUB_CLIENT_ID && process.env.NC_GITHUB_CLIENT_SECRET |
||||||
|
), |
||||||
|
oneClick: !!process.env.NC_ONE_CLICK, |
||||||
|
connectToExternalDB: !process.env.NC_CONNECT_TO_EXTERNAL_DB_DISABLED, |
||||||
|
version: packageVersion, |
||||||
|
defaultLimit: Math.max( |
||||||
|
Math.min( |
||||||
|
+process.env.DB_QUERY_LIMIT_DEFAULT || 25, |
||||||
|
+process.env.DB_QUERY_LIMIT_MAX || 100 |
||||||
|
), |
||||||
|
+process.env.DB_QUERY_LIMIT_MIN || 1 |
||||||
|
), |
||||||
|
timezone: defaultConnectionConfig.timezone, |
||||||
|
ncMin: !!process.env.NC_MIN, |
||||||
|
teleEnabled: process.env.NC_DISABLE_TELE === 'true' ? false : true, |
||||||
|
auditEnabled: process.env.NC_DISABLE_AUDIT === 'true' ? false : true, |
||||||
|
ncSiteUrl: (param.req as any).ncSiteUrl, |
||||||
|
ee: Noco.isEE(), |
||||||
|
ncAttachmentFieldSize: NC_ATTACHMENT_FIELD_SIZE, |
||||||
|
ncMaxAttachmentsAllowed: +(process.env.NC_MAX_ATTACHMENTS_ALLOWED || 10), |
||||||
|
}; |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
export async function versionInfo() { |
||||||
|
if ( |
||||||
|
!versionCache.lastFetched || |
||||||
|
(versionCache.lastFetched && |
||||||
|
versionCache.lastFetched < Date.now() - 1000 * 60 * 60) |
||||||
|
) { |
||||||
|
const nonBetaTags = await axios |
||||||
|
.get('https://api.github.com/repos/nocodb/nocodb/tags', { |
||||||
|
timeout: 5000, |
||||||
|
}) |
||||||
|
.then((response) => { |
||||||
|
return response.data |
||||||
|
.map((x) => x.name) |
||||||
|
.filter( |
||||||
|
(v) => validate(v) && !v.includes('finn') && !v.includes('beta') |
||||||
|
) |
||||||
|
.sort((x, y) => compareVersions(y, x)); |
||||||
|
}) |
||||||
|
.catch(() => null); |
||||||
|
if (nonBetaTags && nonBetaTags.length > 0) { |
||||||
|
versionCache.releaseVersion = nonBetaTags[0]; |
||||||
|
} |
||||||
|
versionCache.lastFetched = Date.now(); |
||||||
|
} |
||||||
|
|
||||||
|
const response = { |
||||||
|
currentVersion: packageVersion, |
||||||
|
releaseVersion: versionCache.releaseVersion, |
||||||
|
}; |
||||||
|
|
||||||
|
return response; |
||||||
|
} |
||||||
|
|
||||||
|
export async function appHealth() { |
||||||
|
return { |
||||||
|
message: 'OK', |
||||||
|
timestamp: Date.now(), |
||||||
|
uptime: process.uptime(), |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
async function _axiosRequestMake(param: { |
||||||
|
body: { |
||||||
|
apiMeta: any; |
||||||
|
}; |
||||||
|
}) { |
||||||
|
const { apiMeta } = param.body; |
||||||
|
|
||||||
|
if (apiMeta?.body) { |
||||||
|
try { |
||||||
|
apiMeta.body = JSON.parse(apiMeta.body); |
||||||
|
} catch (e) { |
||||||
|
console.log(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (apiMeta?.auth) { |
||||||
|
try { |
||||||
|
apiMeta.auth = JSON.parse(apiMeta.auth); |
||||||
|
} catch (e) { |
||||||
|
console.log(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
apiMeta.response = {}; |
||||||
|
const _req = { |
||||||
|
params: apiMeta.parameters |
||||||
|
? apiMeta.parameters.reduce((paramsObj, param) => { |
||||||
|
if (param.name && param.enabled) { |
||||||
|
paramsObj[param.name] = param.value; |
||||||
|
} |
||||||
|
return paramsObj; |
||||||
|
}, {}) |
||||||
|
: {}, |
||||||
|
url: apiMeta.url, |
||||||
|
method: apiMeta.method || 'GET', |
||||||
|
data: apiMeta.body || {}, |
||||||
|
headers: apiMeta.headers |
||||||
|
? apiMeta.headers.reduce((headersObj, header) => { |
||||||
|
if (header.name && header.enabled) { |
||||||
|
headersObj[header.name] = header.value; |
||||||
|
} |
||||||
|
return headersObj; |
||||||
|
}, {}) |
||||||
|
: {}, |
||||||
|
responseType: apiMeta.responseType || 'json', |
||||||
|
withCredentials: true, |
||||||
|
}; |
||||||
|
const data = await require('axios')(_req); |
||||||
|
return data?.data; |
||||||
|
} |
||||||
|
|
||||||
|
export async function axiosRequestMake(param: { |
||||||
|
body: { |
||||||
|
apiMeta: any; |
||||||
|
}; |
||||||
|
}) { |
||||||
|
const { |
||||||
|
apiMeta: { url }, |
||||||
|
} = param.body; |
||||||
|
const isExcelImport = /.*\.(xls|xlsx|xlsm|ods|ots)/; |
||||||
|
const isCSVImport = /.*\.(csv)/; |
||||||
|
const ipBlockList = |
||||||
|
/(10)(\.([2]([0-5][0-5]|[01234][6-9])|[1][0-9][0-9]|[1-9][0-9]|[0-9])){3}|(172)\.(1[6-9]|2[0-9]|3[0-1])(\.(2[0-4][0-9]|25[0-5]|[1][0-9][0-9]|[1-9][0-9]|[0-9])){2}|(192)\.(168)(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){2}|(0.0.0.0)|localhost?/g; |
||||||
|
if ( |
||||||
|
ipBlockList.test(url) || |
||||||
|
(!isCSVImport.test(url) && !isExcelImport.test(url)) |
||||||
|
) { |
||||||
|
return {}; |
||||||
|
} |
||||||
|
if (isCSVImport || isExcelImport) { |
||||||
|
param.body.apiMeta.responseType = 'arraybuffer'; |
||||||
|
} |
||||||
|
return await _axiosRequestMake({ |
||||||
|
body: param.body, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
export async function urlToDbConfig(param: { |
||||||
|
body: { |
||||||
|
url: string; |
||||||
|
}; |
||||||
|
}) { |
||||||
|
const { url } = param.body; |
||||||
|
try { |
||||||
|
const connectionConfig = NcConfigFactory.extractXcUrlFromJdbc(url, true); |
||||||
|
return connectionConfig; |
||||||
|
} catch (error) { |
||||||
|
return NcError.internalServerError(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
interface ViewCount { |
||||||
|
formCount: number | null; |
||||||
|
gridCount: number | null; |
||||||
|
galleryCount: number | null; |
||||||
|
kanbanCount: number | null; |
||||||
|
total: number | null; |
||||||
|
sharedFormCount: number | null; |
||||||
|
sharedGridCount: number | null; |
||||||
|
sharedGalleryCount: number | null; |
||||||
|
sharedKanbanCount: number | null; |
||||||
|
sharedTotal: number | null; |
||||||
|
sharedLockedCount: number | null; |
||||||
|
} |
||||||
|
|
||||||
|
interface AllMeta { |
||||||
|
projectCount: number; |
||||||
|
projects: ( |
||||||
|
| { |
||||||
|
external?: boolean | null; |
||||||
|
tableCount: { |
||||||
|
table: number; |
||||||
|
view: number; |
||||||
|
} | null; |
||||||
|
viewCount: ViewCount; |
||||||
|
webhookCount: number | null; |
||||||
|
filterCount: number | null; |
||||||
|
sortCount: number | null; |
||||||
|
rowCount: ({ totalRecords: number } | null)[] | null; |
||||||
|
userCount: number | null; |
||||||
|
} |
||||||
|
| { error: string } |
||||||
|
)[]; |
||||||
|
userCount: number; |
||||||
|
sharedBaseCount: number; |
||||||
|
} |
||||||
|
|
||||||
|
export async function aggregatedMetaInfo() { |
||||||
|
const [projects, userCount] = await Promise.all([ |
||||||
|
Project.list({}), |
||||||
|
Noco.ncMeta.metaCount(null, null, MetaTable.USERS), |
||||||
|
]); |
||||||
|
|
||||||
|
const result: AllMeta = { |
||||||
|
projectCount: projects.length, |
||||||
|
projects: [], |
||||||
|
userCount, |
||||||
|
sharedBaseCount: 0, |
||||||
|
}; |
||||||
|
|
||||||
|
result.projects.push( |
||||||
|
...extractResultOrNull( |
||||||
|
await Promise.allSettled( |
||||||
|
projects.map(async (project) => { |
||||||
|
if (project.uuid) result.sharedBaseCount++; |
||||||
|
const [ |
||||||
|
tableCount, |
||||||
|
dbViewCount, |
||||||
|
viewCount, |
||||||
|
webhookCount, |
||||||
|
filterCount, |
||||||
|
sortCount, |
||||||
|
rowCount, |
||||||
|
userCount, |
||||||
|
] = extractResultOrNull( |
||||||
|
await Promise.allSettled([ |
||||||
|
// db tables count
|
||||||
|
Noco.ncMeta.metaCount(project.id, null, MetaTable.MODELS, { |
||||||
|
condition: { |
||||||
|
type: 'table', |
||||||
|
}, |
||||||
|
}), |
||||||
|
// db views count
|
||||||
|
Noco.ncMeta.metaCount(project.id, null, MetaTable.MODELS, { |
||||||
|
condition: { |
||||||
|
type: 'view', |
||||||
|
}, |
||||||
|
}), |
||||||
|
// views count
|
||||||
|
(async () => { |
||||||
|
const views = await Noco.ncMeta.metaList2( |
||||||
|
project.id, |
||||||
|
null, |
||||||
|
MetaTable.VIEWS |
||||||
|
); |
||||||
|
// grid, form, gallery, kanban and shared count
|
||||||
|
return views.reduce<ViewCount>( |
||||||
|
(out, view) => { |
||||||
|
out.total++; |
||||||
|
|
||||||
|
switch (view.type) { |
||||||
|
case ViewTypes.GRID: |
||||||
|
out.gridCount++; |
||||||
|
if (view.uuid) out.sharedGridCount++; |
||||||
|
break; |
||||||
|
case ViewTypes.FORM: |
||||||
|
out.formCount++; |
||||||
|
if (view.uuid) out.sharedFormCount++; |
||||||
|
break; |
||||||
|
case ViewTypes.GALLERY: |
||||||
|
out.galleryCount++; |
||||||
|
if (view.uuid) out.sharedGalleryCount++; |
||||||
|
break; |
||||||
|
case ViewTypes.KANBAN: |
||||||
|
out.kanbanCount++; |
||||||
|
if (view.uuid) out.sharedKanbanCount++; |
||||||
|
} |
||||||
|
|
||||||
|
if (view.uuid) { |
||||||
|
if (view.password) out.sharedLockedCount++; |
||||||
|
out.sharedTotal++; |
||||||
|
} |
||||||
|
|
||||||
|
return out; |
||||||
|
}, |
||||||
|
{ |
||||||
|
formCount: 0, |
||||||
|
gridCount: 0, |
||||||
|
galleryCount: 0, |
||||||
|
kanbanCount: 0, |
||||||
|
total: 0, |
||||||
|
sharedFormCount: 0, |
||||||
|
sharedGridCount: 0, |
||||||
|
sharedGalleryCount: 0, |
||||||
|
sharedKanbanCount: 0, |
||||||
|
sharedTotal: 0, |
||||||
|
sharedLockedCount: 0, |
||||||
|
} |
||||||
|
); |
||||||
|
})(), |
||||||
|
// webhooks count
|
||||||
|
Noco.ncMeta.metaCount(project.id, null, MetaTable.HOOKS), |
||||||
|
// filters count
|
||||||
|
Noco.ncMeta.metaCount(project.id, null, MetaTable.FILTER_EXP), |
||||||
|
// sorts count
|
||||||
|
Noco.ncMeta.metaCount(project.id, null, MetaTable.SORT), |
||||||
|
// row count per base
|
||||||
|
project.getBases().then(async (bases) => { |
||||||
|
return extractResultOrNull( |
||||||
|
await Promise.allSettled( |
||||||
|
bases.map(async (base) => |
||||||
|
(await NcConnectionMgrv2.getSqlClient(base)) |
||||||
|
.totalRecords?.() |
||||||
|
?.then((result) => result?.data) |
||||||
|
) |
||||||
|
) |
||||||
|
); |
||||||
|
}), |
||||||
|
// project users count
|
||||||
|
Noco.ncMeta.metaCount(null, null, MetaTable.PROJECT_USERS, { |
||||||
|
condition: { |
||||||
|
project_id: project.id, |
||||||
|
}, |
||||||
|
aggField: '*', |
||||||
|
}), |
||||||
|
]) |
||||||
|
); |
||||||
|
|
||||||
|
return { |
||||||
|
tableCount: { table: tableCount, view: dbViewCount }, |
||||||
|
external: !project.is_meta, |
||||||
|
viewCount, |
||||||
|
webhookCount, |
||||||
|
filterCount, |
||||||
|
sortCount, |
||||||
|
rowCount, |
||||||
|
userCount, |
||||||
|
}; |
||||||
|
}) |
||||||
|
) |
||||||
|
) |
||||||
|
); |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
const extractResultOrNull = (results: PromiseSettledResult<any>[]) => { |
||||||
|
return results.map((result) => { |
||||||
|
if (result.status === 'fulfilled') { |
||||||
|
return result.value; |
||||||
|
} |
||||||
|
console.log(result.reason); |
||||||
|
return null; |
||||||
|
}); |
||||||
|
}; |
Loading…
Reference in new issue