Browse Source

refcator: handler to service-controller - form, gallery, grid, kanban, plugin (WIP)

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/5239/head
Pranav C 2 years ago
parent
commit
10195c84b0
  1. 11
      packages/nocodb/src/lib/controllers/formViewColumnController.ts
  2. 29
      packages/nocodb/src/lib/controllers/galleryViewController.ts
  3. 58
      packages/nocodb/src/lib/controllers/hookController.ts
  4. 21
      packages/nocodb/src/lib/controllers/pluginController.ts
  5. 59
      packages/nocodb/src/lib/controllers/utilService.ts
  6. 10
      packages/nocodb/src/lib/models/FormView.ts
  7. 12
      packages/nocodb/src/lib/models/GalleryView.ts
  8. 13
      packages/nocodb/src/lib/services/formViewColumnService.ts
  9. 31
      packages/nocodb/src/lib/services/formViewService.ts
  10. 31
      packages/nocodb/src/lib/services/galleryViewService.ts
  11. 26
      packages/nocodb/src/lib/services/gridViewService.ts
  12. 82
      packages/nocodb/src/lib/services/hookService.ts
  13. 8
      packages/nocodb/src/lib/services/index.ts
  14. 29
      packages/nocodb/src/lib/services/kanbanViewService.ts
  15. 30
      packages/nocodb/src/lib/services/pluginService.ts
  16. 381
      packages/nocodb/src/lib/services/utilService.ts
  17. 1
      packages/nocodb/src/lib/services/viewService.ts

11
packages/nocodb/src/lib/controllers/formViewColumnController.ts

@ -1,13 +1,16 @@
import { Request, Response, Router } from 'express'; import { Request, Response, Router } from 'express';
import FormViewColumn from '../models/FormViewColumn';
import { Tele } from 'nc-help';
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; import ncMetaAclMw from '../meta/helpers/ncMetaAclMw';
import { metaApiMetrics } from '../meta/helpers/apiMetrics'; import { metaApiMetrics } from '../meta/helpers/apiMetrics';
import { getAjvValidatorMw } from '../meta/api/helpers'; import { getAjvValidatorMw } from '../meta/api/helpers';
import { formViewColumnService } from '../services';
export async function columnUpdate(req: Request, res: Response) { export async function columnUpdate(req: Request, res: Response) {
Tele.emit('evt', { evt_type: 'formViewColumn:updated' }); res.json(
res.json(await FormViewColumn.update(req.params.formViewColumnId, req.body)); await formViewColumnService.columnUpdate({
formViewColumnId: req.params.formViewColumnId,
formViewColumn: req.body,
})
);
} }
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });

29
packages/nocodb/src/lib/controllers/galleryViewController.ts

@ -1,29 +1,34 @@
import { Request, Response, Router } from 'express'; import { Request, Response, Router } from 'express';
import { GalleryType, ViewTypes } from 'nocodb-sdk'; import { GalleryType } from 'nocodb-sdk';
import View from '../models/View';
import GalleryView from '../models/GalleryView';
import { Tele } from 'nc-help';
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; import ncMetaAclMw from '../meta/helpers/ncMetaAclMw';
import { metaApiMetrics } from '../meta/helpers/apiMetrics'; import { metaApiMetrics } from '../meta/helpers/apiMetrics';
import { getAjvValidatorMw } from '../meta/api/helpers'; import { getAjvValidatorMw } from '../meta/api/helpers';
import { galleryViewService } from '../services';
export async function galleryViewGet(req: Request, res: Response<GalleryType>) { export async function galleryViewGet(req: Request, res: Response<GalleryType>) {
res.json(await GalleryView.get(req.params.galleryViewId)); res.json(
await galleryViewService.galleryViewGet({
galleryViewId: req.params.galleryViewId,
})
);
} }
export async function galleryViewCreate(req: Request<any, any>, res) { export async function galleryViewCreate(req: Request<any, any>, res) {
Tele.emit('evt', { evt_type: 'vtable:created', show_as: 'gallery' }); const view = await galleryViewService.galleryViewCreate({
const view = await View.insert({ gallery: req.body,
...req.body,
// todo: sanitize // todo: sanitize
fk_model_id: req.params.tableId, tableId: req.params.tableId,
type: ViewTypes.GALLERY,
}); });
res.json(view); res.json(view);
} }
export async function galleryViewUpdate(req, res) { export async function galleryViewUpdate(req, res) {
Tele.emit('evt', { evt_type: 'view:updated', type: 'gallery' }); res.json(
res.json(await GalleryView.update(req.params.galleryViewId, req.body)); await galleryViewService.galleryViewUpdate({
galleryViewId: req.params.galleryViewId,
gallery: req.body,
})
);
} }
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });

58
packages/nocodb/src/lib/controllers/hookController.ts

@ -1,15 +1,11 @@
import { Tele } from 'nc-help';
import catchError from '../meta/helpers/catchError'; import catchError from '../meta/helpers/catchError';
import { Request, Response, Router } from 'express'; import { Request, Response, Router } from 'express';
import Hook from '../models/Hook';
import { HookListType, HookType } from 'nocodb-sdk'; import { HookListType, HookType } from 'nocodb-sdk';
import { PagedResponseImpl } from '../meta/helpers/PagedResponse'; import { PagedResponseImpl } from '../meta/helpers/PagedResponse';
import { invokeWebhook } from '../meta/helpers/webhookHelpers';
import Model from '../models/Model';
import populateSamplePayload from '../meta/helpers/populateSamplePayload';
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; import ncMetaAclMw from '../meta/helpers/ncMetaAclMw';
import { metaApiMetrics } from '../meta/helpers/apiMetrics'; import { metaApiMetrics } from '../meta/helpers/apiMetrics';
import { getAjvValidatorMw } from '../meta/api/helpers'; import { getAjvValidatorMw } from '../meta/api/helpers';
import { hookService } from '../services';
export async function hookList( export async function hookList(
req: Request<any, any, any>, req: Request<any, any, any>,
@ -17,7 +13,9 @@ export async function hookList(
) { ) {
// todo: pagination // todo: pagination
res.json( res.json(
new PagedResponseImpl(await Hook.list({ fk_model_id: req.params.tableId })) new PagedResponseImpl(
await hookService.hookList({ tableId: req.params.tableId })
)
); );
} }
@ -25,10 +23,9 @@ export async function hookCreate(
req: Request<any, HookType>, req: Request<any, HookType>,
res: Response<HookType> res: Response<HookType>
) { ) {
Tele.emit('evt', { evt_type: 'webhooks:created' }); const hook = await hookService.hookCreate({
const hook = await Hook.insert({ hook: req.body,
...req.body, tableId: req.params.tableId,
fk_model_id: req.params.tableId,
}); });
res.json(hook); res.json(hook);
} }
@ -37,44 +34,35 @@ export async function hookDelete(
req: Request<any, HookType>, req: Request<any, HookType>,
res: Response<any> res: Response<any>
) { ) {
Tele.emit('evt', { evt_type: 'webhooks:deleted' }); res.json(await hookService.hookDelete({ hookId: req.params.hookId }));
res.json(await Hook.delete(req.params.hookId));
} }
export async function hookUpdate( export async function hookUpdate(
req: Request<any, HookType>, req: Request<any, HookType>,
res: Response<HookType> res: Response<HookType>
) { ) {
Tele.emit('evt', { evt_type: 'webhooks:updated' }); res.json(
await hookService.hookUpdate({ hookId: req.params.hookId, hook: req.body })
res.json(await Hook.update(req.params.hookId, req.body)); );
} }
export async function hookTest(req: Request<any, any>, res: Response) { export async function hookTest(req: Request<any, any>, res: Response) {
const model = await Model.getByIdOrName({ id: req.params.tableId }); await hookService.hookTest({
hookTest: req.body,
const { tableId: req.params.tableId,
hook, });
payload: { data, user },
} = req.body;
await invokeWebhook(
new Hook(hook),
model,
data,
user,
(hook as any)?.filters,
true
);
Tele.emit('evt', { evt_type: 'webhooks:tested' });
res.json({ msg: 'Success' }); res.json({ msg: 'Success' });
} }
export async function tableSampleData(req: Request, res: Response) {
const model = await Model.getByIdOrName({ id: req.params.tableId });
export async function tableSampleData(req: Request, res: Response) {
res // todo: pagination res // todo: pagination
.json(await populateSamplePayload(model, false, req.params.operation)); .json(
await hookService.tableSampleData({
tableId: req.params.tableId,
// todo: replace any with type
operation: req.params.operation as any,
})
);
} }
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });

21
packages/nocodb/src/lib/controllers/pluginController.ts

@ -1,38 +1,33 @@
import { Request, Response, Router } from 'express'; import { Request, Response, Router } from 'express';
import { Tele } from 'nc-help';
import { PagedResponseImpl } from '../meta/helpers/PagedResponse'; import { PagedResponseImpl } from '../meta/helpers/PagedResponse';
import Plugin from '../models/Plugin';
import { PluginType } from 'nocodb-sdk'; import { PluginType } from 'nocodb-sdk';
import NcPluginMgrv2 from '../meta/helpers/NcPluginMgrv2';
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; import ncMetaAclMw from '../meta/helpers/ncMetaAclMw';
import { metaApiMetrics } from '../meta/helpers/apiMetrics'; import { metaApiMetrics } from '../meta/helpers/apiMetrics';
import { getAjvValidatorMw } from '../meta/api/helpers'; import { getAjvValidatorMw } from '../meta/api/helpers';
import { pluginService } from '../services';
export async function pluginList(_req: Request, res: Response) { export async function pluginList(_req: Request, res: Response) {
res.json(new PagedResponseImpl(await Plugin.list())); res.json(new PagedResponseImpl(await pluginService.pluginList()));
} }
export async function pluginTest(req: Request<any, any>, res: Response) { export async function pluginTest(req: Request<any, any>, res: Response) {
Tele.emit('evt', { evt_type: 'plugin:tested' }); res.json(await pluginService.pluginTest({ body: req.body }));
res.json(await NcPluginMgrv2.test(req.body));
} }
export async function pluginRead(req: Request, res: Response) { export async function pluginRead(req: Request, res: Response) {
res.json(await Plugin.get(req.params.pluginId)); res.json(await pluginService.pluginRead({ pluginId: req.params.pluginId }));
} }
export async function pluginUpdate( export async function pluginUpdate(
req: Request<any, any, PluginType>, req: Request<any, any, PluginType>,
res: Response res: Response
) { ) {
const plugin = await Plugin.update(req.params.pluginId, req.body); const plugin = await pluginService.pluginUpdate({ pluginId: req.params.pluginId, plugin:req.body });
Tele.emit('evt', {
evt_type: plugin.active ? 'plugin:installed' : 'plugin:uninstalled',
title: plugin.title,
});
res.json(plugin); res.json(plugin);
} }
export async function isPluginActive(req: Request, res: Response) { export async function isPluginActive(req: Request, res: Response) {
res.json(await Plugin.isPluginActive(req.params.pluginTitle)); res.json(await pluginService.isPluginActive({ pluginTitle: req.params.pluginTitle }));
} }
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });

59
packages/nocodb/src/lib/controllers/utilService.ts

@ -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')
);
};

10
packages/nocodb/src/lib/models/FormView.ts

@ -1,6 +1,6 @@
import Noco from '../Noco'; import Noco from '../Noco';
import { CacheGetType, CacheScope, MetaTable } from '../utils/globals'; import { CacheGetType, CacheScope, MetaTable } from '../utils/globals';
import { FormType } from 'nocodb-sdk'; import { BoolType, FormType } from 'nocodb-sdk';
import { deserializeJSON, serializeJSON } from '../utils/serialize'; import { deserializeJSON, serializeJSON } from '../utils/serialize';
import FormViewColumn from './FormViewColumn'; import FormViewColumn from './FormViewColumn';
import View from './View'; import View from './View';
@ -8,8 +8,8 @@ import NocoCache from '../cache/NocoCache';
import { extractProps } from '../meta/helpers/extractProps'; import { extractProps } from '../meta/helpers/extractProps';
export default class FormView implements FormType { export default class FormView implements FormType {
show: boolean; show: BoolType;
is_default: boolean; is_default: BoolType;
order: number; order: number;
title?: string; title?: string;
heading?: string; heading?: string;
@ -20,8 +20,8 @@ export default class FormView implements FormType {
email?: string; email?: string;
banner_image_url?: string; banner_image_url?: string;
logo_url?: string; logo_url?: string;
submit_another_form?: boolean; submit_another_form?: BoolType;
show_blank_form?: boolean; show_blank_form?: BoolType;
fk_view_id: string; fk_view_id: string;
columns?: FormViewColumn[]; columns?: FormViewColumn[];

12
packages/nocodb/src/lib/models/GalleryView.ts

@ -1,24 +1,24 @@
import Noco from '../Noco'; import Noco from '../Noco';
import { CacheGetType, CacheScope, MetaTable } from '../utils/globals'; import { CacheGetType, CacheScope, MetaTable } from '../utils/globals';
import { GalleryColumnType, GalleryType, UITypes } from 'nocodb-sdk'; import { BoolType, GalleryColumnType, GalleryType, UITypes } from 'nocodb-sdk'
import View from './View'; import View from './View';
import NocoCache from '../cache/NocoCache'; import NocoCache from '../cache/NocoCache';
import { extractProps } from '../meta/helpers/extractProps'; import { extractProps } from '../meta/helpers/extractProps';
export default class GalleryView implements GalleryType { export default class GalleryView implements GalleryType {
fk_view_id?: string; fk_view_id?: string;
deleted?: boolean; deleted?: BoolType;
order?: number; order?: number;
next_enabled?: boolean; next_enabled?: BoolType;
prev_enabled?: boolean; prev_enabled?: BoolType;
cover_image_idx?: number; cover_image_idx?: number;
cover_image?: string; cover_image?: string;
restrict_types?: string; restrict_types?: string;
restrict_size?: string; restrict_size?: string;
restrict_number?: string; restrict_number?: string;
public?: boolean; public?: BoolType;
password?: string; password?: string;
show_all_fields?: boolean; show_all_fields?: BoolType;
fk_cover_image_col_id?: string; fk_cover_image_col_id?: string;
project_id?: string; project_id?: string;

13
packages/nocodb/src/lib/services/formViewColumnService.ts

@ -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
);
}

31
packages/nocodb/src/lib/services/formViewService.ts

@ -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);
}

31
packages/nocodb/src/lib/services/galleryViewService.ts

@ -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);
}

26
packages/nocodb/src/lib/services/gridViewService.ts

@ -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);
}

82
packages/nocodb/src/lib/services/hookService.ts

@ -1,30 +1,19 @@
import { Tele } from 'nc-help'; import { Tele } from 'nc-help';
import catchError from '../helpers/catchError';
import { Request, Response, Router } from 'express';
import { Hook, Model } from '../models'; import { Hook, Model } from '../models';
import { HookListType, HookReqType, HookTestReqType, HookType, TableReqType } from 'nocodb-sdk' import { HookReqType, HookTestReqType } from 'nocodb-sdk';
import { PagedResponseImpl } from '../helpers/PagedResponse';
import { invokeWebhook } from '../helpers/webhookHelpers';
import populateSamplePayload from '../helpers/populateSamplePayload';
import ncMetaAclMw from '../helpers/ncMetaAclMw';
import { metaApiMetrics } from '../helpers/apiMetrics';
import { getAjvValidatorMw } from './helpers';
export async function hookList( import { invokeWebhook } from '../meta/helpers/webhookHelpers';
param: { import populateSamplePayload from '../meta/helpers/populateSamplePayload';
tableId: string;
} export async function hookList(param: { tableId: string }) {
) {
// todo: pagination // todo: pagination
await Hook.list({ fk_model_id: param.tableId })) return await Hook.list({ fk_model_id: param.tableId });
} }
export async function hookCreate( export async function hookCreate(param: {
param: {
tableId: string; tableId: string;
hook: HookReqType hook: HookReqType;
} }) {
) {
Tele.emit('evt', { evt_type: 'webhooks:created' }); Tele.emit('evt', { evt_type: 'webhooks:created' });
const hook = await Hook.insert({ const hook = await Hook.insert({
...param.hook, ...param.hook,
@ -33,25 +22,16 @@ param: {
return hook; return hook;
} }
export async function hookDelete( export async function hookDelete(param: { hookId: string }) {
param :{
hookId: string;
}
) {
Tele.emit('evt', { evt_type: 'webhooks:deleted' }); Tele.emit('evt', { evt_type: 'webhooks:deleted' });
await Hook.delete(param.hookId); await Hook.delete(param.hookId);
return true; return true;
} }
export async function hookUpdate( export async function hookUpdate(param: { hookId: string; hook: HookReqType }) {
param: {
hookId: string;
hook: HookReqType;
}
) {
Tele.emit('evt', { evt_type: 'webhooks:updated' }); Tele.emit('evt', { evt_type: 'webhooks:updated' });
return await Hook.update(param.hookId, param.hook) return await Hook.update(param.hookId, param.hook);
} }
export async function hookTest(param: { export async function hookTest(param: {
@ -75,7 +55,7 @@ export async function hookTest(param: {
Tele.emit('evt', { evt_type: 'webhooks:tested' }); Tele.emit('evt', { evt_type: 'webhooks:tested' });
return true return true;
} }
export async function tableSampleData(param: { export async function tableSampleData(param: {
tableId: string; tableId: string;
@ -85,39 +65,3 @@ export async function tableSampleData(param:{
return await populateSamplePayload(model, false, param.operation); return await populateSamplePayload(model, false, param.operation);
} }
const router = Router({ mergeParams: true });
router.get(
'/api/v1/db/meta/tables/:tableId/hooks',
metaApiMetrics,
ncMetaAclMw(hookList, 'hookList')
);
router.post(
'/api/v1/db/meta/tables/:tableId/hooks/test',
metaApiMetrics,
getAjvValidatorMw('swagger.json#/components/schemas/HookTestReq'),
ncMetaAclMw(hookTest, 'hookTest')
);
router.post(
'/api/v1/db/meta/tables/:tableId/hooks',
metaApiMetrics,
getAjvValidatorMw('swagger.json#/components/schemas/HookReq'),
ncMetaAclMw(hookCreate, 'hookCreate')
);
router.delete(
'/api/v1/db/meta/hooks/:hookId',
metaApiMetrics,
ncMetaAclMw(hookDelete, 'hookDelete')
);
router.patch(
'/api/v1/db/meta/hooks/:hookId',
metaApiMetrics,
getAjvValidatorMw('swagger.json#/components/schemas/HookReq'),
ncMetaAclMw(hookUpdate, 'hookUpdate')
);
router.get(
'/api/v1/db/meta/tables/:tableId/hooks/samplePayload/:operation',
metaApiMetrics,
catchError(tableSampleData)
);
export default router;

8
packages/nocodb/src/lib/services/index.ts

@ -6,3 +6,11 @@ export * as sortService from './sortService';
export * as baseService from './baseService'; export * as baseService from './baseService';
export * as apiTokenService from './apiTokenService'; export * as apiTokenService from './apiTokenService';
export * as viewService from './viewService'; export * as viewService from './viewService';
export * as hookService from './hookService';
export * as pluginService from './pluginService';
export * as utilService from './utilService';
export * as formViewService from './formViewService';
export * as formViewColumnService from './formViewColumnService';
export * as gridViewService from './gridViewService';
export * as galleryViewService from './galleryViewService';
export * as kanbanViewService from './kanbanViewService';

29
packages/nocodb/src/lib/services/kanbanViewService.ts

@ -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);
}

30
packages/nocodb/src/lib/services/pluginService.ts

@ -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)
}

381
packages/nocodb/src/lib/services/utilService.ts

@ -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;
});
};

1
packages/nocodb/src/lib/services/viewService.ts

@ -3,7 +3,6 @@ import { Tele } from 'nc-help';
import { SharedViewReqType, ViewReqType } from 'nocodb-sdk'; import { SharedViewReqType, ViewReqType } from 'nocodb-sdk';
import { xcVisibilityMetaGet } from '../meta/api/modelVisibilityApis'; import { xcVisibilityMetaGet } from '../meta/api/modelVisibilityApis';
export async function viewList(param: { export async function viewList(param: {
tableId: string; tableId: string;
user: { user: {

Loading…
Cancel
Save