@commercetools-frontend-extensions/operations 2.0.1 → 3.1.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.
Files changed (68) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +138 -71
  3. package/dist/commercetools-frontend-extensions-operations.cjs.dev.js +979 -143
  4. package/dist/commercetools-frontend-extensions-operations.cjs.prod.js +979 -143
  5. package/dist/commercetools-frontend-extensions-operations.esm.js +929 -140
  6. package/dist/declarations/src/@api/file-import-jobs.d.ts +7 -0
  7. package/dist/declarations/src/@api/index.d.ts +1 -0
  8. package/dist/declarations/src/@api/test-fixtures.d.ts +8 -1
  9. package/dist/declarations/src/@api/urls.d.ts +30 -0
  10. package/dist/declarations/src/@components/uploading-modal/uploading-modal.d.ts +3 -2
  11. package/dist/declarations/src/@constants/file-import-job.d.ts +1 -0
  12. package/dist/declarations/src/@constants/import-limits.d.ts +6 -0
  13. package/dist/declarations/src/@constants/index.d.ts +2 -1
  14. package/dist/declarations/src/@errors/index.d.ts +5 -4
  15. package/dist/declarations/src/@errors/polling-aborted-error.d.ts +3 -0
  16. package/dist/declarations/src/@hooks/index.d.ts +4 -0
  17. package/dist/declarations/src/@hooks/use-fetch-file-import-job-records.d.ts +18 -0
  18. package/dist/declarations/src/@hooks/use-fetch-file-import-job.d.ts +17 -0
  19. package/dist/declarations/src/@hooks/use-file-import-job-upload.d.ts +18 -0
  20. package/dist/declarations/src/@hooks/use-file-upload.d.ts +29 -0
  21. package/dist/declarations/src/@hooks/use-import-container-upload.d.ts +2 -1
  22. package/dist/declarations/src/@types/export-operation.d.ts +3 -1
  23. package/dist/declarations/src/@types/file-import-job.d.ts +99 -0
  24. package/dist/declarations/src/@types/file-upload-result.d.ts +21 -0
  25. package/dist/declarations/src/@types/file-upload.d.ts +2 -2
  26. package/dist/declarations/src/@types/index.d.ts +2 -0
  27. package/dist/declarations/src/@utils/file-import-job-helpers.d.ts +12 -0
  28. package/dist/declarations/src/@utils/file-upload.d.ts +8 -0
  29. package/dist/declarations/src/@utils/index.d.ts +2 -0
  30. package/dist/declarations/src/@utils/poll-job-until-validated.d.ts +11 -0
  31. package/package.json +12 -13
  32. package/src/@api/fetcher.ts +10 -0
  33. package/src/@api/file-import-jobs.ts +217 -0
  34. package/src/@api/file-upload.spec.ts +4 -2
  35. package/src/@api/index.ts +1 -0
  36. package/src/@api/test-fixtures.ts +127 -5
  37. package/src/@api/urls.ts +77 -1
  38. package/src/@components/uploading-modal/uploading-modal.tsx +7 -5
  39. package/src/@constants/file-import-job.ts +1 -0
  40. package/src/@constants/import-limits.ts +13 -0
  41. package/src/@constants/index.ts +2 -1
  42. package/src/@errors/index.ts +5 -4
  43. package/src/@errors/polling-aborted-error.ts +6 -0
  44. package/src/@hooks/index.ts +4 -0
  45. package/src/@hooks/use-fetch-file-import-job-records.ts +58 -0
  46. package/src/@hooks/use-fetch-file-import-job.spec.ts +131 -0
  47. package/src/@hooks/use-fetch-file-import-job.ts +38 -0
  48. package/src/@hooks/use-fetch.spec.ts +1 -9
  49. package/src/@hooks/use-fetch.ts +4 -8
  50. package/src/@hooks/use-file-import-job-upload.spec.ts +273 -0
  51. package/src/@hooks/use-file-import-job-upload.ts +101 -0
  52. package/src/@hooks/use-file-upload.ts +231 -0
  53. package/src/@hooks/use-import-container-upload.spec.ts +16 -13
  54. package/src/@hooks/use-import-container-upload.ts +6 -2
  55. package/src/@types/export-operation.ts +3 -0
  56. package/src/@types/file-import-job.ts +165 -0
  57. package/src/@types/file-upload-result.ts +23 -0
  58. package/src/@types/file-upload.ts +2 -2
  59. package/src/@types/index.ts +2 -0
  60. package/src/@utils/error-mapping.ts +10 -9
  61. package/src/@utils/file-import-job-helpers.spec.ts +147 -0
  62. package/src/@utils/file-import-job-helpers.ts +47 -0
  63. package/src/@utils/file-upload.ts +39 -0
  64. package/src/@utils/index.ts +2 -0
  65. package/src/@utils/poll-job-until-validated.ts +76 -0
  66. package/dist/declarations/src/@constants/upload-limits.d.ts +0 -10
  67. package/src/@constants/upload-limits.ts +0 -11
  68. package/src/@hooks/messages.ts +0 -11
@@ -0,0 +1,7 @@
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, onProgress, abortSignal, }: CreateFileImportJobParameters): Promise<FileImportJob>;
3
+ export declare function getFileImportJob({ projectKey, importContainerKey, jobId, }: GetFileImportJobParameters): Promise<FileImportJob>;
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>;
6
+ export declare function deleteFileImportJob({ projectKey, importContainerKey, jobId, }: DeleteFileImportJobParameters): Promise<void>;
7
+ export declare function listFileImportJobs({ projectKey, importContainerKey, limit, offset, }: ListFileImportJobsParameters): Promise<ListFileImportJobsResponse>;
@@ -1,5 +1,6 @@
1
1
  export * from "./fetcher.js";
2
2
  export * from "./file-upload.js";
3
+ export * from "./file-import-jobs.js";
3
4
  export * from "./import-containers.js";
4
5
  export * from "./import-operations.js";
5
6
  export * from "./export-operations.js";
@@ -1,4 +1,4 @@
1
- import { type ProcessFileResponse, type ExportOperation, ImportStates, type ImportSummary, FileUploadResponse } from "../@types/index.js";
1
+ import { type ProcessFileResponse, type ExportOperation, ImportStates, type ImportSummary, type FileUploadResponse, type FileImportJob, type FileImportJobRecordsResponse, type ProcessFileImportJobResponse } from "../@types/index.js";
2
2
  export declare const automatedImportContainerKey = "automated-container-key";
3
3
  export declare const fileUploadImportContainerKey = "eyJ0aW1lc3RhbXAiOiAxNzA1MDc0MzIxODY4LCAiZmlsZU5hbWUiOiAiZmlsZS11cGxvYWQtY29udGFpbmVyLWtleS5jc3YifQ";
4
4
  export declare const manualImports: {
@@ -270,3 +270,10 @@ export declare const fileUploadMissingKeysResponse: {
270
270
  export declare const validProcessFileResponse: ProcessFileResponse;
271
271
  export declare const exportOperationsCompleted: ExportOperation[];
272
272
  export declare const exportOperationsProcessing: ExportOperation[];
273
+ export declare const validFileImportJobQueued: FileImportJob;
274
+ export declare const validFileImportJobProcessing: FileImportJob;
275
+ export declare const validFileImportJobValidated: FileImportJob;
276
+ export declare const invalidFileImportJobValidated: FileImportJob;
277
+ export declare const validFileImportJobRecordsResponse: FileImportJobRecordsResponse;
278
+ export declare const invalidFileImportJobRecordsResponse: FileImportJobRecordsResponse;
279
+ export declare const processFileImportJobResponse: ProcessFileImportJobResponse;
@@ -42,3 +42,33 @@ export declare function getExportOperationsURL({ projectKey, queryParams, }: {
42
42
  projectKey: string;
43
43
  queryParams: ExportOperationQueryParams;
44
44
  }): string;
45
+ export declare function getFileImportJobsURL({ projectKey, resourceType, importContainerKey, }: {
46
+ projectKey: string;
47
+ resourceType: string;
48
+ importContainerKey: string;
49
+ }): string;
50
+ export declare function getFileImportJobByIdURL({ projectKey, importContainerKey, jobId, }: {
51
+ projectKey: string;
52
+ importContainerKey: string;
53
+ jobId: string;
54
+ }): string;
55
+ export declare function getFileImportJobRecordsURL({ projectKey, importContainerKey, jobId, }: {
56
+ projectKey: string;
57
+ importContainerKey: string;
58
+ jobId: string;
59
+ }): string;
60
+ export declare function getFileImportJobProcessURL({ projectKey, resourceType, importContainerKey, jobId, }: {
61
+ projectKey: string;
62
+ resourceType: string;
63
+ importContainerKey: string;
64
+ jobId: string;
65
+ }): string;
66
+ export declare function getFileImportJobDeleteURL({ projectKey, importContainerKey, jobId, }: {
67
+ projectKey: string;
68
+ importContainerKey: string;
69
+ jobId: string;
70
+ }): string;
71
+ export declare function getFileImportJobsListURL({ projectKey, importContainerKey, }: {
72
+ projectKey: string;
73
+ importContainerKey: string;
74
+ }): string;
@@ -3,10 +3,11 @@ type UploadingModalProps = {
3
3
  title: string;
4
4
  fileName: string;
5
5
  fileSize: number;
6
- progress: number;
6
+ progress?: number;
7
7
  cancelLabel: string;
8
8
  onCancel: () => void;
9
9
  onClose: () => void;
10
+ statusMessage?: string;
10
11
  };
11
- export declare const UploadingModal: ({ isOpen, title, fileName, fileSize, progress, cancelLabel, onCancel, onClose, }: UploadingModalProps) => import("@emotion/react/jsx-runtime").JSX.Element;
12
+ export declare const UploadingModal: ({ isOpen, title, fileName, fileSize, progress, cancelLabel, onCancel, onClose, statusMessage, }: UploadingModalProps) => import("@emotion/react/jsx-runtime").JSX.Element;
12
13
  export {};
@@ -0,0 +1 @@
1
+ export declare const FILE_IMPORT_JOB_POLLING_INTERVAL = 2000;
@@ -0,0 +1,6 @@
1
+ export declare const IMPORT_MAX_FILE_SIZE_MB = 200;
2
+ export declare const IMPORT_MAX_ITEM_COUNT = 500000;
3
+ /** @deprecated Use IMPORT_MAX_FILE_SIZE_MB instead. Remove after migration. */
4
+ export declare const IMPORT_LEGACY_MAX_FILE_SIZE_MB = 35;
5
+ /** @deprecated Use IMPORT_MAX_ITEM_COUNT instead. Remove after migration. */
6
+ export declare const IMPORT_LEGACY_MAX_ROW_COUNT = 80000;
@@ -1,4 +1,5 @@
1
1
  export * from "./delimiters.js";
2
+ export * from "./file-import-job.js";
3
+ export * from "./import-limits.js";
2
4
  export * from "./import-tags.js";
3
5
  export * from "./resource-links.js";
4
- export * from "./upload-limits.js";
@@ -1,8 +1,9 @@
1
- export * from "./unexpected-column-error.js";
2
- export * from "./unexpected-operation-state-error.js";
3
- export * from "./unexpected-resource-type-error.js";
4
1
  export * from "./http-error.js";
5
2
  export * from "./invalid-response-error.js";
6
- export * from "./query-predicate-error.js";
7
3
  export * from "./no-resources-to-export-error.js";
4
+ export * from "./polling-aborted-error.js";
8
5
  export * from "./project-key-not-available-error.js";
6
+ export * from "./query-predicate-error.js";
7
+ export * from "./unexpected-column-error.js";
8
+ export * from "./unexpected-operation-state-error.js";
9
+ export * from "./unexpected-resource-type-error.js";
@@ -0,0 +1,3 @@
1
+ export declare class PollingAbortedError extends Error {
2
+ constructor();
3
+ }
@@ -1,5 +1,9 @@
1
1
  export * from "./use-fetch-export-operations.js";
2
+ export * from "./use-fetch-file-import-job.js";
3
+ export * from "./use-fetch-file-import-job-records.js";
2
4
  export * from "./use-fetch-import-container-details.js";
3
5
  export * from "./use-fetch-import-operations.js";
4
6
  export * from "./use-fetch-import-summaries.js";
7
+ export * from "./use-file-import-job-upload.js";
8
+ export * from "./use-file-upload.js";
5
9
  export * from "./use-import-container-upload.js";
@@ -0,0 +1,18 @@
1
+ import type { FileImportJobRecordsResponse } from "../@types/index.js";
2
+ type UseFetchFileImportJobRecordsConfig = {
3
+ projectKey?: string;
4
+ importContainerKey?: string;
5
+ jobId?: string;
6
+ limit?: number;
7
+ offset?: number;
8
+ isValid?: boolean;
9
+ skip?: boolean;
10
+ };
11
+ export declare const useFetchFileImportJobRecords: ({ projectKey, importContainerKey, jobId, limit, offset, isValid, skip, }: UseFetchFileImportJobRecordsConfig) => {
12
+ data: FileImportJobRecordsResponse | null;
13
+ error: Error | null;
14
+ isLoading: boolean;
15
+ refetch: () => void;
16
+ lastFetchTime: Date;
17
+ };
18
+ export {};
@@ -0,0 +1,17 @@
1
+ import type { FileImportJob } from "../@types/index.js";
2
+ type UseFetchFileImportJobConfig = {
3
+ projectKey: string;
4
+ resourceType: string;
5
+ importContainerKey: string;
6
+ jobId: string;
7
+ pollingInterval?: number;
8
+ shouldContinuePolling?: (data: FileImportJob) => boolean;
9
+ };
10
+ export declare const useFetchFileImportJob: ({ projectKey, importContainerKey, jobId, pollingInterval, shouldContinuePolling, }: UseFetchFileImportJobConfig) => {
11
+ data: FileImportJob | null;
12
+ error: Error | null;
13
+ isLoading: boolean;
14
+ refetch: () => void;
15
+ lastFetchTime: Date;
16
+ };
17
+ export {};
@@ -0,0 +1,18 @@
1
+ import type { ResourceTypeId } from '@commercetools/importapi-sdk';
2
+ import type { ExtendedImportContainerDraft } from "../@types/index.js";
3
+ export type UseFileImportJobUploadConfig = {
4
+ file: File;
5
+ resourceType: ResourceTypeId;
6
+ settings?: ExtendedImportContainerDraft['settings'];
7
+ onSuccess: (jobId: string, importContainerKey: string) => void;
8
+ onError?: (error: unknown) => void;
9
+ onProgress?: (progress: number) => void;
10
+ abortSignal?: AbortSignal;
11
+ };
12
+ export declare const useFileImportJobUpload: ({ projectKey, }: {
13
+ projectKey: string;
14
+ }) => {
15
+ upload: (config: UseFileImportJobUploadConfig) => Promise<void>;
16
+ isUploading: boolean;
17
+ progress: number;
18
+ };
@@ -0,0 +1,29 @@
1
+ import type { ResourceTypeId } from '@commercetools/importapi-sdk';
2
+ import type { ExtendedImportContainerDraft, FileUploadResult, FileImportJob } from "../@types/index.js";
3
+ export type ValidationProgress = {
4
+ processed: number;
5
+ total: number;
6
+ isValidating: boolean;
7
+ };
8
+ export type FileUploadConfig = {
9
+ file: File;
10
+ resourceType: ResourceTypeId;
11
+ settings?: ExtendedImportContainerDraft['settings'];
12
+ onSuccess: (result: FileUploadResult) => void;
13
+ onError?: (error: unknown) => void;
14
+ onProgress?: (progress: number) => void;
15
+ onValidationProgress?: (job: FileImportJob) => void;
16
+ abortSignal?: AbortSignal;
17
+ };
18
+ export type FileUploadOptions = {
19
+ projectKey: string;
20
+ useJobBasedFlow?: boolean;
21
+ pollingInterval?: number;
22
+ maxPollingAttempts?: number;
23
+ };
24
+ export declare const useFileUpload: ({ projectKey, useJobBasedFlow, pollingInterval, maxPollingAttempts, }: FileUploadOptions) => {
25
+ upload: (config: FileUploadConfig) => Promise<void>;
26
+ isUploading: boolean;
27
+ progress: number;
28
+ validationProgress: ValidationProgress;
29
+ };
@@ -7,11 +7,12 @@ export type UseImportContainerUploadConfig = {
7
7
  onSuccess: (response: FileUploadResponse, importContainerKey: string) => void;
8
8
  onError?: (error: unknown) => void;
9
9
  onProgress?: (progress: number) => void;
10
+ abortSignal?: AbortSignal;
10
11
  };
11
12
  export declare const useImportContainerUpload: ({ projectKey, }: {
12
13
  projectKey: string;
13
14
  }) => {
14
- upload: ({ file, resourceType, settings, onSuccess, onError, onProgress, }: UseImportContainerUploadConfig) => Promise<XMLHttpRequest>;
15
+ upload: ({ file, resourceType, settings, onSuccess, onError, onProgress, abortSignal, }: UseImportContainerUploadConfig) => Promise<XMLHttpRequest | undefined>;
15
16
  abort: () => void;
16
17
  isUploading: boolean;
17
18
  progress: number;
@@ -87,9 +87,11 @@ export interface ExportApiErrorResponse {
87
87
  errors: ValidationError[];
88
88
  message: string;
89
89
  }
90
- export type ValidationErrorCode = 'DuplicateFields' | 'NotSupportedField' | 'FieldDefinitionNotFound' | 'AttributeDefinitionNotFound' | 'LocalizedFieldWithoutLocale' | 'IncompleteField';
90
+ export type ValidationErrorCode = 'DuplicateFields' | 'NotSupportedField' | 'FieldDefinitionNotFound' | 'AttributeDefinitionNotFound' | 'LocalizedFieldWithoutLocale' | 'IncompleteField' | 'AttributeLevelMismatch';
91
91
  export type ValidationError = {
92
92
  code: ValidationErrorCode;
93
93
  message: string;
94
94
  field?: string;
95
+ requestedLevel?: string;
96
+ actualLevel?: string;
95
97
  };
@@ -0,0 +1,99 @@
1
+ export type FileImportJobState = 'queued' | 'processing' | 'validated' | 'initialising' | 'ready' | 'rejected';
2
+ export interface FileImportJobSummary {
3
+ total: number;
4
+ invalid: number;
5
+ valid: number;
6
+ fieldsCount: number;
7
+ fields: string[];
8
+ ignoredFields: string[];
9
+ }
10
+ export interface FileImportJobValidationError {
11
+ code: string;
12
+ message: string;
13
+ rowValue?: Record<string, string>;
14
+ metadata?: {
15
+ row?: number;
16
+ };
17
+ }
18
+ export interface FileImportJob {
19
+ id: string;
20
+ fileName: string;
21
+ importContainerKey: string;
22
+ state: FileImportJobState;
23
+ summary: FileImportJobSummary;
24
+ jobError?: FileImportJobValidationError | null;
25
+ }
26
+ export interface CreateFileImportJobWithStreamPayload {
27
+ fileType: 'csv' | 'json';
28
+ fileName: string;
29
+ file: File;
30
+ }
31
+ export interface CreateFileImportJobWithReferencePayload {
32
+ payloadType: 'fileReference';
33
+ fileName: string;
34
+ fileUrl: string;
35
+ }
36
+ export type CreateFileImportJobPayload = CreateFileImportJobWithStreamPayload | CreateFileImportJobWithReferencePayload;
37
+ export interface CreateFileImportJobParameters {
38
+ projectKey: string;
39
+ resourceType: string;
40
+ importContainerKey: string;
41
+ payload: CreateFileImportJobPayload;
42
+ onProgress?: (progress: number) => void;
43
+ abortSignal?: AbortSignal;
44
+ }
45
+ export interface GetFileImportJobParameters {
46
+ projectKey: string;
47
+ importContainerKey: string;
48
+ jobId: string;
49
+ }
50
+ export interface FileImportJobError {
51
+ code: string;
52
+ message: string;
53
+ field: string;
54
+ }
55
+ export interface FileImportJobErrorRecord {
56
+ index: number;
57
+ errors: FileImportJobError[];
58
+ }
59
+ export interface FileImportJobRecordsResponse {
60
+ results: FileImportJobErrorRecord[];
61
+ total: number;
62
+ limit: number;
63
+ offset: number;
64
+ count: number;
65
+ }
66
+ export interface GetFileImportJobRecordsParameters {
67
+ projectKey: string;
68
+ importContainerKey: string;
69
+ jobId: string;
70
+ limit?: number;
71
+ offset?: number;
72
+ isValid?: boolean;
73
+ }
74
+ export interface ProcessFileImportJobParameters {
75
+ projectKey: string;
76
+ resourceType: string;
77
+ importContainerKey: string;
78
+ jobId: string;
79
+ action?: 'delete';
80
+ }
81
+ export interface ProcessFileImportJobResponse {
82
+ message: string;
83
+ }
84
+ export interface DeleteFileImportJobParameters {
85
+ projectKey: string;
86
+ importContainerKey: string;
87
+ jobId: string;
88
+ }
89
+ export interface ListFileImportJobsParameters {
90
+ projectKey: string;
91
+ importContainerKey: string;
92
+ limit?: number;
93
+ offset?: number;
94
+ }
95
+ export type ListFileImportJobsResponse = FileImportJob[];
96
+ export declare function assertFileImportJob(maybeJob: unknown): asserts maybeJob is FileImportJob;
97
+ export declare function assertFileImportJobRecordsResponse(maybeRecords: unknown): asserts maybeRecords is FileImportJobRecordsResponse;
98
+ export declare function assertProcessFileImportJobResponse(maybeResponse: unknown): asserts maybeResponse is ProcessFileImportJobResponse;
99
+ export declare function assertListFileImportJobsResponse(maybeResponse: unknown): asserts maybeResponse is ListFileImportJobsResponse;
@@ -0,0 +1,21 @@
1
+ import type { FileImportJob } from "./file-import-job.js";
2
+ import type { RowErrorsResponse } from "./file-upload.js";
3
+ export interface FileUploadResult {
4
+ containerKey: string;
5
+ summary: {
6
+ total: number;
7
+ valid: number;
8
+ invalid: number;
9
+ fieldsCount: number;
10
+ fields: string[];
11
+ ignoredFields: string[];
12
+ /**
13
+ * Validation errors. Format is compatible between old and new flows:
14
+ * - Old flow: { row?: number, index?: number, errors: RowError[] }
15
+ * - New flow: { index: number, errors: FileImportJobError[] }
16
+ */
17
+ results: Array<RowErrorsResponse>;
18
+ };
19
+ jobId?: string;
20
+ job?: FileImportJob;
21
+ }
@@ -29,8 +29,8 @@ export type FileUploadResponse = {
29
29
  itemsCount: number;
30
30
  rowsCount: number;
31
31
  columnsCount: number;
32
- columns: Array<string>;
33
- ignoredColumns: Array<string>;
32
+ fields: Array<string>;
33
+ ignoredFields: Array<string>;
34
34
  };
35
35
  export interface FileUploadRequestParameters {
36
36
  projectKey: string;
@@ -2,6 +2,8 @@ export * from "./api.js";
2
2
  export * from "./basic-error-data-type.js";
3
3
  export * from "./export-operation.js";
4
4
  export * from "./file-upload.js";
5
+ export * from "./file-upload-result.js";
6
+ export * from "./file-import-job.js";
5
7
  export * from "./import-container.js";
6
8
  export * from "./import-operation.js";
7
9
  export * from "./import-states.js";
@@ -0,0 +1,12 @@
1
+ import type { ResourceTypeId } from '@commercetools/importapi-sdk';
2
+ import type { FileImportJob } from "../@types/index.js";
3
+ export declare function getFileImportJobFileType(resourceType: ResourceTypeId): 'csv' | 'json';
4
+ export declare function toImportApiResourceType(resourceType: string): string;
5
+ export declare function isImportJobQueued(job?: FileImportJob): boolean;
6
+ export declare function isImportJobProcessing(job?: FileImportJob): boolean;
7
+ export declare function isImportJobValidated(job?: FileImportJob): boolean;
8
+ export declare function isImportJobInitializing(job?: FileImportJob): boolean;
9
+ export declare function isImportJobReady(job?: FileImportJob): boolean;
10
+ export declare function isImportJobRejected(job?: FileImportJob): boolean;
11
+ export declare function isImportJobTerminal(job?: FileImportJob): boolean;
12
+ export declare function shouldContinuePollingForImportValidation(job?: FileImportJob): boolean;
@@ -36,6 +36,14 @@ export declare const countJsonFileItems: (file: File) => Promise<{
36
36
  isValid: true;
37
37
  itemsCount: number;
38
38
  }>;
39
+ /**
40
+ * Count unique resources in a CSV file by counting unique values in the "key" column.
41
+ * A single resource can span multiple rows (when it has array fields like variants, assets...),
42
+ * so we count unique keys rather than rows.
43
+ * @param file The CSV file to process
44
+ * @returns A promise that resolves to the number of unique resources
45
+ */
46
+ export declare const countUniqueResourcesInCsv: (file: File) => Promise<number>;
39
47
  /**
40
48
  * Map file upload errors to upload file error rows with unique IDs
41
49
  * @param uploadFileErrors Array of file upload errors
@@ -1,6 +1,8 @@
1
1
  export * from "./error-mapping.js";
2
+ export * from "./file-import-job-helpers.js";
2
3
  export * from "./file-upload.js";
3
4
  export * from "./form.js";
4
5
  export * from "./format.js";
5
6
  export * from "./import-container.js";
7
+ export * from "./poll-job-until-validated.js";
6
8
  export * from "./url.js";
@@ -0,0 +1,11 @@
1
+ import type { FileImportJob } from "../@types/index.js";
2
+ export type PollJobUntilValidatedConfig = {
3
+ projectKey: string;
4
+ jobId: string;
5
+ importContainerKey: string;
6
+ pollingInterval?: number;
7
+ maxAttempts?: number;
8
+ onJobUpdate?: (job: FileImportJob) => void;
9
+ abortSignal?: AbortSignal;
10
+ };
11
+ export declare const pollJobUntilValidated: ({ projectKey, jobId, importContainerKey, pollingInterval, maxAttempts, onJobUpdate, abortSignal, }: PollJobUntilValidatedConfig) => Promise<FileImportJob>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commercetools-frontend-extensions/operations",
3
- "version": "2.0.1",
3
+ "version": "3.1.0",
4
4
  "license": "Proprietary",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -18,26 +18,26 @@
18
18
  "react-dropzone": "14.3.8"
19
19
  },
20
20
  "devDependencies": {
21
- "@commercetools-frontend/actions-global": "24.9.0",
22
- "@commercetools-frontend/application-components": "24.9.0",
23
- "@commercetools-frontend/application-shell": "24.9.0",
24
- "@commercetools-frontend/application-shell-connectors": "24.9.0",
25
- "@commercetools-frontend/constants": "24.9.0",
26
- "@commercetools-frontend/jest-preset-mc-app": "24.9.0",
27
- "@commercetools-frontend/permissions": "24.9.0",
28
- "@commercetools-frontend/sentry": "24.9.0",
21
+ "@commercetools-frontend/actions-global": "24.12.0",
22
+ "@commercetools-frontend/application-components": "24.12.0",
23
+ "@commercetools-frontend/application-shell": "24.12.0",
24
+ "@commercetools-frontend/application-shell-connectors": "24.12.0",
25
+ "@commercetools-frontend/constants": "24.12.0",
26
+ "@commercetools-frontend/jest-preset-mc-app": "24.12.0",
27
+ "@commercetools-frontend/permissions": "24.12.0",
28
+ "@commercetools-frontend/sentry": "24.12.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
33
  "@types/jest": "29.5.14",
34
- "@types/papaparse": "5.3.16",
34
+ "@types/papaparse": "5.5.1",
35
35
  "@types/pluralize": "0.0.33",
36
36
  "@types/react": "19.2.0",
37
37
  "msw": "1.3.5",
38
38
  "react": "19.2.0",
39
39
  "react-intl": "7.1.4",
40
- "rimraf": "6.0.1",
40
+ "rimraf": "6.1.2",
41
41
  "typescript": "5.2.2"
42
42
  },
43
43
  "peerDependencies": {
@@ -51,8 +51,7 @@
51
51
  "@commercetools-frontend/ui-kit": "19.x || 20.x",
52
52
  "@emotion/react": "11.x",
53
53
  "@emotion/styled": "11.x",
54
- "react": "17.x || 19.x",
55
- "react-intl": "6.x || 7.x"
54
+ "react": "17.x || 19.x"
56
55
  },
57
56
  "scripts": {
58
57
  "build": "rimraf dist && preconstruct build",
@@ -122,6 +122,16 @@ export const fetchUsingXhr = ({
122
122
  onError(new DOMException('Aborted', 'AbortError'))
123
123
  }
124
124
 
125
+ if (config.abortSignal) {
126
+ if (config.abortSignal.aborted) {
127
+ xhr.abort()
128
+ } else {
129
+ config.abortSignal.addEventListener('abort', () => xhr.abort(), {
130
+ once: true,
131
+ })
132
+ }
133
+ }
134
+
125
135
  xhr.send(payload)
126
136
  return xhr
127
137
  }