@commercetools-frontend-extensions/operations 2.0.1 → 3.0.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 +6 -0
- package/README.md +81 -72
- package/dist/commercetools-frontend-extensions-operations.cjs.dev.js +947 -143
- package/dist/commercetools-frontend-extensions-operations.cjs.prod.js +947 -143
- package/dist/commercetools-frontend-extensions-operations.esm.js +898 -140
- package/dist/declarations/src/@api/file-import-jobs.d.ts +7 -0
- package/dist/declarations/src/@api/index.d.ts +1 -0
- package/dist/declarations/src/@api/test-fixtures.d.ts +8 -1
- package/dist/declarations/src/@api/urls.d.ts +30 -0
- package/dist/declarations/src/@components/uploading-modal/uploading-modal.d.ts +3 -2
- package/dist/declarations/src/@constants/file-import-job.d.ts +1 -0
- package/dist/declarations/src/@constants/import-limits.d.ts +6 -0
- package/dist/declarations/src/@constants/index.d.ts +2 -1
- package/dist/declarations/src/@errors/index.d.ts +5 -4
- package/dist/declarations/src/@errors/polling-aborted-error.d.ts +3 -0
- package/dist/declarations/src/@hooks/index.d.ts +3 -0
- package/dist/declarations/src/@hooks/use-fetch-file-import-job.d.ts +17 -0
- package/dist/declarations/src/@hooks/use-file-import-job-upload.d.ts +18 -0
- package/dist/declarations/src/@hooks/use-file-upload.d.ts +28 -0
- package/dist/declarations/src/@hooks/use-import-container-upload.d.ts +2 -1
- package/dist/declarations/src/@types/export-operation.d.ts +3 -1
- package/dist/declarations/src/@types/file-import-job.d.ts +99 -0
- package/dist/declarations/src/@types/file-upload-result.d.ts +21 -0
- package/dist/declarations/src/@types/file-upload.d.ts +2 -2
- package/dist/declarations/src/@types/index.d.ts +2 -0
- package/dist/declarations/src/@utils/file-import-job-helpers.d.ts +12 -0
- package/dist/declarations/src/@utils/file-upload.d.ts +8 -0
- package/dist/declarations/src/@utils/index.d.ts +2 -0
- package/dist/declarations/src/@utils/poll-job-until-validated.d.ts +11 -0
- package/package.json +12 -13
- package/src/@api/fetcher.ts +10 -0
- package/src/@api/file-import-jobs.ts +217 -0
- package/src/@api/file-upload.spec.ts +4 -2
- package/src/@api/index.ts +1 -0
- package/src/@api/test-fixtures.ts +127 -5
- package/src/@api/urls.ts +77 -1
- package/src/@components/uploading-modal/uploading-modal.tsx +7 -5
- package/src/@constants/file-import-job.ts +1 -0
- package/src/@constants/import-limits.ts +13 -0
- package/src/@constants/index.ts +2 -1
- package/src/@errors/index.ts +5 -4
- package/src/@errors/polling-aborted-error.ts +6 -0
- package/src/@hooks/index.ts +3 -0
- package/src/@hooks/use-fetch-file-import-job.spec.ts +131 -0
- package/src/@hooks/use-fetch-file-import-job.ts +38 -0
- package/src/@hooks/use-fetch.spec.ts +1 -9
- package/src/@hooks/use-fetch.ts +4 -8
- package/src/@hooks/use-file-import-job-upload.spec.ts +273 -0
- package/src/@hooks/use-file-import-job-upload.ts +101 -0
- package/src/@hooks/use-file-upload.ts +223 -0
- package/src/@hooks/use-import-container-upload.spec.ts +16 -13
- package/src/@hooks/use-import-container-upload.ts +6 -2
- package/src/@types/export-operation.ts +3 -0
- package/src/@types/file-import-job.ts +165 -0
- package/src/@types/file-upload-result.ts +23 -0
- package/src/@types/file-upload.ts +2 -2
- package/src/@types/index.ts +2 -0
- package/src/@utils/error-mapping.ts +10 -9
- package/src/@utils/file-import-job-helpers.spec.ts +147 -0
- package/src/@utils/file-import-job-helpers.ts +47 -0
- package/src/@utils/file-upload.ts +39 -0
- package/src/@utils/index.ts +2 -0
- package/src/@utils/poll-job-until-validated.ts +76 -0
- package/dist/declarations/src/@constants/upload-limits.d.ts +0 -10
- package/src/@constants/upload-limits.ts +0 -11
- 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,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
|
|
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,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";
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export * from "./use-fetch-export-operations.js";
|
|
2
|
+
export * from "./use-fetch-file-import-job.js";
|
|
2
3
|
export * from "./use-fetch-import-container-details.js";
|
|
3
4
|
export * from "./use-fetch-import-operations.js";
|
|
4
5
|
export * from "./use-fetch-import-summaries.js";
|
|
6
|
+
export * from "./use-file-import-job-upload.js";
|
|
7
|
+
export * from "./use-file-upload.js";
|
|
5
8
|
export * from "./use-import-container-upload.js";
|
|
@@ -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,28 @@
|
|
|
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
|
+
isValidating: boolean;
|
|
6
|
+
};
|
|
7
|
+
export type FileUploadConfig = {
|
|
8
|
+
file: File;
|
|
9
|
+
resourceType: ResourceTypeId;
|
|
10
|
+
settings?: ExtendedImportContainerDraft['settings'];
|
|
11
|
+
onSuccess: (result: FileUploadResult) => void;
|
|
12
|
+
onError?: (error: unknown) => void;
|
|
13
|
+
onProgress?: (progress: number) => void;
|
|
14
|
+
onValidationProgress?: (job: FileImportJob) => void;
|
|
15
|
+
abortSignal?: AbortSignal;
|
|
16
|
+
};
|
|
17
|
+
export type FileUploadOptions = {
|
|
18
|
+
projectKey: string;
|
|
19
|
+
useJobBasedFlow?: boolean;
|
|
20
|
+
pollingInterval?: number;
|
|
21
|
+
maxPollingAttempts?: number;
|
|
22
|
+
};
|
|
23
|
+
export declare const useFileUpload: ({ projectKey, useJobBasedFlow, pollingInterval, maxPollingAttempts, }: FileUploadOptions) => {
|
|
24
|
+
upload: (config: FileUploadConfig) => Promise<void>;
|
|
25
|
+
isUploading: boolean;
|
|
26
|
+
progress: number;
|
|
27
|
+
validationProgress: ValidationProgress;
|
|
28
|
+
};
|
|
@@ -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
|
-
|
|
33
|
-
|
|
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": "
|
|
3
|
+
"version": "3.0.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.
|
|
22
|
-
"@commercetools-frontend/application-components": "24.
|
|
23
|
-
"@commercetools-frontend/application-shell": "24.
|
|
24
|
-
"@commercetools-frontend/application-shell-connectors": "24.
|
|
25
|
-
"@commercetools-frontend/constants": "24.
|
|
26
|
-
"@commercetools-frontend/jest-preset-mc-app": "24.
|
|
27
|
-
"@commercetools-frontend/permissions": "24.
|
|
28
|
-
"@commercetools-frontend/sentry": "24.
|
|
21
|
+
"@commercetools-frontend/actions-global": "24.11.0",
|
|
22
|
+
"@commercetools-frontend/application-components": "24.11.0",
|
|
23
|
+
"@commercetools-frontend/application-shell": "24.11.0",
|
|
24
|
+
"@commercetools-frontend/application-shell-connectors": "24.11.0",
|
|
25
|
+
"@commercetools-frontend/constants": "24.11.0",
|
|
26
|
+
"@commercetools-frontend/jest-preset-mc-app": "24.11.0",
|
|
27
|
+
"@commercetools-frontend/permissions": "24.11.0",
|
|
28
|
+
"@commercetools-frontend/sentry": "24.11.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.
|
|
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.
|
|
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",
|
package/src/@api/fetcher.ts
CHANGED
|
@@ -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
|
}
|