From fff540010ea9543ebc85b8d9691646f86050fc8a Mon Sep 17 00:00:00 2001
From: Anoop M D <anoop.md1421@gmail.com>
Date: Sat, 21 Jan 2023 23:22:45 +0530
Subject: [PATCH] feat: hardening seq number functionality

---
 .../ReduxStore/slices/collections/actions.js  |  6 ++++++
 .../bruno-app/src/utils/collections/index.js  |  7 ++++---
 .../src/utils/importers/bruno-collection.js   |  3 ++-
 .../bruno-app/src/utils/importers/common.js   | 19 +++++++++++++++++++
 .../src/utils/importers/postman-collection.js |  3 ++-
 .../bruno-schema/src/collections/index.js     |  2 +-
 6 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js
index d09b562f..bf63c668 100644
--- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js
+++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js
@@ -516,9 +516,13 @@ export const newHttpRequest = (params) => (dispatch, getState) => {
       }
     };
 
+    // itemUid is null when we are creating a new request at the root level
     const filename = resolveRequestFilename(requestName);
     if (!itemUid) {
       const reqWithSameNameExists = find(collection.items, (i) => i.type !== 'folder' && trim(i.filename) === trim(filename));
+      item.seq = collectionCopy.items ? collectionCopy.items.length : 1;
+      item.seq = item.seq + 1;
+
       if (!reqWithSameNameExists) {
         const fullName = `${collection.pathname}${PATH_SEPARATOR}${filename}`;
         const { ipcRenderer } = window;
@@ -531,6 +535,8 @@ export const newHttpRequest = (params) => (dispatch, getState) => {
       const currentItem = findItemInCollection(collection, itemUid);
       if (currentItem) {
         const reqWithSameNameExists = find(currentItem.items, (i) => i.type !== 'folder' && trim(i.filename) === trim(filename));
+        item.seq = currentItem.items ? currentItem.items.length : 1;
+        item.seq = item.seq + 1;
         if (!reqWithSameNameExists) {
           const fullName = `${currentItem.pathname}${PATH_SEPARATOR}${filename}`;
           const { ipcRenderer } = window;
diff --git a/packages/bruno-app/src/utils/collections/index.js b/packages/bruno-app/src/utils/collections/index.js
index 3498458c..1bf2894a 100644
--- a/packages/bruno-app/src/utils/collections/index.js
+++ b/packages/bruno-app/src/utils/collections/index.js
@@ -256,11 +256,11 @@ export const transformCollectionToSaveToIdb = (collection, options = {}) => {
     each(sourceItems, (si) => {
       const di = {
         uid: si.uid,
-        type: si.type
+        type: si.type,
+        name: si.name,
+        seq: si.seq
       };
 
-      di.name = si.name;
-
       // if items is draft, then take data from draft to save
       // The condition "!options.ignoreDraft" may appear confusing
       // When saving a collection, this option allows the caller to specify to ignore any draft changes while still saving rest of the collection.
@@ -337,6 +337,7 @@ export const transformRequestToSaveToFilesystem = (item) => {
     uid: _item.uid,
     type: _item.type,
     name: _item.name,
+    seq: _item.seq,
     request: {
       method: _item.request.method,
       url: _item.request.url,
diff --git a/packages/bruno-app/src/utils/importers/bruno-collection.js b/packages/bruno-app/src/utils/importers/bruno-collection.js
index 019314d5..8431d28f 100644
--- a/packages/bruno-app/src/utils/importers/bruno-collection.js
+++ b/packages/bruno-app/src/utils/importers/bruno-collection.js
@@ -1,6 +1,6 @@
 import fileDialog from 'file-dialog';
 import { BrunoError } from 'utils/common/error';
-import { validateSchema, updateUidsInCollection } from './common';
+import { validateSchema, updateUidsInCollection, hydrateSeqInCollection } from './common';
 
 const readFile = (files) => {
   return new Promise((resolve, reject) => {
@@ -28,6 +28,7 @@ const importCollection = () => {
     fileDialog({ accept: 'application/json' })
       .then(readFile)
       .then(parseJsonCollection)
+      .then(hydrateSeqInCollection)
       .then(updateUidsInCollection)
       .then(validateSchema)
       .then((collection) => resolve(collection))
diff --git a/packages/bruno-app/src/utils/importers/common.js b/packages/bruno-app/src/utils/importers/common.js
index e9995b73..7f05b56d 100644
--- a/packages/bruno-app/src/utils/importers/common.js
+++ b/packages/bruno-app/src/utils/importers/common.js
@@ -4,6 +4,7 @@ import get from 'lodash/get';
 
 import cloneDeep from 'lodash/cloneDeep';
 import { uuid } from 'utils/common';
+import { isItemARequest } from 'utils/collections';
 import { collectionSchema } from '@usebruno/schema';
 import { BrunoError } from 'utils/common/error';
 
@@ -51,3 +52,21 @@ export const updateUidsInCollection = (_collection) => {
 
   return collection;
 };
+
+export const hydrateSeqInCollection = (collection) => {
+  const hydrateSeq = (items = []) => {
+    let index = 1;
+    each(items, (item) => {
+      if(isItemARequest(item) && !item.seq) {
+        item.seq = index;
+        index++;
+      }
+      if (item.items && item.items.length) {
+        hydrateSeq(item.items);
+      }
+    });
+  };
+  hydrateSeq(collection.items);
+
+  return collection;
+}
diff --git a/packages/bruno-app/src/utils/importers/postman-collection.js b/packages/bruno-app/src/utils/importers/postman-collection.js
index 23265f55..65e8ca89 100644
--- a/packages/bruno-app/src/utils/importers/postman-collection.js
+++ b/packages/bruno-app/src/utils/importers/postman-collection.js
@@ -3,7 +3,7 @@ import get from 'lodash/get';
 import fileDialog from 'file-dialog';
 import { uuid } from 'utils/common';
 import { BrunoError } from 'utils/common/error';
-import { validateSchema, updateUidsInCollection } from './common';
+import { validateSchema, hydrateSeqInCollection } from './common';
 
 const readFile = (files) => {
   return new Promise((resolve, reject) => {
@@ -178,6 +178,7 @@ const importCollection = () => {
     fileDialog({ accept: 'application/json' })
       .then(readFile)
       .then(parsePostmanCollection)
+      .then(hydrateSeqInCollection)
       .then(validateSchema)
       .then((collection) => resolve(collection))
       .catch((err) => {
diff --git a/packages/bruno-schema/src/collections/index.js b/packages/bruno-schema/src/collections/index.js
index 2b3eb998..5757a9db 100644
--- a/packages/bruno-schema/src/collections/index.js
+++ b/packages/bruno-schema/src/collections/index.js
@@ -70,7 +70,7 @@ const itemSchema = Yup.object({
   items: Yup.lazy(() => Yup.array().of(itemSchema)),
   filename: Yup.string().max(1024, 'filename cannot be more than 1024 characters').nullable(),
   pathname: Yup.string().max(1024, 'pathname cannot be more than 1024 characters').nullable()
-}).noUnknown(true);
+}).noUnknown(true).strict();
 
 const collectionSchema = Yup.object({
   version: Yup.string().oneOf(['1']).required('version is required'),