Browse Source

Merge pull request #5269 from nocodb/refactor/backend

refactor(nocodb): backend
pull/5301/head
աɨռɢӄաօռɢ 2 years ago committed by GitHub
parent
commit
17f667c67b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      packages/nc-gui/components/account/UserList.vue
  2. 1
      packages/nc-gui/components/cell/TextArea.vue
  3. 2
      packages/nc-gui/components/dashboard/settings/AppStore.vue
  4. 14
      packages/nc-gui/components/dashboard/settings/DataSources.vue
  5. 3
      packages/nc-gui/components/smartsheet/expanded-form/index.vue
  6. 24
      packages/nc-gui/components/smartsheet/header/Menu.vue
  7. 6
      packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue
  8. 2
      packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue
  9. 2
      packages/nc-gui/components/smartsheet/toolbar/SharedViewList.vue
  10. 1
      packages/nc-gui/components/smartsheet/toolbar/SortListMenu.vue
  11. 4
      packages/nc-gui/components/tabs/auth/ApiTokenManagement.vue
  12. 5
      packages/nc-gui/components/tabs/auth/UserManagement.vue
  13. 2
      packages/nc-gui/components/webhook/Editor.vue
  14. 5
      packages/nc-gui/components/webhook/List.vue
  15. 2
      packages/nc-gui/composables/useExpandedFormStore.ts
  16. 22
      packages/nc-gui/composables/useKanbanViewStore.ts
  17. 11
      packages/nc-gui/composables/useMapViewDataStore.ts
  18. 32
      packages/nc-gui/composables/useSharedView.ts
  19. 2
      packages/nc-gui/composables/useSmartsheetStore.ts
  20. 8
      packages/nc-gui/composables/useViewColumns.ts
  21. 7
      packages/nc-gui/composables/useViewData.ts
  22. 10
      packages/nc-gui/composables/useViewFilters.ts
  23. 2
      packages/nc-gui/composables/useViewSorts.ts
  24. 5440
      packages/nocodb-sdk/src/lib/Api.ts
  25. 3
      packages/nocodb/src/lib/Noco.ts
  26. 7
      packages/nocodb/src/lib/controllers/apiToken.ctl.ts
  27. 17
      packages/nocodb/src/lib/controllers/audit.ctl.ts
  28. 14
      packages/nocodb/src/lib/controllers/base.ctl.ts
  29. 5
      packages/nocodb/src/lib/controllers/dbData/data.ctl.ts
  30. 4
      packages/nocodb/src/lib/controllers/dbData/dataAliasNested.ctl.ts
  31. 3
      packages/nocodb/src/lib/controllers/dbData/helpers.ts
  32. 37
      packages/nocodb/src/lib/controllers/filter.ctl.ts
  33. 18
      packages/nocodb/src/lib/controllers/hook.ctl.ts
  34. 91
      packages/nocodb/src/lib/controllers/hookFilter.ctl.ts
  35. 4
      packages/nocodb/src/lib/controllers/metaDiff.ctl.ts
  36. 2
      packages/nocodb/src/lib/controllers/modelVisibility.ctl.ts
  37. 2
      packages/nocodb/src/lib/controllers/orgLicense.ctl.ts
  38. 20
      packages/nocodb/src/lib/controllers/orgUser.ctl.ts
  39. 1
      packages/nocodb/src/lib/controllers/project.ctl.ts
  40. 39
      packages/nocodb/src/lib/controllers/projectUser.ctl.ts
  41. 2
      packages/nocodb/src/lib/controllers/publicControllers/publicData.ctl.ts
  42. 17
      packages/nocodb/src/lib/controllers/sort.ctl.ts
  43. 3
      packages/nocodb/src/lib/controllers/table.ctl.ts
  44. 12
      packages/nocodb/src/lib/controllers/user/initStrategies.ts
  45. 9
      packages/nocodb/src/lib/controllers/user/user.ctl.ts
  46. 1
      packages/nocodb/src/lib/controllers/util.ctl.ts
  47. 23
      packages/nocodb/src/lib/controllers/view.ctl.ts
  48. 13
      packages/nocodb/src/lib/controllers/viewColumn.ctl.ts
  49. 2
      packages/nocodb/src/lib/controllers/views/formView.ctl.ts
  50. 13
      packages/nocodb/src/lib/controllers/views/galleryView.ctl.ts
  51. 38
      packages/nocodb/src/lib/controllers/views/kanbanView.ctl.ts
  52. 2
      packages/nocodb/src/lib/db/sql-client/lib/KnexClient.ts
  53. 3
      packages/nocodb/src/lib/db/sql-client/lib/mysql/MysqlClient.ts
  54. 7
      packages/nocodb/src/lib/db/sql-client/lib/mysql/TidbClient.ts
  55. 11
      packages/nocodb/src/lib/db/sql-client/lib/mysql/VitessClient.ts
  56. 2
      packages/nocodb/src/lib/db/sql-client/lib/pg/PgClient.ts
  57. 15
      packages/nocodb/src/lib/db/sql-client/lib/snowflake/SnowflakeClient.ts
  58. 5
      packages/nocodb/src/lib/db/sql-data-mapper/index.ts
  59. 10
      packages/nocodb/src/lib/db/sql-data-mapper/lib/BaseModel.ts
  60. 21
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSql.ts
  61. 12
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts
  62. 1
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/CustomKnex.ts
  63. 6
      packages/nocodb/src/lib/db/sql-mgr/SqlMgr.ts
  64. 13
      packages/nocodb/src/lib/db/sql-mgr/code/BaseRender.ts
  65. 8
      packages/nocodb/src/lib/db/sql-mgr/code/gql-schema/xc-ts/BaseGqlXcTsSchema.ts
  66. 7
      packages/nocodb/src/lib/db/sql-mgr/code/policies/xc/ExpressXcPolicy.ts
  67. 1
      packages/nocodb/src/lib/db/sql-mgr/code/routers/xc-ts/SwaggerXc.ts
  68. 2
      packages/nocodb/src/lib/db/sql-migrator/lib/KnexMigrator.ts
  69. 8
      packages/nocodb/src/lib/db/sql-migrator/lib/KnexMigratorv2.ts
  70. 1
      packages/nocodb/src/lib/db/sql-migrator/lib/KnexMigratorv2Tans.ts
  71. 1
      packages/nocodb/src/lib/db/util/FileCollection.ts
  72. 5
      packages/nocodb/src/lib/meta/NcMetaIOImpl.ts
  73. 4
      packages/nocodb/src/lib/meta/NcMetaMgr.ts
  74. 1
      packages/nocodb/src/lib/meta/NcMetaMgrEE.ts
  75. 2
      packages/nocodb/src/lib/meta/NcMetaMgrv2.ts
  76. 4
      packages/nocodb/src/lib/meta/api/index.ts
  77. 1
      packages/nocodb/src/lib/meta/helpers/extractProjectIdAndAuthenticate.ts
  78. 11
      packages/nocodb/src/lib/models/Audit.ts
  79. 8
      packages/nocodb/src/lib/models/Filter.ts
  80. 3
      packages/nocodb/src/lib/models/FormView.ts
  81. 2
      packages/nocodb/src/lib/models/FormViewColumn.ts
  82. 24
      packages/nocodb/src/lib/models/GalleryView.ts
  83. 9
      packages/nocodb/src/lib/models/GridView.ts
  84. 2
      packages/nocodb/src/lib/models/GridViewColumn.ts
  85. 12
      packages/nocodb/src/lib/models/Hook.ts
  86. 10
      packages/nocodb/src/lib/models/HookLog.ts
  87. 2
      packages/nocodb/src/lib/models/KanbanView.ts
  88. 18
      packages/nocodb/src/lib/models/MapView.ts
  89. 9
      packages/nocodb/src/lib/models/ModelRoleVisibility.ts
  90. 2
      packages/nocodb/src/lib/models/Plugin.ts
  91. 10
      packages/nocodb/src/lib/models/Project.ts
  92. 2
      packages/nocodb/src/lib/models/Sort.ts
  93. 10
      packages/nocodb/src/lib/models/SyncLogs.ts
  94. 7
      packages/nocodb/src/lib/models/SyncSource.ts
  95. 14
      packages/nocodb/src/lib/models/View.ts
  96. 1
      packages/nocodb/src/lib/plugins/backblaze/BackblazePlugin.ts
  97. 1
      packages/nocodb/src/lib/plugins/discord/DiscordPlugin.ts
  98. 1
      packages/nocodb/src/lib/plugins/gcs/GcsPlugin.ts
  99. 1
      packages/nocodb/src/lib/plugins/linode/LinodeObjectStoragePlugin.ts
  100. 1
      packages/nocodb/src/lib/plugins/mailerSend/MailerSend.ts
  101. Some files were not shown because too many files have changed in this diff Show More

6
packages/nc-gui/components/account/UserList.vue

@ -1,6 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { Modal, message } from 'ant-design-vue' import { Modal, message } from 'ant-design-vue'
import type { RequestParams, UserType } from 'nocodb-sdk' import type { OrgUserReqType, RequestParams, UserType } from 'nocodb-sdk'
import { Role, extractSdkResponseErrorMsg, useApi, useCopy, useDashboard, useNuxtApp } from '#imports' import { Role, extractSdkResponseErrorMsg, useApi, useCopy, useDashboard, useNuxtApp } from '#imports'
import type { User } from '~/lib' import type { User } from '~/lib'
@ -42,9 +42,11 @@ const loadUsers = async (page = currentPage, limit = currentLimit) => {
query: searchText.value, query: searchText.value,
}, },
} as RequestParams) } as RequestParams)
if (!response) return if (!response) return
pagination.total = response.pageInfo.totalRows ?? 0 pagination.total = response.pageInfo.totalRows ?? 0
pagination.pageSize = 10 pagination.pageSize = 10
users = response.list as UserType[] users = response.list as UserType[]
@ -59,7 +61,7 @@ const updateRole = async (userId: string, roles: Role) => {
try { try {
await api.orgUsers.update(userId, { await api.orgUsers.update(userId, {
roles, roles,
} as unknown as UserType) } as OrgUserReqType)
message.success(t('msg.success.roleUpdated')) message.success(t('msg.success.roleUpdated'))
$e('a:org-user:role-updated', { role: roles }) $e('a:org-user:role-updated', { role: roles })

1
packages/nc-gui/components/cell/TextArea.vue

@ -45,6 +45,7 @@ const focus: VNodeRef = (el) => (el as HTMLTextAreaElement)?.focus()
<span v-else>{{ vModel }}</span> <span v-else>{{ vModel }}</span>
</template> </template>
<style> <style>
textarea:focus { textarea:focus {
box-shadow: none; box-shadow: none;

2
packages/nc-gui/components/dashboard/settings/AppStore.vue

@ -20,7 +20,7 @@ const fetchPluginApps = async () => {
apps = plugins.map((p) => ({ apps = plugins.map((p) => ({
...p, ...p,
tags: p.tags ? p.tags.split(',') : [], tags: p.tags ? p.tags.split(',') : [],
parsedInput: p.input && JSON.parse(p.input), parsedInput: p.input && JSON.parse(p.input as string),
})) }))
} catch (e: any) { } catch (e: any) {
message.error(await extractSdkResponseErrorMsg(e)) message.error(await extractSdkResponseErrorMsg(e))

14
packages/nc-gui/components/dashboard/settings/DataSources.vue

@ -19,6 +19,7 @@ const props = defineProps<Props>()
const emits = defineEmits(['update:state', 'update:reload', 'awaken']) const emits = defineEmits(['update:state', 'update:reload', 'awaken'])
const vState = useVModel(props, 'state', emits) const vState = useVModel(props, 'state', emits)
const vReload = useVModel(props, 'reload', emits) const vReload = useVModel(props, 'reload', emits)
const { $api, $e } = useNuxtApp() const { $api, $e } = useNuxtApp()
@ -27,10 +28,15 @@ const { loadProject } = projectStore
const { project } = storeToRefs(projectStore) const { project } = storeToRefs(projectStore)
let sources = $ref<BaseType[]>([]) let sources = $ref<BaseType[]>([])
let activeBaseId = $ref('') let activeBaseId = $ref('')
let metadiffbases = $ref<string[]>([]) let metadiffbases = $ref<string[]>([])
let clientType = $ref<ClientType>(ClientType.MYSQL) let clientType = $ref<ClientType>(ClientType.MYSQL)
let isReloading = $ref(false) let isReloading = $ref(false)
let forceAwakened = $ref(false) let forceAwakened = $ref(false)
async function loadBases() { async function loadBases() {
@ -40,8 +46,8 @@ async function loadBases() {
isReloading = true isReloading = true
vReload.value = true vReload.value = true
const baseList = await $api.base.list(project.value?.id) const baseList = await $api.base.list(project.value?.id)
if (baseList.bases.list && baseList.bases.list.length) { if (baseList.list && baseList.list.length) {
sources = baseList.bases.list sources = baseList.list
} }
} catch (e) { } catch (e) {
console.error(e) console.error(e)
@ -247,7 +253,7 @@ watch(
@click="baseAction(sources[0].id, DataSourcesSubTab.Metadata)" @click="baseAction(sources[0].id, DataSourcesSubTab.Metadata)"
> >
<div class="flex items-center gap-2 text-gray-600 font-light"> <div class="flex items-center gap-2 text-gray-600 font-light">
<a-tooltip v-if="metadiffbases.includes(sources[0].id as string)"> <a-tooltip v-if="metadiffbases.includes(sources[0].id)">
<template #title>Out of sync</template> <template #title>Out of sync</template>
<MdiDatabaseAlert class="text-lg group-hover:text-accent text-primary" /> <MdiDatabaseAlert class="text-lg group-hover:text-accent text-primary" />
</a-tooltip> </a-tooltip>
@ -316,7 +322,7 @@ watch(
@click="baseAction(base.id, DataSourcesSubTab.Metadata)" @click="baseAction(base.id, DataSourcesSubTab.Metadata)"
> >
<div class="flex items-center gap-2 text-gray-600 font-light"> <div class="flex items-center gap-2 text-gray-600 font-light">
<a-tooltip v-if="metadiffbases.includes(base.id as string)"> <a-tooltip v-if="metadiffbases.includes(base.id)">
<template #title>Out of sync</template> <template #title>Out of sync</template>
<MdiDatabaseAlert class="text-lg group-hover:text-accent text-primary" /> <MdiDatabaseAlert class="text-lg group-hover:text-accent text-primary" />
</a-tooltip> </a-tooltip>

3
packages/nc-gui/components/smartsheet/expanded-form/index.vue

@ -333,8 +333,7 @@ export default {
:ref="i ? null : (el) => (cellWrapperEl = el)" :ref="i ? null : (el) => (cellWrapperEl = el)"
class="!bg-white rounded px-1 min-h-[35px] flex items-center mt-2 relative" class="!bg-white rounded px-1 min-h-[35px] flex items-center mt-2 relative"
> >
<LazySmartsheetVirtualCell v-if="isVirtualCol(col)" v-model="row.row[col.title]" :row="row" <LazySmartsheetVirtualCell v-if="isVirtualCol(col)" v-model="row.row[col.title]" :row="row" :column="col" />
:column="col" />
<LazySmartsheetCell <LazySmartsheetCell
v-else v-else

24
packages/nc-gui/components/smartsheet/header/Menu.vue

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { LinkToAnotherRecordType } from 'nocodb-sdk' import type { ColumnReqType, LinkToAnotherRecordType } from 'nocodb-sdk'
import { RelationTypes, UITypes } from 'nocodb-sdk' import { RelationTypes, UITypes } from 'nocodb-sdk'
import { import {
ActiveViewInj, ActiveViewInj,
@ -9,8 +9,6 @@ import {
Modal, Modal,
ReloadViewDataHookInj, ReloadViewDataHookInj,
SmartsheetStoreEvents, SmartsheetStoreEvents,
defineEmits,
defineProps,
extractSdkResponseErrorMsg, extractSdkResponseErrorMsg,
getUniqueColumnName, getUniqueColumnName,
inject, inject,
@ -62,7 +60,7 @@ const deleteColumn = () =>
} }
$e('a:column:delete') $e('a:column:delete')
} catch (e) { } catch (e: any) {
message.error(await extractSdkResponseErrorMsg(e)) message.error(await extractSdkResponseErrorMsg(e))
} }
}, },
@ -95,7 +93,7 @@ const sortByColumn = async (direction: 'asc' | 'desc') => {
}) })
eventBus.emit(SmartsheetStoreEvents.SORT_RELOAD) eventBus.emit(SmartsheetStoreEvents.SORT_RELOAD)
reloadDataHook?.trigger() reloadDataHook?.trigger()
} catch (e) { } catch (e: any) {
message.error(await extractSdkResponseErrorMsg(e)) message.error(await extractSdkResponseErrorMsg(e))
} }
} }
@ -107,7 +105,7 @@ const duplicateColumn = async () => {
const duplicateColumnName = getUniqueColumnName(`${column!.value.title}_copy`, meta!.value!.columns!) const duplicateColumnName = getUniqueColumnName(`${column!.value.title}_copy`, meta!.value!.columns!)
// construct column create payload // construct column create payload
switch (column.value.uidt) { switch (column?.value.uidt) {
case UITypes.LinkToAnotherRecord: case UITypes.LinkToAnotherRecord:
case UITypes.Lookup: case UITypes.Lookup:
case UITypes.Rollup: case UITypes.Rollup:
@ -144,14 +142,14 @@ const duplicateColumn = async () => {
} }
try { try {
const gridViewColumnList = await $api.dbViewColumn.list(view.value?.id as string) const gridViewColumnList = (await $api.dbViewColumn.list(view.value?.id as string)).list
const currentColumnIndex = gridViewColumnList.findIndex((f) => f.fk_column_id === column!.value.id) const currentColumnIndex = gridViewColumnList.findIndex((f) => f.fk_column_id === column!.value.id)
let newColumnOrder let newColumnOrder
if (currentColumnIndex === gridViewColumnList.length - 1) { if (currentColumnIndex === gridViewColumnList.length - 1) {
newColumnOrder = gridViewColumnList[currentColumnIndex].order + 1 newColumnOrder = gridViewColumnList[currentColumnIndex].order! + 1
} else { } else {
newColumnOrder = (gridViewColumnList[currentColumnIndex].order! + gridViewColumnList[currentColumnIndex + 1]?.order) / 2 newColumnOrder = (gridViewColumnList[currentColumnIndex].order! + gridViewColumnList[currentColumnIndex + 1].order!) / 2
} }
await $api.dbTableColumn.create(meta!.value!.id!, { await $api.dbTableColumn.create(meta!.value!.id!, {
@ -161,7 +159,7 @@ const duplicateColumn = async () => {
order: newColumnOrder, order: newColumnOrder,
view_id: view.value?.id as string, view_id: view.value?.id as string,
}, },
}) } as ColumnReqType)
await getMeta(meta!.value!.id!, true) await getMeta(meta!.value!.id!, true)
eventBus.emit(SmartsheetStoreEvents.FIELD_RELOAD) eventBus.emit(SmartsheetStoreEvents.FIELD_RELOAD)
@ -175,7 +173,7 @@ const duplicateColumn = async () => {
// add column before or after current column // add column before or after current column
const addColumn = async (before = false) => { const addColumn = async (before = false) => {
const gridViewColumnList = await $api.dbViewColumn.list(view.value?.id as string) const gridViewColumnList = (await $api.dbViewColumn.list(view.value?.id as string)).list
const currentColumnIndex = gridViewColumnList.findIndex((f) => f.fk_column_id === column!.value.id) const currentColumnIndex = gridViewColumnList.findIndex((f) => f.fk_column_id === column!.value.id)
@ -204,11 +202,11 @@ const addColumn = async (before = false) => {
// hide the field in view // hide the field in view
const hideField = async () => { const hideField = async () => {
const gridViewColumnList = await $api.dbViewColumn.list(view.value?.id as string) const gridViewColumnList = (await $api.dbViewColumn.list(view.value?.id as string)).list
const currentColumn = gridViewColumnList.find((f) => f.fk_column_id === column!.value.id) const currentColumn = gridViewColumnList.find((f) => f.fk_column_id === column!.value.id)
await $api.dbViewColumn.update(view.value.id, currentColumn.id, { show: false }) await $api.dbViewColumn.update(view.value!.id!, currentColumn!.id!, { show: false })
eventBus.emit(SmartsheetStoreEvents.FIELD_RELOAD) eventBus.emit(SmartsheetStoreEvents.FIELD_RELOAD)
} }
</script> </script>

6
packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue

@ -199,7 +199,11 @@ defineExpose({
<template> <template>
<div <div
class="p-4 menu-filter-dropdown bg-gray-50 !border" class="p-4 menu-filter-dropdown bg-gray-50 !border"
:class="{ 'min-w-[430px]': filters.length, 'shadow max-h-[max(80vh,500px)] overflow-auto': !nested, 'border-1 w-full': nested }" :class="{
'min-w-[430px]': filters.length,
'shadow max-h-[max(80vh,500px)] overflow-auto': !nested,
'border-1 w-full': nested,
}"
> >
<div <div
v-if="filters && filters.length" v-if="filters && filters.length"

2
packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue

@ -125,13 +125,11 @@ const coverImageColumnId = computed({
) { ) {
if (activeView.value?.type === ViewTypes.GALLERY) { if (activeView.value?.type === ViewTypes.GALLERY) {
await $api.dbView.galleryUpdate(activeView.value?.id, { await $api.dbView.galleryUpdate(activeView.value?.id, {
...activeView.value?.view,
fk_cover_image_col_id: val, fk_cover_image_col_id: val,
}) })
;(activeView.value.view as GalleryType).fk_cover_image_col_id = val ;(activeView.value.view as GalleryType).fk_cover_image_col_id = val
} else if (activeView.value?.type === ViewTypes.KANBAN) { } else if (activeView.value?.type === ViewTypes.KANBAN) {
await $api.dbView.kanbanUpdate(activeView.value?.id, { await $api.dbView.kanbanUpdate(activeView.value?.id, {
...activeView.value?.view,
fk_cover_image_col_id: val, fk_cover_image_col_id: val,
}) })
;(activeView.value.view as KanbanType).fk_cover_image_col_id = val ;(activeView.value.view as KanbanType).fk_cover_image_col_id = val

2
packages/nc-gui/components/smartsheet/toolbar/SharedViewList.vue

@ -34,7 +34,7 @@ const { dashboardUrl } = useDashboard()
const sharedViewList = ref<SharedViewType[]>() const sharedViewList = ref<SharedViewType[]>()
const loadSharedViewsList = async () => { const loadSharedViewsList = async () => {
sharedViewList.value = await $api.dbViewShare.list(meta.value?.id as string) sharedViewList.value = (await $api.dbViewShare.list(meta.value?.id as string)).list as SharedViewType[]
// todo: show active view in list separately // todo: show active view in list separately
// const index = sharedViewList.value.findIndex((v) => { // const index = sharedViewList.value.findIndex((v) => {

1
packages/nc-gui/components/smartsheet/toolbar/SortListMenu.vue

@ -30,7 +30,6 @@ const removeIcon = ref<HTMLElement>()
const addSort = () => { const addSort = () => {
_addSort() _addSort()
nextTick(() => { nextTick(() => {
console.log(removeIcon.value)
removeIcon.value?.[removeIcon.value?.length - 1]?.$el?.scrollIntoView() removeIcon.value?.[removeIcon.value?.length - 1]?.$el?.scrollIntoView()
}) })
} }

4
packages/nc-gui/components/tabs/auth/ApiTokenManagement.vue

@ -25,7 +25,7 @@ let selectedTokenData = $ref<ApiToken>({})
const loadApiTokens = async () => { const loadApiTokens = async () => {
if (!project?.id) return if (!project?.id) return
tokensInfo = await $api.apiToken.list(project.id) tokensInfo = (await $api.apiToken.list(project.id)).list
} }
const openNewTokenModal = () => { const openNewTokenModal = () => {
@ -40,7 +40,7 @@ const copyToken = async (token: string | undefined) => {
await copy(token) await copy(token)
// Copied to clipboard // Copied to clipboard
message.info(t('msg.info.copiedToClipboard')) message.info(t('msg.info.copiedToClipboard'))
} catch (e) { } catch (e: any) {
message.error(e.message) message.error(e.message)
} }
$e('c:api-token:copy') $e('c:api-token:copy')

5
packages/nc-gui/components/tabs/auth/UserManagement.vue

@ -77,6 +77,11 @@ const inviteUser = async (user: User) => {
try { try {
if (!project.value?.id) return if (!project.value?.id) return
if (!user.roles) {
// mark it as editor by default
user.roles = 'editor'
}
await api.auth.projectUserAdd(project.value.id, user) await api.auth.projectUserAdd(project.value.id, user)
// Successfully added user to project // Successfully added user to project

2
packages/nc-gui/components/webhook/Editor.vue

@ -659,9 +659,9 @@ onMounted(loadPluginList)
</a-checkbox> </a-checkbox>
<LazySmartsheetToolbarColumnFilter <LazySmartsheetToolbarColumnFilter
class="mt-4"
v-if="hook.condition" v-if="hook.condition"
ref="filterRef" ref="filterRef"
class="mt-4"
:auto-save="false" :auto-save="false"
:show-loading="false" :show-loading="false"
:hook-id="hook.id" :hook-id="hook.id"

5
packages/nc-gui/components/webhook/List.vue

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { HookType } from 'nocodb-sdk'
import { MetaInj, extractSdkResponseErrorMsg, inject, message, onMounted, ref, useI18n, useNuxtApp } from '#imports' import { MetaInj, extractSdkResponseErrorMsg, inject, message, onMounted, ref, useI18n, useNuxtApp } from '#imports'
const emit = defineEmits(['edit', 'add']) const emit = defineEmits(['edit', 'add'])
@ -13,9 +14,9 @@ const meta = inject(MetaInj, ref())
async function loadHooksList() { async function loadHooksList() {
try { try {
const hookList = (await $api.dbTableWebhook.list(meta.value?.id as string)).list as Record<string, any>[] const hookList = (await $api.dbTableWebhook.list(meta.value?.id as string)).list as HookType[]
hooks.value = hookList.map((hook) => { hooks.value = hookList.map((hook) => {
hook.notification = hook.notification && JSON.parse(hook.notification) hook.notification = typeof hook.notification === 'string' ? JSON.parse(hook.notification) : hook.notification
return hook return hook
}) })
} catch (e: any) { } catch (e: any) {

2
packages/nc-gui/composables/useExpandedFormStore.ts

@ -104,7 +104,7 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m
fk_model_id: meta.value.id as string, fk_model_id: meta.value.id as string,
comments_only: commentsOnly.value, comments_only: commentsOnly.value,
}) })
)?.reverse?.() || [] ).list?.reverse?.() || []
} }
const isYou = (email: string) => { const isYou = (email: string) => {

22
packages/nc-gui/composables/useKanbanViewStore.ts

@ -153,7 +153,7 @@ const [useProvideKanbanViewStore, useKanbanViewStore] = useInjectionState(
) )
} }
for (const data of groupData) { for (const data of groupData ?? []) {
const key = data.key const key = data.key
formattedData.value.set(key, formatData(data.value.list)) formattedData.value.set(key, formatData(data.value.list))
countByStack.value.set(key, data.value.pageInfo.totalRows || 0) countByStack.value.set(key, data.value.pageInfo.totalRows || 0)
@ -167,17 +167,26 @@ const [useProvideKanbanViewStore, useKanbanViewStore] = useInjectionState(
where = `(${groupingField.value},is,null)` where = `(${groupingField.value},is,null)`
} }
if (xWhere.value) {
where = `${where} and ${xWhere.value}`
}
const response = !isPublic.value const response = !isPublic.value
? await api.dbViewRow.list('noco', project.value.id!, meta.value!.id!, viewMeta.value!.id!, { ? await api.dbViewRow.list('noco', project.value.id!, meta.value!.id!, viewMeta.value!.id!, {
...{ where: xWhere.value },
...params, ...params,
...(isUIAllowed('sortSync') ? {} : { sortArrJson: JSON.stringify(sorts.value) }), ...(isUIAllowed('sortSync') ? {} : { sortArrJson: JSON.stringify(sorts.value) }),
...(isUIAllowed('filterSync') ? {} : { filterArrJson: JSON.stringify(nestedFilters.value) }), ...(isUIAllowed('filterSync') ? {} : { filterArrJson: JSON.stringify(nestedFilters.value) }),
where, where,
}) })
: await fetchSharedViewData({ sortsArr: sorts.value, filtersArr: nestedFilters.value, offset: params.offset }) : await fetchSharedViewData({
...params,
sortsArr: sorts.value,
filtersArr: nestedFilters.value,
offset: params.offset,
where,
})
formattedData.value.set(stackTitle, [...formattedData.value.get(stackTitle)!, ...formatData(response.list)]) formattedData.value.set(stackTitle, [...formattedData.value.get(stackTitle)!, ...formatData(response!.list!)])
} }
async function loadKanbanMeta() { async function loadKanbanMeta() {
@ -299,10 +308,7 @@ const [useProvideKanbanViewStore, useKanbanViewStore] = useInjectionState(
async function updateKanbanMeta(updateObj: Partial<KanbanType>) { async function updateKanbanMeta(updateObj: Partial<KanbanType>) {
if (!viewMeta?.value?.id || !isUIAllowed('xcDatatableEditable')) return if (!viewMeta?.value?.id || !isUIAllowed('xcDatatableEditable')) return
await $api.dbView.kanbanUpdate(viewMeta.value.id, { await $api.dbView.kanbanUpdate(viewMeta.value.id, updateObj)
...kanbanMetaData.value,
...updateObj,
})
} }
async function insertRow(row: Record<string, any>, rowIndex = formattedData.value.get(null)!.length) { async function insertRow(row: Record<string, any>, rowIndex = formattedData.value.get(null)!.length) {

11
packages/nc-gui/composables/useMapViewDataStore.ts

@ -23,7 +23,7 @@ const formatData = (list: Record<string, any>[]) =>
const [useProvideMapViewStore, useMapViewStore] = useInjectionState( const [useProvideMapViewStore, useMapViewStore] = useInjectionState(
( (
meta: Ref<TableType | undefined>, meta: Ref<TableType | undefined>,
viewMeta: Ref<ViewType | MapType | undefined> | ComputedRef<(ViewType & { id: string }) | undefined>, viewMeta: Ref<(ViewType | MapType | undefined) & { id: string }> | ComputedRef<(ViewType & { id: string }) | undefined>,
shared = false, shared = false,
where?: ComputedRef<string | undefined>, where?: ComputedRef<string | undefined>,
) => { ) => {
@ -88,15 +88,12 @@ const [useProvideMapViewStore, useMapViewStore] = useInjectionState(
}) })
: await fetchSharedViewData({ sortsArr: sorts.value, filtersArr: nestedFilters.value }) : await fetchSharedViewData({ sortsArr: sorts.value, filtersArr: nestedFilters.value })
formattedData.value = formatData(res.list) formattedData.value = formatData(res!.list)
} }
async function updateMapMeta(updateObj: Partial<MapType>) { async function updateMapMeta(updateObj: Partial<MapType>) {
if (!viewMeta?.value?.id || !isUIAllowed('xcDatatableEditable')) return if (!viewMeta?.value?.id || !isUIAllowed('xcDatatableEditable')) return
await $api.dbView.mapUpdate(viewMeta.value.id, { await $api.dbView.mapUpdate(viewMeta.value.id, updateObj)
...mapMetaData.value,
...updateObj,
})
} }
const { getMeta } = useMetas() const { getMeta } = useMetas()
@ -107,7 +104,7 @@ const [useProvideMapViewStore, useMapViewStore] = useInjectionState(
{ {
metaValue = meta.value, metaValue = meta.value,
viewMetaValue = viewMeta.value, viewMetaValue = viewMeta.value,
}: { metaValue?: MapType; viewMetaValue?: ViewType | MapType } = {}, }: { metaValue?: MapType & { id: string }; viewMetaValue?: (ViewType | MapType) & { id: string } } = {},
) { ) {
const row = currentRow.row const row = currentRow.row
if (currentRow.rowMeta) currentRow.rowMeta.saving = true if (currentRow.rowMeta) currentRow.rowMeta.saving = true

32
packages/nc-gui/composables/useSharedView.ts

@ -56,7 +56,7 @@ export function useSharedView() {
} }
if (localPassword) password.value = localPassword if (localPassword) password.value = localPassword
sharedView.value = { title: '', ...viewMeta } sharedView.value = { title: '', ...viewMeta } as ViewType
meta.value = { ...viewMeta.model } meta.value = { ...viewMeta.model }
let order = 1 let order = 1
@ -83,29 +83,34 @@ export function useSharedView() {
Object.keys(relatedMetas).forEach((key) => setMeta(relatedMetas[key])) Object.keys(relatedMetas).forEach((key) => setMeta(relatedMetas[key]))
} }
const fetchSharedViewData = async ({ const fetchSharedViewData = async (param: {
sortsArr,
filtersArr,
offset,
}: {
sortsArr: SortType[] sortsArr: SortType[]
filtersArr: FilterType[] filtersArr: FilterType[]
fields?: any[]
sort?: any[]
where?: string
/** Query params for nested data */
nested?: any
offset?: number offset?: number
}) => { }) => {
if (!sharedView.value) return if (!sharedView.value)
return {
list: [],
pageInfo: {},
}
if (!offset) { if (!param.offset) {
const page = paginationData.value.page || 1 const page = paginationData.value.page || 1
const pageSize = paginationData.value.pageSize || appInfoDefaultLimit const pageSize = paginationData.value.pageSize || appInfoDefaultLimit
offset = (page - 1) * pageSize param.offset = (page - 1) * pageSize
} }
const { data } = await $api.public.dataList( return await $api.public.dataList(
sharedView.value.uuid!, sharedView.value.uuid!,
{ {
offset, ...param,
filterArrJson: JSON.stringify(filtersArr ?? nestedFilters.value), filterArrJson: JSON.stringify(param.filtersArr ?? nestedFilters.value),
sortArrJson: JSON.stringify(sortsArr ?? sorts.value), sortArrJson: JSON.stringify(param.sortsArr ?? sorts.value),
} as any, } as any,
{ {
headers: { headers: {
@ -113,7 +118,6 @@ export function useSharedView() {
}, },
}, },
) )
return data
} }
const fetchSharedViewGroupedData = async ( const fetchSharedViewGroupedData = async (

2
packages/nc-gui/composables/useSmartsheetStore.ts

@ -63,7 +63,7 @@ const [useProvideSmartsheetStore, useSmartsheetStore] = useInjectionState(
}) })
const isSqlView = computed(() => (meta.value as TableType)?.type === 'view') const isSqlView = computed(() => (meta.value as TableType)?.type === 'view')
const sorts = ref<Required<SortType>[]>((unref(initialSorts) as Required<SortType>[]) ?? []) const sorts = ref<SortType[]>(unref(initialSorts) ?? [])
const nestedFilters = ref<FilterType[]>(unref(initialFilters) ?? []) const nestedFilters = ref<FilterType[]>(unref(initialFilters) ?? [])
return { return {

8
packages/nc-gui/composables/useViewColumns.ts

@ -35,13 +35,13 @@ export function useViewColumns(
const metaColumnById = computed<Record<string, ColumnType>>(() => { const metaColumnById = computed<Record<string, ColumnType>>(() => {
if (!meta.value?.columns) return {} if (!meta.value?.columns) return {}
return meta.value.columns.reduce( return (meta.value.columns as ColumnType[]).reduce(
(acc, curr) => ({ (acc, curr) => ({
...acc, ...acc,
[curr.id!]: curr, [curr.id!]: curr,
}), }),
{}, {},
) ) as Record<string, ColumnType>
}) })
const loadViewColumns = async () => { const loadViewColumns = async () => {
@ -50,7 +50,7 @@ export function useViewColumns(
let order = 1 let order = 1
if (view.value?.id) { if (view.value?.id) {
const data = (isPublic.value ? meta.value?.columns : await $api.dbViewColumn.list(view.value.id)) as any[] const data = (isPublic.value ? meta.value?.columns : (await $api.dbViewColumn.list(view.value.id)).list) as any[]
const fieldById = data.reduce<Record<string, any>>((acc, curr) => { const fieldById = data.reduce<Record<string, any>>((acc, curr) => {
curr.show = !!curr.show curr.show = !!curr.show
@ -162,7 +162,7 @@ export function useViewColumns(
const showSystemFields = computed({ const showSystemFields = computed({
get() { get() {
return view.value?.show_system_fields || false return (view.value?.show_system_fields as boolean) || false
}, },
set(v: boolean) { set(v: boolean) {
if (view?.value?.id) { if (view?.value?.id) {

7
packages/nc-gui/composables/useViewData.ts

@ -27,7 +27,7 @@ import {
} from '#imports' } from '#imports'
import type { Row } from '~/lib' import type { Row } from '~/lib'
const formatData = (list: Row[]) => const formatData = (list: Record<string, any>[]) =>
list.map((row) => ({ list.map((row) => ({
row: { ...row }, row: { ...row },
oldRow: { ...row }, oldRow: { ...row },
@ -59,7 +59,7 @@ export function useViewData(
const _paginationData = ref<PaginatedType>({ page: 1, pageSize: appInfoDefaultLimit }) const _paginationData = ref<PaginatedType>({ page: 1, pageSize: appInfoDefaultLimit })
const aggCommentCount = ref<{ row_id: string; count: number }[]>([]) const aggCommentCount = ref<{ row_id: string; count: string }[]>([])
const galleryData = ref<GalleryType>() const galleryData = ref<GalleryType>()
@ -183,7 +183,7 @@ export function useViewData(
for (const row of formattedData.value) { for (const row of formattedData.value) {
const id = extractPkFromRow(row.row, meta.value?.columns as ColumnType[]) const id = extractPkFromRow(row.row, meta.value?.columns as ColumnType[])
row.rowMeta.commentCount = aggCommentCount.value?.find((c: Record<string, any>) => c.row_id === id)?.count || 0 row.rowMeta.commentCount = +(aggCommentCount.value?.find((c: Record<string, any>) => c.row_id === id)?.count || 0)
} }
} }
@ -198,6 +198,7 @@ export function useViewData(
where: where?.value, where: where?.value,
}) })
: await fetchSharedViewData({ sortsArr: sorts.value, filtersArr: nestedFilters.value }) : await fetchSharedViewData({ sortsArr: sorts.value, filtersArr: nestedFilters.value })
formattedData.value = formatData(response.list) formattedData.value = formatData(response.list)
paginationData.value = response.pageInfo paginationData.value = response.pageInfo

10
packages/nc-gui/composables/useViewFilters.ts

@ -162,6 +162,7 @@ export function useViewFilters(
const placeholderFilter = (): Filter => { const placeholderFilter = (): Filter => {
return { return {
// TODO: fix type
comparison_op: comparisonOpList(options.value?.[0].uidt as UITypes).filter((compOp) => comparison_op: comparisonOpList(options.value?.[0].uidt as UITypes).filter((compOp) =>
isComparisonOpAllowed({ fk_column_id: options.value?.[0].id }, compOp), isComparisonOpAllowed({ fk_column_id: options.value?.[0].id }, compOp),
)?.[0].value, )?.[0].value,
@ -181,16 +182,15 @@ export function useViewFilters(
try { try {
if (hookId) { if (hookId) {
if (parentId) { if (parentId) {
filters.value = await $api.dbTableFilter.childrenRead(parentId) filters.value = (await $api.dbTableFilter.childrenRead(parentId)).list as Filter[]
} else { } else {
// todo: return type is incorrect filters.value = (await $api.dbTableWebhookFilter.read(hookId!)).list as Filter[]
filters.value = (await $api.dbTableWebhookFilter.read(hookId!)) as unknown as Filter[]
} }
} else { } else {
if (parentId) { if (parentId) {
filters.value = await $api.dbTableFilter.childrenRead(parentId) filters.value = (await $api.dbTableFilter.childrenRead(parentId)).list as Filter[]
} else { } else {
filters.value = await $api.dbTableFilter.read(view.value!.id!) filters.value = (await $api.dbTableFilter.read(view.value!.id!)).list as Filter[]
} }
} }
} catch (e: any) { } catch (e: any) {

2
packages/nc-gui/composables/useViewSorts.ts

@ -50,7 +50,7 @@ export function useViewSorts(view: Ref<ViewType | undefined>, reloadData?: () =>
} }
} }
if (!view?.value) return if (!view?.value) return
sorts.value = (await $api.dbTableSort.list(view.value!.id!)).sorts?.list || [] sorts.value = (await $api.dbTableSort.list(view.value!.id!)).list as SortType[]
} catch (e: any) { } catch (e: any) {
console.error(e) console.error(e)
message.error(await extractSdkResponseErrorMsg(e)) message.error(await extractSdkResponseErrorMsg(e))

5440
packages/nocodb-sdk/src/lib/Api.ts

File diff suppressed because it is too large Load Diff

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

@ -2,7 +2,6 @@
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { promisify } from 'util'; import { promisify } from 'util';
import * as Sentry from '@sentry/node'; import * as Sentry from '@sentry/node';
import bodyParser from 'body-parser'; import bodyParser from 'body-parser';
import clear from 'clear'; import clear from 'clear';
@ -14,14 +13,12 @@ import morgan from 'morgan';
import NcToolGui from 'nc-lib-gui'; import NcToolGui from 'nc-lib-gui';
import requestIp from 'request-ip'; import requestIp from 'request-ip';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { T } from 'nc-help'; import { T } from 'nc-help';
import mkdirp from 'mkdirp'; import mkdirp from 'mkdirp';
import { NC_LICENSE_KEY } from './constants'; import { NC_LICENSE_KEY } from './constants';
import Migrator from './db/sql-migrator/lib/KnexMigrator'; import Migrator from './db/sql-migrator/lib/KnexMigrator';
import Store from './models/Store'; import Store from './models/Store';
import NcConfigFactory from './utils/NcConfigFactory'; import NcConfigFactory from './utils/NcConfigFactory';
import NcProjectBuilderCE from './v1-legacy/NcProjectBuilder'; import NcProjectBuilderCE from './v1-legacy/NcProjectBuilder';
import NcProjectBuilderEE from './v1-legacy/NcProjectBuilderEE'; import NcProjectBuilderEE from './v1-legacy/NcProjectBuilderEE';
import NcMetaImplCE from './meta/NcMetaIOImpl'; import NcMetaImplCE from './meta/NcMetaIOImpl';

7
packages/nocodb/src/lib/controllers/apiToken.ctl.ts

@ -1,11 +1,16 @@
import { Router } from 'express'; import { Router } from 'express';
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 { PagedResponseImpl } from '../meta/helpers/PagedResponse';
import { apiTokenService } from '../services'; import { apiTokenService } from '../services';
import type { Request, Response } from 'express'; import type { Request, Response } from 'express';
export async function apiTokenList(req: Request, res: Response) { export async function apiTokenList(req: Request, res: Response) {
res.json(await apiTokenService.apiTokenList({ userId: req['user'].id })); res.json(
new PagedResponseImpl(
await apiTokenService.apiTokenList({ userId: req['user'].id })
)
);
} }
export async function apiTokenCreate(req: Request, res: Response) { export async function apiTokenCreate(req: Request, res: Response) {

17
packages/nocodb/src/lib/controllers/audit.ctl.ts

@ -25,13 +25,18 @@ export async function auditRowUpdate(req: Request<any, any>, res) {
} }
export async function commentList(req: Request<any, any, any>, res) { export async function commentList(req: Request<any, any, any>, res) {
res.json(await Audit.commentsList(req.query)); res.json(
new PagedResponseImpl(await auditService.commentList({ query: req.query }))
);
} }
export async function auditList(req: Request, res: Response) { export async function auditList(req: Request, res: Response) {
res.json( res.json(
new PagedResponseImpl( new PagedResponseImpl(
await Audit.projectAuditList(req.params.projectId, req.query), await auditService.auditList({
query: req.query,
projectId: req.params.projectId,
}),
{ {
count: await Audit.projectAuditCount(req.params.projectId), count: await Audit.projectAuditCount(req.params.projectId),
...req.query, ...req.query,
@ -42,7 +47,7 @@ export async function auditList(req: Request, res: Response) {
export async function commentsCount(req: Request<any, any, any>, res) { export async function commentsCount(req: Request<any, any, any>, res) {
res.json( res.json(
await Audit.commentsCount({ await auditService.commentsCount({
fk_model_id: req.query.fk_model_id as string, fk_model_id: req.query.fk_model_id as string,
ids: req.query.ids as string[], ids: req.query.ids as string[],
}) })
@ -50,24 +55,30 @@ export async function commentsCount(req: Request<any, any, any>, res) {
} }
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });
router.get( router.get(
'/api/v1/db/meta/audits/comments', '/api/v1/db/meta/audits/comments',
ncMetaAclMw(commentList, 'commentList') ncMetaAclMw(commentList, 'commentList')
); );
router.post( router.post(
'/api/v1/db/meta/audits/comments', '/api/v1/db/meta/audits/comments',
ncMetaAclMw(commentRow, 'commentRow') ncMetaAclMw(commentRow, 'commentRow')
); );
router.post( router.post(
'/api/v1/db/meta/audits/rows/:rowId/update', '/api/v1/db/meta/audits/rows/:rowId/update',
ncMetaAclMw(auditRowUpdate, 'auditRowUpdate') ncMetaAclMw(auditRowUpdate, 'auditRowUpdate')
); );
router.get( router.get(
'/api/v1/db/meta/audits/comments/count', '/api/v1/db/meta/audits/comments/count',
ncMetaAclMw(commentsCount, 'commentsCount') ncMetaAclMw(commentsCount, 'commentsCount')
); );
router.get( router.get(
'/api/v1/db/meta/projects/:projectId/audits', '/api/v1/db/meta/projects/:projectId/audits',
ncMetaAclMw(auditList, 'auditList') ncMetaAclMw(auditList, 'auditList')
); );
export default router; export default router;

14
packages/nocodb/src/lib/controllers/base.ctl.ts

@ -1,7 +1,6 @@
import { PagedResponseImpl } from '../meta/helpers/PagedResponse'; import { PagedResponseImpl } from '../meta/helpers/PagedResponse';
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 { baseService } from '../services'; import { baseService } from '../services';
import type Base from '../models/Base'; import type Base from '../models/Base';
import type { BaseListType } from 'nocodb-sdk'; import type { BaseListType } from 'nocodb-sdk';
@ -32,13 +31,12 @@ async function baseList(
projectId: req.params.projectId, projectId: req.params.projectId,
}); });
res // todo: pagination res.json(
.json({ new PagedResponseImpl(bases, {
bases: new PagedResponseImpl(bases, { count: bases.length,
count: bases.length, limit: bases.length,
limit: bases.length, })
}), );
});
} }
export async function baseDelete( export async function baseDelete(

5
packages/nocodb/src/lib/controllers/dbData/data.ctl.ts

@ -118,10 +118,9 @@ async function relationDataDelete(req, res) {
cookie: req, cookie: req,
}); });
res.json({ msg: 'success' }); res.json({ msg: 'The relation data has been deleted successfully' });
} }
//@ts-ignore
async function relationDataAdd(req, res) { async function relationDataAdd(req, res) {
await dataService.relationDataAdd({ await dataService.relationDataAdd({
viewId: req.params.viewId, viewId: req.params.viewId,
@ -131,7 +130,7 @@ async function relationDataAdd(req, res) {
cookie: req, cookie: req,
}); });
res.json({ msg: 'success' }); res.json({ msg: 'The relation data has been created successfully' });
} }
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });

4
packages/nocodb/src/lib/controllers/dbData/dataAliasNested.ctl.ts

@ -77,7 +77,7 @@ async function relationDataRemove(req, res) {
refRowId: req.params.refRowId, refRowId: req.params.refRowId,
}); });
res.json({ msg: 'success' }); res.json({ msg: 'The relation data has been deleted successfully' });
} }
//@ts-ignore //@ts-ignore
@ -92,7 +92,7 @@ async function relationDataAdd(req, res) {
refRowId: req.params.refRowId, refRowId: req.params.refRowId,
}); });
res.json({ msg: 'success' }); res.json({ msg: 'The relation data has been created successfully' });
} }
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });

3
packages/nocodb/src/lib/controllers/dbData/helpers.ts

@ -7,13 +7,12 @@ import Model from '../../models/Model';
import View from '../../models/View'; import View from '../../models/View';
import Base from '../../models/Base'; import Base from '../../models/Base';
import NcConnectionMgrv2 from '../../utils/common/NcConnectionMgrv2'; import NcConnectionMgrv2 from '../../utils/common/NcConnectionMgrv2';
import Column from '../../models/Column'; import Column from '../../models/Column';
import { dataService } from '../../services'; import { dataService } from '../../services';
import type LookupColumn from '../../models/LookupColumn'; import type LookupColumn from '../../models/LookupColumn';
import type LinkToAnotherRecordColumn from '../../models/LinkToAnotherRecordColumn'; import type LinkToAnotherRecordColumn from '../../models/LinkToAnotherRecordColumn';
import type { Request } from 'express'; import type { Request } from 'express';
export async function getViewAndModelFromRequestByAliasOrId( export async function getViewAndModelFromRequestByAliasOrId(
req: req:
| Request<{ projectName: string; tableName: string; viewName?: string }> | Request<{ projectName: string; tableName: string; viewName?: string }>

37
packages/nocodb/src/lib/controllers/filter.ctl.ts

@ -1,32 +1,33 @@
import { Router } from 'express'; import { Router } from 'express';
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 { PagedResponseImpl } from '../meta/helpers/PagedResponse';
import { filterService } from '../services'; import { filterService } from '../services';
import type { FilterReqType } from 'nocodb-sdk'; import type { FilterListType, FilterReqType } from 'nocodb-sdk';
import type { Request, Response } from 'express'; import type { Request, Response } from 'express';
// @ts-ignore
export async function filterGet(req: Request, res: Response) { export async function filterGet(req: Request, res: Response) {
res.json(await filterService.filterGet({ filterId: req.params.filterId })); res.json(await filterService.filterGet({ filterId: req.params.filterId }));
} }
// @ts-ignore export async function filterList(req: Request, res: Response<FilterListType>) {
export async function filterList(req: Request, res: Response) {
res.json( res.json(
await filterService.filterList({ new PagedResponseImpl(
viewId: req.params.viewId, await filterService.filterList({
}) viewId: req.params.viewId,
})
)
); );
} }
// @ts-ignore
export async function filterChildrenRead(req: Request, res: Response) { export async function filterChildrenRead(req: Request, res: Response) {
const filter = await filterService.filterChildrenList({ res.json(
filterId: req.params.filterParentId, new PagedResponseImpl(
}); await filterService.filterChildrenList({
filterId: req.params.filterParentId,
res.json(filter); })
)
);
} }
export async function filterCreate(req: Request<any, any, FilterReqType>, res) { export async function filterCreate(req: Request<any, any, FilterReqType>, res) {
@ -54,9 +55,11 @@ export async function filterDelete(req: Request, res: Response) {
export async function hookFilterList(req: Request, res: Response) { export async function hookFilterList(req: Request, res: Response) {
res.json( res.json(
await filterService.hookFilterList({ new PagedResponseImpl(
hookId: req.params.hookId, await filterService.hookFilterList({
}) hookId: req.params.hookId,
})
)
); );
} }

18
packages/nocodb/src/lib/controllers/hook.ctl.ts

@ -11,7 +11,6 @@ export async function hookList(
req: Request<any, any, any>, req: Request<any, any, any>,
res: Response<HookListType> res: Response<HookListType>
) { ) {
// todo: pagination
res.json( res.json(
new PagedResponseImpl( new PagedResponseImpl(
await hookService.hookList({ tableId: req.params.tableId }) await hookService.hookList({ tableId: req.params.tableId })
@ -51,18 +50,17 @@ export async function hookTest(req: Request<any, any>, res: Response) {
hookTest: req.body, hookTest: req.body,
tableId: req.params.tableId, tableId: req.params.tableId,
}); });
res.json({ msg: 'Success' }); res.json({ msg: 'The hook has been tested successfully' });
} }
export async function tableSampleData(req: Request, res: Response) { export async function tableSampleData(req: Request, res: Response) {
res // todo: pagination res.json(
.json( await hookService.tableSampleData({
await hookService.tableSampleData({ tableId: req.params.tableId,
tableId: req.params.tableId, // todo: replace any with type
// todo: replace any with type operation: req.params.operation as any,
operation: req.params.operation as any, })
}) );
);
} }
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });

91
packages/nocodb/src/lib/controllers/hookFilter.ctl.ts

@ -1,91 +0,0 @@
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;

4
packages/nocodb/src/lib/controllers/metaDiff.ctl.ts

@ -18,7 +18,7 @@ export async function baseMetaDiff(req, res) {
export async function metaDiffSync(req, res) { export async function metaDiffSync(req, res) {
await metaDiffService.metaDiffSync({ projectId: req.params.projectId }); await metaDiffService.metaDiffSync({ projectId: req.params.projectId });
res.json({ msg: 'success' }); res.json({ msg: 'The meta has been synchronized successfully' });
} }
export async function baseMetaDiffSync(req, res) { export async function baseMetaDiffSync(req, res) {
@ -27,7 +27,7 @@ export async function baseMetaDiffSync(req, res) {
baseId: req.params.baseId, baseId: req.params.baseId,
}); });
res.json({ msg: 'success' }); res.json({ msg: 'The base meta has been synchronized successfully' });
} }
const router = Router(); const router = Router();

2
packages/nocodb/src/lib/controllers/modelVisibility.ctl.ts

@ -9,7 +9,7 @@ async function xcVisibilityMetaSetAll(req, res) {
projectId: req.params.projectId, projectId: req.params.projectId,
}); });
res.json({ msg: 'success' }); res.json({ msg: 'UI ACL has been created successfully' });
} }
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });

2
packages/nocodb/src/lib/controllers/orgLicense.ctl.ts

@ -10,7 +10,7 @@ async function licenseGet(_req, res) {
async function licenseSet(req, res) { async function licenseSet(req, res) {
await orgLicenseService.licenseSet({ key: req.body.key }); await orgLicenseService.licenseSet({ key: req.body.key });
res.json({ msg: 'License key saved' }); res.json({ msg: 'The license key has been saved' });
} }
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });

20
packages/nocodb/src/lib/controllers/orgUser.ctl.ts

@ -2,13 +2,21 @@ import { Router } from 'express';
import { OrgUserRoles } from 'nocodb-sdk'; import { OrgUserRoles } from 'nocodb-sdk';
import { metaApiMetrics } from '../meta/helpers/apiMetrics'; import { metaApiMetrics } from '../meta/helpers/apiMetrics';
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; import ncMetaAclMw from '../meta/helpers/ncMetaAclMw';
import { PagedResponseImpl } from '../meta/helpers/PagedResponse';
import { orgUserService } from '../services'; import { orgUserService } from '../services';
import { User } from '../models';
async function userList(req, res) { async function userList(req, res) {
res.json( res.json(
await orgUserService.userList({ new PagedResponseImpl(
query: req.query, await orgUserService.userList({
}) query: req.query,
}),
{
...req.query,
count: await User.count(req.query),
}
)
); );
} }
@ -25,7 +33,7 @@ async function userDelete(req, res) {
await orgUserService.userDelete({ await orgUserService.userDelete({
userId: req.params.userId, userId: req.params.userId,
}); });
res.json({ msg: 'success' }); res.json({ msg: 'The user has been deleted successfully' });
} }
async function userAdd(req, res) { async function userAdd(req, res) {
@ -49,7 +57,7 @@ async function userInviteResend(req, res): Promise<any> {
req, req,
}); });
res.json({ msg: 'success' }); res.json({ msg: 'The invitation has been sent to the user' });
} }
async function generateResetUrl(req, res) { async function generateResetUrl(req, res) {
@ -71,7 +79,7 @@ async function appSettingsSet(req, res) {
settings: req.body, settings: req.body,
}); });
res.json({ msg: 'Settings saved' }); res.json({ msg: 'The app settings have been saved' });
} }
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });

1
packages/nocodb/src/lib/controllers/project.ctl.ts

@ -9,7 +9,6 @@ import Noco from '../Noco';
import Project from '../models/Project'; import Project from '../models/Project';
import { metaApiMetrics } from '../meta/helpers/apiMetrics'; import { metaApiMetrics } from '../meta/helpers/apiMetrics';
import Filter from '../models/Filter'; import Filter from '../models/Filter';
import { projectService } from '../services'; import { projectService } from '../services';
import type { ProjectListType } from 'nocodb-sdk'; import type { ProjectListType } from 'nocodb-sdk';
import type { ProjectType } from 'nocodb-sdk'; import type { ProjectType } from 'nocodb-sdk';

39
packages/nocodb/src/lib/controllers/projectUser.ctl.ts

@ -22,16 +22,16 @@ async function userInvite(req, res): Promise<any> {
); );
} }
// @ts-ignore async function projectUserUpdate(req, res): Promise<any> {
async function projectUserUpdate(req, res, next): Promise<any> { await projectUserService.projectUserUpdate({
res.json( projectUser: req.body,
await projectUserService.projectUserUpdate({ projectId: req.params.projectId,
projectUser: req.body, userId: req.params.userId,
projectId: req.params.projectId, req,
userId: req.params.userId, });
req, res.json({
}) msg: 'The user has been updated successfully',
); });
} }
async function projectUserDelete(req, res): Promise<any> { async function projectUserDelete(req, res): Promise<any> {
@ -41,19 +41,20 @@ async function projectUserDelete(req, res): Promise<any> {
req, req,
}); });
res.json({ res.json({
msg: 'success', msg: 'The user has been deleted successfully',
}); });
} }
async function projectUserInviteResend(req, res): Promise<any> { async function projectUserInviteResend(req, res): Promise<any> {
res.json( await projectUserService.projectUserInviteResend({
await projectUserService.projectUserInviteResend({ projectId: req.params.projectId,
projectId: req.params.projectId, userId: req.params.userId,
userId: req.params.userId, projectUser: req.body,
projectUser: req.body, req,
req, });
}) res.json({
); msg: 'The invitation has been sent to the user',
});
} }
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });

2
packages/nocodb/src/lib/controllers/publicControllers/publicData.ctl.ts

@ -11,7 +11,7 @@ export async function dataList(req: Request, res: Response) {
password: req.headers?.['xc-password'] as string, password: req.headers?.['xc-password'] as string,
sharedViewUuid: req.params.sharedViewUuid, sharedViewUuid: req.params.sharedViewUuid,
}); });
res.json({ data: pagedResponse }); res.json(pagedResponse);
} }
// todo: Handle the error case where view doesnt belong to model // todo: Handle the error case where view doesnt belong to model

17
packages/nocodb/src/lib/controllers/sort.ctl.ts

@ -2,25 +2,23 @@ import { Router } from 'express';
import { PagedResponseImpl } from '../meta/helpers/PagedResponse'; import { PagedResponseImpl } from '../meta/helpers/PagedResponse';
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 { sortService } from '../services'; import { sortService } from '../services';
import type { SortListType, SortReqType } from 'nocodb-sdk'; import type { SortListType, SortReqType } from 'nocodb-sdk';
import type { Request, Response } from 'express'; import type { Request, Response } from 'express';
// @ts-ignore
export async function sortList( export async function sortList(
req: Request<any, any, any>, req: Request<any, any, any>,
res: Response<SortListType> res: Response<SortListType>
) { ) {
const sortList = await sortService.sortList({ res.json(
viewId: req.params.viewId, new PagedResponseImpl(
}); await sortService.sortList({
res.json({ viewId: req.params.viewId,
sorts: new PagedResponseImpl(sortList), })
}); )
);
} }
// @ts-ignore
export async function sortCreate(req: Request<any, any, SortReqType>, res) { export async function sortCreate(req: Request<any, any, SortReqType>, res) {
const sort = await sortService.sortCreate({ const sort = await sortService.sortCreate({
sort: req.body, sort: req.body,
@ -43,6 +41,7 @@ export async function sortDelete(req: Request, res: Response) {
}); });
res.json(sort); res.json(sort);
} }
export async function sortGet(req: Request, res: Response) { export async function sortGet(req: Request, res: Response) {
const sort = await sortService.sortGet({ const sort = await sortService.sortGet({
sortId: req.params.sortId, sortId: req.params.sortId,

3
packages/nocodb/src/lib/controllers/table.ctl.ts

@ -58,14 +58,13 @@ export async function tableReorder(req: Request, res: Response) {
); );
} }
// todo: move to table service
export async function tableUpdate(req: Request<any, any>, res) { export async function tableUpdate(req: Request<any, any>, res) {
await tableService.tableUpdate({ await tableService.tableUpdate({
tableId: req.params.tableId, tableId: req.params.tableId,
table: req.body, table: req.body,
projectId: (req as any).ncProjectId, projectId: (req as any).ncProjectId,
}); });
res.json({ msg: 'success' }); res.json({ msg: 'The table has been updated successfully' });
} }
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });

12
packages/nocodb/src/lib/controllers/user/initStrategies.ts

@ -5,6 +5,12 @@ import passport from 'passport';
import passportJWT from 'passport-jwt'; import passportJWT from 'passport-jwt';
import { Strategy as AuthTokenStrategy } from 'passport-auth-token'; import { Strategy as AuthTokenStrategy } from 'passport-auth-token';
import { Strategy as GoogleStrategy } from 'passport-google-oauth20'; import { Strategy as GoogleStrategy } from 'passport-google-oauth20';
import bcrypt from 'bcryptjs';
import NocoCache from '../../cache/NocoCache';
import { ApiToken, Plugin, Project, ProjectUser, User } from '../../models';
import Noco from '../../Noco';
import { CacheGetType, CacheScope } from '../../utils/globals';
import { userService } from '../../services';
const ExtractJwt = passportJWT.ExtractJwt; const ExtractJwt = passportJWT.ExtractJwt;
const JwtStrategy = passportJWT.Strategy; const JwtStrategy = passportJWT.Strategy;
@ -13,12 +19,6 @@ const jwtOptions = {
jwtFromRequest: ExtractJwt.fromHeader('xc-auth'), jwtFromRequest: ExtractJwt.fromHeader('xc-auth'),
}; };
import bcrypt from 'bcryptjs';
import NocoCache from '../../cache/NocoCache';
import { ApiToken, Plugin, Project, ProjectUser, User } from '../../models';
import Noco from '../../Noco';
import { CacheGetType, CacheScope } from '../../utils/globals';
import { userService } from '../../services';
const PassportLocalStrategy = require('passport-local').Strategy; const PassportLocalStrategy = require('passport-local').Strategy;
export function initStrategies(router): void { export function initStrategies(router): void {

9
packages/nocodb/src/lib/controllers/user/user.ctl.ts

@ -1,6 +1,5 @@
import { promisify } from 'util'; import { promisify } from 'util';
import * as ejs from 'ejs'; import * as ejs from 'ejs';
import passport from 'passport'; import passport from 'passport';
import catchError, { NcError } from '../../meta/helpers/catchError'; import catchError, { NcError } from '../../meta/helpers/catchError';
import extractProjectIdAndAuthenticate from '../../meta/helpers/extractProjectIdAndAuthenticate'; import extractProjectIdAndAuthenticate from '../../meta/helpers/extractProjectIdAndAuthenticate';
@ -132,7 +131,7 @@ async function passwordChange(req: Request<any, any>, res): Promise<any> {
body: req.body, body: req.body,
}); });
res.json({ msg: 'Password updated successfully' }); res.json({ msg: 'Password has been updated successfully' });
} }
async function passwordForgot(req: Request<any, any>, res): Promise<any> { async function passwordForgot(req: Request<any, any>, res): Promise<any> {
@ -149,7 +148,7 @@ async function tokenValidate(req, res): Promise<any> {
await userService.tokenValidate({ await userService.tokenValidate({
token: req.params.tokenId, token: req.params.tokenId,
}); });
res.json(true); res.json({ msg: 'Token has been validated successfully' });
} }
async function passwordReset(req, res): Promise<any> { async function passwordReset(req, res): Promise<any> {
@ -159,7 +158,7 @@ async function passwordReset(req, res): Promise<any> {
req, req,
}); });
res.json({ msg: 'Password reset successful' }); res.json({ msg: 'Password has been reset successfully' });
} }
async function emailVerification(req, res): Promise<any> { async function emailVerification(req, res): Promise<any> {
@ -168,7 +167,7 @@ async function emailVerification(req, res): Promise<any> {
req, req,
}); });
res.json({ msg: 'Email verified successfully' }); res.json({ msg: 'Email has been verified successfully' });
} }
async function renderPasswordReset(req, res): Promise<any> { async function renderPasswordReset(req, res): Promise<any> {

1
packages/nocodb/src/lib/controllers/util.ctl.ts

@ -1,4 +1,3 @@
// // Project CRUD
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw'; import ncMetaAclMw from '../meta/helpers/ncMetaAclMw';
import catchError from '../meta/helpers/catchError'; import catchError from '../meta/helpers/catchError';
import { utilService } from '../services'; import { utilService } from '../services';

23
packages/nocodb/src/lib/controllers/view.ctl.ts

@ -9,14 +9,15 @@ import type { Request, Response } from 'express';
// @ts-ignore // @ts-ignore
export async function viewGet(req: Request, res: Response) {} export async function viewGet(req: Request, res: Response) {}
// @ts-ignore
export async function viewList(req: Request<any, any, any>, res: Response) { export async function viewList(req: Request<any, any, any>, res: Response) {
const filteredViewList = await viewService.viewList({ res.json(
tableId: req.params.tableId, new PagedResponseImpl(
user: (req as any).session?.passport?.user, await viewService.viewList({
}); tableId: req.params.tableId,
user: (req as any).session?.passport?.user,
res.json(new PagedResponseImpl(filteredViewList)); })
)
);
} }
// @ts-ignore // @ts-ignore
@ -78,9 +79,11 @@ async function hideAllColumns(req: Request<any, any>, res) {
async function shareViewList(req: Request<any, any>, res) { async function shareViewList(req: Request<any, any>, res) {
res.json( res.json(
await viewService.shareViewList({ new PagedResponseImpl(
tableId: req.params.tableId, await viewService.shareViewList({
}) tableId: req.params.tableId,
})
)
); );
} }

13
packages/nocodb/src/lib/controllers/viewColumn.ctl.ts

@ -2,20 +2,21 @@ import { Router } from 'express';
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 { viewColumnService } from '../services'; import { viewColumnService } from '../services';
import { PagedResponseImpl } from '../meta/helpers/PagedResponse';
import type { Request, Response } from 'express'; import type { Request, Response } from 'express';
export async function columnList(req: Request, res: Response) { export async function columnList(req: Request, res: Response) {
res.json(await viewColumnService.columnList({ viewId: req.params.viewId })); res.json(
new PagedResponseImpl(
await viewColumnService.columnList({ viewId: req.params.viewId })
)
);
} }
export async function columnAdd(req: Request, res: Response) { export async function columnAdd(req: Request, res: Response) {
const viewColumn = await viewColumnService.columnAdd({ const viewColumn = await viewColumnService.columnAdd({
viewId: req.params.viewId, viewId: req.params.viewId,
columnId: req.body.fk_column_id, column: req.body,
column: {
...req.body,
view_id: req.params.viewId,
},
}); });
res.json(viewColumn); res.json(viewColumn);
} }

2
packages/nocodb/src/lib/controllers/views/formView.ctl.ts

@ -24,7 +24,7 @@ export async function formViewUpdate(req, res) {
res.json( res.json(
await formViewService.formViewUpdate({ await formViewService.formViewUpdate({
formViewId: req.params.formViewId, formViewId: req.params.formViewId,
body: req.body, form: req.body,
}) })
); );
} }

13
packages/nocodb/src/lib/controllers/views/galleryView.ctl.ts

@ -14,12 +14,13 @@ export async function galleryViewGet(req: Request, res: Response<GalleryType>) {
} }
export async function galleryViewCreate(req: Request<any, any>, res) { export async function galleryViewCreate(req: Request<any, any>, res) {
const view = await galleryViewService.galleryViewCreate({ res.json(
gallery: req.body, await galleryViewService.galleryViewCreate({
// todo: sanitize gallery: req.body,
tableId: req.params.tableId, // todo: sanitize
}); tableId: req.params.tableId,
res.json(view); })
);
} }
export async function galleryViewUpdate(req, res) { export async function galleryViewUpdate(req, res) {

38
packages/nocodb/src/lib/controllers/views/kanbanView.ctl.ts

@ -1,33 +1,34 @@
import { Router } from 'express'; import { Router } from 'express';
import { ViewTypes } from 'nocodb-sdk';
import { T } from 'nc-help';
import View from '../../models/View';
import KanbanView from '../../models/KanbanView';
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 { kanbanViewService } from '../../services';
import type { KanbanType } from 'nocodb-sdk'; import type { KanbanType } from 'nocodb-sdk';
import type { Request, Response } from 'express'; import type { Request, Response } from 'express';
// todo: map to service
export async function kanbanViewGet(req: Request, res: Response<KanbanType>) { export async function kanbanViewGet(req: Request, res: Response<KanbanType>) {
res.json(await KanbanView.get(req.params.kanbanViewId)); res.json(
await kanbanViewService.kanbanViewGet({
kanbanViewId: req.params.kanbanViewId,
})
);
} }
export async function kanbanViewCreate(req: Request<any, any>, res) { export async function kanbanViewCreate(req: Request<any, any>, res) {
T.emit('evt', { evt_type: 'vtable:created', show_as: 'kanban' }); res.json(
const view = await View.insert({ await kanbanViewService.kanbanViewCreate({
...req.body, tableId: req.params.tableId,
// todo: sanitize kanban: req.body,
fk_model_id: req.params.tableId, })
type: ViewTypes.KANBAN, );
});
res.json(view);
} }
export async function kanbanViewUpdate(req, res) { export async function kanbanViewUpdate(req, res) {
T.emit('evt', { evt_type: 'view:updated', type: 'kanban' }); res.json(
res.json(await KanbanView.update(req.params.kanbanViewId, req.body)); await kanbanViewService.kanbanViewUpdate({
kanbanViewId: req.params.kanbanViewId,
kanban: req.body,
})
);
} }
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });
@ -37,14 +38,17 @@ router.post(
metaApiMetrics, metaApiMetrics,
ncMetaAclMw(kanbanViewCreate, 'kanbanViewCreate') ncMetaAclMw(kanbanViewCreate, 'kanbanViewCreate')
); );
router.patch( router.patch(
'/api/v1/db/meta/kanbans/:kanbanViewId', '/api/v1/db/meta/kanbans/:kanbanViewId',
metaApiMetrics, metaApiMetrics,
ncMetaAclMw(kanbanViewUpdate, 'kanbanViewUpdate') ncMetaAclMw(kanbanViewUpdate, 'kanbanViewUpdate')
); );
router.get( router.get(
'/api/v1/db/meta/kanbans/:kanbanViewId', '/api/v1/db/meta/kanbans/:kanbanViewId',
metaApiMetrics, metaApiMetrics,
ncMetaAclMw(kanbanViewGet, 'kanbanViewGet') ncMetaAclMw(kanbanViewGet, 'kanbanViewGet')
); );
export default router; export default router;

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

@ -4,7 +4,6 @@ import { promisify } from 'util';
import path from 'path'; import path from 'path';
import { knex } from 'knex'; import { knex } from 'knex';
import { T } from 'nc-help'; import { T } from 'nc-help';
import findIndex from 'lodash/findIndex'; import findIndex from 'lodash/findIndex';
import find from 'lodash/find'; import find from 'lodash/find';
import jsonfile from 'jsonfile'; import jsonfile from 'jsonfile';
@ -15,6 +14,7 @@ import Debug from '../../util/Debug';
import * as dataHelp from './data.helper'; import * as dataHelp from './data.helper';
import SqlClient from './SqlClient'; import SqlClient from './SqlClient';
import type { Knex } from 'knex'; import type { Knex } from 'knex';
const evt = new Emit(); const evt = new Emit();
const log = new Debug('KnexClient'); const log = new Debug('KnexClient');

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

@ -1,7 +1,6 @@
import path from 'path'; import path from 'path';
import { promisify } from 'util'; import { promisify } from 'util';
import knex from 'knex'; import knex from 'knex';
import isEmpty from 'lodash/isEmpty'; import isEmpty from 'lodash/isEmpty';
import mapKeys from 'lodash/mapKeys'; import mapKeys from 'lodash/mapKeys';
import find from 'lodash/find'; import find from 'lodash/find';
@ -12,10 +11,8 @@ import levenshtein from 'fast-levenshtein';
import Debug from '../../../util/Debug'; import Debug from '../../../util/Debug';
import Emit from '../../../util/emit'; import Emit from '../../../util/emit';
import Result from '../../../util/Result'; import Result from '../../../util/Result';
import KnexClient from '../KnexClient'; import KnexClient from '../KnexClient';
import queries from './mysql.queries'; import queries from './mysql.queries';
import fakerFunctionList from './fakerFunctionList'; import fakerFunctionList from './fakerFunctionList';
import * as findDataType from './findDataTypeMapping'; import * as findDataType from './findDataTypeMapping';

7
packages/nocodb/src/lib/db/sql-client/lib/mysql/TidbClient.ts

@ -1,11 +1,10 @@
import _ from 'lodash'; import mapKeys from 'lodash/mapKeys';
import Debug from '../../../util/Debug'; import Debug from '../../../util/Debug';
import Result from '../../../util/Result'; import Result from '../../../util/Result';
import MysqlClient from './MysqlClient';
const log = new Debug('TidbClient'); const log = new Debug('TidbClient');
import MysqlClient from './MysqlClient';
class Tidb extends MysqlClient { class Tidb extends MysqlClient {
/** /**
* *
@ -33,7 +32,7 @@ class Tidb extends MysqlClient {
for (let i = 0; i < response[0].length; ++i) { for (let i = 0; i < response[0].length; ++i) {
let index = response[0][i]; let index = response[0][i];
index = _.mapKeys(index, function (_v, k) { index = mapKeys(index, function (_v, k) {
return k.toLowerCase(); return k.toLowerCase();
}); });
indexes.push(index); indexes.push(index);

11
packages/nocodb/src/lib/db/sql-client/lib/mysql/VitessClient.ts

@ -1,11 +1,10 @@
import _ from 'lodash'; import mapKeys from 'lodash/mapKeys';
import Debug from '../../../util/Debug'; import Debug from '../../../util/Debug';
import Result from '../../../util/Result'; import Result from '../../../util/Result';
import MysqlClient from './MysqlClient';
const log = new Debug('VitessClient'); const log = new Debug('VitessClient');
import MysqlClient from './MysqlClient';
class Vitess extends MysqlClient { class Vitess extends MysqlClient {
constructor(connectionConfig: any) { constructor(connectionConfig: any) {
super(connectionConfig); super(connectionConfig);
@ -141,9 +140,7 @@ class Vitess extends MysqlClient {
for (let i = 0; i < response[0].length; ++i) { for (let i = 0; i < response[0].length; ++i) {
const column: any = {}; const column: any = {};
response[0][i] = _.mapKeys(response[0][i], (_v, k) => response[0][i] = mapKeys(response[0][i], (_v, k) => k.toLowerCase());
k.toLowerCase()
);
column.tn = args.tn; column.tn = args.tn;
column.cn = response[0][i].cn; column.cn = response[0][i].cn;
@ -220,7 +217,7 @@ class Vitess extends MysqlClient {
for (let i = 0; i < response[0].length; ++i) { for (let i = 0; i < response[0].length; ++i) {
let index = response[0][i]; let index = response[0][i];
index = _.mapKeys(index, function (_v, k) { index = mapKeys(index, function (_v, k) {
return k.toLowerCase(); return k.toLowerCase();
}); });
indexes.push(index); indexes.push(index);

2
packages/nocodb/src/lib/db/sql-client/lib/pg/PgClient.ts

@ -1,5 +1,4 @@
import { nanoid } from 'nanoid'; import { nanoid } from 'nanoid';
import knex from 'knex'; import knex from 'knex';
import isEmpty from 'lodash/isEmpty'; import isEmpty from 'lodash/isEmpty';
import mapKeys from 'lodash/mapKeys'; import mapKeys from 'lodash/mapKeys';
@ -8,6 +7,7 @@ import KnexClient from '../KnexClient';
import Debug from '../../../util/Debug'; import Debug from '../../../util/Debug';
import Result from '../../../util/Result'; import Result from '../../../util/Result';
import queries from './pg.queries'; import queries from './pg.queries';
const log = new Debug('PGClient'); const log = new Debug('PGClient');
class PGClient extends KnexClient { class PGClient extends KnexClient {

15
packages/nocodb/src/lib/db/sql-client/lib/snowflake/SnowflakeClient.ts

@ -1,11 +1,11 @@
import { nanoid } from 'nanoid'; import { nanoid } from 'nanoid';
import find from 'lodash/find';
import _ from 'lodash'; import isEmpty from 'lodash/isEmpty';
import lodash from 'lodash';
import KnexClient from '../KnexClient'; import KnexClient from '../KnexClient';
import Debug from '../../../util/Debug'; import Debug from '../../../util/Debug';
import Result from '../../../util/Result'; import Result from '../../../util/Result';
import queries from './snowflake.queries'; import queries from './snowflake.queries';
const log = new Debug('SnowflakeClient'); const log = new Debug('SnowflakeClient');
const rowsToLower = (arr) => { const rowsToLower = (arr) => {
@ -1341,7 +1341,7 @@ class SnowflakeClient extends KnexClient {
*/ */
async _getQuery(args) { async _getQuery(args) {
try { try {
if (_.isEmpty(this._version)) { if (isEmpty(this._version)) {
const result = await this.version(); const result = await this.version();
this._version = result.data.object; this._version = result.data.object;
log.debug( log.debug(
@ -1350,8 +1350,6 @@ class SnowflakeClient extends KnexClient {
); );
} }
// log.debug(this._version, args);
if (this._version.key in this.queries[args.func]) { if (this._version.key in this.queries[args.func]) {
return this.queries[args.func][this._version.key].sql; return this.queries[args.func][this._version.key].sql;
} }
@ -1831,7 +1829,7 @@ class SnowflakeClient extends KnexClient {
let downQuery = ''; let downQuery = '';
for (let i = 0; i < args.columns.length; ++i) { for (let i = 0; i < args.columns.length; ++i) {
const oldColumn = lodash.find(originalColumns, { const oldColumn = find(originalColumns, {
cn: args.columns[i].cno, cn: args.columns[i].cno,
}); });
@ -2640,7 +2638,6 @@ function getDefaultValue(n) {
case 'dec': case 'dec':
return n.cdf; return n.cdf;
break; break;
case 'datetime': case 'datetime':
case 'timestamp': case 'timestamp':
case 'date': case 'date':
@ -2651,10 +2648,8 @@ function getDefaultValue(n) {
) { ) {
return n.cdf; return n.cdf;
} }
// return JSON.stringify(n.cdf);
break; break;
default: default:
// return JSON.stringify(n.cdf);
break; break;
} }
return n.cdf; return n.cdf;

5
packages/nocodb/src/lib/db/sql-data-mapper/index.ts

@ -1,6 +1,5 @@
export { DbFactory } from './lib/DbFactory';
export { BaseModelSql } from './lib/sql/BaseModelSql';
import XKnex, { Knex } from './lib/sql/CustomKnex'; import XKnex, { Knex } from './lib/sql/CustomKnex';
export { DbFactory } from './lib/DbFactory';
export { BaseModelSql } from './lib/sql/BaseModelSql';
export { XKnex, Knex }; export { XKnex, Knex };

10
packages/nocodb/src/lib/db/sql-data-mapper/lib/BaseModel.ts

@ -1,10 +1,10 @@
/* eslint-disable @typescript-eslint/ban-types,prefer-const */ /* eslint-disable @typescript-eslint/ban-types,prefer-const */
import groupBy from 'lodash/groupBy';
import type { Knex } from 'knex'; import type { Knex } from 'knex';
import type Filter from '../../../models/Filter'; import type Filter from '../../../models/Filter';
import type Sort from '../../../models/Sort'; import type Sort from '../../../models/Sort';
const autoBind = require('auto-bind'); const autoBind = require('auto-bind');
const _ = require('lodash');
const Validator = require('validator'); const Validator = require('validator');
// interface BaseModel { // interface BaseModel {
@ -977,7 +977,7 @@ abstract class BaseModel {
) )
); );
const gs = _.groupBy(childs, cn); const gs = groupBy(childs, cn);
parent.forEach((row) => { parent.forEach((row) => {
row[child] = gs[row[this.pks?.[0]?.cn]] || []; row[child] = gs[row[this.pks?.[0]?.cn]] || [];
}); });
@ -1133,7 +1133,7 @@ abstract class BaseModel {
.whereIn(rcn, parentIds) .whereIn(rcn, parentIds)
); );
const gs = _.groupBy(parents, rcn); const gs = groupBy(parents, rcn);
childs.forEach((row) => { childs.forEach((row) => {
row[parent] = gs[row[cn]] && gs[row[cn]][0]; row[parent] = gs[row[cn]] && gs[row[cn]][0];
@ -1179,7 +1179,7 @@ abstract class BaseModel {
) )
); );
return _.groupBy(childs, cn); return groupBy(childs, cn);
} catch (e) { } catch (e) {
console.log(e); console.log(e);
throw e; throw e;
@ -1224,7 +1224,7 @@ abstract class BaseModel {
); );
return childs.map(({ count }) => count); return childs.map(({ count }) => count);
// return _.groupBy(childs, cn); // return groupBy(childs, cn);
} catch (e) { } catch (e) {
console.log(e); console.log(e);
throw e; throw e;

21
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSql.ts

@ -1,7 +1,8 @@
import autoBind from 'auto-bind'; import autoBind from 'auto-bind';
import _ from 'lodash'; import groupBy from 'lodash/groupBy';
import isEmpty from 'lodash/isEmpty';
import difference from 'lodash/difference';
import Validator from 'validator'; import Validator from 'validator';
import Papaparse from 'papaparse'; import Papaparse from 'papaparse';
import BaseModel from '../BaseModel'; import BaseModel from '../BaseModel';
import formulaQueryBuilder from './formulaQueryBuilderFromString'; import formulaQueryBuilder from './formulaQueryBuilderFromString';
@ -316,7 +317,7 @@ class BaseModelSql extends BaseModel {
: response?.[ai._cn], : response?.[ai._cn],
this.defaultNestedBtQueryParams this.defaultNestedBtQueryParams
); );
response = !_.isEmpty(nestedResponse) ? nestedResponse : response; response = !isEmpty(nestedResponse) ? nestedResponse : response;
} }
if (Array.isArray(response)) { if (Array.isArray(response)) {
@ -1214,7 +1215,7 @@ class BaseModelSql extends BaseModel {
private _buildDistinctQuery(columns: string[]) { private _buildDistinctQuery(columns: string[]) {
const query = this.$db; const query = this.$db;
const formulaColumns = this.filterFormulaColumns(columns); const formulaColumns = this.filterFormulaColumns(columns);
const otherColumns = _.difference(columns, formulaColumns); const otherColumns = difference(columns, formulaColumns);
if (!otherColumns.length && !formulaColumns.length) { if (!otherColumns.length && !formulaColumns.length) {
query.distinct(this.selectQuery('')).distinct(...this.selectFormulas); query.distinct(this.selectQuery('')).distinct(...this.selectFormulas);
} }
@ -1331,7 +1332,7 @@ class BaseModelSql extends BaseModel {
) )
); );
const gs = _.groupBy(childs, _cn); const gs = groupBy(childs, _cn);
parent.forEach((row) => { parent.forEach((row) => {
row[`${this.dbModels?.[child]?._tn || child}List`] = row[`${this.dbModels?.[child]?._tn || child}List`] =
gs[row[_cn] || row[this.pks[0]._cn]] || []; gs[row[_cn] || row[this.pks[0]._cn]] || [];
@ -1409,7 +1410,7 @@ class BaseModelSql extends BaseModel {
) )
); );
const gs = _.groupBy(childs, `${tn}_${vcn}`); const gs = groupBy(childs, `${tn}_${vcn}`);
return parentIds.map((id) => gs[id] || []); return parentIds.map((id) => gs[id] || []);
} }
@ -2005,7 +2006,7 @@ class BaseModelSql extends BaseModel {
.whereIn(rcn, parentIds) .whereIn(rcn, parentIds)
); );
const gs = _.groupBy( const gs = groupBy(
parents, parents,
this.dbModels[parent]?.columnToAlias?.[rcn] || rcn this.dbModels[parent]?.columnToAlias?.[rcn] || rcn
); );
@ -2084,8 +2085,8 @@ class BaseModelSql extends BaseModel {
) )
); );
// return _.groupBy(childs, cn); // return groupBy(childs, cn);
return _.groupBy(childs, this.dbModels?.[child]?.columnToAlias[cn]); return groupBy(childs, this.dbModels?.[child]?.columnToAlias[cn]);
} catch (e) { } catch (e) {
console.log(e); console.log(e);
throw e; throw e;
@ -2134,7 +2135,7 @@ class BaseModelSql extends BaseModel {
); );
return childs.map(({ count }) => count); return childs.map(({ count }) => count);
// return _.groupBy(childs, cn); // return groupBy(childs, cn);
} catch (e) { } catch (e) {
console.log(e); console.log(e);
throw e; throw e;

12
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts

@ -1,6 +1,5 @@
import autoBind from 'auto-bind'; import autoBind from 'auto-bind';
import _ from 'lodash'; import groupBy from 'lodash/groupBy';
import DataLoader from 'dataloader'; import DataLoader from 'dataloader';
import { import {
AuditOperationSubTypes, AuditOperationSubTypes,
@ -437,7 +436,7 @@ class BaseModelSqlv2 {
}) })
).getProto(); ).getProto();
return _.groupBy( return groupBy(
children.map((c) => { children.map((c) => {
c.__proto__ = proto; c.__proto__ = proto;
return c; return c;
@ -605,7 +604,6 @@ class BaseModelSqlv2 {
.first(); .first();
const { count } = await query; const { count } = await query;
return count; return count;
// return _.groupBy(children, cn);
} catch (e) { } catch (e) {
console.log(e); console.log(e);
throw e; throw e;
@ -683,7 +681,7 @@ class BaseModelSqlv2 {
dbDriver: this.dbDriver, dbDriver: this.dbDriver,
}) })
).getProto(); ).getProto();
const gs = _.groupBy( const gs = groupBy(
children.map((c) => { children.map((c) => {
c.__proto__ = proto; c.__proto__ = proto;
return c; return c;
@ -800,7 +798,7 @@ class BaseModelSqlv2 {
!this.isSqlite !this.isSqlite
); );
const gs = _.groupBy(children, GROUP_COL); const gs = groupBy(children, GROUP_COL);
return parentIds.map((id) => gs?.[id]?.[0] || []); return parentIds.map((id) => gs?.[id]?.[0] || []);
} }
@ -1362,7 +1360,7 @@ class BaseModelSqlv2 {
}, },
true true
); );
const gs = _.groupBy(data, pCol.title); const gs = groupBy(data, pCol.title);
return ids.map(async (id: string) => gs?.[id]?.[0]); return ids.map(async (id: string) => gs?.[id]?.[0]);
} catch (e) { } catch (e) {
console.log(e); console.log(e);

1
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/CustomKnex.ts

@ -2,7 +2,6 @@ import { Knex, knex } from 'knex';
import { SnowflakeClient } from 'nc-help'; import { SnowflakeClient } from 'nc-help';
import Filter from '../../../../models/Filter'; import Filter from '../../../../models/Filter';
import type { FilterType } from 'nocodb-sdk'; import type { FilterType } from 'nocodb-sdk';
import type { BaseModelSql } from './BaseModelSql'; import type { BaseModelSql } from './BaseModelSql';
const types = require('pg').types; const types = require('pg').types;

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

@ -2,7 +2,6 @@ import fs from 'fs';
import path from 'path'; import path from 'path';
import url from 'url'; import url from 'url';
import { promisify } from 'util'; import { promisify } from 'util';
import fsExtra from 'fs-extra'; import fsExtra from 'fs-extra';
import importFresh from 'import-fresh'; import importFresh from 'import-fresh';
import inflection from 'inflection'; import inflection from 'inflection';
@ -10,14 +9,10 @@ import slash from 'slash';
import { T } from 'nc-help'; import { T } from 'nc-help';
import { customAlphabet } from 'nanoid'; import { customAlphabet } from 'nanoid';
import SqlClientFactory from '../sql-client/lib/SqlClientFactory'; import SqlClientFactory from '../sql-client/lib/SqlClientFactory';
// import debug from 'debug';
import KnexMigrator from '../sql-migrator/lib/KnexMigrator'; import KnexMigrator from '../sql-migrator/lib/KnexMigrator';
// import {XKnex} from "../sql-data-mapper";
import NcConnectionMgr from '../../utils/common/NcConnectionMgr'; import NcConnectionMgr from '../../utils/common/NcConnectionMgr';
import Debug from '../util/Debug'; import Debug from '../util/Debug';
import Result from '../util/Result'; import Result from '../util/Result';
import type MssqlClient from '../sql-client/lib/mssql/MssqlClient'; import type MssqlClient from '../sql-client/lib/mssql/MssqlClient';
import type MysqlClient from '../sql-client/lib/mysql/MysqlClient'; import type MysqlClient from '../sql-client/lib/mysql/MysqlClient';
import type OracleClient from '../sql-client/lib/oracle/OracleClient'; import type OracleClient from '../sql-client/lib/oracle/OracleClient';
@ -26,6 +21,7 @@ import type SnowflakeClient from '../sql-client/lib/snowflake/SnowflakeClient';
import type SqliteClient from '../sql-client/lib/sqlite/SqliteClient'; import type SqliteClient from '../sql-client/lib/sqlite/SqliteClient';
const randomID = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 20); const randomID = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 20);
const log = new Debug('SqlMgr'); const log = new Debug('SqlMgr');
const ToolOps = { const ToolOps = {

13
packages/nocodb/src/lib/db/sql-mgr/code/BaseRender.ts

@ -1,16 +1,3 @@
// import path from "path";
// import mkdirp from "mkdirp";
// import {promisify} from "util";
//
// import ejs from "ejs";
// import fs from "fs";
// import js_beautify from "js-beautify";
// import fsExtra from "fs-extra";
// import md5 from "md5";
// import dayjs from "dayjs";import Emit from "../../sql-migrator/util/emit";
// const beautify = js_beautify.js;
import Debug from '../../util/Debug'; import Debug from '../../util/Debug';
import Emit from '../../util/emit'; import Emit from '../../util/emit';

8
packages/nocodb/src/lib/db/sql-mgr/code/gql-schema/xc-ts/BaseGqlXcTsSchema.ts

@ -1,7 +1,5 @@
import lodash from 'lodash'; import uniqBy from 'lodash/uniqBy';
import BaseRender from '../../BaseRender'; import BaseRender from '../../BaseRender';
import { AGG_DEFAULT_COLS, GROUPBY_DEFAULT_COLS } from './schemaHelp'; import { AGG_DEFAULT_COLS, GROUPBY_DEFAULT_COLS } from './schemaHelp';
abstract class BaseGqlXcTsSchema extends BaseRender { abstract class BaseGqlXcTsSchema extends BaseRender {
@ -142,7 +140,7 @@ abstract class BaseGqlXcTsSchema extends BaseRender {
let hasManyRelations = args.hasMany; let hasManyRelations = args.hasMany;
if (hasManyRelations.length > 1) { if (hasManyRelations.length > 1) {
hasManyRelations = lodash.uniqBy(hasManyRelations, (e) => { hasManyRelations = uniqBy(hasManyRelations, (e) => {
return [e.tn, e.rtn].join(); return [e.tn, e.rtn].join();
}); });
} }
@ -161,7 +159,7 @@ abstract class BaseGqlXcTsSchema extends BaseRender {
let belongsToRelations = args.belongsTo; let belongsToRelations = args.belongsTo;
if (belongsToRelations.length > 1) { if (belongsToRelations.length > 1) {
belongsToRelations = lodash.uniqBy(belongsToRelations, (e) => { belongsToRelations = uniqBy(belongsToRelations, (e) => {
return [e.tn, e.rtn].join(); return [e.tn, e.rtn].join();
}); });
} }

7
packages/nocodb/src/lib/db/sql-mgr/code/policies/xc/ExpressXcPolicy.ts

@ -1,5 +1,4 @@
import lodash from 'lodash'; import uniqBy from 'lodash/uniqBy';
import BaseRender from '../../BaseRender'; import BaseRender from '../../BaseRender';
import type { Acl } from '../../../../../../interface/config'; import type { Acl } from '../../../../../../interface/config';
@ -60,7 +59,7 @@ class ExpressXcMiddleware extends BaseRender {
? args.relations.filter((r) => r.rtn === args.tn) ? args.relations.filter((r) => r.rtn === args.tn)
: []; : [];
if (hmRelations.length > 1) if (hmRelations.length > 1)
hmRelations = lodash.uniqBy(hmRelations, function (e) { hmRelations = uniqBy(hmRelations, function (e) {
return [e.tn, e.rtn].join(); return [e.tn, e.rtn].join();
}); });
for (let i = 0; i < hmRelations.length; ++i) { for (let i = 0; i < hmRelations.length; ++i) {
@ -86,7 +85,7 @@ class ExpressXcMiddleware extends BaseRender {
? args.relations.filter((r) => r.tn === args.tn) ? args.relations.filter((r) => r.tn === args.tn)
: []; : [];
if (btRelations.length > 1) if (btRelations.length > 1)
btRelations = lodash.uniqBy(btRelations, function (e) { btRelations = uniqBy(btRelations, function (e) {
return [e.tn, e.rtn].join(); return [e.tn, e.rtn].join();
}); });
for (let i = 0; i < btRelations.length; ++i) { for (let i = 0; i < btRelations.length; ++i) {

1
packages/nocodb/src/lib/db/sql-mgr/code/routers/xc-ts/SwaggerXc.ts

@ -1,5 +1,4 @@
import BaseRender from '../../BaseRender'; import BaseRender from '../../BaseRender';
import SwaggerTypes from './SwaggerTypes'; import SwaggerTypes from './SwaggerTypes';
class SwaggerXc extends BaseRender { class SwaggerXc extends BaseRender {

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

@ -1,7 +1,6 @@
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { promisify } from 'util'; import { promisify } from 'util';
import glob from 'glob'; import glob from 'glob';
import Handlebars from 'handlebars'; import Handlebars from 'handlebars';
import mkdirp from 'mkdirp'; import mkdirp from 'mkdirp';
@ -11,7 +10,6 @@ import Debug from '../../util/Debug';
import Emit from '../../util/emit'; import Emit from '../../util/emit';
import Result from '../../util/Result'; import Result from '../../util/Result';
import * as fileHelp from '../../util/file.help'; import * as fileHelp from '../../util/file.help';
import NcConfigFactory from '../../../utils/NcConfigFactory'; import NcConfigFactory from '../../../utils/NcConfigFactory';
import SqlMigrator from './SqlMigrator'; import SqlMigrator from './SqlMigrator';

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

@ -1,17 +1,11 @@
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { promisify } from 'util'; import { promisify } from 'util';
import glob from 'glob'; import glob from 'glob';
import SqlClientFactory from '../../sql-client/lib/SqlClientFactory'; import SqlClientFactory from '../../sql-client/lib/SqlClientFactory';
import Debug from '../../util/Debug'; import Debug from '../../util/Debug';
import Emit from '../../util/emit'; import Emit from '../../util/emit';
// import Handlebars from 'handlebars';
// import mkdirp from 'mkdirp';
import * as fileHelp from '../../util/file.help'; import * as fileHelp from '../../util/file.help';
// import SqlMigrator from './SqlMigrator';
// import NcConfigFactory from '../../../utils/NcConfigFactory';
import Noco from '../../../Noco'; import Noco from '../../../Noco';
import Project from '../../../models/Project'; import Project from '../../../models/Project';
import NcConnectionMgrv2 from '../../../utils/common/NcConnectionMgrv2'; import NcConnectionMgrv2 from '../../../utils/common/NcConnectionMgrv2';
@ -21,7 +15,9 @@ import type { XKnex } from '../../sql-data-mapper';
import type { Knex } from 'knex'; import type { Knex } from 'knex';
const evt = new Emit(); const evt = new Emit();
const log = new Debug('KnexMigrator'); const log = new Debug('KnexMigrator');
const NC_MIGRATION = 'nc_migrations'; const NC_MIGRATION = 'nc_migrations';
/** /**
* Class to create an instance of KnexMigrator * Class to create an instance of KnexMigrator

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

@ -10,7 +10,6 @@ import KnexMigratorv2 from './KnexMigratorv2';
import type Base from '../../../models/Base'; import type Base from '../../../models/Base';
import type { XKnex } from '../../sql-data-mapper'; import type { XKnex } from '../../sql-data-mapper';
import type NcMetaIO from '../../../meta/NcMetaIO'; import type NcMetaIO from '../../../meta/NcMetaIO';
import type MssqlClient from '../../sql-client/lib/mssql/MssqlClient'; import type MssqlClient from '../../sql-client/lib/mssql/MssqlClient';
import type MysqlClient from '../../sql-client/lib/mysql/MysqlClient'; import type MysqlClient from '../../sql-client/lib/mysql/MysqlClient';
import type OracleClient from '../../sql-client/lib/oracle/OracleClient'; import type OracleClient from '../../sql-client/lib/oracle/OracleClient';

1
packages/nocodb/src/lib/db/util/FileCollection.ts

@ -1,6 +1,5 @@
import fs from 'fs'; import fs from 'fs';
import { promisify } from 'util'; import { promisify } from 'util';
import jsonfile from 'jsonfile'; import jsonfile from 'jsonfile';
export default class FileCollection { export default class FileCollection {

5
packages/nocodb/src/lib/meta/NcMetaIOImpl.ts

@ -1,9 +1,7 @@
import CryptoJS from 'crypto-js'; import CryptoJS from 'crypto-js';
import { customAlphabet } from 'nanoid'; import { customAlphabet } from 'nanoid';
import { XKnex } from '../db/sql-data-mapper'; import { XKnex } from '../db/sql-data-mapper';
import XcMigrationSource from '../migrations/XcMigrationSource'; import XcMigrationSource from '../migrations/XcMigrationSource';
import NcConnectionMgr from '../utils/common/NcConnectionMgr'; import NcConnectionMgr from '../utils/common/NcConnectionMgr';
import { MetaTable } from '../utils/globals'; import { MetaTable } from '../utils/globals';
import XcMigrationSourcev2 from '../migrations/XcMigrationSourcev2'; import XcMigrationSourcev2 from '../migrations/XcMigrationSourcev2';
@ -12,9 +10,8 @@ import type Noco from '../Noco';
import type { Knex } from '../db/sql-data-mapper'; import type { Knex } from '../db/sql-data-mapper';
import type { NcConfig } from '../../interface/config'; import type { NcConfig } from '../../interface/config';
// import { nanoid } from 'nanoid';
/*import { v4 as uuidv4 } from 'uuid';*/
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 4); const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 4);
const nanoidv2 = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 14); const nanoidv2 = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 14);
export default class NcMetaIOImpl extends NcMetaIO { export default class NcMetaIOImpl extends NcMetaIO {

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

@ -3,7 +3,6 @@ import path from 'path';
import { promisify } from 'util'; import { promisify } from 'util';
import CryptoJS from 'crypto-js'; import CryptoJS from 'crypto-js';
import mkdirp from 'mkdirp'; import mkdirp from 'mkdirp';
import archiver from 'archiver'; import archiver from 'archiver';
import axios from 'axios'; import axios from 'axios';
import bodyParser from 'body-parser'; import bodyParser from 'body-parser';
@ -18,7 +17,6 @@ import { ncp } from 'ncp';
import { UITypes } from 'nocodb-sdk'; import { UITypes } from 'nocodb-sdk';
import { T } from 'nc-help'; import { T } from 'nc-help';
import { Result } from '../../interface/config'; import { Result } from '../../interface/config';
import SqlClientFactory from '../db/sql-client/lib/SqlClientFactory'; import SqlClientFactory from '../db/sql-client/lib/SqlClientFactory';
import { NcConfigFactory } from '../index'; import { NcConfigFactory } from '../index';
import ProjectMgr from '../db/sql-mgr/ProjectMgr'; import ProjectMgr from '../db/sql-mgr/ProjectMgr';
@ -46,7 +44,9 @@ import type IStorageAdapter from '../../interface/IStorageAdapter';
import type IEmailAdapter from '../../interface/IEmailAdapter'; import type IEmailAdapter from '../../interface/IEmailAdapter';
import type express from 'express'; import type express from 'express';
import type { Handler } from 'express'; import type { Handler } from 'express';
const randomID = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 10); const randomID = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 10);
const XC_PLUGIN_DET = 'XC_PLUGIN_DET'; const XC_PLUGIN_DET = 'XC_PLUGIN_DET';
const NOCO_RELEASE = 'NOCO_RELEASE'; const NOCO_RELEASE = 'NOCO_RELEASE';

1
packages/nocodb/src/lib/meta/NcMetaMgrEE.ts

@ -1,6 +1,5 @@
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { T } from 'nc-help'; import { T } from 'nc-help';
import NcMetaMgr from './NcMetaMgr'; import NcMetaMgr from './NcMetaMgr';
export default class NcMetaMgrEE extends NcMetaMgr { export default class NcMetaMgrEE extends NcMetaMgr {

2
packages/nocodb/src/lib/meta/NcMetaMgrv2.ts

@ -1,7 +1,6 @@
import bodyParser from 'body-parser'; import bodyParser from 'body-parser';
import { Router } from 'express'; import { Router } from 'express';
import multer from 'multer'; import multer from 'multer';
import ProjectMgr from '../db/sql-mgr/ProjectMgr'; import ProjectMgr from '../db/sql-mgr/ProjectMgr';
import { packageVersion } from '../utils/packageVersion'; import { packageVersion } from '../utils/packageVersion';
import projectAcl from '../utils/projectAcl'; import projectAcl from '../utils/projectAcl';
@ -13,7 +12,6 @@ import type NcMetaIO from './NcMetaIO';
import type Noco from '../Noco'; import type Noco from '../Noco';
import type { NcConfig } from '../../interface/config'; import type { NcConfig } from '../../interface/config';
import type { Handler } from 'express'; import type { Handler } from 'express';
// import ncGetMeta from './handlersv2/ncGetMeta';
export default class NcMetaMgrv2 { export default class NcMetaMgrv2 {
public projectConfigs = {}; public projectConfigs = {};

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

@ -25,7 +25,6 @@ import pluginController from '../../controllers/plugin.ctl';
import gridViewColumnController from '../../controllers/views/gridViewColumn.ctl'; import gridViewColumnController from '../../controllers/views/gridViewColumn.ctl';
import kanbanViewController from '../../controllers/views/kanbanView.ctl'; import kanbanViewController from '../../controllers/views/kanbanView.ctl';
import { userController } from '../../controllers/user'; import { userController } from '../../controllers/user';
// import extractProjectIdAndAuthenticate from './helpers/extractProjectIdAndAuthenticate';
import utilController from '../../controllers/util.ctl'; import utilController from '../../controllers/util.ctl';
import projectUserController from '../../controllers/projectUser.ctl'; import projectUserController from '../../controllers/projectUser.ctl';
import sharedBaseController from '../../controllers/sharedBase.ctl'; import sharedBaseController from '../../controllers/sharedBase.ctl';
@ -34,7 +33,6 @@ import modelVisibilityController from '../../controllers/modelVisibility.ctl';
import metaDiffController from '../../controllers/metaDiff.ctl'; import metaDiffController from '../../controllers/metaDiff.ctl';
import cacheController from '../../controllers/cache.ctl'; import cacheController from '../../controllers/cache.ctl';
import apiTokenController from '../../controllers/apiToken.ctl'; import apiTokenController from '../../controllers/apiToken.ctl';
import hookFilterController from '../../controllers/hookFilter.ctl';
import testController from '../../controllers/test.ctl'; import testController from '../../controllers/test.ctl';
import { import {
bulkDataAliasController, bulkDataAliasController,
@ -49,7 +47,6 @@ import {
publicDataExportController, publicDataExportController,
publicMetaController, publicMetaController,
} from '../../controllers/publicControllers'; } from '../../controllers/publicControllers';
import swaggerController from '../../controllers/apiDocs'; import swaggerController from '../../controllers/apiDocs';
import { importController, syncSourceController } from '../../controllers/sync'; import { importController, syncSourceController } from '../../controllers/sync';
import mapViewController from '../../controllers/views/mapView.ctl'; import mapViewController from '../../controllers/views/mapView.ctl';
@ -102,7 +99,6 @@ export default function (router: Router, server) {
router.use(metaDiffController); router.use(metaDiffController);
router.use(cacheController); router.use(cacheController);
router.use(apiTokenController); router.use(apiTokenController);
router.use(hookFilterController);
router.use(swaggerController); router.use(swaggerController);
router.use(syncSourceController); router.use(syncSourceController);
router.use(kanbanViewController); router.use(kanbanViewController);

1
packages/nocodb/src/lib/meta/helpers/extractProjectIdAndAuthenticate.ts

@ -1,5 +1,4 @@
import { promisify } from 'util'; import { promisify } from 'util';
import passport from 'passport'; import passport from 'passport';
import Model from '../../models/Model'; import Model from '../../models/Model';
import View from '../../models/View'; import View from '../../models/View';

11
packages/nocodb/src/lib/models/Audit.ts

@ -78,12 +78,7 @@ export default class Audit implements AuditType {
// Will only await for Audit insertion if `forceAwait` is true, which will be true in test environment by default // Will only await for Audit insertion if `forceAwait` is true, which will be true in test environment by default
public static async insert( public static async insert(
audit: Partial< audit: Partial<Audit>,
Audit & {
created_at?;
updated_at?;
}
>,
ncMeta = Noco.ncMeta, ncMeta = Noco.ncMeta,
{ forceAwait }: { forceAwait: boolean } = { { forceAwait }: { forceAwait: boolean } = {
forceAwait: process.env['TEST'] === 'true', forceAwait: process.env['TEST'] === 'true',
@ -105,8 +100,6 @@ export default class Audit implements AuditType {
'status', 'status',
'description', 'description',
'details', 'details',
'created_at',
'updated_at',
]); ]);
if (!insertObj.project_id && insertObj.fk_model_id) { if (!insertObj.project_id && insertObj.fk_model_id) {
insertObj.project_id = ( insertObj.project_id = (
@ -120,7 +113,7 @@ export default class Audit implements AuditType {
if (forceAwait) { if (forceAwait) {
return await insertAudit(); return await insertAudit();
} else { } else {
insertAudit(); return insertAudit();
} }
} }

8
packages/nocodb/src/lib/models/Filter.ts

@ -272,7 +272,13 @@ export default class Filter implements FilterType {
await NocoCache.set(key, o); await NocoCache.set(key, o);
} }
// set meta // set meta
await ncMeta.metaUpdate(null, null, MetaTable.FILTER_EXP, updateObj, id); return await ncMeta.metaUpdate(
null,
null,
MetaTable.FILTER_EXP,
updateObj,
id
);
} }
static async delete(id: string, ncMeta = Noco.ncMeta) { static async delete(id: string, ncMeta = Noco.ncMeta) {

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

@ -5,6 +5,7 @@ import NocoCache from '../cache/NocoCache';
import { extractProps } from '../meta/helpers/extractProps'; import { extractProps } from '../meta/helpers/extractProps';
import FormViewColumn from './FormViewColumn'; import FormViewColumn from './FormViewColumn';
import View from './View'; import View from './View';
import type { MetaType } from 'nocodb-sdk';
import type { BoolType, FormType } from 'nocodb-sdk'; import type { BoolType, FormType } from 'nocodb-sdk';
export default class FormView implements FormType { export default class FormView implements FormType {
@ -27,7 +28,7 @@ export default class FormView implements FormType {
columns?: FormViewColumn[]; columns?: FormViewColumn[];
project_id?: string; project_id?: string;
base_id?: string; base_id?: string;
meta?: string | Record<string, any>; meta?: MetaType;
constructor(data: FormView) { constructor(data: FormView) {
Object.assign(this, data); Object.assign(this, data);

2
packages/nocodb/src/lib/models/FormViewColumn.ts

@ -182,7 +182,7 @@ export default class FormViewColumn implements FormColumnType {
} }
// update meta // update meta
await ncMeta.metaUpdate( return await ncMeta.metaUpdate(
null, null,
null, null,
MetaTable.FORM_VIEW_COLUMNS, MetaTable.FORM_VIEW_COLUMNS,

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

@ -4,7 +4,12 @@ import { CacheGetType, CacheScope, MetaTable } from '../utils/globals';
import NocoCache from '../cache/NocoCache'; import NocoCache from '../cache/NocoCache';
import { extractProps } from '../meta/helpers/extractProps'; import { extractProps } from '../meta/helpers/extractProps';
import View from './View'; import View from './View';
import type { BoolType, GalleryColumnType, GalleryType } from 'nocodb-sdk'; import type {
BoolType,
GalleryColumnType,
GalleryType,
MetaType,
} from 'nocodb-sdk';
export default class GalleryView implements GalleryType { export default class GalleryView implements GalleryType {
fk_view_id?: string; fk_view_id?: string;
@ -26,6 +31,7 @@ export default class GalleryView implements GalleryType {
base_id?: string; base_id?: string;
columns?: GalleryColumnType[]; columns?: GalleryColumnType[];
meta?: MetaType;
constructor(data: GalleryView) { constructor(data: GalleryView) {
Object.assign(this, data); Object.assign(this, data);
@ -95,16 +101,12 @@ export default class GalleryView implements GalleryType {
// get existing cache // get existing cache
const key = `${CacheScope.GALLERY_VIEW}:${galleryId}`; const key = `${CacheScope.GALLERY_VIEW}:${galleryId}`;
let o = await NocoCache.get(key, CacheGetType.TYPE_OBJECT); let o = await NocoCache.get(key, CacheGetType.TYPE_OBJECT);
const updateObj = extractProps(body, [
'next_enabled', const updateObj = extractProps(body, ['fk_cover_image_col_id', 'meta']);
'prev_enabled', if (updateObj.meta && typeof updateObj.meta === 'object') {
'cover_image_idx', updateObj.meta = JSON.stringify(updateObj.meta ?? {});
'cover_image', }
'restrict_types',
'restrict_size',
'restrict_number',
'fk_cover_image_col_id',
]);
if (o) { if (o) {
o = { ...o, ...updateObj }; o = { ...o, ...updateObj };
// set cache // set cache

9
packages/nocodb/src/lib/models/GridView.ts

@ -10,10 +10,8 @@ export default class GridView implements GridType {
fk_view_id: string; fk_view_id: string;
project_id?: string; project_id?: string;
base_id?: string; base_id?: string;
meta?: MetaType; meta?: MetaType;
row_height?: number; row_height?: number;
columns?: GridViewColumn[]; columns?: GridViewColumn[];
constructor(data: GridView) { constructor(data: GridView) {
@ -73,7 +71,12 @@ export default class GridView implements GridType {
// get existing cache // get existing cache
const key = `${CacheScope.GRID_VIEW}:${viewId}`; const key = `${CacheScope.GRID_VIEW}:${viewId}`;
let o = await NocoCache.get(key, CacheGetType.TYPE_OBJECT); let o = await NocoCache.get(key, CacheGetType.TYPE_OBJECT);
const updateObj = extractProps(body, ['row_height']); const updateObj = extractProps(body, ['row_height', 'meta']);
if (updateObj.meta && typeof updateObj.meta === 'object') {
updateObj.meta = JSON.stringify(updateObj.meta ?? {});
}
if (o) { if (o) {
o = { ...o, ...updateObj }; o = { ...o, ...updateObj };
// set cache // set cache

2
packages/nocodb/src/lib/models/GridViewColumn.ts

@ -133,7 +133,7 @@ export default class GridViewColumn implements GridColumnType {
await NocoCache.set(key, o); await NocoCache.set(key, o);
} }
// set meta // set meta
await ncMeta.metaUpdate( return await ncMeta.metaUpdate(
null, null,
null, null,
MetaTable.GRID_VIEW_COLUMNS, MetaTable.GRID_VIEW_COLUMNS,

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

@ -113,15 +113,7 @@ export default class Hook implements HookType {
return hooks?.map((h) => new Hook(h)); return hooks?.map((h) => new Hook(h));
} }
public static async insert( public static async insert(hook: Partial<Hook>, ncMeta = Noco.ncMeta) {
hook: Partial<
Hook & {
created_at?;
updated_at?;
}
>,
ncMeta = Noco.ncMeta
) {
const insertObj = extractProps(hook, [ const insertObj = extractProps(hook, [
'fk_model_id', 'fk_model_id',
'title', 'title',
@ -140,8 +132,6 @@ export default class Hook implements HookType {
'active', 'active',
'project_id', 'project_id',
'base_id', 'base_id',
'created_at',
'updated_at',
]); ]);
if (insertObj.event) { if (insertObj.event) {

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

@ -64,15 +64,7 @@ export default class HookLog implements HookLogType {
return hookLogs?.map((h) => new HookLog(h)); return hookLogs?.map((h) => new HookLog(h));
} }
public static async insert( public static async insert(hookLog: Partial<HookLog>, ncMeta = Noco.ncMeta) {
hookLog: Partial<
HookLog & {
created_at?;
updated_at?;
}
>,
ncMeta = Noco.ncMeta
) {
const insertObj: any = extractProps(hookLog, [ const insertObj: any = extractProps(hookLog, [
'base_id', 'base_id',
'project_id', 'project_id',

2
packages/nocodb/src/lib/models/KanbanView.ts

@ -104,8 +104,8 @@ export default class KanbanView implements KanbanType {
let o = await NocoCache.get(key, CacheGetType.TYPE_OBJECT); let o = await NocoCache.get(key, CacheGetType.TYPE_OBJECT);
const updateObj = extractProps(body, [ const updateObj = extractProps(body, [
'title',
'fk_cover_image_col_id', 'fk_cover_image_col_id',
'fk_grp_col_id',
'meta', 'meta',
]); ]);

18
packages/nocodb/src/lib/models/MapView.ts

@ -1,8 +1,10 @@
import Noco from '../Noco'; import Noco from '../Noco';
import { CacheGetType, CacheScope, MetaTable } from '../utils/globals'; import { CacheGetType, CacheScope, MetaTable } from '../utils/globals';
import NocoCache from '../cache/NocoCache'; import NocoCache from '../cache/NocoCache';
import { extractProps } from '../meta/helpers/extractProps';
import View from './View'; import View from './View';
import MapViewColumn from './MapViewColumn'; import MapViewColumn from './MapViewColumn';
import type { MetaType } from 'nocodb-sdk';
import type { MapType } from 'nocodb-sdk'; import type { MapType } from 'nocodb-sdk';
export default class MapView implements MapType { export default class MapView implements MapType {
@ -11,7 +13,7 @@ export default class MapView implements MapType {
project_id?: string; project_id?: string;
base_id?: string; base_id?: string;
fk_geo_data_col_id?: string; fk_geo_data_col_id?: string;
meta?: string | Record<string, unknown>; meta?: MetaType;
// below fields are not in use at this moment // below fields are not in use at this moment
// keep them for time being // keep them for time being
@ -71,13 +73,13 @@ export default class MapView implements MapType {
// get existing cache // get existing cache
const key = `${CacheScope.MAP_VIEW}:${mapId}`; const key = `${CacheScope.MAP_VIEW}:${mapId}`;
let o = await NocoCache.get(key, CacheGetType.TYPE_OBJECT); let o = await NocoCache.get(key, CacheGetType.TYPE_OBJECT);
const updateObj = {
...body, const updateObj = extractProps(body, ['fk_geo_data_col_id', 'meta']);
meta:
typeof body.meta === 'string' if (updateObj.meta && typeof updateObj.meta === 'object') {
? body.meta updateObj.meta = JSON.stringify(updateObj.meta ?? {});
: JSON.stringify(body.meta ?? {}), }
};
if (o) { if (o) {
o = { ...o, ...updateObj }; o = { ...o, ...updateObj };
// set cache // set cache

9
packages/nocodb/src/lib/models/ModelRoleVisibility.ts

@ -127,12 +127,7 @@ export default class ModelRoleVisibility implements ModelRoleVisibilityType {
} }
static async insert( static async insert(
body: Partial< body: Partial<ModelRoleVisibilityType>,
ModelRoleVisibilityType & {
created_at?;
updated_at?;
}
>,
ncMeta = Noco.ncMeta ncMeta = Noco.ncMeta
) { ) {
const insertObj = extractProps(body, [ const insertObj = extractProps(body, [
@ -141,8 +136,6 @@ export default class ModelRoleVisibility implements ModelRoleVisibilityType {
'fk_view_id', 'fk_view_id',
'project_id', 'project_id',
'base_id', 'base_id',
'created_at',
'updated_at',
]); ]);
if (!(insertObj.project_id && insertObj.base_id)) { if (!(insertObj.project_id && insertObj.base_id)) {

2
packages/nocodb/src/lib/models/Plugin.ts

@ -19,7 +19,7 @@ export default class Plugin implements PluginType {
tags?: string; tags?: string;
category?: string; category?: string;
input_schema?: string; input_schema?: string;
input?: string; input?: string | null;
creator?: string; creator?: string;
creator_website?: string; creator_website?: string;
price?: string; price?: string;

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

@ -24,9 +24,6 @@ export default class Project implements ProjectType {
public is_meta = false; public is_meta = false;
public bases?: Base[]; public bases?: Base[];
created_at: any;
updated_at: any;
// shared base props // shared base props
uuid?: string; uuid?: string;
password?: string; password?: string;
@ -37,10 +34,7 @@ export default class Project implements ProjectType {
} }
public static async createProject( public static async createProject(
project: ProjectType & { project: Partial<ProjectType>,
created_at?;
updated_at?;
},
ncMeta = Noco.ncMeta ncMeta = Noco.ncMeta
): Promise<Project> { ): Promise<Project> {
const insertObj = extractProps(project, [ const insertObj = extractProps(project, [
@ -49,8 +43,6 @@ export default class Project implements ProjectType {
'prefix', 'prefix',
'description', 'description',
'is_meta', 'is_meta',
'created_at',
'updated_at',
]); ]);
const { id: projectId } = await ncMeta.metaInsert2( const { id: projectId } = await ncMeta.metaInsert2(

2
packages/nocodb/src/lib/models/Sort.ts

@ -144,7 +144,7 @@ export default class Sort {
await NocoCache.set(key, o); await NocoCache.set(key, o);
} }
// set meta // set meta
await ncMeta.metaUpdate( return await ncMeta.metaUpdate(
null, null,
null, null,
MetaTable.SORT, MetaTable.SORT,

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

@ -26,15 +26,7 @@ export default class SyncLogs {
return syncLogs?.map((h) => new SyncLogs(h)); return syncLogs?.map((h) => new SyncLogs(h));
} }
public static async insert( public static async insert(syncLog: Partial<SyncLogs>, ncMeta = Noco.ncMeta) {
syncLog: Partial<
SyncLogs & {
created_at?;
updated_at?;
}
>,
ncMeta = Noco.ncMeta
) {
const insertObj = extractProps(syncLog, [ const insertObj = extractProps(syncLog, [
'project_id', 'project_id',
'fk_sync_source_id', 'fk_sync_source_id',

7
packages/nocodb/src/lib/models/SyncSource.ts

@ -65,12 +65,7 @@ export default class SyncSource {
} }
public static async insert( public static async insert(
syncSource: Partial< syncSource: Partial<SyncSource>,
SyncSource & {
created_at?;
updated_at?;
}
>,
ncMeta = Noco.ncMeta ncMeta = Noco.ncMeta
) { ) {
const insertObj = extractProps(syncSource, [ const insertObj = extractProps(syncSource, [

14
packages/nocodb/src/lib/models/View.ts

@ -246,8 +246,6 @@ export default class View implements ViewType {
Partial<FormView | GridView | GalleryView | KanbanView | MapView> & { Partial<FormView | GridView | GalleryView | KanbanView | MapView> & {
copy_from_id?: string; copy_from_id?: string;
fk_grp_col_id?: string; fk_grp_col_id?: string;
created_at?;
updated_at?;
}, },
ncMeta = Noco.ncMeta ncMeta = Noco.ncMeta
) { ) {
@ -259,8 +257,6 @@ export default class View implements ViewType {
'fk_model_id', 'fk_model_id',
'project_id', 'project_id',
'base_id', 'base_id',
'created_at',
'updated_at',
'meta', 'meta',
]); ]);
@ -656,11 +652,10 @@ export default class View implements ViewType {
colId: string, colId: string,
colData: { colData: {
order?: number; order?: number;
show?: boolean; show?: BoolType;
}, },
ncMeta = Noco.ncMeta ncMeta = Noco.ncMeta
): Promise<Array<GridViewColumn | any>> { ) {
const columns: Array<GridViewColumn | any> = [];
const view = await this.get(viewId, ncMeta); const view = await this.get(viewId, ncMeta);
let table; let table;
let cacheScope; let cacheScope;
@ -726,9 +721,7 @@ export default class View implements ViewType {
await NocoCache.set(key, o); await NocoCache.set(key, o);
} }
// set meta // set meta
await ncMeta.metaUpdate(null, null, table, updateObj, colId); return await ncMeta.metaUpdate(null, null, table, updateObj, colId);
return columns;
} }
static async insertOrUpdateColumn( static async insertOrUpdateColumn(
@ -749,7 +742,6 @@ export default class View implements ViewType {
> { > {
const view = await this.get(viewId); const view = await this.get(viewId);
const table = this.extractViewColumnsTableName(view); const table = this.extractViewColumnsTableName(view);
console.log(table);
const existingCol = await ncMeta.metaGet2(null, null, table, { const existingCol = await ncMeta.metaGet2(null, null, table, {
fk_view_id: viewId, fk_view_id: viewId,

1
packages/nocodb/src/lib/plugins/backblaze/BackblazePlugin.ts

@ -1,5 +1,4 @@
import { XcStoragePlugin } from 'nc-plugin'; import { XcStoragePlugin } from 'nc-plugin';
import Backblaze from './Backblaze'; import Backblaze from './Backblaze';
import type { IStorageAdapterV2 } from 'nc-plugin'; import type { IStorageAdapterV2 } from 'nc-plugin';

1
packages/nocodb/src/lib/plugins/discord/DiscordPlugin.ts

@ -1,5 +1,4 @@
import { XcWebhookNotificationPlugin } from 'nc-plugin'; import { XcWebhookNotificationPlugin } from 'nc-plugin';
import Discord from './Discord'; import Discord from './Discord';
import type { IWebhookNotificationAdapter } from 'nc-plugin'; import type { IWebhookNotificationAdapter } from 'nc-plugin';

1
packages/nocodb/src/lib/plugins/gcs/GcsPlugin.ts

@ -1,5 +1,4 @@
import { XcStoragePlugin } from 'nc-plugin'; import { XcStoragePlugin } from 'nc-plugin';
import Gcs from './Gcs'; import Gcs from './Gcs';
import type { IStorageAdapterV2 } from 'nc-plugin'; import type { IStorageAdapterV2 } from 'nc-plugin';

1
packages/nocodb/src/lib/plugins/linode/LinodeObjectStoragePlugin.ts

@ -1,5 +1,4 @@
import { XcStoragePlugin } from 'nc-plugin'; import { XcStoragePlugin } from 'nc-plugin';
import LinodeObjectStorage from './LinodeObjectStorage'; import LinodeObjectStorage from './LinodeObjectStorage';
import type { IStorageAdapterV2 } from 'nc-plugin'; import type { IStorageAdapterV2 } from 'nc-plugin';

1
packages/nocodb/src/lib/plugins/mailerSend/MailerSend.ts

@ -1,6 +1,5 @@
import MailerSend, { EmailParams, Recipient } from 'mailersend'; import MailerSend, { EmailParams, Recipient } from 'mailersend';
import type { IEmailAdapter } from 'nc-plugin'; import type { IEmailAdapter } from 'nc-plugin';
import type { XcEmail } from '../../../interface/IEmailAdapter'; import type { XcEmail } from '../../../interface/IEmailAdapter';
export default class Mailer implements IEmailAdapter { export default class Mailer implements IEmailAdapter {

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save