diff --git a/packages/nc-gui/components/smartsheet/expanded-form/Header.vue b/packages/nc-gui/components/smartsheet/expanded-form/Header.vue index bd7bc1c2de..b21c2d2d5c 100644 --- a/packages/nc-gui/components/smartsheet/expanded-form/Header.vue +++ b/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 { diff --git a/packages/nc-gui/composables/useExpandedFormStore.ts b/packages/nc-gui/composables/useExpandedFormStore.ts index 69c869bcf8..6e9dad1e48 100644 --- a/packages/nc-gui/composables/useExpandedFormStore.ts +++ b/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, row: Ref) => { 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 = {}) => { let data try { - const updateOrInsertObj = [...changedColumns.value].reduce((obj, col) => { - obj[col] = row.value.row[col] - return obj - }, {} as Record) - 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) + 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) { diff --git a/packages/nc-gui/composables/useViewData.ts b/packages/nc-gui/composables/useViewData.ts index 0dde08157e..3d05bb2a15 100644 --- a/packages/nc-gui/composables/useViewData.ts +++ b/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, rowIndex = formattedData.value?.length, - ltarState?: Record = {}, + ltarState: Record = {}, ) { try { - const missingRequiredColumns = new Set() - const insertObj = await meta?.value?.columns?.reduce(async (_o: Promise, col) => { - const o = await _o - if ( - ltarState && - col.uidt === UITypes.LinkToAnotherRecord && - (col.colOptions).type === RelationTypes.BELONGS_TO - ) { - if (ltarState[col.title!]) { - const colOpt = 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( diff --git a/packages/nc-gui/utils/columnUtils.ts b/packages/nc-gui/utils/columnUtils.ts index 64e9206ae5..915968c28f 100644 --- a/packages/nc-gui/utils/columnUtils.ts +++ b/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) => { - 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 } diff --git a/packages/nc-gui/utils/dataUtils.ts b/packages/nc-gui/utils/dataUtils.ts index 290d445aca..e57f566db8 100644 --- a/packages/nc-gui/utils/dataUtils.ts +++ b/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, columns: ColumnType[]) => { return ( @@ -9,3 +10,51 @@ export const extractPkFromRow = (row: Record, 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 + getMeta: (tableIdOrTitle: string, force?: boolean) => Promise + row: Record +}) { + const missingRequiredColumns = new Set() + const insertObj = await meta.columns?.reduce(async (_o: Promise, 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 && + (col.colOptions).type === RelationTypes.BELONGS_TO + ) { + if (ltarState[col.title!]) { + const colOpt = 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 } +} diff --git a/packages/nocodb-sdk/package-lock.json b/packages/nocodb-sdk/package-lock.json index 4e7656e0e1..497bd8f603 100644 --- a/packages/nocodb-sdk/package-lock.json +++ b/packages/nocodb-sdk/package-lock.json @@ -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 } } } \ No newline at end of file