mirror of https://github.com/nocodb/nocodb
496 changed files with 26345 additions and 18005 deletions
@ -0,0 +1,57 @@ |
|||||||
|
<script lang="ts" setup> |
||||||
|
import { isMac } from '#imports' |
||||||
|
|
||||||
|
const props = defineProps<{ |
||||||
|
keys: string[] |
||||||
|
}>() |
||||||
|
|
||||||
|
const isMacOs = isMac() |
||||||
|
|
||||||
|
const getLabel = (key: string) => { |
||||||
|
if (isMacOs) { |
||||||
|
switch (key.toLowerCase()) { |
||||||
|
case 'alt': |
||||||
|
return '⌥' |
||||||
|
case 'shift': |
||||||
|
return '⇧' |
||||||
|
case 'meta': |
||||||
|
return '⌘' |
||||||
|
case 'control': |
||||||
|
case 'ctrl': |
||||||
|
return '⌃' |
||||||
|
case 'enter': |
||||||
|
return '↩' |
||||||
|
} |
||||||
|
} |
||||||
|
switch (key.toLowerCase()) { |
||||||
|
case 'arrowup': |
||||||
|
return '↑' |
||||||
|
case 'arrowdown': |
||||||
|
return '↓' |
||||||
|
case 'arrowleft': |
||||||
|
return '←' |
||||||
|
case 'arrowright': |
||||||
|
return '→' |
||||||
|
} |
||||||
|
|
||||||
|
return key |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<template> |
||||||
|
<div class="nc-shortcut-label-wrapper"> |
||||||
|
<div v-for="(key, index) in props.keys" :key="index" class="nc-shortcut-label"> |
||||||
|
<span>{{ getLabel(key) }}</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<style scoped> |
||||||
|
.nc-shortcut-label-wrapper { |
||||||
|
@apply flex gap-1; |
||||||
|
} |
||||||
|
|
||||||
|
.nc-shortcut-label { |
||||||
|
@apply text-[0.7rem] leading-6 min-w-5 min-h-5 text-center relative z-0 after:(content-[''] left-0 top-0 -z-1 bg-current opacity-10 absolute w-full h-full rounded) px-1; |
||||||
|
} |
||||||
|
</style> |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,36 @@ |
|||||||
|
import { Router } from 'express'; |
||||||
|
import ncMetaAclMw from '../../meta/helpers/ncMetaAclMw'; |
||||||
|
import { swaggerService } from '../../services'; |
||||||
|
import getSwaggerHtml from './swaggerHtml'; |
||||||
|
import getRedocHtml from './redocHtml'; |
||||||
|
|
||||||
|
async function swaggerJson(req, res) { |
||||||
|
const swagger = await swaggerService.swaggerJson({ |
||||||
|
projectId: req.params.projectId, |
||||||
|
siteUrl: req.ncSiteUrl, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json(swagger); |
||||||
|
} |
||||||
|
|
||||||
|
function swaggerHtml(_, res) { |
||||||
|
res.send(getSwaggerHtml({ ncSiteUrl: process.env.NC_PUBLIC_URL || '' })); |
||||||
|
} |
||||||
|
|
||||||
|
function redocHtml(_, res) { |
||||||
|
res.send(getRedocHtml({ ncSiteUrl: process.env.NC_PUBLIC_URL || '' })); |
||||||
|
} |
||||||
|
|
||||||
|
const router = Router({ mergeParams: true }); |
||||||
|
|
||||||
|
// todo: auth
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/meta/projects/:projectId/swagger.json', |
||||||
|
ncMetaAclMw(swaggerJson, 'swaggerJson') |
||||||
|
); |
||||||
|
|
||||||
|
router.get('/api/v1/db/meta/projects/:projectId/swagger', swaggerHtml); |
||||||
|
|
||||||
|
router.get('/api/v1/db/meta/projects/:projectId/redoc', redocHtml); |
||||||
|
|
||||||
|
export default router; |
@ -0,0 +1,50 @@ |
|||||||
|
import { Router } from 'express'; |
||||||
|
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; |
||||||
|
import { metaApiMetrics } from '../meta/helpers/apiMetrics'; |
||||||
|
import { apiTokenService } from '../services'; |
||||||
|
import type { Request, Response } from 'express'; |
||||||
|
|
||||||
|
export async function apiTokenList(req: Request, res: Response) { |
||||||
|
res.json(await apiTokenService.apiTokenList({ userId: req['user'].id })); |
||||||
|
} |
||||||
|
|
||||||
|
export async function apiTokenCreate(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await apiTokenService.apiTokenCreate({ |
||||||
|
tokenBody: req.body, |
||||||
|
userId: req['user'].id, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function apiTokenDelete(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await apiTokenService.apiTokenDelete({ |
||||||
|
token: req.params.token, |
||||||
|
user: req['user'], |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
// todo: add reset token api to regenerate token
|
||||||
|
|
||||||
|
// deprecated apis
|
||||||
|
const router = Router({ mergeParams: true }); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/meta/projects/:projectId/api-tokens', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(apiTokenList, 'apiTokenList') |
||||||
|
); |
||||||
|
router.post( |
||||||
|
'/api/v1/db/meta/projects/:projectId/api-tokens', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(apiTokenCreate, 'apiTokenCreate') |
||||||
|
); |
||||||
|
router.delete( |
||||||
|
'/api/v1/db/meta/projects/:projectId/api-tokens/:token', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(apiTokenDelete, 'apiTokenDelete') |
||||||
|
); |
||||||
|
|
||||||
|
export default router; |
@ -0,0 +1,128 @@ |
|||||||
|
import path from 'path'; |
||||||
|
import { Router } from 'express'; |
||||||
|
import multer from 'multer'; |
||||||
|
import { OrgUserRoles, ProjectRoles } from 'nocodb-sdk'; |
||||||
|
import Noco from '../Noco'; |
||||||
|
import { MetaTable } from '../utils/globals'; |
||||||
|
import extractProjectIdAndAuthenticate from '../meta/helpers/extractProjectIdAndAuthenticate'; |
||||||
|
import catchError, { NcError } from '../meta/helpers/catchError'; |
||||||
|
import { NC_ATTACHMENT_FIELD_SIZE } from '../constants'; |
||||||
|
import { getCacheMiddleware } from '../meta/api/helpers'; |
||||||
|
import { attachmentService } from '../services'; |
||||||
|
import type { Request, Response } from 'express'; |
||||||
|
|
||||||
|
const isUploadAllowedMw = async (req: Request, _res: Response, next: any) => { |
||||||
|
if (!req['user']?.id) { |
||||||
|
if (!req['user']?.isPublicBase) { |
||||||
|
NcError.unauthorized('Unauthorized'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
// check user is super admin or creator
|
||||||
|
if ( |
||||||
|
req['user'].roles?.includes(OrgUserRoles.SUPER_ADMIN) || |
||||||
|
req['user'].roles?.includes(OrgUserRoles.CREATOR) || |
||||||
|
req['user'].roles?.includes(ProjectRoles.EDITOR) || |
||||||
|
// if viewer then check at-least one project have editor or higher role
|
||||||
|
// todo: cache
|
||||||
|
!!(await Noco.ncMeta |
||||||
|
.knex(MetaTable.PROJECT_USERS) |
||||||
|
.where(function () { |
||||||
|
this.where('roles', ProjectRoles.OWNER); |
||||||
|
this.orWhere('roles', ProjectRoles.CREATOR); |
||||||
|
this.orWhere('roles', ProjectRoles.EDITOR); |
||||||
|
}) |
||||||
|
.andWhere('fk_user_id', req['user'].id) |
||||||
|
.first()) |
||||||
|
) |
||||||
|
return next(); |
||||||
|
} catch {} |
||||||
|
NcError.badRequest('Upload not allowed'); |
||||||
|
}; |
||||||
|
|
||||||
|
export async function upload(req: Request, res: Response) { |
||||||
|
const attachments = await attachmentService.upload({ |
||||||
|
files: (req as any).files, |
||||||
|
path: req.query?.path as string, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json(attachments); |
||||||
|
} |
||||||
|
|
||||||
|
export async function uploadViaURL(req: Request, res: Response) { |
||||||
|
const attachments = await attachmentService.uploadViaURL({ |
||||||
|
urls: req.body, |
||||||
|
path: req.query?.path as string, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json(attachments); |
||||||
|
} |
||||||
|
|
||||||
|
export async function fileRead(req, res) { |
||||||
|
try { |
||||||
|
const { img, type } = await attachmentService.fileRead({ |
||||||
|
path: path.join('nc', 'uploads', req.params?.[0]), |
||||||
|
}); |
||||||
|
|
||||||
|
res.writeHead(200, { 'Content-Type': type }); |
||||||
|
res.end(img, 'binary'); |
||||||
|
} catch (e) { |
||||||
|
console.log(e); |
||||||
|
res.status(404).send('Not found'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const router = Router({ mergeParams: true }); |
||||||
|
|
||||||
|
router.get( |
||||||
|
/^\/dl\/([^/]+)\/([^/]+)\/(.+)$/, |
||||||
|
getCacheMiddleware(), |
||||||
|
async (req, res) => { |
||||||
|
try { |
||||||
|
const { img, type } = await attachmentService.fileRead({ |
||||||
|
path: path.join( |
||||||
|
'nc', |
||||||
|
req.params[0], |
||||||
|
req.params[1], |
||||||
|
'uploads', |
||||||
|
...req.params[2].split('/') |
||||||
|
), |
||||||
|
}); |
||||||
|
|
||||||
|
res.writeHead(200, { 'Content-Type': type }); |
||||||
|
res.end(img, 'binary'); |
||||||
|
} catch (e) { |
||||||
|
res.status(404).send('Not found'); |
||||||
|
} |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
router.post( |
||||||
|
'/api/v1/db/storage/upload', |
||||||
|
multer({ |
||||||
|
storage: multer.diskStorage({}), |
||||||
|
limits: { |
||||||
|
fieldSize: NC_ATTACHMENT_FIELD_SIZE, |
||||||
|
}, |
||||||
|
}).any(), |
||||||
|
[ |
||||||
|
extractProjectIdAndAuthenticate, |
||||||
|
catchError(isUploadAllowedMw), |
||||||
|
catchError(upload), |
||||||
|
] |
||||||
|
); |
||||||
|
|
||||||
|
router.post( |
||||||
|
'/api/v1/db/storage/upload-by-url', |
||||||
|
|
||||||
|
[ |
||||||
|
extractProjectIdAndAuthenticate, |
||||||
|
catchError(isUploadAllowedMw), |
||||||
|
catchError(uploadViaURL), |
||||||
|
] |
||||||
|
); |
||||||
|
|
||||||
|
router.get(/^\/download\/(.+)$/, getCacheMiddleware(), catchError(fileRead)); |
||||||
|
|
||||||
|
export default router; |
@ -0,0 +1,73 @@ |
|||||||
|
import { Router } from 'express'; |
||||||
|
import Audit from '../models/Audit'; |
||||||
|
import { PagedResponseImpl } from '../meta/helpers/PagedResponse'; |
||||||
|
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; |
||||||
|
import { auditService } from '../services'; |
||||||
|
import type { Request, Response } from 'express'; |
||||||
|
|
||||||
|
export async function commentRow(req: Request<any, any>, res) { |
||||||
|
res.json( |
||||||
|
await auditService.commentRow({ |
||||||
|
rowId: req.params.rowId, |
||||||
|
user: (req as any).user, |
||||||
|
body: req.body, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function auditRowUpdate(req: Request<any, any>, res) { |
||||||
|
res.json( |
||||||
|
await auditService.auditRowUpdate({ |
||||||
|
rowId: req.params.rowId, |
||||||
|
body: req.body, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function commentList(req: Request<any, any, any>, res) { |
||||||
|
res.json(await Audit.commentsList(req.query)); |
||||||
|
} |
||||||
|
|
||||||
|
export async function auditList(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
new PagedResponseImpl( |
||||||
|
await Audit.projectAuditList(req.params.projectId, req.query), |
||||||
|
{ |
||||||
|
count: await Audit.projectAuditCount(req.params.projectId), |
||||||
|
...req.query, |
||||||
|
} |
||||||
|
) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function commentsCount(req: Request<any, any, any>, res) { |
||||||
|
res.json( |
||||||
|
await Audit.commentsCount({ |
||||||
|
fk_model_id: req.query.fk_model_id as string, |
||||||
|
ids: req.query.ids as string[], |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
const router = Router({ mergeParams: true }); |
||||||
|
router.get( |
||||||
|
'/api/v1/db/meta/audits/comments', |
||||||
|
ncMetaAclMw(commentList, 'commentList') |
||||||
|
); |
||||||
|
router.post( |
||||||
|
'/api/v1/db/meta/audits/comments', |
||||||
|
ncMetaAclMw(commentRow, 'commentRow') |
||||||
|
); |
||||||
|
router.post( |
||||||
|
'/api/v1/db/meta/audits/rows/:rowId/update', |
||||||
|
ncMetaAclMw(auditRowUpdate, 'auditRowUpdate') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/api/v1/db/meta/audits/comments/count', |
||||||
|
ncMetaAclMw(commentsCount, 'commentsCount') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/api/v1/db/meta/projects/:projectId/audits', |
||||||
|
ncMetaAclMw(auditList, 'auditList') |
||||||
|
); |
||||||
|
export default router; |
@ -0,0 +1,91 @@ |
|||||||
|
import { PagedResponseImpl } from '../meta/helpers/PagedResponse'; |
||||||
|
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; |
||||||
|
import { metaApiMetrics } from '../meta/helpers/apiMetrics'; |
||||||
|
|
||||||
|
import { baseService } from '../services'; |
||||||
|
import type Base from '../models/Base'; |
||||||
|
import type { BaseListType } from 'nocodb-sdk'; |
||||||
|
import type { Request, Response } from 'express'; |
||||||
|
|
||||||
|
async function baseGet(req: Request<any>, res: Response<Base>) { |
||||||
|
const base = await baseService.baseGetWithConfig({ |
||||||
|
baseId: req.params.baseId, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json(base); |
||||||
|
} |
||||||
|
|
||||||
|
async function baseUpdate(req: Request<any, any, any>, res: Response<any>) { |
||||||
|
const base = await baseService.baseUpdate({ |
||||||
|
baseId: req.params.baseId, |
||||||
|
base: req.body, |
||||||
|
projectId: req.params.projectId, |
||||||
|
}); |
||||||
|
res.json(base); |
||||||
|
} |
||||||
|
|
||||||
|
async function baseList( |
||||||
|
req: Request<any, any, any>, |
||||||
|
res: Response<BaseListType> |
||||||
|
) { |
||||||
|
const bases = await baseService.baseList({ |
||||||
|
projectId: req.params.projectId, |
||||||
|
}); |
||||||
|
|
||||||
|
res // todo: pagination
|
||||||
|
.json({ |
||||||
|
bases: new PagedResponseImpl(bases, { |
||||||
|
count: bases.length, |
||||||
|
limit: bases.length, |
||||||
|
}), |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
export async function baseDelete( |
||||||
|
req: Request<any, any, any>, |
||||||
|
res: Response<any> |
||||||
|
) { |
||||||
|
const result = await baseService.baseDelete({ |
||||||
|
baseId: req.params.baseId, |
||||||
|
}); |
||||||
|
res.json(result); |
||||||
|
} |
||||||
|
|
||||||
|
async function baseCreate(req: Request<any, any>, res) { |
||||||
|
const base = await baseService.baseCreate({ |
||||||
|
projectId: req.params.projectId, |
||||||
|
base: req.body, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json(base); |
||||||
|
} |
||||||
|
|
||||||
|
const initRoutes = (router) => { |
||||||
|
router.get( |
||||||
|
'/api/v1/db/meta/projects/:projectId/bases/:baseId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(baseGet, 'baseGet') |
||||||
|
); |
||||||
|
router.patch( |
||||||
|
'/api/v1/db/meta/projects/:projectId/bases/:baseId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(baseUpdate, 'baseUpdate') |
||||||
|
); |
||||||
|
router.delete( |
||||||
|
'/api/v1/db/meta/projects/:projectId/bases/:baseId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(baseDelete, 'baseDelete') |
||||||
|
); |
||||||
|
router.post( |
||||||
|
'/api/v1/db/meta/projects/:projectId/bases', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(baseCreate, 'baseCreate') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/api/v1/db/meta/projects/:projectId/bases', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(baseList, 'baseList') |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default initRoutes; |
@ -0,0 +1,78 @@ |
|||||||
|
import { Router } from 'express'; |
||||||
|
import { metaApiMetrics } from '../meta/helpers/apiMetrics'; |
||||||
|
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; |
||||||
|
import { columnService } from '../services'; |
||||||
|
import type { ColumnReqType, TableType, UITypes } from 'nocodb-sdk'; |
||||||
|
import type { Request, Response } from 'express'; |
||||||
|
|
||||||
|
export async function columnGet(req: Request, res: Response) { |
||||||
|
res.json(await columnService.columnGet({ columnId: req.params.columnId })); |
||||||
|
} |
||||||
|
|
||||||
|
export async function columnAdd( |
||||||
|
req: Request<any, any, ColumnReqType & { uidt: UITypes }>, |
||||||
|
res: Response<TableType> |
||||||
|
) { |
||||||
|
res.json( |
||||||
|
await columnService.columnAdd({ |
||||||
|
tableId: req.params.tableId, |
||||||
|
column: req.body, |
||||||
|
req, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function columnSetAsPrimary(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await columnService.columnSetAsPrimary({ columnId: req.params.columnId }) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function columnUpdate(req: Request, res: Response<TableType>) { |
||||||
|
res.json( |
||||||
|
await columnService.columnUpdate({ |
||||||
|
columnId: req.params.columnId, |
||||||
|
column: req.body, |
||||||
|
req, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function columnDelete(req: Request, res: Response<TableType>) { |
||||||
|
res.json( |
||||||
|
await columnService.columnDelete({ columnId: req.params.columnId, req }) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
const router = Router({ mergeParams: true }); |
||||||
|
|
||||||
|
router.post( |
||||||
|
'/api/v1/db/meta/tables/:tableId/columns/', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(columnAdd, 'columnAdd') |
||||||
|
); |
||||||
|
|
||||||
|
router.patch( |
||||||
|
'/api/v1/db/meta/columns/:columnId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(columnUpdate, 'columnUpdate') |
||||||
|
); |
||||||
|
|
||||||
|
router.delete( |
||||||
|
'/api/v1/db/meta/columns/:columnId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(columnDelete, 'columnDelete') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/meta/columns/:columnId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(columnGet, 'columnGet') |
||||||
|
); |
||||||
|
|
||||||
|
router.post( |
||||||
|
'/api/v1/db/meta/columns/:columnId/primary', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(columnSetAsPrimary, 'columnSetAsPrimary') |
||||||
|
); |
||||||
|
export default router; |
@ -0,0 +1,93 @@ |
|||||||
|
import { Router } from 'express'; |
||||||
|
import { bulkDataService } from '../../services'; |
||||||
|
import ncMetaAclMw from '../../meta/helpers/ncMetaAclMw'; |
||||||
|
import apiMetrics from '../../meta/helpers/apiMetrics'; |
||||||
|
import type { Request, Response } from 'express'; |
||||||
|
|
||||||
|
async function bulkDataInsert(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await bulkDataService.bulkDataInsert({ |
||||||
|
body: req.body, |
||||||
|
cookie: req, |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async function bulkDataUpdate(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await bulkDataService.bulkDataUpdate({ |
||||||
|
body: req.body, |
||||||
|
cookie: req, |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
// todo: Integrate with filterArrJson bulkDataUpdateAll
|
||||||
|
async function bulkDataUpdateAll(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await bulkDataService.bulkDataUpdateAll({ |
||||||
|
body: req.body, |
||||||
|
cookie: req, |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
query: req.query, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async function bulkDataDelete(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await bulkDataService.bulkDataDelete({ |
||||||
|
body: req.body, |
||||||
|
cookie: req, |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
// todo: Integrate with filterArrJson bulkDataDeleteAll
|
||||||
|
async function bulkDataDeleteAll(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await bulkDataService.bulkDataDeleteAll({ |
||||||
|
// cookie: req,
|
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
query: req.query, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
const router = Router({ mergeParams: true }); |
||||||
|
|
||||||
|
router.post( |
||||||
|
'/api/v1/db/data/bulk/:orgs/:projectName/:tableName', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(bulkDataInsert, 'bulkDataInsert') |
||||||
|
); |
||||||
|
router.patch( |
||||||
|
'/api/v1/db/data/bulk/:orgs/:projectName/:tableName', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(bulkDataUpdate, 'bulkDataUpdate') |
||||||
|
); |
||||||
|
router.patch( |
||||||
|
'/api/v1/db/data/bulk/:orgs/:projectName/:tableName/all', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(bulkDataUpdateAll, 'bulkDataUpdateAll') |
||||||
|
); |
||||||
|
router.delete( |
||||||
|
'/api/v1/db/data/bulk/:orgs/:projectName/:tableName', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(bulkDataDelete, 'bulkDataDelete') |
||||||
|
); |
||||||
|
router.delete( |
||||||
|
'/api/v1/db/data/bulk/:orgs/:projectName/:tableName/all', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(bulkDataDeleteAll, 'bulkDataDeleteAll') |
||||||
|
); |
||||||
|
|
||||||
|
export default router; |
@ -0,0 +1,193 @@ |
|||||||
|
import { Router } from 'express'; |
||||||
|
import { dataService } from '../../services'; |
||||||
|
import ncMetaAclMw from '../../meta/helpers/ncMetaAclMw'; |
||||||
|
import apiMetrics from '../../meta/helpers/apiMetrics'; |
||||||
|
import type { Request, Response } from 'express'; |
||||||
|
|
||||||
|
export async function dataList(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataService.dataListByViewId({ |
||||||
|
viewId: req.params.viewId, |
||||||
|
query: req.query, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function mmList(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataService.mmList({ |
||||||
|
viewId: req.params.viewId, |
||||||
|
colId: req.params.colId, |
||||||
|
rowId: req.params.rowId, |
||||||
|
query: req.query, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function mmExcludedList(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataService.mmExcludedList({ |
||||||
|
viewId: req.params.viewId, |
||||||
|
colId: req.params.colId, |
||||||
|
rowId: req.params.rowId, |
||||||
|
query: req.query, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function hmExcludedList(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataService.hmExcludedList({ |
||||||
|
viewId: req.params.viewId, |
||||||
|
colId: req.params.colId, |
||||||
|
rowId: req.params.rowId, |
||||||
|
query: req.query, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function btExcludedList(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataService.btExcludedList({ |
||||||
|
viewId: req.params.viewId, |
||||||
|
colId: req.params.colId, |
||||||
|
rowId: req.params.rowId, |
||||||
|
query: req.query, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function hmList(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataService.hmList({ |
||||||
|
viewId: req.params.viewId, |
||||||
|
colId: req.params.colId, |
||||||
|
rowId: req.params.rowId, |
||||||
|
query: req.query, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async function dataRead(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataService.dataReadByViewId({ |
||||||
|
viewId: req.params.viewId, |
||||||
|
rowId: req.params.rowId, |
||||||
|
query: req.query, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async function dataInsert(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataService.dataInsertByViewId({ |
||||||
|
viewId: req.params.viewId, |
||||||
|
body: req.body, |
||||||
|
cookie: req, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async function dataUpdate(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataService.dataUpdateByViewId({ |
||||||
|
viewId: req.params.viewId, |
||||||
|
rowId: req.params.rowId, |
||||||
|
body: req.body, |
||||||
|
cookie: req, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async function dataDelete(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataService.dataDeleteByViewId({ |
||||||
|
viewId: req.params.viewId, |
||||||
|
rowId: req.params.rowId, |
||||||
|
cookie: req, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async function relationDataDelete(req, res) { |
||||||
|
await dataService.relationDataDelete({ |
||||||
|
viewId: req.params.viewId, |
||||||
|
colId: req.params.colId, |
||||||
|
childId: req.params.childId, |
||||||
|
rowId: req.params.rowId, |
||||||
|
cookie: req, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json({ msg: 'success' }); |
||||||
|
} |
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
|
async function relationDataAdd(req, res) { |
||||||
|
await dataService.relationDataAdd({ |
||||||
|
viewId: req.params.viewId, |
||||||
|
colId: req.params.colId, |
||||||
|
childId: req.params.childId, |
||||||
|
rowId: req.params.rowId, |
||||||
|
cookie: req, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json({ msg: 'success' }); |
||||||
|
} |
||||||
|
|
||||||
|
const router = Router({ mergeParams: true }); |
||||||
|
|
||||||
|
router.get('/data/:viewId/', apiMetrics, ncMetaAclMw(dataList, 'dataList')); |
||||||
|
router.post( |
||||||
|
'/data/:viewId/', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataInsert, 'dataInsert') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/data/:viewId/:rowId', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataRead, 'dataRead') |
||||||
|
); |
||||||
|
router.patch( |
||||||
|
'/data/:viewId/:rowId', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataUpdate, 'dataUpdate') |
||||||
|
); |
||||||
|
router.delete( |
||||||
|
'/data/:viewId/:rowId', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataDelete, 'dataDelete') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/data/:viewId/:rowId/mm/:colId', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(mmList, 'mmList') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/data/:viewId/:rowId/hm/:colId', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(hmList, 'hmList') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/data/:viewId/:rowId/mm/:colId/exclude', |
||||||
|
ncMetaAclMw(mmExcludedList, 'mmExcludedList') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/data/:viewId/:rowId/hm/:colId/exclude', |
||||||
|
ncMetaAclMw(hmExcludedList, 'hmExcludedList') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/data/:viewId/:rowId/bt/:colId/exclude', |
||||||
|
ncMetaAclMw(btExcludedList, 'btExcludedList') |
||||||
|
); |
||||||
|
|
||||||
|
router.post( |
||||||
|
'/data/:viewId/:rowId/:relationType/:colId/:childId', |
||||||
|
ncMetaAclMw(relationDataAdd, 'relationDataAdd') |
||||||
|
); |
||||||
|
router.delete( |
||||||
|
'/data/:viewId/:rowId/:relationType/:colId/:childId', |
||||||
|
ncMetaAclMw(relationDataDelete, 'relationDataDelete') |
||||||
|
); |
||||||
|
export default router; |
@ -0,0 +1,260 @@ |
|||||||
|
import { Router } from 'express'; |
||||||
|
import { dataService } from '../../services'; |
||||||
|
import ncMetaAclMw from '../../meta/helpers/ncMetaAclMw'; |
||||||
|
import apiMetrics from '../../meta/helpers/apiMetrics'; |
||||||
|
import { parseHrtimeToSeconds } from '../../meta/api/helpers'; |
||||||
|
import type { Request, Response } from 'express'; |
||||||
|
|
||||||
|
// todo: Handle the error case where view doesnt belong to model
|
||||||
|
async function dataList(req: Request, res: Response) { |
||||||
|
const startTime = process.hrtime(); |
||||||
|
const responseData = await dataService.dataList({ |
||||||
|
query: req.query, |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
viewName: req.params.viewName, |
||||||
|
}); |
||||||
|
const elapsedSeconds = parseHrtimeToSeconds(process.hrtime(startTime)); |
||||||
|
res.setHeader('xc-db-response', elapsedSeconds); |
||||||
|
res.json(responseData); |
||||||
|
} |
||||||
|
|
||||||
|
async function dataFindOne(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataService.dataFindOne({ |
||||||
|
query: req.query, |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
viewName: req.params.viewName, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async function dataGroupBy(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataService.dataGroupBy({ |
||||||
|
query: req.query, |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
viewName: req.params.viewName, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async function dataCount(req: Request, res: Response) { |
||||||
|
const countResult = await dataService.dataCount({ |
||||||
|
query: req.query, |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
viewName: req.params.viewName, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json(countResult); |
||||||
|
} |
||||||
|
|
||||||
|
async function dataInsert(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataService.dataInsert({ |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
viewName: req.params.viewName, |
||||||
|
body: req.body, |
||||||
|
cookie: req, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async function dataUpdate(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataService.dataUpdate({ |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
viewName: req.params.viewName, |
||||||
|
body: req.body, |
||||||
|
cookie: req, |
||||||
|
rowId: req.params.rowId, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async function dataDelete(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataService.dataDelete({ |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
viewName: req.params.viewName, |
||||||
|
cookie: req, |
||||||
|
rowId: req.params.rowId, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async function dataRead(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataService.dataRead({ |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
viewName: req.params.viewName, |
||||||
|
rowId: req.params.rowId, |
||||||
|
query: req.query, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async function dataExist(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataService.dataExist({ |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
viewName: req.params.viewName, |
||||||
|
rowId: req.params.rowId, |
||||||
|
query: req.query, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
// todo: Handle the error case where view doesnt belong to model
|
||||||
|
async function groupedDataList(req: Request, res: Response) { |
||||||
|
const startTime = process.hrtime(); |
||||||
|
const groupedData = await dataService.groupedDataList({ |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
viewName: req.params.viewName, |
||||||
|
query: req.query, |
||||||
|
columnId: req.params.columnId, |
||||||
|
}); |
||||||
|
const elapsedSeconds = parseHrtimeToSeconds(process.hrtime(startTime)); |
||||||
|
res.setHeader('xc-db-response', elapsedSeconds); |
||||||
|
res.json(groupedData); |
||||||
|
} |
||||||
|
const router = Router({ mergeParams: true }); |
||||||
|
|
||||||
|
// table data crud apis
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataList, 'dataList') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/find-one', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataFindOne, 'dataFindOne') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/groupby', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataGroupBy, 'dataGroupBy') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/group/:columnId', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(groupedDataList, 'groupedDataList') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId/exist', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataExist, 'dataExist') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/count', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataCount, 'dataCount') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName/count', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataCount, 'dataCount') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataRead, 'dataRead') |
||||||
|
); |
||||||
|
|
||||||
|
router.patch( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataUpdate, 'dataUpdate') |
||||||
|
); |
||||||
|
|
||||||
|
router.delete( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataDelete, 'dataDelete') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataList, 'dataList') |
||||||
|
); |
||||||
|
|
||||||
|
// table view data crud apis
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataList, 'dataList') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName/find-one', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataFindOne, 'dataFindOne') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName/groupby', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataGroupBy, 'dataGroupBy') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName/group/:columnId', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(groupedDataList, 'groupedDataList') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName/:rowId/exist', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataExist, 'dataExist') |
||||||
|
); |
||||||
|
|
||||||
|
router.post( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataInsert, 'dataInsert') |
||||||
|
); |
||||||
|
|
||||||
|
router.post( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataInsert, 'dataInsert') |
||||||
|
); |
||||||
|
|
||||||
|
router.patch( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName/:rowId', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataUpdate, 'dataUpdate') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName/:rowId', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataRead, 'dataRead') |
||||||
|
); |
||||||
|
|
||||||
|
router.delete( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName/:rowId', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(dataDelete, 'dataDelete') |
||||||
|
); |
||||||
|
|
||||||
|
export default router; |
@ -1,13 +1,11 @@ |
|||||||
import { Request, Response, Router } from 'express'; |
import { Router } from 'express'; |
||||||
import * as XLSX from 'xlsx'; |
import * as XLSX from 'xlsx'; |
||||||
import ncMetaAclMw from '../../helpers/ncMetaAclMw'; |
import apiMetrics from '../../meta/helpers/apiMetrics'; |
||||||
import { |
import ncMetaAclMw from '../../meta/helpers/ncMetaAclMw'; |
||||||
extractCsvData, |
import { View } from '../../models'; |
||||||
extractXlsxData, |
import { extractCsvData, extractXlsxData } from '../../services/dbData/helpers'; |
||||||
getViewAndModelFromRequestByAliasOrId, |
import { getViewAndModelFromRequestByAliasOrId } from './helpers'; |
||||||
} from './helpers'; |
import type { Request, Response } from 'express'; |
||||||
import apiMetrics from '../../helpers/apiMetrics'; |
|
||||||
import View from '../../../models/View'; |
|
||||||
|
|
||||||
async function excelDataExport(req: Request, res: Response) { |
async function excelDataExport(req: Request, res: Response) { |
||||||
const { model, view } = await getViewAndModelFromRequestByAliasOrId(req); |
const { model, view } = await getViewAndModelFromRequestByAliasOrId(req); |
@ -0,0 +1,138 @@ |
|||||||
|
import { Router } from 'express'; |
||||||
|
import ncMetaAclMw from '../../meta/helpers/ncMetaAclMw'; |
||||||
|
import apiMetrics from '../../meta/helpers/apiMetrics'; |
||||||
|
import { dataAliasNestedService } from '../../services'; |
||||||
|
import type { Request, Response } from 'express'; |
||||||
|
|
||||||
|
// todo: handle case where the given column is not ltar
|
||||||
|
export async function mmList(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataAliasNestedService.mmList({ |
||||||
|
query: req.query, |
||||||
|
columnName: req.params.columnName, |
||||||
|
rowId: req.params.rowId, |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function mmExcludedList(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataAliasNestedService.mmExcludedList({ |
||||||
|
query: req.query, |
||||||
|
columnName: req.params.columnName, |
||||||
|
rowId: req.params.rowId, |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function hmExcludedList(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataAliasNestedService.hmExcludedList({ |
||||||
|
query: req.query, |
||||||
|
columnName: req.params.columnName, |
||||||
|
rowId: req.params.rowId, |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function btExcludedList(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataAliasNestedService.btExcludedList({ |
||||||
|
query: req.query, |
||||||
|
columnName: req.params.columnName, |
||||||
|
rowId: req.params.rowId, |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
// todo: handle case where the given column is not ltar
|
||||||
|
export async function hmList(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await dataAliasNestedService.hmList({ |
||||||
|
query: req.query, |
||||||
|
columnName: req.params.columnName, |
||||||
|
rowId: req.params.rowId, |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
|
async function relationDataRemove(req, res) { |
||||||
|
await dataAliasNestedService.relationDataRemove({ |
||||||
|
columnName: req.params.columnName, |
||||||
|
rowId: req.params.rowId, |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
cookie: req, |
||||||
|
refRowId: req.params.refRowId, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json({ msg: 'success' }); |
||||||
|
} |
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
|
// todo: Give proper error message when reference row is already related and handle duplicate ref row id in hm
|
||||||
|
async function relationDataAdd(req, res) { |
||||||
|
await dataAliasNestedService.relationDataAdd({ |
||||||
|
columnName: req.params.columnName, |
||||||
|
rowId: req.params.rowId, |
||||||
|
projectName: req.params.projectName, |
||||||
|
tableName: req.params.tableName, |
||||||
|
cookie: req, |
||||||
|
refRowId: req.params.refRowId, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json({ msg: 'success' }); |
||||||
|
} |
||||||
|
|
||||||
|
const router = Router({ mergeParams: true }); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId/mm/:columnName/exclude', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(mmExcludedList, 'mmExcludedList') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId/hm/:columnName/exclude', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(hmExcludedList, 'hmExcludedList') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId/bt/:columnName/exclude', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(btExcludedList, 'btExcludedList') |
||||||
|
); |
||||||
|
|
||||||
|
router.post( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId/:relationType/:columnName/:refRowId', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(relationDataAdd, 'relationDataAdd') |
||||||
|
); |
||||||
|
router.delete( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId/:relationType/:columnName/:refRowId', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(relationDataRemove, 'relationDataRemove') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId/mm/:columnName', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(mmList, 'mmList') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId/hm/:columnName', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(hmList, 'hmList') |
||||||
|
); |
||||||
|
|
||||||
|
export default router; |
@ -0,0 +1,270 @@ |
|||||||
|
import { isSystemColumn, UITypes } from 'nocodb-sdk'; |
||||||
|
import * as XLSX from 'xlsx'; |
||||||
|
import papaparse from 'papaparse'; |
||||||
|
import { NcError } from '../../meta/helpers/catchError'; |
||||||
|
import Project from '../../models/Project'; |
||||||
|
import Model from '../../models/Model'; |
||||||
|
import View from '../../models/View'; |
||||||
|
import Base from '../../models/Base'; |
||||||
|
import NcConnectionMgrv2 from '../../utils/common/NcConnectionMgrv2'; |
||||||
|
|
||||||
|
import Column from '../../models/Column'; |
||||||
|
import { dataService } from '../../services'; |
||||||
|
import type LookupColumn from '../../models/LookupColumn'; |
||||||
|
import type LinkToAnotherRecordColumn from '../../models/LinkToAnotherRecordColumn'; |
||||||
|
|
||||||
|
import type { Request } from 'express'; |
||||||
|
export async function getViewAndModelFromRequestByAliasOrId( |
||||||
|
req: |
||||||
|
| Request<{ projectName: string; tableName: string; viewName?: string }> |
||||||
|
| Request |
||||||
|
) { |
||||||
|
const project = await Project.getWithInfoByTitleOrId(req.params.projectName); |
||||||
|
|
||||||
|
const model = await Model.getByAliasOrId({ |
||||||
|
project_id: project.id, |
||||||
|
aliasOrId: req.params.tableName, |
||||||
|
}); |
||||||
|
const view = |
||||||
|
req.params.viewName && |
||||||
|
(await View.getByTitleOrId({ |
||||||
|
titleOrId: req.params.viewName, |
||||||
|
fk_model_id: model.id, |
||||||
|
})); |
||||||
|
if (!model) NcError.notFound('Table not found'); |
||||||
|
return { model, view }; |
||||||
|
} |
||||||
|
|
||||||
|
export async function extractXlsxData(param: { |
||||||
|
view: View; |
||||||
|
query: any; |
||||||
|
siteUrl: string; |
||||||
|
}) { |
||||||
|
const { view, query, siteUrl } = param; |
||||||
|
const base = await Base.get(view.base_id); |
||||||
|
|
||||||
|
await view.getModelWithInfo(); |
||||||
|
await view.getColumns(); |
||||||
|
|
||||||
|
view.model.columns = view.columns |
||||||
|
.filter((c) => c.show) |
||||||
|
.map( |
||||||
|
(c) => |
||||||
|
new Column({ ...c, ...view.model.columnsById[c.fk_column_id] } as any) |
||||||
|
) |
||||||
|
.filter((column) => !isSystemColumn(column) || view.show_system_fields); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: view.model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
const { offset, dbRows, elapsed } = await dataService.getDbRows({ |
||||||
|
baseModel, |
||||||
|
view, |
||||||
|
query, |
||||||
|
siteUrl, |
||||||
|
}); |
||||||
|
|
||||||
|
const fields = query.fields as string[]; |
||||||
|
|
||||||
|
const data = XLSX.utils.json_to_sheet(dbRows, { header: fields }); |
||||||
|
|
||||||
|
return { offset, dbRows, elapsed, data }; |
||||||
|
} |
||||||
|
|
||||||
|
export async function extractCsvData(view: View, req: Request) { |
||||||
|
const base = await Base.get(view.base_id); |
||||||
|
const fields = req.query.fields; |
||||||
|
|
||||||
|
await view.getModelWithInfo(); |
||||||
|
await view.getColumns(); |
||||||
|
|
||||||
|
view.model.columns = view.columns |
||||||
|
.filter((c) => c.show) |
||||||
|
.map( |
||||||
|
(c) => |
||||||
|
new Column({ ...c, ...view.model.columnsById[c.fk_column_id] } as any) |
||||||
|
) |
||||||
|
.filter((column) => !isSystemColumn(column) || view.show_system_fields); |
||||||
|
|
||||||
|
const baseModel = await Model.getBaseModelSQL({ |
||||||
|
id: view.model.id, |
||||||
|
viewId: view?.id, |
||||||
|
dbDriver: await NcConnectionMgrv2.get(base), |
||||||
|
}); |
||||||
|
|
||||||
|
const { offset, dbRows, elapsed } = await dataService.getDbRows({ |
||||||
|
baseModel, |
||||||
|
view, |
||||||
|
query: req.query, |
||||||
|
siteUrl: (req as any).ncSiteUrl, |
||||||
|
}); |
||||||
|
|
||||||
|
const data = papaparse.unparse( |
||||||
|
{ |
||||||
|
fields: view.model.columns |
||||||
|
.sort((c1, c2) => |
||||||
|
Array.isArray(fields) |
||||||
|
? fields.indexOf(c1.title as any) - fields.indexOf(c2.title as any) |
||||||
|
: 0 |
||||||
|
) |
||||||
|
.filter( |
||||||
|
(c) => |
||||||
|
!fields || !Array.isArray(fields) || fields.includes(c.title as any) |
||||||
|
) |
||||||
|
.map((c) => c.title), |
||||||
|
data: dbRows, |
||||||
|
}, |
||||||
|
{ |
||||||
|
escapeFormulae: true, |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
return { offset, dbRows, elapsed, data }; |
||||||
|
} |
||||||
|
//
|
||||||
|
// async function getDbRows(baseModel, view: View, req: Request) {
|
||||||
|
// let offset = +req.query.offset || 0;
|
||||||
|
// const limit = 100;
|
||||||
|
// // const size = +process.env.NC_EXPORT_MAX_SIZE || 1024;
|
||||||
|
// const timeout = +process.env.NC_EXPORT_MAX_TIMEOUT || 5000;
|
||||||
|
// const dbRows = [];
|
||||||
|
// const startTime = process.hrtime();
|
||||||
|
// let elapsed, temp;
|
||||||
|
//
|
||||||
|
// const listArgs: any = { ...req.query };
|
||||||
|
// try {
|
||||||
|
// listArgs.filterArr = JSON.parse(listArgs.filterArrJson);
|
||||||
|
// } catch (e) {}
|
||||||
|
// try {
|
||||||
|
// listArgs.sortArr = JSON.parse(listArgs.sortArrJson);
|
||||||
|
// } catch (e) {}
|
||||||
|
//
|
||||||
|
// for (
|
||||||
|
// elapsed = 0;
|
||||||
|
// elapsed < timeout;
|
||||||
|
// offset += limit,
|
||||||
|
// temp = process.hrtime(startTime),
|
||||||
|
// elapsed = temp[0] * 1000 + temp[1] / 1000000
|
||||||
|
// ) {
|
||||||
|
// const rows = await nocoExecute(
|
||||||
|
// await getAst({
|
||||||
|
// query: req.query,
|
||||||
|
// includePkByDefault: false,
|
||||||
|
// model: view.model,
|
||||||
|
// view,
|
||||||
|
// }),
|
||||||
|
// await baseModel.list({ ...listArgs, offset, limit }),
|
||||||
|
// {},
|
||||||
|
// req.query
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// if (!rows?.length) {
|
||||||
|
// offset = -1;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for (const row of rows) {
|
||||||
|
// const dbRow = { ...row };
|
||||||
|
//
|
||||||
|
// for (const column of view.model.columns) {
|
||||||
|
// if (isSystemColumn(column) && !view.show_system_fields) continue;
|
||||||
|
// dbRow[column.title] = await serializeCellValue({
|
||||||
|
// value: row[column.title],
|
||||||
|
// column,
|
||||||
|
// siteUrl: req['ncSiteUrl'],
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// dbRows.push(dbRow);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return { offset, dbRows, elapsed };
|
||||||
|
// }
|
||||||
|
|
||||||
|
export async function serializeCellValue({ |
||||||
|
value, |
||||||
|
column, |
||||||
|
siteUrl, |
||||||
|
}: { |
||||||
|
column?: Column; |
||||||
|
value: any; |
||||||
|
siteUrl: string; |
||||||
|
}) { |
||||||
|
if (!column) { |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
if (!value) return value; |
||||||
|
|
||||||
|
switch (column?.uidt) { |
||||||
|
case UITypes.Attachment: { |
||||||
|
let data = value; |
||||||
|
try { |
||||||
|
if (typeof value === 'string') { |
||||||
|
data = JSON.parse(value); |
||||||
|
} |
||||||
|
} catch {} |
||||||
|
|
||||||
|
return (data || []).map( |
||||||
|
(attachment) => |
||||||
|
`${encodeURI(attachment.title)}(${encodeURI( |
||||||
|
attachment.path ? `${siteUrl}/${attachment.path}` : attachment.url |
||||||
|
)})` |
||||||
|
); |
||||||
|
} |
||||||
|
case UITypes.Lookup: |
||||||
|
{ |
||||||
|
const colOptions = await column.getColOptions<LookupColumn>(); |
||||||
|
const lookupColumn = await colOptions.getLookupColumn(); |
||||||
|
return ( |
||||||
|
await Promise.all( |
||||||
|
[...(Array.isArray(value) ? value : [value])].map(async (v) => |
||||||
|
serializeCellValue({ |
||||||
|
value: v, |
||||||
|
column: lookupColumn, |
||||||
|
siteUrl, |
||||||
|
}) |
||||||
|
) |
||||||
|
) |
||||||
|
).join(', '); |
||||||
|
} |
||||||
|
break; |
||||||
|
case UITypes.LinkToAnotherRecord: |
||||||
|
{ |
||||||
|
const colOptions = |
||||||
|
await column.getColOptions<LinkToAnotherRecordColumn>(); |
||||||
|
const relatedModel = await colOptions.getRelatedTable(); |
||||||
|
await relatedModel.getColumns(); |
||||||
|
return [...(Array.isArray(value) ? value : [value])] |
||||||
|
.map((v) => { |
||||||
|
return v[relatedModel.displayValue?.title]; |
||||||
|
}) |
||||||
|
.join(', '); |
||||||
|
} |
||||||
|
break; |
||||||
|
default: |
||||||
|
if (value && typeof value === 'object') { |
||||||
|
return JSON.stringify(value); |
||||||
|
} |
||||||
|
return value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export async function getColumnByIdOrName( |
||||||
|
columnNameOrId: string, |
||||||
|
model: Model |
||||||
|
) { |
||||||
|
const column = (await model.getColumns()).find( |
||||||
|
(c) => |
||||||
|
c.title === columnNameOrId || |
||||||
|
c.id === columnNameOrId || |
||||||
|
c.column_name === columnNameOrId |
||||||
|
); |
||||||
|
|
||||||
|
if (!column) |
||||||
|
NcError.notFound(`Column with id/name '${columnNameOrId}' is not found`); |
||||||
|
|
||||||
|
return column; |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
import dataController from './data.ctl'; |
||||||
|
import oldDataController from './oldData.ctl'; |
||||||
|
import dataAliasController from './dataAlias.ctl'; |
||||||
|
import bulkDataAliasController from './bulkDataAlias.ctl'; |
||||||
|
import dataAliasNestedController from './dataAliasNested.ctl'; |
||||||
|
import dataAliasExportController from './dataAliasExport.ctl'; |
||||||
|
|
||||||
|
export { |
||||||
|
dataController, |
||||||
|
oldDataController, |
||||||
|
dataAliasController, |
||||||
|
bulkDataAliasController, |
||||||
|
dataAliasNestedController, |
||||||
|
dataAliasExportController, |
||||||
|
}; |
@ -1,7 +1,8 @@ |
|||||||
import { Request, Response, Router } from 'express'; |
import { Router } from 'express'; |
||||||
import View from '../../models/View'; |
import View from '../models/View'; |
||||||
import ncMetaAclMw from '../helpers/ncMetaAclMw'; |
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; |
||||||
import { extractCsvData } from './dataApis/helpers'; |
import { extractCsvData } from './dbData/helpers'; |
||||||
|
import type { Request, Response } from 'express'; |
||||||
|
|
||||||
async function exportCsv(req: Request, res: Response) { |
async function exportCsv(req: Request, res: Response) { |
||||||
const view = await View.get(req.params.viewId); |
const view = await View.get(req.params.viewId); |
@ -0,0 +1,116 @@ |
|||||||
|
import { Router } from 'express'; |
||||||
|
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; |
||||||
|
import { metaApiMetrics } from '../meta/helpers/apiMetrics'; |
||||||
|
|
||||||
|
import { filterService } from '../services'; |
||||||
|
import type { FilterReqType } from 'nocodb-sdk'; |
||||||
|
import type { Request, Response } from 'express'; |
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
export async function filterGet(req: Request, res: Response) { |
||||||
|
res.json(await filterService.filterGet({ filterId: req.params.filterId })); |
||||||
|
} |
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
export async function filterList(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await filterService.filterList({ |
||||||
|
viewId: req.params.viewId, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
export async function filterChildrenRead(req: Request, res: Response) { |
||||||
|
const filter = await filterService.filterChildrenList({ |
||||||
|
filterId: req.params.filterParentId, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json(filter); |
||||||
|
} |
||||||
|
|
||||||
|
export async function filterCreate(req: Request<any, any, FilterReqType>, res) { |
||||||
|
const filter = await filterService.filterCreate({ |
||||||
|
filter: req.body, |
||||||
|
viewId: req.params.viewId, |
||||||
|
}); |
||||||
|
res.json(filter); |
||||||
|
} |
||||||
|
|
||||||
|
export async function filterUpdate(req, res) { |
||||||
|
const filter = await filterService.filterUpdate({ |
||||||
|
filterId: req.params.filterId, |
||||||
|
filter: req.body, |
||||||
|
}); |
||||||
|
res.json(filter); |
||||||
|
} |
||||||
|
|
||||||
|
export async function filterDelete(req: Request, res: Response) { |
||||||
|
const filter = await filterService.filterDelete({ |
||||||
|
filterId: req.params.filterId, |
||||||
|
}); |
||||||
|
res.json(filter); |
||||||
|
} |
||||||
|
|
||||||
|
export async function hookFilterList(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await filterService.hookFilterList({ |
||||||
|
hookId: req.params.hookId, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function hookFilterCreate( |
||||||
|
req: Request<any, any, FilterReqType>, |
||||||
|
res |
||||||
|
) { |
||||||
|
const filter = await filterService.hookFilterCreate({ |
||||||
|
filter: req.body, |
||||||
|
hookId: req.params.hookId, |
||||||
|
}); |
||||||
|
res.json(filter); |
||||||
|
} |
||||||
|
|
||||||
|
const router = Router({ mergeParams: true }); |
||||||
|
router.get( |
||||||
|
'/api/v1/db/meta/views/:viewId/filters', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(filterList, 'filterList') |
||||||
|
); |
||||||
|
router.post( |
||||||
|
'/api/v1/db/meta/views/:viewId/filters', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(filterCreate, 'filterCreate') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/meta/hooks/:hookId/filters', |
||||||
|
ncMetaAclMw(hookFilterList, 'filterList') |
||||||
|
); |
||||||
|
router.post( |
||||||
|
'/api/v1/db/meta/hooks/:hookId/filters', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(hookFilterCreate, 'filterCreate') |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/meta/filters/:filterId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(filterGet, 'filterGet') |
||||||
|
); |
||||||
|
router.patch( |
||||||
|
'/api/v1/db/meta/filters/:filterId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(filterUpdate, 'filterUpdate') |
||||||
|
); |
||||||
|
router.delete( |
||||||
|
'/api/v1/db/meta/filters/:filterId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(filterDelete, 'filterDelete') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/api/v1/db/meta/filters/:filterParentId/children', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(filterChildrenRead, 'filterChildrenRead') |
||||||
|
); |
||||||
|
export default router; |
@ -0,0 +1,99 @@ |
|||||||
|
import { Router } from 'express'; |
||||||
|
import catchError from '../meta/helpers/catchError'; |
||||||
|
import { PagedResponseImpl } from '../meta/helpers/PagedResponse'; |
||||||
|
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; |
||||||
|
import { metaApiMetrics } from '../meta/helpers/apiMetrics'; |
||||||
|
import { hookService } from '../services'; |
||||||
|
import type { HookListType, HookType } from 'nocodb-sdk'; |
||||||
|
import type { Request, Response } from 'express'; |
||||||
|
|
||||||
|
export async function hookList( |
||||||
|
req: Request<any, any, any>, |
||||||
|
res: Response<HookListType> |
||||||
|
) { |
||||||
|
// todo: pagination
|
||||||
|
res.json( |
||||||
|
new PagedResponseImpl( |
||||||
|
await hookService.hookList({ tableId: req.params.tableId }) |
||||||
|
) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function hookCreate( |
||||||
|
req: Request<any, HookType>, |
||||||
|
res: Response<HookType> |
||||||
|
) { |
||||||
|
const hook = await hookService.hookCreate({ |
||||||
|
hook: req.body, |
||||||
|
tableId: req.params.tableId, |
||||||
|
}); |
||||||
|
res.json(hook); |
||||||
|
} |
||||||
|
|
||||||
|
export async function hookDelete( |
||||||
|
req: Request<any, HookType>, |
||||||
|
res: Response<any> |
||||||
|
) { |
||||||
|
res.json(await hookService.hookDelete({ hookId: req.params.hookId })); |
||||||
|
} |
||||||
|
|
||||||
|
export async function hookUpdate( |
||||||
|
req: Request<any, HookType>, |
||||||
|
res: Response<HookType> |
||||||
|
) { |
||||||
|
res.json( |
||||||
|
await hookService.hookUpdate({ hookId: req.params.hookId, hook: req.body }) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function hookTest(req: Request<any, any>, res: Response) { |
||||||
|
await hookService.hookTest({ |
||||||
|
hookTest: req.body, |
||||||
|
tableId: req.params.tableId, |
||||||
|
}); |
||||||
|
res.json({ msg: 'Success' }); |
||||||
|
} |
||||||
|
|
||||||
|
export async function tableSampleData(req: Request, res: Response) { |
||||||
|
res // todo: pagination
|
||||||
|
.json( |
||||||
|
await hookService.tableSampleData({ |
||||||
|
tableId: req.params.tableId, |
||||||
|
// todo: replace any with type
|
||||||
|
operation: req.params.operation as any, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
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, |
||||||
|
ncMetaAclMw(hookTest, 'hookTest') |
||||||
|
); |
||||||
|
router.post( |
||||||
|
'/api/v1/db/meta/tables/:tableId/hooks', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(hookCreate, 'hookCreate') |
||||||
|
); |
||||||
|
router.delete( |
||||||
|
'/api/v1/db/meta/hooks/:hookId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(hookDelete, 'hookDelete') |
||||||
|
); |
||||||
|
router.patch( |
||||||
|
'/api/v1/db/meta/hooks/:hookId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(hookUpdate, 'hookUpdate') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/api/v1/db/meta/tables/:tableId/hooks/samplePayload/:operation', |
||||||
|
metaApiMetrics, |
||||||
|
catchError(tableSampleData) |
||||||
|
); |
||||||
|
export default router; |
@ -0,0 +1,91 @@ |
|||||||
|
import { Router } from 'express'; |
||||||
|
import { T } from 'nc-help'; |
||||||
|
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; |
||||||
|
import { metaApiMetrics } from '../meta/helpers/apiMetrics'; |
||||||
|
import { hookFilterService } from '../services'; |
||||||
|
import type { Request, Response } from 'express'; |
||||||
|
|
||||||
|
export async function filterGet(req: Request, res: Response) { |
||||||
|
const filter = await hookFilterService.filterGet({ |
||||||
|
hookId: req.params.hookId, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json(filter); |
||||||
|
} |
||||||
|
|
||||||
|
export async function filterList(req: Request, res: Response) { |
||||||
|
const filter = await hookFilterService.filterList({ |
||||||
|
hookId: req.params.hookId, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json(filter); |
||||||
|
} |
||||||
|
|
||||||
|
export async function filterChildrenRead(req: Request, res: Response) { |
||||||
|
const filter = await hookFilterService.filterChildrenRead({ |
||||||
|
hookId: req.params.hookId, |
||||||
|
filterParentId: req.params.filterParentId, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json(filter); |
||||||
|
} |
||||||
|
|
||||||
|
export async function filterCreate(req: Request<any, any>, res) { |
||||||
|
const filter = await hookFilterService.filterCreate({ |
||||||
|
filter: req.body, |
||||||
|
hookId: req.params.hookId, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json(filter); |
||||||
|
} |
||||||
|
|
||||||
|
export async function filterUpdate(req, res) { |
||||||
|
const filter = await hookFilterService.filterUpdate({ |
||||||
|
filterId: req.params.filterId, |
||||||
|
filter: req.body, |
||||||
|
hookId: req.params.hookId, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json(filter); |
||||||
|
} |
||||||
|
|
||||||
|
export async function filterDelete(req: Request, res: Response) { |
||||||
|
const filter = await hookFilterService.filterDelete({ |
||||||
|
filterId: req.params.filterId, |
||||||
|
}); |
||||||
|
T.emit('evt', { evt_type: 'hookFilter:deleted' }); |
||||||
|
res.json(filter); |
||||||
|
} |
||||||
|
|
||||||
|
const router = Router({ mergeParams: true }); |
||||||
|
router.get( |
||||||
|
'/hooks/:hookId/filters/', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(filterList, 'filterList') |
||||||
|
); |
||||||
|
router.post( |
||||||
|
'/hooks/:hookId/filters/', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(filterCreate, 'filterCreate') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/hooks/:hookId/filters/:filterId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(filterGet, 'filterGet') |
||||||
|
); |
||||||
|
router.patch( |
||||||
|
'/hooks/:hookId/filters/:filterId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(filterUpdate, 'filterUpdate') |
||||||
|
); |
||||||
|
router.delete( |
||||||
|
'/hooks/:hookId/filters/:filterId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(filterDelete, 'filterDelete') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/hooks/:hookId/filters/:filterParentId/children', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(filterChildrenRead, 'filterChildrenRead') |
||||||
|
); |
||||||
|
export default router; |
@ -0,0 +1,54 @@ |
|||||||
|
import { Router } from 'express'; |
||||||
|
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; |
||||||
|
import { metaApiMetrics } from '../meta/helpers/apiMetrics'; |
||||||
|
import { metaDiffService } from '../services'; |
||||||
|
|
||||||
|
export async function metaDiff(req, res) { |
||||||
|
res.json(await metaDiffService.metaDiff({ projectId: req.params.projectId })); |
||||||
|
} |
||||||
|
|
||||||
|
export async function baseMetaDiff(req, res) { |
||||||
|
res.json( |
||||||
|
await metaDiffService.baseMetaDiff({ |
||||||
|
baseId: req.params.baseId, |
||||||
|
projectId: req.params.projectId, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function metaDiffSync(req, res) { |
||||||
|
await metaDiffService.metaDiffSync({ projectId: req.params.projectId }); |
||||||
|
res.json({ msg: 'success' }); |
||||||
|
} |
||||||
|
|
||||||
|
export async function baseMetaDiffSync(req, res) { |
||||||
|
await metaDiffService.baseMetaDiffSync({ |
||||||
|
projectId: req.params.projectId, |
||||||
|
baseId: req.params.baseId, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json({ msg: 'success' }); |
||||||
|
} |
||||||
|
|
||||||
|
const router = Router(); |
||||||
|
router.get( |
||||||
|
'/api/v1/db/meta/projects/:projectId/meta-diff', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(metaDiff, 'metaDiff') |
||||||
|
); |
||||||
|
router.post( |
||||||
|
'/api/v1/db/meta/projects/:projectId/meta-diff', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(metaDiffSync, 'metaDiffSync') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/api/v1/db/meta/projects/:projectId/meta-diff/:baseId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(baseMetaDiff, 'baseMetaDiff') |
||||||
|
); |
||||||
|
router.post( |
||||||
|
'/api/v1/db/meta/projects/:projectId/meta-diff/:baseId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(baseMetaDiffSync, 'baseMetaDiffSync') |
||||||
|
); |
||||||
|
export default router; |
@ -0,0 +1,34 @@ |
|||||||
|
import { Router } from 'express'; |
||||||
|
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; |
||||||
|
import { metaApiMetrics } from '../meta/helpers/apiMetrics'; |
||||||
|
import { modelVisibilityService } from '../services'; |
||||||
|
|
||||||
|
async function xcVisibilityMetaSetAll(req, res) { |
||||||
|
await modelVisibilityService.xcVisibilityMetaSetAll({ |
||||||
|
visibilityRule: req.body, |
||||||
|
projectId: req.params.projectId, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json({ msg: 'success' }); |
||||||
|
} |
||||||
|
|
||||||
|
const router = Router({ mergeParams: true }); |
||||||
|
router.get( |
||||||
|
'/api/v1/db/meta/projects/:projectId/visibility-rules', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(async (req, res) => { |
||||||
|
res.json( |
||||||
|
await modelVisibilityService.xcVisibilityMetaGet({ |
||||||
|
projectId: req.params.projectId, |
||||||
|
includeM2M: |
||||||
|
req.query.includeM2M === true || req.query.includeM2M === 'true', |
||||||
|
}) |
||||||
|
); |
||||||
|
}, 'modelVisibilityList') |
||||||
|
); |
||||||
|
router.post( |
||||||
|
'/api/v1/db/meta/projects/:projectId/visibility-rules', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(xcVisibilityMetaSetAll, 'modelVisibilitySet') |
||||||
|
); |
||||||
|
export default router; |
@ -0,0 +1,64 @@ |
|||||||
|
import { Router } from 'express'; |
||||||
|
import { metaApiMetrics } from '../meta/helpers/apiMetrics'; |
||||||
|
import { getConditionalHandler } from '../meta/helpers/getHandler'; |
||||||
|
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; |
||||||
|
import { orgTokenService, orgTokenServiceEE } from '../services'; |
||||||
|
import type { Request, Response } from 'express'; |
||||||
|
|
||||||
|
async function apiTokenList(req, res) { |
||||||
|
res.json( |
||||||
|
await getConditionalHandler( |
||||||
|
orgTokenService.apiTokenList, |
||||||
|
orgTokenServiceEE.apiTokenListEE |
||||||
|
)({ |
||||||
|
query: req.query, |
||||||
|
user: req['user'], |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function apiTokenCreate(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await orgTokenService.apiTokenCreate({ |
||||||
|
apiToken: req.body, |
||||||
|
user: req['user'], |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function apiTokenDelete(req: Request, res: Response) { |
||||||
|
res.json( |
||||||
|
await orgTokenService.apiTokenDelete({ |
||||||
|
token: req.params.token, |
||||||
|
user: req['user'], |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
const router = Router({ mergeParams: true }); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/tokens', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(apiTokenList, 'apiTokenList', { |
||||||
|
// allowedRoles: [OrgUserRoles.SUPER],
|
||||||
|
blockApiTokenAccess: true, |
||||||
|
}) |
||||||
|
); |
||||||
|
router.post( |
||||||
|
'/api/v1/tokens', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(apiTokenCreate, 'apiTokenCreate', { |
||||||
|
// allowedRoles: [OrgUserRoles.SUPER],
|
||||||
|
blockApiTokenAccess: true, |
||||||
|
}) |
||||||
|
); |
||||||
|
router.delete( |
||||||
|
'/api/v1/tokens/:token', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(apiTokenDelete, 'apiTokenDelete', { |
||||||
|
// allowedRoles: [OrgUserRoles.SUPER],
|
||||||
|
blockApiTokenAccess: true, |
||||||
|
}) |
||||||
|
); |
||||||
|
export default router; |
@ -0,0 +1,154 @@ |
|||||||
|
import { Router } from 'express'; |
||||||
|
import { OrgUserRoles } from 'nocodb-sdk'; |
||||||
|
import { metaApiMetrics } from '../meta/helpers/apiMetrics'; |
||||||
|
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; |
||||||
|
import { orgUserService } from '../services'; |
||||||
|
|
||||||
|
async function userList(req, res) { |
||||||
|
res.json( |
||||||
|
await orgUserService.userList({ |
||||||
|
query: req.query, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async function userUpdate(req, res) { |
||||||
|
res.json( |
||||||
|
await orgUserService.userUpdate({ |
||||||
|
user: req.body, |
||||||
|
userId: req.params.userId, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
async function userDelete(req, res) { |
||||||
|
await orgUserService.userDelete({ |
||||||
|
userId: req.params.userId, |
||||||
|
}); |
||||||
|
res.json({ msg: 'success' }); |
||||||
|
} |
||||||
|
|
||||||
|
async function userAdd(req, res) { |
||||||
|
const result = await orgUserService.userAdd({ |
||||||
|
user: req.body, |
||||||
|
req, |
||||||
|
projectId: req.params.projectId, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json(result); |
||||||
|
} |
||||||
|
|
||||||
|
async function userSettings(_req, res): Promise<any> { |
||||||
|
await orgUserService.userSettings({}); |
||||||
|
res.json({}); |
||||||
|
} |
||||||
|
|
||||||
|
async function userInviteResend(req, res): Promise<any> { |
||||||
|
await orgUserService.userInviteResend({ |
||||||
|
userId: req.params.userId, |
||||||
|
req, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json({ msg: 'success' }); |
||||||
|
} |
||||||
|
|
||||||
|
async function generateResetUrl(req, res) { |
||||||
|
const result = await orgUserService.generateResetUrl({ |
||||||
|
siteUrl: req.ncSiteUrl, |
||||||
|
userId: req.params.userId, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json(result); |
||||||
|
} |
||||||
|
|
||||||
|
async function appSettingsGet(_req, res) { |
||||||
|
const settings = await orgUserService.appSettingsGet(); |
||||||
|
res.json(settings); |
||||||
|
} |
||||||
|
|
||||||
|
async function appSettingsSet(req, res) { |
||||||
|
await orgUserService.appSettingsSet({ |
||||||
|
settings: req.body, |
||||||
|
}); |
||||||
|
|
||||||
|
res.json({ msg: 'Settings saved' }); |
||||||
|
} |
||||||
|
|
||||||
|
const router = Router({ mergeParams: true }); |
||||||
|
router.get( |
||||||
|
'/api/v1/users', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(userList, 'userList', { |
||||||
|
allowedRoles: [OrgUserRoles.SUPER_ADMIN], |
||||||
|
blockApiTokenAccess: true, |
||||||
|
}) |
||||||
|
); |
||||||
|
router.patch( |
||||||
|
'/api/v1/users/:userId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(userUpdate, 'userUpdate', { |
||||||
|
allowedRoles: [OrgUserRoles.SUPER_ADMIN], |
||||||
|
blockApiTokenAccess: true, |
||||||
|
}) |
||||||
|
); |
||||||
|
router.delete( |
||||||
|
'/api/v1/users/:userId', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(userDelete, 'userDelete', { |
||||||
|
allowedRoles: [OrgUserRoles.SUPER_ADMIN], |
||||||
|
blockApiTokenAccess: true, |
||||||
|
}) |
||||||
|
); |
||||||
|
router.post( |
||||||
|
'/api/v1/users', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(userAdd, 'userAdd', { |
||||||
|
allowedRoles: [OrgUserRoles.SUPER_ADMIN], |
||||||
|
blockApiTokenAccess: true, |
||||||
|
}) |
||||||
|
); |
||||||
|
router.post( |
||||||
|
'/api/v1/users/settings', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(userSettings, 'userSettings', { |
||||||
|
allowedRoles: [OrgUserRoles.SUPER_ADMIN], |
||||||
|
blockApiTokenAccess: true, |
||||||
|
}) |
||||||
|
); |
||||||
|
router.post( |
||||||
|
'/api/v1/users/:userId/resend-invite', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(userInviteResend, 'userInviteResend', { |
||||||
|
allowedRoles: [OrgUserRoles.SUPER_ADMIN], |
||||||
|
blockApiTokenAccess: true, |
||||||
|
}) |
||||||
|
); |
||||||
|
|
||||||
|
router.post( |
||||||
|
'/api/v1/users/:userId/generate-reset-url', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(generateResetUrl, 'generateResetUrl', { |
||||||
|
allowedRoles: [OrgUserRoles.SUPER_ADMIN], |
||||||
|
blockApiTokenAccess: true, |
||||||
|
}) |
||||||
|
); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/app-settings', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(appSettingsGet, 'appSettingsGet', { |
||||||
|
allowedRoles: [OrgUserRoles.SUPER_ADMIN], |
||||||
|
blockApiTokenAccess: true, |
||||||
|
}) |
||||||
|
); |
||||||
|
|
||||||
|
router.post( |
||||||
|
'/api/v1/app-settings', |
||||||
|
metaApiMetrics, |
||||||
|
ncMetaAclMw(appSettingsSet, 'appSettingsSet', { |
||||||
|
allowedRoles: [OrgUserRoles.SUPER_ADMIN], |
||||||
|
blockApiTokenAccess: true, |
||||||
|
}) |
||||||
|
); |
||||||
|
|
||||||
|
export default router; |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue