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>
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 type { User } from '~/lib'
@ -42,9 +42,11 @@ const loadUsers = async (page = currentPage, limit = currentLimit) => {
query: searchText.value,
},
} as RequestParams)
if (!response) return
pagination.total = response.pageInfo.totalRows ?? 0
pagination.pageSize = 10
users = response.list as UserType[]
@ -59,7 +61,7 @@ const updateRole = async (userId: string, roles: Role) => {
try {
await api.orgUsers.update(userId, {
roles,
} as unknown as UserType)
} as OrgUserReqType)
message.success(t('msg.success.roleUpdated'))
$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>
</template>
<style>
textarea:focus {
box-shadow: none;

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

@ -20,7 +20,7 @@ const fetchPluginApps = async () => {
apps = plugins.map((p) => ({
...p,
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) {
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 vState = useVModel(props, 'state', emits)
const vReload = useVModel(props, 'reload', emits)
const { $api, $e } = useNuxtApp()
@ -27,10 +28,15 @@ const { loadProject } = projectStore
const { project } = storeToRefs(projectStore)
let sources = $ref<BaseType[]>([])
let activeBaseId = $ref('')
let metadiffbases = $ref<string[]>([])
let clientType = $ref<ClientType>(ClientType.MYSQL)
let isReloading = $ref(false)
let forceAwakened = $ref(false)
async function loadBases() {
@ -40,8 +46,8 @@ async function loadBases() {
isReloading = true
vReload.value = true
const baseList = await $api.base.list(project.value?.id)
if (baseList.bases.list && baseList.bases.list.length) {
sources = baseList.bases.list
if (baseList.list && baseList.list.length) {
sources = baseList.list
}
} catch (e) {
console.error(e)
@ -247,7 +253,7 @@ watch(
@click="baseAction(sources[0].id, DataSourcesSubTab.Metadata)"
>
<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>
<MdiDatabaseAlert class="text-lg group-hover:text-accent text-primary" />
</a-tooltip>
@ -316,7 +322,7 @@ watch(
@click="baseAction(base.id, DataSourcesSubTab.Metadata)"
>
<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>
<MdiDatabaseAlert class="text-lg group-hover:text-accent text-primary" />
</a-tooltip>

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

@ -333,8 +333,7 @@ export default {
:ref="i ? null : (el) => (cellWrapperEl = el)"
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"
:column="col" />
<LazySmartsheetVirtualCell v-if="isVirtualCol(col)" v-model="row.row[col.title]" :row="row" :column="col" />
<LazySmartsheetCell
v-else

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

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

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

@ -199,7 +199,11 @@ defineExpose({
<template>
<div
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
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) {
await $api.dbView.galleryUpdate(activeView.value?.id, {
...activeView.value?.view,
fk_cover_image_col_id: val,
})
;(activeView.value.view as GalleryType).fk_cover_image_col_id = val
} else if (activeView.value?.type === ViewTypes.KANBAN) {
await $api.dbView.kanbanUpdate(activeView.value?.id, {
...activeView.value?.view,
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 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
// 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 = () => {
_addSort()
nextTick(() => {
console.log(removeIcon.value)
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 () => {
if (!project?.id) return
tokensInfo = await $api.apiToken.list(project.id)
tokensInfo = (await $api.apiToken.list(project.id)).list
}
const openNewTokenModal = () => {
@ -40,7 +40,7 @@ const copyToken = async (token: string | undefined) => {
await copy(token)
// Copied to clipboard
message.info(t('msg.info.copiedToClipboard'))
} catch (e) {
} catch (e: any) {
message.error(e.message)
}
$e('c:api-token:copy')

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

@ -77,6 +77,11 @@ const inviteUser = async (user: User) => {
try {
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)
// Successfully added user to project

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

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

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

@ -1,4 +1,5 @@
<script setup lang="ts">
import type { HookType } from 'nocodb-sdk'
import { MetaInj, extractSdkResponseErrorMsg, inject, message, onMounted, ref, useI18n, useNuxtApp } from '#imports'
const emit = defineEmits(['edit', 'add'])
@ -13,9 +14,9 @@ const meta = inject(MetaInj, ref())
async function loadHooksList() {
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) => {
hook.notification = hook.notification && JSON.parse(hook.notification)
hook.notification = typeof hook.notification === 'string' ? JSON.parse(hook.notification) : hook.notification
return hook
})
} 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,
comments_only: commentsOnly.value,
})
)?.reverse?.() || []
).list?.reverse?.() || []
}
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
formattedData.value.set(key, formatData(data.value.list))
countByStack.value.set(key, data.value.pageInfo.totalRows || 0)
@ -167,17 +167,26 @@ const [useProvideKanbanViewStore, useKanbanViewStore] = useInjectionState(
where = `(${groupingField.value},is,null)`
}
if (xWhere.value) {
where = `${where} and ${xWhere.value}`
}
const response = !isPublic.value
? await api.dbViewRow.list('noco', project.value.id!, meta.value!.id!, viewMeta.value!.id!, {
...{ where: xWhere.value },
...params,
...(isUIAllowed('sortSync') ? {} : { sortArrJson: JSON.stringify(sorts.value) }),
...(isUIAllowed('filterSync') ? {} : { filterArrJson: JSON.stringify(nestedFilters.value) }),
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() {
@ -299,10 +308,7 @@ const [useProvideKanbanViewStore, useKanbanViewStore] = useInjectionState(
async function updateKanbanMeta(updateObj: Partial<KanbanType>) {
if (!viewMeta?.value?.id || !isUIAllowed('xcDatatableEditable')) return
await $api.dbView.kanbanUpdate(viewMeta.value.id, {
...kanbanMetaData.value,
...updateObj,
})
await $api.dbView.kanbanUpdate(viewMeta.value.id, updateObj)
}
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(
(
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,
where?: ComputedRef<string | undefined>,
) => {
@ -88,15 +88,12 @@ const [useProvideMapViewStore, useMapViewStore] = useInjectionState(
})
: await fetchSharedViewData({ sortsArr: sorts.value, filtersArr: nestedFilters.value })
formattedData.value = formatData(res.list)
formattedData.value = formatData(res!.list)
}
async function updateMapMeta(updateObj: Partial<MapType>) {
if (!viewMeta?.value?.id || !isUIAllowed('xcDatatableEditable')) return
await $api.dbView.mapUpdate(viewMeta.value.id, {
...mapMetaData.value,
...updateObj,
})
await $api.dbView.mapUpdate(viewMeta.value.id, updateObj)
}
const { getMeta } = useMetas()
@ -107,7 +104,7 @@ const [useProvideMapViewStore, useMapViewStore] = useInjectionState(
{
metaValue = meta.value,
viewMetaValue = viewMeta.value,
}: { metaValue?: MapType; viewMetaValue?: ViewType | MapType } = {},
}: { metaValue?: MapType & { id: string }; viewMetaValue?: (ViewType | MapType) & { id: string } } = {},
) {
const row = currentRow.row
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
sharedView.value = { title: '', ...viewMeta }
sharedView.value = { title: '', ...viewMeta } as ViewType
meta.value = { ...viewMeta.model }
let order = 1
@ -83,29 +83,34 @@ export function useSharedView() {
Object.keys(relatedMetas).forEach((key) => setMeta(relatedMetas[key]))
}
const fetchSharedViewData = async ({
sortsArr,
filtersArr,
offset,
}: {
const fetchSharedViewData = async (param: {
sortsArr: SortType[]
filtersArr: FilterType[]
fields?: any[]
sort?: any[]
where?: string
/** Query params for nested data */
nested?: any
offset?: number
}) => {
if (!sharedView.value) return
if (!sharedView.value)
return {
list: [],
pageInfo: {},
}
if (!offset) {
if (!param.offset) {
const page = paginationData.value.page || 1
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!,
{
offset,
filterArrJson: JSON.stringify(filtersArr ?? nestedFilters.value),
sortArrJson: JSON.stringify(sortsArr ?? sorts.value),
...param,
filterArrJson: JSON.stringify(param.filtersArr ?? nestedFilters.value),
sortArrJson: JSON.stringify(param.sortsArr ?? sorts.value),
} as any,
{
headers: {
@ -113,7 +118,6 @@ export function useSharedView() {
},
},
)
return data
}
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 sorts = ref<Required<SortType>[]>((unref(initialSorts) as Required<SortType>[]) ?? [])
const sorts = ref<SortType[]>(unref(initialSorts) ?? [])
const nestedFilters = ref<FilterType[]>(unref(initialFilters) ?? [])
return {

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

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

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

@ -27,7 +27,7 @@ import {
} from '#imports'
import type { Row } from '~/lib'
const formatData = (list: Row[]) =>
const formatData = (list: Record<string, any>[]) =>
list.map((row) => ({
row: { ...row },
oldRow: { ...row },
@ -59,7 +59,7 @@ export function useViewData(
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>()
@ -183,7 +183,7 @@ export function useViewData(
for (const row of formattedData.value) {
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,
})
: await fetchSharedViewData({ sortsArr: sorts.value, filtersArr: nestedFilters.value })
formattedData.value = formatData(response.list)
paginationData.value = response.pageInfo

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

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

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

@ -50,7 +50,7 @@ export function useViewSorts(view: Ref<ViewType | undefined>, reloadData?: () =>
}
}
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) {
console.error(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 path from 'path';
import { promisify } from 'util';
import * as Sentry from '@sentry/node';
import bodyParser from 'body-parser';
import clear from 'clear';
@ -14,14 +13,12 @@ import morgan from 'morgan';
import NcToolGui from 'nc-lib-gui';
import requestIp from 'request-ip';
import { v4 as uuidv4 } from 'uuid';
import { T } from 'nc-help';
import mkdirp from 'mkdirp';
import { NC_LICENSE_KEY } from './constants';
import Migrator from './db/sql-migrator/lib/KnexMigrator';
import Store from './models/Store';
import NcConfigFactory from './utils/NcConfigFactory';
import NcProjectBuilderCE from './v1-legacy/NcProjectBuilder';
import NcProjectBuilderEE from './v1-legacy/NcProjectBuilderEE';
import NcMetaImplCE from './meta/NcMetaIOImpl';

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

@ -1,11 +1,16 @@
import { Router } from 'express';
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw';
import { metaApiMetrics } from '../meta/helpers/apiMetrics';
import { PagedResponseImpl } from '../meta/helpers/PagedResponse';
import { apiTokenService } from '../services';
import type { Request, Response } from 'express';
export async function apiTokenList(req: Request, res: Response) {
res.json(await apiTokenService.apiTokenList({ userId: req['user'].id }));
res.json(
new PagedResponseImpl(
await apiTokenService.apiTokenList({ userId: req['user'].id })
)
);
}
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) {
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) {
res.json(
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),
...req.query,
@ -42,7 +47,7 @@ export async function auditList(req: Request, res: Response) {
export async function commentsCount(req: Request<any, any, any>, res) {
res.json(
await Audit.commentsCount({
await auditService.commentsCount({
fk_model_id: req.query.fk_model_id 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 });
router.get(
'/api/v1/db/meta/audits/comments',
ncMetaAclMw(commentList, 'commentList')
);
router.post(
'/api/v1/db/meta/audits/comments',
ncMetaAclMw(commentRow, 'commentRow')
);
router.post(
'/api/v1/db/meta/audits/rows/:rowId/update',
ncMetaAclMw(auditRowUpdate, 'auditRowUpdate')
);
router.get(
'/api/v1/db/meta/audits/comments/count',
ncMetaAclMw(commentsCount, 'commentsCount')
);
router.get(
'/api/v1/db/meta/projects/:projectId/audits',
ncMetaAclMw(auditList, 'auditList')
);
export default router;

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

@ -1,7 +1,6 @@
import { PagedResponseImpl } from '../meta/helpers/PagedResponse';
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw';
import { metaApiMetrics } from '../meta/helpers/apiMetrics';
import { baseService } from '../services';
import type Base from '../models/Base';
import type { BaseListType } from 'nocodb-sdk';
@ -32,13 +31,12 @@ async function baseList(
projectId: req.params.projectId,
});
res // todo: pagination
.json({
bases: new PagedResponseImpl(bases, {
count: bases.length,
limit: bases.length,
}),
});
res.json(
new PagedResponseImpl(bases, {
count: bases.length,
limit: bases.length,
})
);
}
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,
});
res.json({ msg: 'success' });
res.json({ msg: 'The relation data has been deleted successfully' });
}
//@ts-ignore
async function relationDataAdd(req, res) {
await dataService.relationDataAdd({
viewId: req.params.viewId,
@ -131,7 +130,7 @@ async function relationDataAdd(req, res) {
cookie: req,
});
res.json({ msg: 'success' });
res.json({ msg: 'The relation data has been created successfully' });
}
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,
});
res.json({ msg: 'success' });
res.json({ msg: 'The relation data has been deleted successfully' });
}
//@ts-ignore
@ -92,7 +92,7 @@ async function relationDataAdd(req, res) {
refRowId: req.params.refRowId,
});
res.json({ msg: 'success' });
res.json({ msg: 'The relation data has been created successfully' });
}
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 Base from '../../models/Base';
import NcConnectionMgrv2 from '../../utils/common/NcConnectionMgrv2';
import Column from '../../models/Column';
import { dataService } from '../../services';
import type LookupColumn from '../../models/LookupColumn';
import type LinkToAnotherRecordColumn from '../../models/LinkToAnotherRecordColumn';
import type { Request } from 'express';
export async function getViewAndModelFromRequestByAliasOrId(
req:
| Request<{ projectName: string; tableName: string; viewName?: string }>

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

@ -1,32 +1,33 @@
import { Router } from 'express';
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw';
import { metaApiMetrics } from '../meta/helpers/apiMetrics';
import { PagedResponseImpl } from '../meta/helpers/PagedResponse';
import { filterService } from '../services';
import type { FilterReqType } from 'nocodb-sdk';
import type { FilterListType, FilterReqType } from 'nocodb-sdk';
import type { Request, Response } from 'express';
// @ts-ignore
export async function filterGet(req: Request, res: Response) {
res.json(await filterService.filterGet({ filterId: req.params.filterId }));
}
// @ts-ignore
export async function filterList(req: Request, res: Response) {
export async function filterList(req: Request, res: Response<FilterListType>) {
res.json(
await filterService.filterList({
viewId: req.params.viewId,
})
new PagedResponseImpl(
await filterService.filterList({
viewId: req.params.viewId,
})
)
);
}
// @ts-ignore
export async function filterChildrenRead(req: Request, res: Response) {
const filter = await filterService.filterChildrenList({
filterId: req.params.filterParentId,
});
res.json(filter);
res.json(
new PagedResponseImpl(
await filterService.filterChildrenList({
filterId: req.params.filterParentId,
})
)
);
}
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) {
res.json(
await filterService.hookFilterList({
hookId: req.params.hookId,
})
new PagedResponseImpl(
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>,
res: Response<HookListType>
) {
// todo: pagination
res.json(
new PagedResponseImpl(
await hookService.hookList({ tableId: req.params.tableId })
@ -51,18 +50,17 @@ export async function hookTest(req: Request<any, any>, res: Response) {
hookTest: req.body,
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) {
res // todo: pagination
.json(
await hookService.tableSampleData({
tableId: req.params.tableId,
// todo: replace any with type
operation: req.params.operation as any,
})
);
res.json(
await hookService.tableSampleData({
tableId: req.params.tableId,
// todo: replace any with type
operation: req.params.operation as any,
})
);
}
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) {
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) {
@ -27,7 +27,7 @@ export async function baseMetaDiffSync(req, res) {
baseId: req.params.baseId,
});
res.json({ msg: 'success' });
res.json({ msg: 'The base meta has been synchronized successfully' });
}
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,
});
res.json({ msg: 'success' });
res.json({ msg: 'UI ACL has been created successfully' });
}
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) {
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 });

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

@ -2,13 +2,21 @@ import { Router } from 'express';
import { OrgUserRoles } from 'nocodb-sdk';
import { metaApiMetrics } from '../meta/helpers/apiMetrics';
import ncMetaAclMw from '../meta/helpers/ncMetaAclMw';
import { PagedResponseImpl } from '../meta/helpers/PagedResponse';
import { orgUserService } from '../services';
import { User } from '../models';
async function userList(req, res) {
res.json(
await orgUserService.userList({
query: req.query,
})
new PagedResponseImpl(
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({
userId: req.params.userId,
});
res.json({ msg: 'success' });
res.json({ msg: 'The user has been deleted successfully' });
}
async function userAdd(req, res) {
@ -49,7 +57,7 @@ async function userInviteResend(req, res): Promise<any> {
req,
});
res.json({ msg: 'success' });
res.json({ msg: 'The invitation has been sent to the user' });
}
async function generateResetUrl(req, res) {
@ -71,7 +79,7 @@ async function appSettingsSet(req, res) {
settings: req.body,
});
res.json({ msg: 'Settings saved' });
res.json({ msg: 'The app settings have been saved' });
}
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 { metaApiMetrics } from '../meta/helpers/apiMetrics';
import Filter from '../models/Filter';
import { projectService } from '../services';
import type { ProjectListType } 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, next): Promise<any> {
res.json(
await projectUserService.projectUserUpdate({
projectUser: req.body,
projectId: req.params.projectId,
userId: req.params.userId,
req,
})
);
async function projectUserUpdate(req, res): Promise<any> {
await projectUserService.projectUserUpdate({
projectUser: req.body,
projectId: req.params.projectId,
userId: req.params.userId,
req,
});
res.json({
msg: 'The user has been updated successfully',
});
}
async function projectUserDelete(req, res): Promise<any> {
@ -41,19 +41,20 @@ async function projectUserDelete(req, res): Promise<any> {
req,
});
res.json({
msg: 'success',
msg: 'The user has been deleted successfully',
});
}
async function projectUserInviteResend(req, res): Promise<any> {
res.json(
await projectUserService.projectUserInviteResend({
projectId: req.params.projectId,
userId: req.params.userId,
projectUser: req.body,
req,
})
);
await projectUserService.projectUserInviteResend({
projectId: req.params.projectId,
userId: req.params.userId,
projectUser: req.body,
req,
});
res.json({
msg: 'The invitation has been sent to the user',
});
}
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,
sharedViewUuid: req.params.sharedViewUuid,
});
res.json({ data: pagedResponse });
res.json(pagedResponse);
}
// 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 ncMetaAclMw from '../meta/helpers/ncMetaAclMw';
import { metaApiMetrics } from '../meta/helpers/apiMetrics';
import { sortService } from '../services';
import type { SortListType, SortReqType } from 'nocodb-sdk';
import type { Request, Response } from 'express';
// @ts-ignore
export async function sortList(
req: Request<any, any, any>,
res: Response<SortListType>
) {
const sortList = await sortService.sortList({
viewId: req.params.viewId,
});
res.json({
sorts: new PagedResponseImpl(sortList),
});
res.json(
new PagedResponseImpl(
await sortService.sortList({
viewId: req.params.viewId,
})
)
);
}
// @ts-ignore
export async function sortCreate(req: Request<any, any, SortReqType>, res) {
const sort = await sortService.sortCreate({
sort: req.body,
@ -43,6 +41,7 @@ export async function sortDelete(req: Request, res: Response) {
});
res.json(sort);
}
export async function sortGet(req: Request, res: Response) {
const sort = await sortService.sortGet({
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) {
await tableService.tableUpdate({
tableId: req.params.tableId,
table: req.body,
projectId: (req as any).ncProjectId,
});
res.json({ msg: 'success' });
res.json({ msg: 'The table has been updated successfully' });
}
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 { Strategy as AuthTokenStrategy } from 'passport-auth-token';
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 JwtStrategy = passportJWT.Strategy;
@ -13,12 +19,6 @@ const jwtOptions = {
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;
export function initStrategies(router): void {

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

@ -1,6 +1,5 @@
import { promisify } from 'util';
import * as ejs from 'ejs';
import passport from 'passport';
import catchError, { NcError } from '../../meta/helpers/catchError';
import extractProjectIdAndAuthenticate from '../../meta/helpers/extractProjectIdAndAuthenticate';
@ -132,7 +131,7 @@ async function passwordChange(req: Request<any, any>, res): Promise<any> {
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> {
@ -149,7 +148,7 @@ async function tokenValidate(req, res): Promise<any> {
await userService.tokenValidate({
token: req.params.tokenId,
});
res.json(true);
res.json({ msg: 'Token has been validated successfully' });
}
async function passwordReset(req, res): Promise<any> {
@ -159,7 +158,7 @@ async function passwordReset(req, res): Promise<any> {
req,
});
res.json({ msg: 'Password reset successful' });
res.json({ msg: 'Password has been reset successfully' });
}
async function emailVerification(req, res): Promise<any> {
@ -168,7 +167,7 @@ async function emailVerification(req, res): Promise<any> {
req,
});
res.json({ msg: 'Email verified successfully' });
res.json({ msg: 'Email has been verified successfully' });
}
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 catchError from '../meta/helpers/catchError';
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
export async function viewGet(req: Request, res: Response) {}
// @ts-ignore
export async function viewList(req: Request<any, any, any>, res: Response) {
const filteredViewList = await viewService.viewList({
tableId: req.params.tableId,
user: (req as any).session?.passport?.user,
});
res.json(new PagedResponseImpl(filteredViewList));
res.json(
new PagedResponseImpl(
await viewService.viewList({
tableId: req.params.tableId,
user: (req as any).session?.passport?.user,
})
)
);
}
// @ts-ignore
@ -78,9 +79,11 @@ async function hideAllColumns(req: Request<any, any>, res) {
async function shareViewList(req: Request<any, any>, res) {
res.json(
await viewService.shareViewList({
tableId: req.params.tableId,
})
new PagedResponseImpl(
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 { metaApiMetrics } from '../meta/helpers/apiMetrics';
import { viewColumnService } from '../services';
import { PagedResponseImpl } from '../meta/helpers/PagedResponse';
import type { Request, Response } from 'express';
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) {
const viewColumn = await viewColumnService.columnAdd({
viewId: req.params.viewId,
columnId: req.body.fk_column_id,
column: {
...req.body,
view_id: req.params.viewId,
},
column: req.body,
});
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(
await formViewService.formViewUpdate({
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) {
const view = await galleryViewService.galleryViewCreate({
gallery: req.body,
// todo: sanitize
tableId: req.params.tableId,
});
res.json(view);
res.json(
await galleryViewService.galleryViewCreate({
gallery: req.body,
// todo: sanitize
tableId: req.params.tableId,
})
);
}
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 { 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 { metaApiMetrics } from '../../meta/helpers/apiMetrics';
import { kanbanViewService } from '../../services';
import type { KanbanType } from 'nocodb-sdk';
import type { Request, Response } from 'express';
// todo: map to service
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) {
T.emit('evt', { evt_type: 'vtable:created', show_as: 'kanban' });
const view = await View.insert({
...req.body,
// todo: sanitize
fk_model_id: req.params.tableId,
type: ViewTypes.KANBAN,
});
res.json(view);
res.json(
await kanbanViewService.kanbanViewCreate({
tableId: req.params.tableId,
kanban: req.body,
})
);
}
export async function kanbanViewUpdate(req, res) {
T.emit('evt', { evt_type: 'view:updated', type: 'kanban' });
res.json(await KanbanView.update(req.params.kanbanViewId, req.body));
res.json(
await kanbanViewService.kanbanViewUpdate({
kanbanViewId: req.params.kanbanViewId,
kanban: req.body,
})
);
}
const router = Router({ mergeParams: true });
@ -37,14 +38,17 @@ router.post(
metaApiMetrics,
ncMetaAclMw(kanbanViewCreate, 'kanbanViewCreate')
);
router.patch(
'/api/v1/db/meta/kanbans/:kanbanViewId',
metaApiMetrics,
ncMetaAclMw(kanbanViewUpdate, 'kanbanViewUpdate')
);
router.get(
'/api/v1/db/meta/kanbans/:kanbanViewId',
metaApiMetrics,
ncMetaAclMw(kanbanViewGet, 'kanbanViewGet')
);
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 { knex } from 'knex';
import { T } from 'nc-help';
import findIndex from 'lodash/findIndex';
import find from 'lodash/find';
import jsonfile from 'jsonfile';
@ -15,6 +14,7 @@ import Debug from '../../util/Debug';
import * as dataHelp from './data.helper';
import SqlClient from './SqlClient';
import type { Knex } from 'knex';
const evt = new Emit();
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 { promisify } from 'util';
import knex from 'knex';
import isEmpty from 'lodash/isEmpty';
import mapKeys from 'lodash/mapKeys';
import find from 'lodash/find';
@ -12,10 +11,8 @@ import levenshtein from 'fast-levenshtein';
import Debug from '../../../util/Debug';
import Emit from '../../../util/emit';
import Result from '../../../util/Result';
import KnexClient from '../KnexClient';
import queries from './mysql.queries';
import fakerFunctionList from './fakerFunctionList';
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 Result from '../../../util/Result';
import MysqlClient from './MysqlClient';
const log = new Debug('TidbClient');
import MysqlClient from './MysqlClient';
class Tidb extends MysqlClient {
/**
*
@ -33,7 +32,7 @@ class Tidb extends MysqlClient {
for (let i = 0; i < response[0].length; ++i) {
let index = response[0][i];
index = _.mapKeys(index, function (_v, k) {
index = mapKeys(index, function (_v, k) {
return k.toLowerCase();
});
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 Result from '../../../util/Result';
import MysqlClient from './MysqlClient';
const log = new Debug('VitessClient');
import MysqlClient from './MysqlClient';
class Vitess extends MysqlClient {
constructor(connectionConfig: any) {
super(connectionConfig);
@ -141,9 +140,7 @@ class Vitess extends MysqlClient {
for (let i = 0; i < response[0].length; ++i) {
const column: any = {};
response[0][i] = _.mapKeys(response[0][i], (_v, k) =>
k.toLowerCase()
);
response[0][i] = mapKeys(response[0][i], (_v, k) => k.toLowerCase());
column.tn = args.tn;
column.cn = response[0][i].cn;
@ -220,7 +217,7 @@ class Vitess extends MysqlClient {
for (let i = 0; i < response[0].length; ++i) {
let index = response[0][i];
index = _.mapKeys(index, function (_v, k) {
index = mapKeys(index, function (_v, k) {
return k.toLowerCase();
});
indexes.push(index);

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

@ -1,5 +1,4 @@
import { nanoid } from 'nanoid';
import knex from 'knex';
import isEmpty from 'lodash/isEmpty';
import mapKeys from 'lodash/mapKeys';
@ -8,6 +7,7 @@ import KnexClient from '../KnexClient';
import Debug from '../../../util/Debug';
import Result from '../../../util/Result';
import queries from './pg.queries';
const log = new Debug('PGClient');
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 _ from 'lodash';
import lodash from 'lodash';
import find from 'lodash/find';
import isEmpty from 'lodash/isEmpty';
import KnexClient from '../KnexClient';
import Debug from '../../../util/Debug';
import Result from '../../../util/Result';
import queries from './snowflake.queries';
const log = new Debug('SnowflakeClient');
const rowsToLower = (arr) => {
@ -1341,7 +1341,7 @@ class SnowflakeClient extends KnexClient {
*/
async _getQuery(args) {
try {
if (_.isEmpty(this._version)) {
if (isEmpty(this._version)) {
const result = await this.version();
this._version = result.data.object;
log.debug(
@ -1350,8 +1350,6 @@ class SnowflakeClient extends KnexClient {
);
}
// log.debug(this._version, args);
if (this._version.key in this.queries[args.func]) {
return this.queries[args.func][this._version.key].sql;
}
@ -1831,7 +1829,7 @@ class SnowflakeClient extends KnexClient {
let downQuery = '';
for (let i = 0; i < args.columns.length; ++i) {
const oldColumn = lodash.find(originalColumns, {
const oldColumn = find(originalColumns, {
cn: args.columns[i].cno,
});
@ -2640,7 +2638,6 @@ function getDefaultValue(n) {
case 'dec':
return n.cdf;
break;
case 'datetime':
case 'timestamp':
case 'date':
@ -2651,10 +2648,8 @@ function getDefaultValue(n) {
) {
return n.cdf;
}
// return JSON.stringify(n.cdf);
break;
default:
// return JSON.stringify(n.cdf);
break;
}
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';
export { DbFactory } from './lib/DbFactory';
export { BaseModelSql } from './lib/sql/BaseModelSql';
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 */
import groupBy from 'lodash/groupBy';
import type { Knex } from 'knex';
import type Filter from '../../../models/Filter';
import type Sort from '../../../models/Sort';
const autoBind = require('auto-bind');
const _ = require('lodash');
const Validator = require('validator');
// interface BaseModel {
@ -977,7 +977,7 @@ abstract class BaseModel {
)
);
const gs = _.groupBy(childs, cn);
const gs = groupBy(childs, cn);
parent.forEach((row) => {
row[child] = gs[row[this.pks?.[0]?.cn]] || [];
});
@ -1133,7 +1133,7 @@ abstract class BaseModel {
.whereIn(rcn, parentIds)
);
const gs = _.groupBy(parents, rcn);
const gs = groupBy(parents, rcn);
childs.forEach((row) => {
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) {
console.log(e);
throw e;
@ -1224,7 +1224,7 @@ abstract class BaseModel {
);
return childs.map(({ count }) => count);
// return _.groupBy(childs, cn);
// return groupBy(childs, cn);
} catch (e) {
console.log(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 _ from 'lodash';
import groupBy from 'lodash/groupBy';
import isEmpty from 'lodash/isEmpty';
import difference from 'lodash/difference';
import Validator from 'validator';
import Papaparse from 'papaparse';
import BaseModel from '../BaseModel';
import formulaQueryBuilder from './formulaQueryBuilderFromString';
@ -316,7 +317,7 @@ class BaseModelSql extends BaseModel {
: response?.[ai._cn],
this.defaultNestedBtQueryParams
);
response = !_.isEmpty(nestedResponse) ? nestedResponse : response;
response = !isEmpty(nestedResponse) ? nestedResponse : response;
}
if (Array.isArray(response)) {
@ -1214,7 +1215,7 @@ class BaseModelSql extends BaseModel {
private _buildDistinctQuery(columns: string[]) {
const query = this.$db;
const formulaColumns = this.filterFormulaColumns(columns);
const otherColumns = _.difference(columns, formulaColumns);
const otherColumns = difference(columns, formulaColumns);
if (!otherColumns.length && !formulaColumns.length) {
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) => {
row[`${this.dbModels?.[child]?._tn || child}List`] =
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] || []);
}
@ -2005,7 +2006,7 @@ class BaseModelSql extends BaseModel {
.whereIn(rcn, parentIds)
);
const gs = _.groupBy(
const gs = groupBy(
parents,
this.dbModels[parent]?.columnToAlias?.[rcn] || rcn
);
@ -2084,8 +2085,8 @@ class BaseModelSql extends BaseModel {
)
);
// return _.groupBy(childs, cn);
return _.groupBy(childs, this.dbModels?.[child]?.columnToAlias[cn]);
// return groupBy(childs, cn);
return groupBy(childs, this.dbModels?.[child]?.columnToAlias[cn]);
} catch (e) {
console.log(e);
throw e;
@ -2134,7 +2135,7 @@ class BaseModelSql extends BaseModel {
);
return childs.map(({ count }) => count);
// return _.groupBy(childs, cn);
// return groupBy(childs, cn);
} catch (e) {
console.log(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 _ from 'lodash';
import groupBy from 'lodash/groupBy';
import DataLoader from 'dataloader';
import {
AuditOperationSubTypes,
@ -437,7 +436,7 @@ class BaseModelSqlv2 {
})
).getProto();
return _.groupBy(
return groupBy(
children.map((c) => {
c.__proto__ = proto;
return c;
@ -605,7 +604,6 @@ class BaseModelSqlv2 {
.first();
const { count } = await query;
return count;
// return _.groupBy(children, cn);
} catch (e) {
console.log(e);
throw e;
@ -683,7 +681,7 @@ class BaseModelSqlv2 {
dbDriver: this.dbDriver,
})
).getProto();
const gs = _.groupBy(
const gs = groupBy(
children.map((c) => {
c.__proto__ = proto;
return c;
@ -800,7 +798,7 @@ class BaseModelSqlv2 {
!this.isSqlite
);
const gs = _.groupBy(children, GROUP_COL);
const gs = groupBy(children, GROUP_COL);
return parentIds.map((id) => gs?.[id]?.[0] || []);
}
@ -1362,7 +1360,7 @@ class BaseModelSqlv2 {
},
true
);
const gs = _.groupBy(data, pCol.title);
const gs = groupBy(data, pCol.title);
return ids.map(async (id: string) => gs?.[id]?.[0]);
} catch (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 Filter from '../../../../models/Filter';
import type { FilterType } from 'nocodb-sdk';
import type { BaseModelSql } from './BaseModelSql';
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 url from 'url';
import { promisify } from 'util';
import fsExtra from 'fs-extra';
import importFresh from 'import-fresh';
import inflection from 'inflection';
@ -10,14 +9,10 @@ import slash from 'slash';
import { T } from 'nc-help';
import { customAlphabet } from 'nanoid';
import SqlClientFactory from '../sql-client/lib/SqlClientFactory';
// import debug from 'debug';
import KnexMigrator from '../sql-migrator/lib/KnexMigrator';
// import {XKnex} from "../sql-data-mapper";
import NcConnectionMgr from '../../utils/common/NcConnectionMgr';
import Debug from '../util/Debug';
import Result from '../util/Result';
import type MssqlClient from '../sql-client/lib/mssql/MssqlClient';
import type MysqlClient from '../sql-client/lib/mysql/MysqlClient';
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';
const randomID = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 20);
const log = new Debug('SqlMgr');
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 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 { AGG_DEFAULT_COLS, GROUPBY_DEFAULT_COLS } from './schemaHelp';
abstract class BaseGqlXcTsSchema extends BaseRender {
@ -142,7 +140,7 @@ abstract class BaseGqlXcTsSchema extends BaseRender {
let hasManyRelations = args.hasMany;
if (hasManyRelations.length > 1) {
hasManyRelations = lodash.uniqBy(hasManyRelations, (e) => {
hasManyRelations = uniqBy(hasManyRelations, (e) => {
return [e.tn, e.rtn].join();
});
}
@ -161,7 +159,7 @@ abstract class BaseGqlXcTsSchema extends BaseRender {
let belongsToRelations = args.belongsTo;
if (belongsToRelations.length > 1) {
belongsToRelations = lodash.uniqBy(belongsToRelations, (e) => {
belongsToRelations = uniqBy(belongsToRelations, (e) => {
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 type { Acl } from '../../../../../../interface/config';
@ -60,7 +59,7 @@ class ExpressXcMiddleware extends BaseRender {
? args.relations.filter((r) => r.rtn === args.tn)
: [];
if (hmRelations.length > 1)
hmRelations = lodash.uniqBy(hmRelations, function (e) {
hmRelations = uniqBy(hmRelations, function (e) {
return [e.tn, e.rtn].join();
});
for (let i = 0; i < hmRelations.length; ++i) {
@ -86,7 +85,7 @@ class ExpressXcMiddleware extends BaseRender {
? args.relations.filter((r) => r.tn === args.tn)
: [];
if (btRelations.length > 1)
btRelations = lodash.uniqBy(btRelations, function (e) {
btRelations = uniqBy(btRelations, function (e) {
return [e.tn, e.rtn].join();
});
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 SwaggerTypes from './SwaggerTypes';
class SwaggerXc extends BaseRender {

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

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

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

@ -1,17 +1,11 @@
import fs from 'fs';
import path from 'path';
import { promisify } from 'util';
import glob from 'glob';
import SqlClientFactory from '../../sql-client/lib/SqlClientFactory';
import Debug from '../../util/Debug';
import Emit from '../../util/emit';
// import Handlebars from 'handlebars';
// import mkdirp from 'mkdirp';
import * as fileHelp from '../../util/file.help';
// import SqlMigrator from './SqlMigrator';
// import NcConfigFactory from '../../../utils/NcConfigFactory';
import Noco from '../../../Noco';
import Project from '../../../models/Project';
import NcConnectionMgrv2 from '../../../utils/common/NcConnectionMgrv2';
@ -21,7 +15,9 @@ import type { XKnex } from '../../sql-data-mapper';
import type { Knex } from 'knex';
const evt = new Emit();
const log = new Debug('KnexMigrator');
const NC_MIGRATION = 'nc_migrations';
/**
* 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 { XKnex } from '../../sql-data-mapper';
import type NcMetaIO from '../../../meta/NcMetaIO';
import type MssqlClient from '../../sql-client/lib/mssql/MssqlClient';
import type MysqlClient from '../../sql-client/lib/mysql/MysqlClient';
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 { promisify } from 'util';
import jsonfile from 'jsonfile';
export default class FileCollection {

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

@ -1,9 +1,7 @@
import CryptoJS from 'crypto-js';
import { customAlphabet } from 'nanoid';
import { XKnex } from '../db/sql-data-mapper';
import XcMigrationSource from '../migrations/XcMigrationSource';
import NcConnectionMgr from '../utils/common/NcConnectionMgr';
import { MetaTable } from '../utils/globals';
import XcMigrationSourcev2 from '../migrations/XcMigrationSourcev2';
@ -12,9 +10,8 @@ import type Noco from '../Noco';
import type { Knex } from '../db/sql-data-mapper';
import type { NcConfig } from '../../interface/config';
// import { nanoid } from 'nanoid';
/*import { v4 as uuidv4 } from 'uuid';*/
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 4);
const nanoidv2 = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 14);
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 CryptoJS from 'crypto-js';
import mkdirp from 'mkdirp';
import archiver from 'archiver';
import axios from 'axios';
import bodyParser from 'body-parser';
@ -18,7 +17,6 @@ import { ncp } from 'ncp';
import { UITypes } from 'nocodb-sdk';
import { T } from 'nc-help';
import { Result } from '../../interface/config';
import SqlClientFactory from '../db/sql-client/lib/SqlClientFactory';
import { NcConfigFactory } from '../index';
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 express from 'express';
import type { Handler } from 'express';
const randomID = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 10);
const XC_PLUGIN_DET = 'XC_PLUGIN_DET';
const NOCO_RELEASE = 'NOCO_RELEASE';

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

@ -1,6 +1,5 @@
import { v4 as uuidv4 } from 'uuid';
import { T } from 'nc-help';
import NcMetaMgr from './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 { Router } from 'express';
import multer from 'multer';
import ProjectMgr from '../db/sql-mgr/ProjectMgr';
import { packageVersion } from '../utils/packageVersion';
import projectAcl from '../utils/projectAcl';
@ -13,7 +12,6 @@ import type NcMetaIO from './NcMetaIO';
import type Noco from '../Noco';
import type { NcConfig } from '../../interface/config';
import type { Handler } from 'express';
// import ncGetMeta from './handlersv2/ncGetMeta';
export default class NcMetaMgrv2 {
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 kanbanViewController from '../../controllers/views/kanbanView.ctl';
import { userController } from '../../controllers/user';
// import extractProjectIdAndAuthenticate from './helpers/extractProjectIdAndAuthenticate';
import utilController from '../../controllers/util.ctl';
import projectUserController from '../../controllers/projectUser.ctl';
import sharedBaseController from '../../controllers/sharedBase.ctl';
@ -34,7 +33,6 @@ import modelVisibilityController from '../../controllers/modelVisibility.ctl';
import metaDiffController from '../../controllers/metaDiff.ctl';
import cacheController from '../../controllers/cache.ctl';
import apiTokenController from '../../controllers/apiToken.ctl';
import hookFilterController from '../../controllers/hookFilter.ctl';
import testController from '../../controllers/test.ctl';
import {
bulkDataAliasController,
@ -49,7 +47,6 @@ import {
publicDataExportController,
publicMetaController,
} from '../../controllers/publicControllers';
import swaggerController from '../../controllers/apiDocs';
import { importController, syncSourceController } from '../../controllers/sync';
import mapViewController from '../../controllers/views/mapView.ctl';
@ -102,7 +99,6 @@ export default function (router: Router, server) {
router.use(metaDiffController);
router.use(cacheController);
router.use(apiTokenController);
router.use(hookFilterController);
router.use(swaggerController);
router.use(syncSourceController);
router.use(kanbanViewController);

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

@ -1,5 +1,4 @@
import { promisify } from 'util';
import passport from 'passport';
import Model from '../../models/Model';
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
public static async insert(
audit: Partial<
Audit & {
created_at?;
updated_at?;
}
>,
audit: Partial<Audit>,
ncMeta = Noco.ncMeta,
{ forceAwait }: { forceAwait: boolean } = {
forceAwait: process.env['TEST'] === 'true',
@ -105,8 +100,6 @@ export default class Audit implements AuditType {
'status',
'description',
'details',
'created_at',
'updated_at',
]);
if (!insertObj.project_id && insertObj.fk_model_id) {
insertObj.project_id = (
@ -120,7 +113,7 @@ export default class Audit implements AuditType {
if (forceAwait) {
return await insertAudit();
} 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);
}
// 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) {

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

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

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

@ -182,7 +182,7 @@ export default class FormViewColumn implements FormColumnType {
}
// update meta
await ncMeta.metaUpdate(
return await ncMeta.metaUpdate(
null,
null,
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 { extractProps } from '../meta/helpers/extractProps';
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 {
fk_view_id?: string;
@ -26,6 +31,7 @@ export default class GalleryView implements GalleryType {
base_id?: string;
columns?: GalleryColumnType[];
meta?: MetaType;
constructor(data: GalleryView) {
Object.assign(this, data);
@ -95,16 +101,12 @@ export default class GalleryView implements GalleryType {
// get existing cache
const key = `${CacheScope.GALLERY_VIEW}:${galleryId}`;
let o = await NocoCache.get(key, CacheGetType.TYPE_OBJECT);
const updateObj = extractProps(body, [
'next_enabled',
'prev_enabled',
'cover_image_idx',
'cover_image',
'restrict_types',
'restrict_size',
'restrict_number',
'fk_cover_image_col_id',
]);
const updateObj = extractProps(body, ['fk_cover_image_col_id', 'meta']);
if (updateObj.meta && typeof updateObj.meta === 'object') {
updateObj.meta = JSON.stringify(updateObj.meta ?? {});
}
if (o) {
o = { ...o, ...updateObj };
// set cache

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

@ -10,10 +10,8 @@ export default class GridView implements GridType {
fk_view_id: string;
project_id?: string;
base_id?: string;
meta?: MetaType;
row_height?: number;
columns?: GridViewColumn[];
constructor(data: GridView) {
@ -73,7 +71,12 @@ export default class GridView implements GridType {
// get existing cache
const key = `${CacheScope.GRID_VIEW}:${viewId}`;
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) {
o = { ...o, ...updateObj };
// 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);
}
// set meta
await ncMeta.metaUpdate(
return await ncMeta.metaUpdate(
null,
null,
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));
}
public static async insert(
hook: Partial<
Hook & {
created_at?;
updated_at?;
}
>,
ncMeta = Noco.ncMeta
) {
public static async insert(hook: Partial<Hook>, ncMeta = Noco.ncMeta) {
const insertObj = extractProps(hook, [
'fk_model_id',
'title',
@ -140,8 +132,6 @@ export default class Hook implements HookType {
'active',
'project_id',
'base_id',
'created_at',
'updated_at',
]);
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));
}
public static async insert(
hookLog: Partial<
HookLog & {
created_at?;
updated_at?;
}
>,
ncMeta = Noco.ncMeta
) {
public static async insert(hookLog: Partial<HookLog>, ncMeta = Noco.ncMeta) {
const insertObj: any = extractProps(hookLog, [
'base_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);
const updateObj = extractProps(body, [
'title',
'fk_cover_image_col_id',
'fk_grp_col_id',
'meta',
]);

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

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

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

@ -127,12 +127,7 @@ export default class ModelRoleVisibility implements ModelRoleVisibilityType {
}
static async insert(
body: Partial<
ModelRoleVisibilityType & {
created_at?;
updated_at?;
}
>,
body: Partial<ModelRoleVisibilityType>,
ncMeta = Noco.ncMeta
) {
const insertObj = extractProps(body, [
@ -141,8 +136,6 @@ export default class ModelRoleVisibility implements ModelRoleVisibilityType {
'fk_view_id',
'project_id',
'base_id',
'created_at',
'updated_at',
]);
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;
category?: string;
input_schema?: string;
input?: string;
input?: string | null;
creator?: string;
creator_website?: 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 bases?: Base[];
created_at: any;
updated_at: any;
// shared base props
uuid?: string;
password?: string;
@ -37,10 +34,7 @@ export default class Project implements ProjectType {
}
public static async createProject(
project: ProjectType & {
created_at?;
updated_at?;
},
project: Partial<ProjectType>,
ncMeta = Noco.ncMeta
): Promise<Project> {
const insertObj = extractProps(project, [
@ -49,8 +43,6 @@ export default class Project implements ProjectType {
'prefix',
'description',
'is_meta',
'created_at',
'updated_at',
]);
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);
}
// set meta
await ncMeta.metaUpdate(
return await ncMeta.metaUpdate(
null,
null,
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));
}
public static async insert(
syncLog: Partial<
SyncLogs & {
created_at?;
updated_at?;
}
>,
ncMeta = Noco.ncMeta
) {
public static async insert(syncLog: Partial<SyncLogs>, ncMeta = Noco.ncMeta) {
const insertObj = extractProps(syncLog, [
'project_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(
syncSource: Partial<
SyncSource & {
created_at?;
updated_at?;
}
>,
syncSource: Partial<SyncSource>,
ncMeta = Noco.ncMeta
) {
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> & {
copy_from_id?: string;
fk_grp_col_id?: string;
created_at?;
updated_at?;
},
ncMeta = Noco.ncMeta
) {
@ -259,8 +257,6 @@ export default class View implements ViewType {
'fk_model_id',
'project_id',
'base_id',
'created_at',
'updated_at',
'meta',
]);
@ -656,11 +652,10 @@ export default class View implements ViewType {
colId: string,
colData: {
order?: number;
show?: boolean;
show?: BoolType;
},
ncMeta = Noco.ncMeta
): Promise<Array<GridViewColumn | any>> {
const columns: Array<GridViewColumn | any> = [];
) {
const view = await this.get(viewId, ncMeta);
let table;
let cacheScope;
@ -726,9 +721,7 @@ export default class View implements ViewType {
await NocoCache.set(key, o);
}
// set meta
await ncMeta.metaUpdate(null, null, table, updateObj, colId);
return columns;
return await ncMeta.metaUpdate(null, null, table, updateObj, colId);
}
static async insertOrUpdateColumn(
@ -749,7 +742,6 @@ export default class View implements ViewType {
> {
const view = await this.get(viewId);
const table = this.extractViewColumnsTableName(view);
console.log(table);
const existingCol = await ncMeta.metaGet2(null, null, table, {
fk_view_id: viewId,

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

@ -1,5 +1,4 @@
import { XcStoragePlugin } from 'nc-plugin';
import Backblaze from './Backblaze';
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 Discord from './Discord';
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 Gcs from './Gcs';
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 LinodeObjectStorage from './LinodeObjectStorage';
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 type { IEmailAdapter } from 'nc-plugin';
import type { XcEmail } from '../../../interface/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