Browse Source

feat(gui): save expanded form data only if all required field values provided

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/3953/head
Pranav C 2 years ago
parent
commit
c93e2afda0
  1. 4
      packages/nc-gui/components/smartsheet/expanded-form/Header.vue
  2. 84
      packages/nc-gui/composables/useExpandedFormStore.ts
  3. 67
      packages/nc-gui/composables/useViewData.ts
  4. 5
      packages/nc-gui/utils/columnUtils.ts
  5. 51
      packages/nc-gui/utils/dataUtils.ts
  6. 281
      packages/nocodb-sdk/package-lock.json

4
packages/nc-gui/components/smartsheet/expanded-form/Header.vue

@ -19,7 +19,7 @@ const { meta, isSqlView } = useSmartsheetStoreOrThrow()
const { commentsDrawer, primaryValue, primaryKey, save: _save, loadRow } = useExpandedFormStoreOrThrow()
const { isNew, syncLTARRefs } = useSmartsheetRowStoreOrThrow()
const { isNew, syncLTARRefs, state } = useSmartsheetRowStoreOrThrow()
const { isUIAllowed } = useUIPermission()
@ -27,7 +27,7 @@ const reloadTrigger = inject(ReloadRowDataHookInj, createEventHook())
const save = async () => {
if (isNew.value) {
const data = await _save()
const data = await _save(state.value)
await syncLTARRefs(data)
reloadTrigger?.trigger()
} else {

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

@ -19,7 +19,9 @@ import {
useProvideSmartsheetRowStore,
useSharedView,
} from '#imports'
import { useMetas } from '~/composables/useMetas'
import type { Row } from '~/lib'
import { populateInsertObject } from '~/utils'
const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((meta: Ref<TableType>, row: Ref<Row>) => {
const { $e, $state, $api } = useNuxtApp()
@ -132,53 +134,65 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m
$e('a:row-expand:comment')
}
const save = async () => {
const save = async (ltarState: Record<string, any> = {}) => {
let data
try {
const updateOrInsertObj = [...changedColumns.value].reduce((obj, col) => {
obj[col] = row.value.row[col]
return obj
}, {} as Record<string, any>)
const isNewRow = row.value.rowMeta?.new ?? false
if (isNewRow) {
data = await $api.dbTableRow.create('noco', project.value.title as string, meta.value.title, updateOrInsertObj)
const { getMeta } = useMetas()
const { missingRequiredColumns, insertObj } = await populateInsertObject({
meta: meta.value,
ltarState,
getMeta,
row: row.value.row,
})
if (missingRequiredColumns.size) return
data = await $api.dbTableRow.create('noco', project.value.title as string, meta.value.title, insertObj)
Object.assign(row.value, {
row: data,
rowMeta: {},
oldRow: { ...data },
})
} else if (Object.keys(updateOrInsertObj).length) {
const id = extractPkFromRow(row.value.row, meta.value.columns as ColumnType[])
if (!id) {
return message.info("Update not allowed for table which doesn't have primary Key")
}
await $api.dbTableRow.update(NOCO, project.value.title as string, meta.value.title, id, updateOrInsertObj)
for (const key of Object.keys(updateOrInsertObj)) {
// audit
$api.utils
.auditRowUpdate(id, {
fk_model_id: meta.value.id,
column_name: key,
row_id: id,
value: getHTMLEncodedText(updateOrInsertObj[key]),
prev_value: getHTMLEncodedText(row.value.oldRow[key]),
})
.then(async () => {
/** load latest comments/audit if right drawer is open */
if (commentsDrawer.value) {
await loadCommentsAndLogs()
}
})
}
} else {
// No columns to update
return message.info(t('msg.info.noColumnsToUpdate'))
const updateOrInsertObj = [...changedColumns.value].reduce((obj, col) => {
obj[col] = row.value.row[col]
return obj
}, {} as Record<string, any>)
if (Object.keys(updateOrInsertObj).length) {
const id = extractPkFromRow(row.value.row, meta.value.columns as ColumnType[])
if (!id) {
return message.info("Update not allowed for table which doesn't have primary Key")
}
await $api.dbTableRow.update(NOCO, project.value.title as string, meta.value.title, id, updateOrInsertObj)
for (const key of Object.keys(updateOrInsertObj)) {
// audit
$api.utils
.auditRowUpdate(id, {
fk_model_id: meta.value.id,
column_name: key,
row_id: id,
value: getHTMLEncodedText(updateOrInsertObj[key]),
prev_value: getHTMLEncodedText(row.value.oldRow[key]),
})
.then(async () => {
/** load latest comments/audit if right drawer is open */
if (commentsDrawer.value) {
await loadCommentsAndLogs()
}
})
}
} else {
// No columns to update
return message.info(t('msg.info.noColumnsToUpdate'))
}
}
if (activeView.value?.type === ViewTypes.KANBAN) {

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

@ -1,14 +1,5 @@
import { RelationTypes, UITypes, ViewTypes } from 'nocodb-sdk'
import type {
Api,
ColumnType,
FormType,
GalleryType,
LinkToAnotherRecordType,
PaginatedType,
TableType,
ViewType,
} from 'nocodb-sdk'
import { ViewTypes } from 'nocodb-sdk'
import type { Api, ColumnType, FormType, GalleryType, PaginatedType, TableType, ViewType } from 'nocodb-sdk'
import type { ComputedRef, Ref } from 'vue'
import {
IsPublicInj,
@ -17,8 +8,8 @@ import {
extractPkFromRow,
extractSdkResponseErrorMsg,
getHTMLEncodedText,
isColumnRequiredAndNull,
message,
populateInsertObject,
ref,
useApi,
useGlobal,
@ -51,7 +42,6 @@ export function useViewData(
const { t } = useI18n()
const { api, isLoading, error } = useApi()
const { metas, getMeta } = useMetas()
const { appInfo } = $(useGlobal())
const appInfoDefaultLimit = appInfo.defaultLimit || 25
@ -186,12 +176,12 @@ export function useViewData(
if ((!project?.value?.id || !meta.value?.id || !viewMeta.value?.id) && !isPublic.value) return
const response = !isPublic.value
? await api.dbViewRow.list('noco', project.value.id!, meta.value!.id!, viewMeta.value!.id!, {
...queryParams.value,
...params,
...(isUIAllowed('sortSync') ? {} : { sortArrJson: JSON.stringify(sorts.value) }),
...(isUIAllowed('filterSync') ? {} : { filterArrJson: JSON.stringify(nestedFilters.value) }),
where: where?.value,
})
...queryParams.value,
...params,
...(isUIAllowed('sortSync') ? {} : { sortArrJson: JSON.stringify(sorts.value) }),
...(isUIAllowed('filterSync') ? {} : { filterArrJson: JSON.stringify(nestedFilters.value) }),
where: where?.value,
})
: await fetchSharedViewData({ sortsArr: sorts.value, filtersArr: nestedFilters.value })
formattedData.value = formatData(response.list)
paginationData.value = response.pageInfo
@ -209,40 +199,12 @@ export function useViewData(
async function insertRow(
row: Record<string, any>,
rowIndex = formattedData.value?.length,
ltarState?: Record<string, any> = {},
ltarState: Record<string, any> = {},
) {
try {
const missingRequiredColumns = new Set()
const insertObj = await meta?.value?.columns?.reduce(async (_o: Promise<any>, col) => {
const o = await _o
if (
ltarState &&
col.uidt === UITypes.LinkToAnotherRecord &&
(<LinkToAnotherRecordType>col.colOptions).type === RelationTypes.BELONGS_TO
) {
if (ltarState[col.title!]) {
const colOpt = <LinkToAnotherRecordType>col.colOptions
const childCol = meta.value!.columns!.find((c) => colOpt.fk_child_column_id === c.id)
const relatedTableMeta = (await getMeta(colOpt.fk_related_model_id!)) as TableType
if (relatedTableMeta && childCol) {
o[childCol.title!] =
ltarState[col.title!][relatedTableMeta!.columns!.find((c) => c.id === colOpt.fk_parent_column_id)!.title!]
missingRequiredColumns.delete(childCol.title)
}
}
}
const { getMeta } = useMetas()
// check all the required columns are not null
if (isColumnRequiredAndNull(col, row)) {
missingRequiredColumns.add(col.title)
}
if (!col.ai && row?.[col.title as string] !== null) {
o[col.title as string] = row?.[col.title as string]
}
return o
}, Promise.resolve({}))
const { missingRequiredColumns, insertObj } = await populateInsertObject({ meta, ltarState, getMeta, row })
if (missingRequiredColumns.size) return
@ -294,8 +256,7 @@ export function useViewData(
value: getHTMLEncodedText(toUpdate.row[property]),
prev_value: getHTMLEncodedText(toUpdate.oldRow[property]),
})
.then(() => {
})
.then(() => {})
/** update row data(to sync formula and other related columns) */
Object.assign(toUpdate.row, updatedRowData)
@ -324,7 +285,7 @@ export function useViewData(
async function deleteRowById(id: string) {
if (!id) {
throw new Error('Delete not allowed for table which doesn\'t have primary Key')
throw new Error("Delete not allowed for table which doesn't have primary Key")
}
const res: any = await $api.dbViewRow.delete(

5
packages/nc-gui/utils/columnUtils.ts

@ -1,4 +1,5 @@
import { ColumnType, UITypes } from 'nocodb-sdk'
import type { ColumnType } from 'nocodb-sdk'
import { UITypes } from 'nocodb-sdk'
import LinkVariant from '~icons/mdi/link-variant'
import TableColumnPlusBefore from '~icons/mdi/table-column-plus-before'
import FormatColorText from '~icons/mdi/format-color-text'
@ -170,7 +171,7 @@ const getUIDTIcon = (uidt: UITypes | string) => {
const isColumnRequired = (col: ColumnType) => col.rqd && !col.cdf && !col.ai
const isColumnRequiredAndNull = (col: ColumnType, row: Record<string, any>) => {
return isColumnRequired(col) && (row[col.title!] === undefined || row[col.title!] === null)
return isColumnRequired(col) && (row[col.title!] === undefined || row[col.title!] === null) // && isVirtualColRequired()
}
export { uiTypes, getUIDTIcon, isColumnRequiredAndNull }

51
packages/nc-gui/utils/dataUtils.ts

@ -1,4 +1,5 @@
import type { ColumnType } from 'nocodb-sdk'
import { RelationTypes, UITypes } from 'nocodb-sdk'
import type { ColumnType, LinkToAnotherRecordType, TableInfoType, TableType } from 'nocodb-sdk'
export const extractPkFromRow = (row: Record<string, any>, columns: ColumnType[]) => {
return (
@ -9,3 +10,51 @@ export const extractPkFromRow = (row: Record<string, any>, columns: ColumnType[]
.join('___')
)
}
// a function to populate insert object and verify if all required fields are present
export async function populateInsertObject({
getMeta,
row,
meta,
ltarState,
}: {
meta: TableType
ltarState: Record<string, any>
getMeta: (tableIdOrTitle: string, force?: boolean) => Promise<TableType | TableInfoType | null>
row: Record<string, any>
}) {
const missingRequiredColumns = new Set()
const insertObj = await meta.columns?.reduce(async (_o: Promise<any>, col) => {
const o = await _o
// if column is BT relation then check if foreign key is not_null(required)
if (
ltarState &&
col.uidt === UITypes.LinkToAnotherRecord &&
(<LinkToAnotherRecordType>col.colOptions).type === RelationTypes.BELONGS_TO
) {
if (ltarState[col.title!]) {
const colOpt = <LinkToAnotherRecordType>col.colOptions
const childCol = meta.columns!.find((c) => colOpt.fk_child_column_id === c.id)
const relatedTableMeta = (await getMeta(colOpt.fk_related_model_id!)) as TableType
if (relatedTableMeta && childCol) {
o[childCol.title!] =
ltarState[col.title!][relatedTableMeta!.columns!.find((c) => c.id === colOpt.fk_parent_column_id)!.title!]
missingRequiredColumns.delete(childCol.title)
}
}
}
// check all the required columns are not null
if (isColumnRequiredAndNull(col, row)) {
missingRequiredColumns.add(col.title)
}
if (!col.ai && row?.[col.title as string] !== null) {
o[col.title as string] = row?.[col.title as string]
}
return o
}, Promise.resolve({}))
return { missingRequiredColumns, insertObj }
}

281
packages/nocodb-sdk/package-lock.json generated

@ -538,6 +538,19 @@
"node": ">=8"
}
},
"node_modules/nyc/node_modules/yargs-parser": {
"version": "18.1.3",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"dev": true,
"dependencies": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/table/node_modules/ansi-styles": {
"version": "4.3.0",
"dev": true,
@ -1565,6 +1578,18 @@
"node": ">=10"
}
},
"node_modules/gh-pages/node_modules/array-union": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
"integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==",
"dev": true,
"dependencies": {
"array-uniq": "^1.0.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/escape-goat": {
"version": "2.1.1",
"dev": true,
@ -1786,6 +1811,15 @@
"node": ">=0.10.0"
}
},
"node_modules/nyc/node_modules/camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/npm-run-all/node_modules/path-key": {
"version": "2.0.1",
"dev": true,
@ -2106,6 +2140,15 @@
"node": ">= 8"
}
},
"node_modules/gh-pages/node_modules/universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true,
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/signal-exit": {
"version": "3.0.7",
"dev": true,
@ -2539,6 +2582,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/typedoc/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/trim-repeated": {
"version": "1.0.0",
"dev": true,
@ -2970,6 +3022,18 @@
"node": ">=8"
}
},
"node_modules/git-semver-tags/node_modules/type-fest": {
"version": "0.18.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
"integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/strip-indent": {
"version": "3.0.0",
"dev": true,
@ -4094,6 +4158,15 @@
"node": ">=0.8.0"
}
},
"node_modules/inquirer/node_modules/is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/dotgitignore/node_modules/path-exists": {
"version": "3.0.0",
"dev": true,
@ -5144,6 +5217,15 @@
"once": "^1.4.0"
}
},
"node_modules/array-uniq": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
"integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/escalade": {
"version": "3.1.1",
"dev": true,
@ -5160,6 +5242,21 @@
"node": ">=4.0.0"
}
},
"node_modules/standard-version/node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"dev": true,
"dependencies": {
"yocto-queue": "^0.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint-module-utils/node_modules/p-limit": {
"version": "1.3.0",
"dev": true,
@ -5596,6 +5693,15 @@
"node": "^10.12.0 || >=12.0.0"
}
},
"node_modules/standard-version/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/js-tokens": {
"version": "4.0.0",
"dev": true,
@ -7101,6 +7207,18 @@
"node": ">=4.8"
}
},
"node_modules/standard-version/node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"dependencies": {
"has-flag": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/spawn-wrap": {
"version": "2.0.0",
"dev": true,
@ -7133,6 +7251,18 @@
"dev": true,
"license": "MIT"
},
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/strip-json-comments": {
"version": "2.0.1",
"dev": true,
@ -7210,6 +7340,21 @@
"license": "MIT",
"optional": true
},
"node_modules/standard-version/node_modules/p-locate": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
"dev": true,
"dependencies": {
"p-limit": "^3.0.2"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@nodelib/fs.walk": {
"version": "1.2.8",
"dev": true,
@ -7463,6 +7608,21 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/standard-version/node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dev": true,
"dependencies": {
"p-locate": "^5.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/detect-newline": {
"version": "3.1.0",
"dev": true,
@ -8451,6 +8611,15 @@
"ini": "^1.3.2"
}
},
"node_modules/standard-version/node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/semver-diff": {
"version": "3.1.1",
"dev": true,
@ -10468,6 +10637,12 @@
"version": "2.1.0",
"dev": true
},
"array-uniq": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
"integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==",
"dev": true
},
"array.prototype.flat": {
"version": "1.2.5",
"dev": true,
@ -12614,6 +12789,15 @@
"globby": "^6.1.0"
},
"dependencies": {
"array-union": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
"integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==",
"dev": true,
"requires": {
"array-uniq": "^1.0.1"
}
},
"commander": {
"version": "2.20.3",
"dev": true
@ -12641,6 +12825,12 @@
"pify": {
"version": "2.3.0",
"dev": true
},
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true
}
}
},
@ -12737,6 +12927,12 @@
"semver": {
"version": "6.3.0",
"dev": true
},
"type-fest": {
"version": "0.18.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
"integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
"dev": true
}
}
},
@ -13104,6 +13300,12 @@
"version": "3.0.0",
"dev": true
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
"dev": true
},
"restore-cursor": {
"version": "2.0.0",
"dev": true,
@ -14064,6 +14266,12 @@
"color-convert": "^2.0.1"
}
},
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true
},
"cliui": {
"version": "6.0.0",
"dev": true,
@ -14105,6 +14313,16 @@
"y18n": "^4.0.0",
"yargs-parser": "^18.1.2"
}
},
"yargs-parser": {
"version": "18.1.3",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"dev": true,
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
}
}
},
@ -15042,6 +15260,12 @@
"supports-color": "^5.3.0"
}
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"dev": true
},
"find-up": {
"version": "5.0.0",
"dev": true,
@ -15049,6 +15273,48 @@
"locate-path": "^6.0.0",
"path-exists": "^4.0.0"
}
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true
},
"locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dev": true,
"requires": {
"p-locate": "^5.0.0"
}
},
"p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
"dev": true,
"requires": {
"yocto-queue": "^0.1.0"
}
},
"p-locate": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
"dev": true,
"requires": {
"p-limit": "^3.0.2"
}
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
@ -15528,6 +15794,15 @@
"shiki": "^0.10.1"
},
"dependencies": {
"brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0"
}
},
"glob": {
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
@ -15804,6 +16079,12 @@
"yn": {
"version": "3.1.1",
"dev": true
},
"yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"dev": true
}
}
}
Loading…
Cancel
Save