@commercetools-frontend-extensions/operations 3.2.1 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @commercetools-frontend-extensions/operations
2
2
 
3
+ ## 3.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1703](https://github.com/commercetools/merchant-center-operations/pull/1703) [`6b101a8`](https://github.com/commercetools/merchant-center-operations/commit/6b101a8d0e846b5340767086434fd6f3abe8ef24) Thanks [@yassinejebli](https://github.com/yassinejebli)! - refactor: adjust product delete endpoints for the new import flow
8
+
9
+ ## 3.3.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#1699](https://github.com/commercetools/merchant-center-operations/pull/1699) [`d93cfd9`](https://github.com/commercetools/merchant-center-operations/commit/d93cfd9c2aa82779ec4c1eafeccde4ca930c143a) Thanks [@Sarah4VT](https://github.com/Sarah4VT)! - Update Jest to v30
14
+
3
15
  ## 3.2.1
4
16
 
5
17
  ### Patch Changes
@@ -22,6 +22,7 @@ var _inherits = require('@babel/runtime-corejs3/helpers/inherits');
22
22
  var _wrapNativeSuper = require('@babel/runtime-corejs3/helpers/wrapNativeSuper');
23
23
  var constants = require('@commercetools-frontend/constants');
24
24
  var _everyInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/every');
25
+ var _includesInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/includes');
25
26
  var pluralize = require('pluralize');
26
27
  var _Array$isArray = require('@babel/runtime-corejs3/core-js-stable/array/is-array');
27
28
  var _reduceInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/reduce');
@@ -29,7 +30,6 @@ var _flatMapInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/in
29
30
  var _mapInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/map');
30
31
  var _Promise = require('@babel/runtime-corejs3/core-js-stable/promise');
31
32
  var _findInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/find');
32
- var _includesInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/includes');
33
33
  var _someInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/some');
34
34
  var Papa = require('papaparse');
35
35
  var _sliceInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/slice');
@@ -63,13 +63,13 @@ var _forEachInstanceProperty__default = /*#__PURE__*/_interopDefault(_forEachIns
63
63
  var _Object$keys__default = /*#__PURE__*/_interopDefault(_Object$keys);
64
64
  var _Reflect$construct__default = /*#__PURE__*/_interopDefault(_Reflect$construct);
65
65
  var _everyInstanceProperty__default = /*#__PURE__*/_interopDefault(_everyInstanceProperty);
66
+ var _includesInstanceProperty__default = /*#__PURE__*/_interopDefault(_includesInstanceProperty);
66
67
  var _Array$isArray__default = /*#__PURE__*/_interopDefault(_Array$isArray);
67
68
  var _reduceInstanceProperty__default = /*#__PURE__*/_interopDefault(_reduceInstanceProperty);
68
69
  var _flatMapInstanceProperty__default = /*#__PURE__*/_interopDefault(_flatMapInstanceProperty);
69
70
  var _mapInstanceProperty__default = /*#__PURE__*/_interopDefault(_mapInstanceProperty);
70
71
  var _Promise__default = /*#__PURE__*/_interopDefault(_Promise);
71
72
  var _findInstanceProperty__default = /*#__PURE__*/_interopDefault(_findInstanceProperty);
72
- var _includesInstanceProperty__default = /*#__PURE__*/_interopDefault(_includesInstanceProperty);
73
73
  var _someInstanceProperty__default = /*#__PURE__*/_interopDefault(_someInstanceProperty);
74
74
  var Papa__default = /*#__PURE__*/_interopDefault(Papa);
75
75
  var _sliceInstanceProperty__default = /*#__PURE__*/_interopDefault(_sliceInstanceProperty);
@@ -806,6 +806,13 @@ function formatQueryString() {
806
806
  return queryString.toString() ? `?${queryString.toString()}` : '';
807
807
  }
808
808
 
809
+ const OPERATION_RESOURCE_TYPES = ['product-delete', 'product-unpublish'];
810
+ function pluralizeResourceType(resourceType) {
811
+ if (_includesInstanceProperty__default["default"](OPERATION_RESOURCE_TYPES).call(OPERATION_RESOURCE_TYPES, resourceType)) {
812
+ return resourceType;
813
+ }
814
+ return pluralize.plural(resourceType);
815
+ }
809
816
  function getImportContainersURL(_ref) {
810
817
  let projectKey = _ref.projectKey,
811
818
  queryParams = _ref.queryParams;
@@ -865,7 +872,7 @@ function getFileImportJobsURL(_ref1) {
865
872
  let projectKey = _ref1.projectKey,
866
873
  resourceType = _ref1.resourceType,
867
874
  importContainerKey = _ref1.importContainerKey;
868
- return `/${projectKey}/${pluralize.plural(toImportApiResourceType(resourceType))}/import-containers/${importContainerKey}/file-import-jobs`;
875
+ return `/${projectKey}/${pluralizeResourceType(toImportApiResourceType(resourceType))}/import-containers/${importContainerKey}/file-import-jobs`;
869
876
  }
870
877
  function getFileImportJobByIdURL(_ref10) {
871
878
  let projectKey = _ref10.projectKey,
@@ -884,7 +891,7 @@ function getFileImportJobProcessURL(_ref12) {
884
891
  resourceType = _ref12.resourceType,
885
892
  importContainerKey = _ref12.importContainerKey,
886
893
  jobId = _ref12.jobId;
887
- return `/${projectKey}/${pluralize.plural(toImportApiResourceType(resourceType))}/import-containers/${importContainerKey}/file-import-jobs/${jobId}/process`;
894
+ return `/${projectKey}/${pluralizeResourceType(toImportApiResourceType(resourceType))}/import-containers/${importContainerKey}/file-import-jobs/${jobId}/process`;
888
895
  }
889
896
  function getFileImportJobDeleteURL(_ref13) {
890
897
  let projectKey = _ref13.projectKey,
@@ -943,11 +950,13 @@ function createFileImportJob(_ref) {
943
950
  payload = _ref.payload,
944
951
  _ref$autoProcess = _ref.autoProcess,
945
952
  autoProcess = _ref$autoProcess === void 0 ? false : _ref$autoProcess,
953
+ operationType = _ref.operationType,
946
954
  onProgress = _ref.onProgress,
947
955
  abortSignal = _ref.abortSignal;
956
+ const urlResourceType = operationType ? `${resourceType}-${operationType}` : resourceType;
948
957
  const url = getFileImportJobsURL({
949
958
  projectKey,
950
- resourceType,
959
+ resourceType: urlResourceType,
951
960
  importContainerKey
952
961
  });
953
962
  if ('fileType' in payload) {
@@ -1045,15 +1054,16 @@ async function processFileImportJob(_ref4) {
1045
1054
  resourceType = _ref4.resourceType,
1046
1055
  importContainerKey = _ref4.importContainerKey,
1047
1056
  jobId = _ref4.jobId,
1048
- action = _ref4.action;
1057
+ operationType = _ref4.operationType;
1058
+ const urlResourceType = operationType ? `${resourceType}-${operationType}` : resourceType;
1049
1059
  const url = getFileImportJobProcessURL({
1050
1060
  projectKey,
1051
- resourceType,
1061
+ resourceType: urlResourceType,
1052
1062
  importContainerKey,
1053
1063
  jobId
1054
1064
  });
1055
- const payload = action ? {
1056
- action
1065
+ const payload = operationType ? {
1066
+ action: operationType
1057
1067
  } : {};
1058
1068
  const response = await fetcher({
1059
1069
  url,
@@ -1390,7 +1400,6 @@ async function processUploadedFile(_ref) {
1390
1400
  importContainerKey = _ref.importContainerKey,
1391
1401
  resourceType = _ref.resourceType,
1392
1402
  action = _ref.action;
1393
- // For delete operations with action (like 'delete') -> use different URL and payload structure
1394
1403
  const uri = action ? getImportContainerTasksURL({
1395
1404
  projectKey,
1396
1405
  importContainerKey
@@ -2890,6 +2899,7 @@ const useFileImportJobUpload = _ref => {
2890
2899
  file: config.file
2891
2900
  },
2892
2901
  autoProcess: config.autoProcess,
2902
+ operationType: config.operationType,
2893
2903
  onProgress: uploadProgress => {
2894
2904
  setProgress(uploadProgress);
2895
2905
  config.onProgress?.(uploadProgress);
@@ -3079,6 +3089,7 @@ const useFileUpload = _ref2 => {
3079
3089
  resourceType: config.resourceType,
3080
3090
  settings: config.settings,
3081
3091
  autoProcess: config.autoProcess,
3092
+ operationType: config.operationType,
3082
3093
  abortSignal: config.abortSignal,
3083
3094
  onSuccess: async (jobId, containerKey) => {
3084
3095
  if (config.skipValidationPolling) {
@@ -22,6 +22,7 @@ var _inherits = require('@babel/runtime-corejs3/helpers/inherits');
22
22
  var _wrapNativeSuper = require('@babel/runtime-corejs3/helpers/wrapNativeSuper');
23
23
  var constants = require('@commercetools-frontend/constants');
24
24
  var _everyInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/every');
25
+ var _includesInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/includes');
25
26
  var pluralize = require('pluralize');
26
27
  var _Array$isArray = require('@babel/runtime-corejs3/core-js-stable/array/is-array');
27
28
  var _reduceInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/reduce');
@@ -29,7 +30,6 @@ var _flatMapInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/in
29
30
  var _mapInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/map');
30
31
  var _Promise = require('@babel/runtime-corejs3/core-js-stable/promise');
31
32
  var _findInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/find');
32
- var _includesInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/includes');
33
33
  var _someInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/some');
34
34
  var Papa = require('papaparse');
35
35
  var _sliceInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/slice');
@@ -63,13 +63,13 @@ var _forEachInstanceProperty__default = /*#__PURE__*/_interopDefault(_forEachIns
63
63
  var _Object$keys__default = /*#__PURE__*/_interopDefault(_Object$keys);
64
64
  var _Reflect$construct__default = /*#__PURE__*/_interopDefault(_Reflect$construct);
65
65
  var _everyInstanceProperty__default = /*#__PURE__*/_interopDefault(_everyInstanceProperty);
66
+ var _includesInstanceProperty__default = /*#__PURE__*/_interopDefault(_includesInstanceProperty);
66
67
  var _Array$isArray__default = /*#__PURE__*/_interopDefault(_Array$isArray);
67
68
  var _reduceInstanceProperty__default = /*#__PURE__*/_interopDefault(_reduceInstanceProperty);
68
69
  var _flatMapInstanceProperty__default = /*#__PURE__*/_interopDefault(_flatMapInstanceProperty);
69
70
  var _mapInstanceProperty__default = /*#__PURE__*/_interopDefault(_mapInstanceProperty);
70
71
  var _Promise__default = /*#__PURE__*/_interopDefault(_Promise);
71
72
  var _findInstanceProperty__default = /*#__PURE__*/_interopDefault(_findInstanceProperty);
72
- var _includesInstanceProperty__default = /*#__PURE__*/_interopDefault(_includesInstanceProperty);
73
73
  var _someInstanceProperty__default = /*#__PURE__*/_interopDefault(_someInstanceProperty);
74
74
  var Papa__default = /*#__PURE__*/_interopDefault(Papa);
75
75
  var _sliceInstanceProperty__default = /*#__PURE__*/_interopDefault(_sliceInstanceProperty);
@@ -806,6 +806,13 @@ function formatQueryString() {
806
806
  return queryString.toString() ? `?${queryString.toString()}` : '';
807
807
  }
808
808
 
809
+ const OPERATION_RESOURCE_TYPES = ['product-delete', 'product-unpublish'];
810
+ function pluralizeResourceType(resourceType) {
811
+ if (_includesInstanceProperty__default["default"](OPERATION_RESOURCE_TYPES).call(OPERATION_RESOURCE_TYPES, resourceType)) {
812
+ return resourceType;
813
+ }
814
+ return pluralize.plural(resourceType);
815
+ }
809
816
  function getImportContainersURL(_ref) {
810
817
  let projectKey = _ref.projectKey,
811
818
  queryParams = _ref.queryParams;
@@ -865,7 +872,7 @@ function getFileImportJobsURL(_ref1) {
865
872
  let projectKey = _ref1.projectKey,
866
873
  resourceType = _ref1.resourceType,
867
874
  importContainerKey = _ref1.importContainerKey;
868
- return `/${projectKey}/${pluralize.plural(toImportApiResourceType(resourceType))}/import-containers/${importContainerKey}/file-import-jobs`;
875
+ return `/${projectKey}/${pluralizeResourceType(toImportApiResourceType(resourceType))}/import-containers/${importContainerKey}/file-import-jobs`;
869
876
  }
870
877
  function getFileImportJobByIdURL(_ref10) {
871
878
  let projectKey = _ref10.projectKey,
@@ -884,7 +891,7 @@ function getFileImportJobProcessURL(_ref12) {
884
891
  resourceType = _ref12.resourceType,
885
892
  importContainerKey = _ref12.importContainerKey,
886
893
  jobId = _ref12.jobId;
887
- return `/${projectKey}/${pluralize.plural(toImportApiResourceType(resourceType))}/import-containers/${importContainerKey}/file-import-jobs/${jobId}/process`;
894
+ return `/${projectKey}/${pluralizeResourceType(toImportApiResourceType(resourceType))}/import-containers/${importContainerKey}/file-import-jobs/${jobId}/process`;
888
895
  }
889
896
  function getFileImportJobDeleteURL(_ref13) {
890
897
  let projectKey = _ref13.projectKey,
@@ -943,11 +950,13 @@ function createFileImportJob(_ref) {
943
950
  payload = _ref.payload,
944
951
  _ref$autoProcess = _ref.autoProcess,
945
952
  autoProcess = _ref$autoProcess === void 0 ? false : _ref$autoProcess,
953
+ operationType = _ref.operationType,
946
954
  onProgress = _ref.onProgress,
947
955
  abortSignal = _ref.abortSignal;
956
+ const urlResourceType = operationType ? `${resourceType}-${operationType}` : resourceType;
948
957
  const url = getFileImportJobsURL({
949
958
  projectKey,
950
- resourceType,
959
+ resourceType: urlResourceType,
951
960
  importContainerKey
952
961
  });
953
962
  if ('fileType' in payload) {
@@ -1045,15 +1054,16 @@ async function processFileImportJob(_ref4) {
1045
1054
  resourceType = _ref4.resourceType,
1046
1055
  importContainerKey = _ref4.importContainerKey,
1047
1056
  jobId = _ref4.jobId,
1048
- action = _ref4.action;
1057
+ operationType = _ref4.operationType;
1058
+ const urlResourceType = operationType ? `${resourceType}-${operationType}` : resourceType;
1049
1059
  const url = getFileImportJobProcessURL({
1050
1060
  projectKey,
1051
- resourceType,
1061
+ resourceType: urlResourceType,
1052
1062
  importContainerKey,
1053
1063
  jobId
1054
1064
  });
1055
- const payload = action ? {
1056
- action
1065
+ const payload = operationType ? {
1066
+ action: operationType
1057
1067
  } : {};
1058
1068
  const response = await fetcher({
1059
1069
  url,
@@ -1390,7 +1400,6 @@ async function processUploadedFile(_ref) {
1390
1400
  importContainerKey = _ref.importContainerKey,
1391
1401
  resourceType = _ref.resourceType,
1392
1402
  action = _ref.action;
1393
- // For delete operations with action (like 'delete') -> use different URL and payload structure
1394
1403
  const uri = action ? getImportContainerTasksURL({
1395
1404
  projectKey,
1396
1405
  importContainerKey
@@ -2882,6 +2891,7 @@ const useFileImportJobUpload = _ref => {
2882
2891
  file: config.file
2883
2892
  },
2884
2893
  autoProcess: config.autoProcess,
2894
+ operationType: config.operationType,
2885
2895
  onProgress: uploadProgress => {
2886
2896
  setProgress(uploadProgress);
2887
2897
  config.onProgress?.(uploadProgress);
@@ -3071,6 +3081,7 @@ const useFileUpload = _ref2 => {
3071
3081
  resourceType: config.resourceType,
3072
3082
  settings: config.settings,
3073
3083
  autoProcess: config.autoProcess,
3084
+ operationType: config.operationType,
3074
3085
  abortSignal: config.abortSignal,
3075
3086
  onSuccess: async (jobId, containerKey) => {
3076
3087
  if (config.skipValidationPolling) {
@@ -18,6 +18,7 @@ import _inherits from '@babel/runtime-corejs3/helpers/esm/inherits';
18
18
  import _wrapNativeSuper from '@babel/runtime-corejs3/helpers/esm/wrapNativeSuper';
19
19
  import { MC_API_PROXY_TARGETS } from '@commercetools-frontend/constants';
20
20
  import _everyInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/every';
21
+ import _includesInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/includes';
21
22
  import { plural } from 'pluralize';
22
23
  import _Array$isArray from '@babel/runtime-corejs3/core-js-stable/array/is-array';
23
24
  import _reduceInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/reduce';
@@ -25,7 +26,6 @@ import _flatMapInstanceProperty from '@babel/runtime-corejs3/core-js-stable/inst
25
26
  import _mapInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/map';
26
27
  import _Promise from '@babel/runtime-corejs3/core-js-stable/promise';
27
28
  import _findInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/find';
28
- import _includesInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/includes';
29
29
  import _someInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/some';
30
30
  import Papa from 'papaparse';
31
31
  import _sliceInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/slice';
@@ -769,6 +769,13 @@ function formatQueryString() {
769
769
  return queryString.toString() ? `?${queryString.toString()}` : '';
770
770
  }
771
771
 
772
+ const OPERATION_RESOURCE_TYPES = ['product-delete', 'product-unpublish'];
773
+ function pluralizeResourceType(resourceType) {
774
+ if (_includesInstanceProperty(OPERATION_RESOURCE_TYPES).call(OPERATION_RESOURCE_TYPES, resourceType)) {
775
+ return resourceType;
776
+ }
777
+ return plural(resourceType);
778
+ }
772
779
  function getImportContainersURL(_ref) {
773
780
  let projectKey = _ref.projectKey,
774
781
  queryParams = _ref.queryParams;
@@ -828,7 +835,7 @@ function getFileImportJobsURL(_ref1) {
828
835
  let projectKey = _ref1.projectKey,
829
836
  resourceType = _ref1.resourceType,
830
837
  importContainerKey = _ref1.importContainerKey;
831
- return `/${projectKey}/${plural(toImportApiResourceType(resourceType))}/import-containers/${importContainerKey}/file-import-jobs`;
838
+ return `/${projectKey}/${pluralizeResourceType(toImportApiResourceType(resourceType))}/import-containers/${importContainerKey}/file-import-jobs`;
832
839
  }
833
840
  function getFileImportJobByIdURL(_ref10) {
834
841
  let projectKey = _ref10.projectKey,
@@ -847,7 +854,7 @@ function getFileImportJobProcessURL(_ref12) {
847
854
  resourceType = _ref12.resourceType,
848
855
  importContainerKey = _ref12.importContainerKey,
849
856
  jobId = _ref12.jobId;
850
- return `/${projectKey}/${plural(toImportApiResourceType(resourceType))}/import-containers/${importContainerKey}/file-import-jobs/${jobId}/process`;
857
+ return `/${projectKey}/${pluralizeResourceType(toImportApiResourceType(resourceType))}/import-containers/${importContainerKey}/file-import-jobs/${jobId}/process`;
851
858
  }
852
859
  function getFileImportJobDeleteURL(_ref13) {
853
860
  let projectKey = _ref13.projectKey,
@@ -906,11 +913,13 @@ function createFileImportJob(_ref) {
906
913
  payload = _ref.payload,
907
914
  _ref$autoProcess = _ref.autoProcess,
908
915
  autoProcess = _ref$autoProcess === void 0 ? false : _ref$autoProcess,
916
+ operationType = _ref.operationType,
909
917
  onProgress = _ref.onProgress,
910
918
  abortSignal = _ref.abortSignal;
919
+ const urlResourceType = operationType ? `${resourceType}-${operationType}` : resourceType;
911
920
  const url = getFileImportJobsURL({
912
921
  projectKey,
913
- resourceType,
922
+ resourceType: urlResourceType,
914
923
  importContainerKey
915
924
  });
916
925
  if ('fileType' in payload) {
@@ -1008,15 +1017,16 @@ async function processFileImportJob(_ref4) {
1008
1017
  resourceType = _ref4.resourceType,
1009
1018
  importContainerKey = _ref4.importContainerKey,
1010
1019
  jobId = _ref4.jobId,
1011
- action = _ref4.action;
1020
+ operationType = _ref4.operationType;
1021
+ const urlResourceType = operationType ? `${resourceType}-${operationType}` : resourceType;
1012
1022
  const url = getFileImportJobProcessURL({
1013
1023
  projectKey,
1014
- resourceType,
1024
+ resourceType: urlResourceType,
1015
1025
  importContainerKey,
1016
1026
  jobId
1017
1027
  });
1018
- const payload = action ? {
1019
- action
1028
+ const payload = operationType ? {
1029
+ action: operationType
1020
1030
  } : {};
1021
1031
  const response = await fetcher({
1022
1032
  url,
@@ -1353,7 +1363,6 @@ async function processUploadedFile(_ref) {
1353
1363
  importContainerKey = _ref.importContainerKey,
1354
1364
  resourceType = _ref.resourceType,
1355
1365
  action = _ref.action;
1356
- // For delete operations with action (like 'delete') -> use different URL and payload structure
1357
1366
  const uri = action ? getImportContainerTasksURL({
1358
1367
  projectKey,
1359
1368
  importContainerKey
@@ -2853,6 +2862,7 @@ const useFileImportJobUpload = _ref => {
2853
2862
  file: config.file
2854
2863
  },
2855
2864
  autoProcess: config.autoProcess,
2865
+ operationType: config.operationType,
2856
2866
  onProgress: uploadProgress => {
2857
2867
  setProgress(uploadProgress);
2858
2868
  config.onProgress?.(uploadProgress);
@@ -3042,6 +3052,7 @@ const useFileUpload = _ref2 => {
3042
3052
  resourceType: config.resourceType,
3043
3053
  settings: config.settings,
3044
3054
  autoProcess: config.autoProcess,
3055
+ operationType: config.operationType,
3045
3056
  abortSignal: config.abortSignal,
3046
3057
  onSuccess: async (jobId, containerKey) => {
3047
3058
  if (config.skipValidationPolling) {
@@ -4,12 +4,12 @@ export declare const fetchUsingXhr: ({ url, payload, config, onProgress, onSucce
4
4
  url: string;
5
5
  payload: FormData;
6
6
  config: {
7
- abortSignal?: AbortSignal | undefined;
8
- proxy?: string | undefined;
7
+ abortSignal?: AbortSignal;
8
+ proxy?: string;
9
9
  method: string;
10
10
  headers?: {
11
11
  [key: string]: string | null;
12
- } | undefined;
12
+ };
13
13
  };
14
14
  onProgress: (progress: number) => void;
15
15
  onSuccess: (data: any) => void;
@@ -1,8 +1,8 @@
1
1
  import type { FileImportJob, CreateFileImportJobParameters, GetFileImportJobParameters, GetFileImportJobRecordsParameters, ProcessFileImportJobParameters, ProcessFileImportJobResponse, DeleteFileImportJobParameters, ListFileImportJobsParameters, ListFileImportJobsResponse, FileImportJobRecordsResponse } from "../@types/index.js";
2
- export declare function createFileImportJob({ projectKey, resourceType, importContainerKey, payload, autoProcess, onProgress, abortSignal, }: CreateFileImportJobParameters): Promise<FileImportJob>;
2
+ export declare function createFileImportJob({ projectKey, resourceType, importContainerKey, payload, autoProcess, operationType, onProgress, abortSignal, }: CreateFileImportJobParameters): Promise<FileImportJob>;
3
3
  export declare function getFileImportJob({ projectKey, importContainerKey, jobId, }: GetFileImportJobParameters): Promise<FileImportJob>;
4
4
  export declare function getFileImportJobRecords({ projectKey, importContainerKey, jobId, limit, offset, isValid, }: GetFileImportJobRecordsParameters): Promise<FileImportJobRecordsResponse>;
5
- export declare function processFileImportJob({ projectKey, resourceType, importContainerKey, jobId, action, }: ProcessFileImportJobParameters): Promise<ProcessFileImportJobResponse>;
5
+ export declare function processFileImportJob({ projectKey, resourceType, importContainerKey, jobId, operationType, }: ProcessFileImportJobParameters): Promise<ProcessFileImportJobResponse>;
6
6
  export declare function deleteFileImportJob({ projectKey, importContainerKey, jobId, }: DeleteFileImportJobParameters): Promise<void>;
7
7
  export declare function listFileImportJobs({ projectKey, importContainerKey, limit, offset, }: ListFileImportJobsParameters): Promise<ListFileImportJobsResponse>;
8
8
  export type FileImportJobInfo = {
@@ -1,7 +1,6 @@
1
1
  import type { FileImportJob } from "../@types/index.js";
2
2
  type UseFetchFileImportJobConfig = {
3
3
  projectKey: string;
4
- resourceType: string;
5
4
  importContainerKey: string;
6
5
  jobId: string;
7
6
  pollingInterval?: number;
@@ -5,6 +5,7 @@ export type UseFileImportJobUploadConfig = {
5
5
  resourceType: ResourceTypeId;
6
6
  settings?: ExtendedImportContainerDraft['settings'];
7
7
  autoProcess?: boolean;
8
+ operationType?: 'delete';
8
9
  onSuccess: (jobId: string, importContainerKey: string) => void;
9
10
  onError?: (error: unknown) => void;
10
11
  onProgress?: (progress: number) => void;
@@ -10,6 +10,7 @@ export type FileUploadConfig = {
10
10
  settings?: ExtendedImportContainerDraft['settings'];
11
11
  autoProcess?: boolean;
12
12
  skipValidationPolling?: boolean;
13
+ operationType?: 'delete';
13
14
  onSuccess: (result: FileUploadResult) => void;
14
15
  onError?: (error: unknown) => void;
15
16
  onProgress?: (progress: number) => void;
@@ -40,6 +40,7 @@ export interface CreateFileImportJobParameters {
40
40
  importContainerKey: string;
41
41
  payload: CreateFileImportJobPayload;
42
42
  autoProcess?: boolean;
43
+ operationType?: 'delete';
43
44
  onProgress?: (progress: number) => void;
44
45
  abortSignal?: AbortSignal;
45
46
  }
@@ -77,7 +78,7 @@ export interface ProcessFileImportJobParameters {
77
78
  resourceType: string;
78
79
  importContainerKey: string;
79
80
  jobId: string;
80
- action?: 'delete';
81
+ operationType?: 'delete';
81
82
  }
82
83
  export interface ProcessFileImportJobResponse {
83
84
  message: string;
@@ -41,6 +41,6 @@ export declare const countJsonFileItems: (file: File) => Promise<{
41
41
  * @param uploadFileErrors Array of file upload errors
42
42
  * @returns Array of upload file errors with unique id field
43
43
  */
44
- export declare const mapFileUploadErrorsToUploadFileErrorRows: <T extends Record<string, unknown>>(uploadFileErrors: T[]) => (T & {
44
+ export declare const mapFileUploadErrorsToUploadFileErrorRows: <T extends Record<string, unknown>>(uploadFileErrors: T[]) => Array<T & {
45
45
  id: string;
46
- })[];
46
+ }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commercetools-frontend-extensions/operations",
3
- "version": "3.2.1",
3
+ "version": "3.4.0",
4
4
  "license": "Proprietary",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -18,19 +18,19 @@
18
18
  "react-dropzone": "14.3.8"
19
19
  },
20
20
  "devDependencies": {
21
- "@commercetools-frontend/actions-global": "24.13.0",
22
- "@commercetools-frontend/application-components": "24.13.0",
23
- "@commercetools-frontend/application-shell": "24.13.0",
24
- "@commercetools-frontend/application-shell-connectors": "24.13.0",
25
- "@commercetools-frontend/constants": "24.13.0",
26
- "@commercetools-frontend/jest-preset-mc-app": "24.13.0",
27
- "@commercetools-frontend/permissions": "24.13.0",
28
- "@commercetools-frontend/sentry": "24.13.0",
21
+ "@commercetools-frontend/actions-global": "25.1.0",
22
+ "@commercetools-frontend/application-components": "25.1.0",
23
+ "@commercetools-frontend/application-shell": "25.1.0",
24
+ "@commercetools-frontend/application-shell-connectors": "25.1.0",
25
+ "@commercetools-frontend/constants": "25.1.0",
26
+ "@commercetools-frontend/jest-preset-mc-app": "25.1.0",
27
+ "@commercetools-frontend/permissions": "25.1.0",
28
+ "@commercetools-frontend/sentry": "25.1.0",
29
29
  "@commercetools-frontend/ui-kit": "20.3.0",
30
30
  "@emotion/react": "11.14.0",
31
31
  "@emotion/styled": "11.14.1",
32
32
  "@testing-library/react": "16.1.0",
33
- "@types/jest": "29.5.14",
33
+ "@types/jest": "30.0.0",
34
34
  "@types/papaparse": "5.5.2",
35
35
  "@types/pluralize": "0.0.33",
36
36
  "@types/react": "19.2.0",
@@ -38,16 +38,16 @@
38
38
  "react": "19.2.0",
39
39
  "react-intl": "7.1.4",
40
40
  "rimraf": "6.1.2",
41
- "typescript": "5.2.2"
41
+ "typescript": "5.4.5"
42
42
  },
43
43
  "peerDependencies": {
44
- "@commercetools-frontend/actions-global": "23.x || 24.x",
45
- "@commercetools-frontend/application-components": "23.x || 24.x",
46
- "@commercetools-frontend/application-shell": "23.x || 24.x",
47
- "@commercetools-frontend/application-shell-connectors": "23.x || 24.x",
48
- "@commercetools-frontend/constants": "23.x || 24.x",
49
- "@commercetools-frontend/permissions": "23.x || 24.x",
50
- "@commercetools-frontend/sentry": "23.x || 24.x",
44
+ "@commercetools-frontend/actions-global": "24.x || 25.x",
45
+ "@commercetools-frontend/application-components": "24.x || 25.x",
46
+ "@commercetools-frontend/application-shell": "24.x || 25.x",
47
+ "@commercetools-frontend/application-shell-connectors": "24.x || 25.x",
48
+ "@commercetools-frontend/constants": "24.x || 25.x",
49
+ "@commercetools-frontend/permissions": "24.x || 25.x",
50
+ "@commercetools-frontend/sentry": "24.x || 25.x",
51
51
  "@commercetools-frontend/ui-kit": "19.x || 20.x",
52
52
  "@emotion/react": "11.x",
53
53
  "@emotion/styled": "11.x",
@@ -34,12 +34,17 @@ export function createFileImportJob({
34
34
  importContainerKey,
35
35
  payload,
36
36
  autoProcess = false,
37
+ operationType,
37
38
  onProgress,
38
39
  abortSignal,
39
40
  }: CreateFileImportJobParameters): Promise<FileImportJob> {
41
+ const urlResourceType = operationType
42
+ ? `${resourceType}-${operationType}`
43
+ : resourceType
44
+
40
45
  const url = getFileImportJobsURL({
41
46
  projectKey,
42
- resourceType,
47
+ resourceType: urlResourceType,
43
48
  importContainerKey,
44
49
  })
45
50
 
@@ -145,16 +150,20 @@ export async function processFileImportJob({
145
150
  resourceType,
146
151
  importContainerKey,
147
152
  jobId,
148
- action,
153
+ operationType,
149
154
  }: ProcessFileImportJobParameters): Promise<ProcessFileImportJobResponse> {
155
+ const urlResourceType = operationType
156
+ ? `${resourceType}-${operationType}`
157
+ : resourceType
158
+
150
159
  const url = getFileImportJobProcessURL({
151
160
  projectKey,
152
- resourceType,
161
+ resourceType: urlResourceType,
153
162
  importContainerKey,
154
163
  jobId,
155
164
  })
156
165
 
157
- const payload = action ? { action } : {}
166
+ const payload = operationType ? { action: operationType } : {}
158
167
 
159
168
  const response = await fetcher<ProcessFileImportJobResponse>({
160
169
  url,
@@ -13,7 +13,6 @@ export async function processUploadedFile({
13
13
  resourceType,
14
14
  action,
15
15
  }: ProcessUploadedFileRequestParameters): Promise<ProcessFileResponse> {
16
- // For delete operations with action (like 'delete') -> use different URL and payload structure
17
16
  const uri = action
18
17
  ? getImportContainerTasksURL({ projectKey, importContainerKey })
19
18
  : getProccessFileURL({ projectKey, resourceType, importContainerKey })
package/src/@api/urls.ts CHANGED
@@ -6,6 +6,15 @@ import type {
6
6
  ExportOperationQueryParams,
7
7
  } from '../@types'
8
8
 
9
+ const OPERATION_RESOURCE_TYPES = ['product-delete', 'product-unpublish']
10
+
11
+ function pluralizeResourceType(resourceType: string): string {
12
+ if (OPERATION_RESOURCE_TYPES.includes(resourceType)) {
13
+ return resourceType
14
+ }
15
+ return plural(resourceType)
16
+ }
17
+
9
18
  export function getImportContainersURL({
10
19
  projectKey,
11
20
  queryParams,
@@ -126,7 +135,7 @@ export function getFileImportJobsURL({
126
135
  resourceType: string
127
136
  importContainerKey: string
128
137
  }): string {
129
- return `/${projectKey}/${plural(
138
+ return `/${projectKey}/${pluralizeResourceType(
130
139
  toImportApiResourceType(resourceType)
131
140
  )}/import-containers/${importContainerKey}/file-import-jobs`
132
141
  }
@@ -166,7 +175,7 @@ export function getFileImportJobProcessURL({
166
175
  importContainerKey: string
167
176
  jobId: string
168
177
  }): string {
169
- return `/${projectKey}/${plural(
178
+ return `/${projectKey}/${pluralizeResourceType(
170
179
  toImportApiResourceType(resourceType)
171
180
  )}/import-containers/${importContainerKey}/file-import-jobs/${jobId}/process`
172
181
  }
@@ -16,7 +16,6 @@ const mockGetFileImportJob = getFileImportJob as jest.MockedFunction<
16
16
 
17
17
  describe('useFetchFileImportJob', () => {
18
18
  const projectKey = 'test-with-big-data'
19
- const resourceType = 'product'
20
19
  const importContainerKey = 'test-container'
21
20
  const jobId = 'test-job-id'
22
21
 
@@ -45,7 +44,6 @@ describe('useFetchFileImportJob', () => {
45
44
  const { result } = renderHook(() =>
46
45
  useFetchFileImportJob({
47
46
  projectKey,
48
- resourceType,
49
47
  importContainerKey,
50
48
  jobId,
51
49
  })
@@ -57,7 +55,6 @@ describe('useFetchFileImportJob', () => {
57
55
 
58
56
  expect(mockGetFileImportJob).toHaveBeenCalledWith({
59
57
  projectKey,
60
- resourceType,
61
58
  importContainerKey,
62
59
  jobId,
63
60
  })
@@ -70,7 +67,6 @@ describe('useFetchFileImportJob', () => {
70
67
  const { result } = renderHook(() =>
71
68
  useFetchFileImportJob({
72
69
  projectKey,
73
- resourceType,
74
70
  importContainerKey,
75
71
  jobId,
76
72
  })
@@ -92,7 +88,6 @@ describe('useFetchFileImportJob', () => {
92
88
  const { result } = renderHook(() =>
93
89
  useFetchFileImportJob({
94
90
  projectKey,
95
- resourceType,
96
91
  importContainerKey,
97
92
  jobId,
98
93
  pollingInterval,
@@ -106,7 +101,6 @@ describe('useFetchFileImportJob', () => {
106
101
 
107
102
  expect(mockGetFileImportJob).toHaveBeenCalledWith({
108
103
  projectKey,
109
- resourceType,
110
104
  importContainerKey,
111
105
  jobId,
112
106
  })
@@ -116,7 +110,6 @@ describe('useFetchFileImportJob', () => {
116
110
  const { result } = renderHook(() =>
117
111
  useFetchFileImportJob({
118
112
  projectKey: '',
119
- resourceType,
120
113
  importContainerKey,
121
114
  jobId,
122
115
  })
@@ -6,7 +6,6 @@ import { useFetch } from './use-fetch'
6
6
 
7
7
  type UseFetchFileImportJobConfig = {
8
8
  projectKey: string
9
- resourceType: string
10
9
  importContainerKey: string
11
10
  jobId: string
12
11
  pollingInterval?: number
@@ -5,7 +5,10 @@ import {
5
5
  createFileImportJob,
6
6
  } from '../@api'
7
7
  import { ProjectKeyNotAvailableError } from '../@errors'
8
- import { encodeFileNameWithTimestampToContainerKey } from '../@utils'
8
+ import {
9
+ encodeFileNameWithTimestampToContainerKey,
10
+ getFileImportJobFileType,
11
+ } from '../@utils'
9
12
  import {
10
13
  useFileImportJobUpload,
11
14
  UseFileImportJobUploadConfig,
@@ -28,6 +31,10 @@ const mockEncodeFileNameWithTimestampToContainerKey =
28
31
  encodeFileNameWithTimestampToContainerKey as jest.MockedFunction<
29
32
  typeof encodeFileNameWithTimestampToContainerKey
30
33
  >
34
+ const mockGetFileImportJobFileType =
35
+ getFileImportJobFileType as jest.MockedFunction<
36
+ typeof getFileImportJobFileType
37
+ >
31
38
 
32
39
  describe('useFileImportJobUpload', () => {
33
40
  const projectKey = 'test-with-big-data'
@@ -53,6 +60,9 @@ describe('useFileImportJobUpload', () => {
53
60
  mockEncodeFileNameWithTimestampToContainerKey.mockReturnValue(
54
61
  importContainerKey
55
62
  )
63
+ mockGetFileImportJobFileType.mockImplementation((resourceType) =>
64
+ resourceType === 'custom-object' ? 'json' : 'csv'
65
+ )
56
66
  mockCreateImportContainerForFileUpload.mockResolvedValue({
57
67
  key: importContainerKey,
58
68
  })
@@ -112,7 +122,10 @@ describe('useFileImportJobUpload', () => {
112
122
  fileName: 'test.csv',
113
123
  file: mockFile,
114
124
  },
125
+ autoProcess: undefined,
126
+ operationType: undefined,
115
127
  onProgress: expect.any(Function),
128
+ abortSignal: undefined,
116
129
  })
117
130
 
118
131
  expect(onSuccess).toHaveBeenCalledWith('job-123', importContainerKey)
@@ -147,7 +160,10 @@ describe('useFileImportJobUpload', () => {
147
160
  fileName: 'test.json',
148
161
  file: mockJsonFile,
149
162
  },
163
+ autoProcess: undefined,
164
+ operationType: undefined,
150
165
  onProgress: expect.any(Function),
166
+ abortSignal: undefined,
151
167
  })
152
168
 
153
169
  expect(onSuccess).toHaveBeenCalledWith('job-123', importContainerKey)
@@ -18,6 +18,7 @@ export type UseFileImportJobUploadConfig = {
18
18
  resourceType: ResourceTypeId
19
19
  settings?: ExtendedImportContainerDraft['settings']
20
20
  autoProcess?: boolean
21
+ operationType?: 'delete'
21
22
  onSuccess: (jobId: string, importContainerKey: string) => void
22
23
  onError?: (error: unknown) => void
23
24
  onProgress?: (progress: number) => void
@@ -66,6 +67,7 @@ export const useFileImportJobUpload = ({
66
67
  file: config.file,
67
68
  },
68
69
  autoProcess: config.autoProcess,
70
+ operationType: config.operationType,
69
71
  onProgress: (uploadProgress) => {
70
72
  setProgress(uploadProgress)
71
73
  config.onProgress?.(uploadProgress)
@@ -22,6 +22,7 @@ export type FileUploadConfig = {
22
22
  settings?: ExtendedImportContainerDraft['settings']
23
23
  autoProcess?: boolean
24
24
  skipValidationPolling?: boolean
25
+ operationType?: 'delete'
25
26
  onSuccess: (result: FileUploadResult) => void
26
27
  onError?: (error: unknown) => void
27
28
  onProgress?: (progress: number) => void
@@ -86,6 +87,7 @@ export const useFileUpload = ({
86
87
  resourceType: config.resourceType,
87
88
  settings: config.settings,
88
89
  autoProcess: config.autoProcess,
90
+ operationType: config.operationType,
89
91
  abortSignal: config.abortSignal,
90
92
  onSuccess: async (jobId, containerKey) => {
91
93
  if (config.skipValidationPolling) {
@@ -57,6 +57,7 @@ export interface CreateFileImportJobParameters {
57
57
  importContainerKey: string
58
58
  payload: CreateFileImportJobPayload
59
59
  autoProcess?: boolean
60
+ operationType?: 'delete'
60
61
  onProgress?: (progress: number) => void
61
62
  abortSignal?: AbortSignal
62
63
  }
@@ -100,7 +101,7 @@ export interface ProcessFileImportJobParameters {
100
101
  resourceType: string
101
102
  importContainerKey: string
102
103
  jobId: string
103
- action?: 'delete'
104
+ operationType?: 'delete'
104
105
  }
105
106
 
106
107
  export interface ProcessFileImportJobResponse {
@@ -53,7 +53,7 @@ export interface ProcessUploadedFileRequestParameters {
53
53
  projectKey: string
54
54
  importContainerKey: string
55
55
  resourceType: ResourceTypeId
56
- action?: 'delete' // Currently only 'delete' action is supported
56
+ action?: 'delete'
57
57
  }
58
58
 
59
59
  export type ProcessFileResponse = {
@@ -6,6 +6,8 @@ type RowErrorsResponse = {
6
6
  errors: Array<{ field: string; code: string; message: string }>
7
7
  }
8
8
 
9
+ // Note: Both `row` and `index` are included in the output for backwards compatibility
10
+ // Old flow uses `row`, new flow uses `index`. After migration, `row` will be removed
9
11
  describe('mapUploadFileErrorsResponseToUploadFileErrorRows', () => {
10
12
  it('should return an empty array if uploadFileErrorsResponse is undefined', () => {
11
13
  const result = mapUploadFileErrorsResponseToUploadFileErrorRows(undefined)
@@ -47,6 +49,7 @@ describe('mapUploadFileErrorsResponseToUploadFileErrorRows', () => {
47
49
  "code": "InvalidField",
48
50
  "field": "name.de2",
49
51
  "id": "1",
52
+ "index": 1,
50
53
  "row": 1,
51
54
  "validationMessage": ""name.de2" is not allowed",
52
55
  },
@@ -54,6 +57,7 @@ describe('mapUploadFileErrorsResponseToUploadFileErrorRows', () => {
54
57
  "code": "InvalidField",
55
58
  "field": "name.enn",
56
59
  "id": "2",
60
+ "index": 1,
57
61
  "row": 1,
58
62
  "validationMessage": ""name.enn" is not allowed",
59
63
  },
@@ -61,6 +65,7 @@ describe('mapUploadFileErrorsResponseToUploadFileErrorRows', () => {
61
65
  "code": "InvalidField",
62
66
  "field": "slug.RU",
63
67
  "id": "3",
68
+ "index": 2,
64
69
  "row": 2,
65
70
  "validationMessage": ""slug.RU" is not allowed",
66
71
  },
@@ -104,6 +109,7 @@ describe('mapUploadFileErrorsResponseToUploadFileErrorRows', () => {
104
109
  "field": "name.de2",
105
110
  "id": "1",
106
111
  "index": 0,
112
+ "row": 0,
107
113
  "validationMessage": ""name.de2" is not allowed",
108
114
  },
109
115
  {
@@ -111,6 +117,7 @@ describe('mapUploadFileErrorsResponseToUploadFileErrorRows', () => {
111
117
  "field": "name.enn",
112
118
  "id": "2",
113
119
  "index": 0,
120
+ "row": 0,
114
121
  "validationMessage": ""name.enn" is not allowed",
115
122
  },
116
123
  {
@@ -118,6 +125,7 @@ describe('mapUploadFileErrorsResponseToUploadFileErrorRows', () => {
118
125
  "field": "slug.RU",
119
126
  "id": "3",
120
127
  "index": 1,
128
+ "row": 1,
121
129
  "validationMessage": ""slug.RU" is not allowed",
122
130
  },
123
131
  ]