@haus-tech/product-import-export-plugin 3.3.2-next.0 → 3.3.2-next.1

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 (49) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.mdx +21 -4
  3. package/package.json +1 -1
  4. package/src/api/product-export.controller.d.ts +1 -0
  5. package/src/api/product-export.controller.js +16 -0
  6. package/src/api/product-export.controller.js.map +1 -1
  7. package/src/api/product-import.controller.js +2 -2
  8. package/src/api/product-import.controller.js.map +1 -1
  9. package/src/constants.d.ts +1 -0
  10. package/src/constants.js +2 -1
  11. package/src/constants.js.map +1 -1
  12. package/src/dashboard/export-dialog.tsx +21 -7
  13. package/src/dashboard/import.tsx +6 -3
  14. package/src/dashboard/utils.ts +0 -1
  15. package/src/index.d.ts +3 -0
  16. package/src/index.js +3 -0
  17. package/src/index.js.map +1 -1
  18. package/src/product-import-export.plugin.js +21 -0
  19. package/src/product-import-export.plugin.js.map +1 -1
  20. package/src/providers/import-providers/import-parser.d.ts +7 -5
  21. package/src/providers/import-providers/import-parser.js +53 -15
  22. package/src/providers/import-providers/import-parser.js.map +1 -1
  23. package/src/providers/import-providers/product-importer.d.ts +1 -0
  24. package/src/providers/import-providers/product-importer.js +120 -74
  25. package/src/providers/import-providers/product-importer.js.map +1 -1
  26. package/src/services/extended-fast-importer.service.d.ts +5 -3
  27. package/src/services/extended-fast-importer.service.js +18 -6
  28. package/src/services/extended-fast-importer.service.js.map +1 -1
  29. package/src/services/import-storage/import-job-storage-strategy.d.ts +22 -0
  30. package/src/services/import-storage/import-job-storage-strategy.js +3 -0
  31. package/src/services/import-storage/import-job-storage-strategy.js.map +1 -0
  32. package/src/services/import-storage/local-import-job-storage-strategy.d.ts +18 -0
  33. package/src/services/import-storage/local-import-job-storage-strategy.js +76 -0
  34. package/src/services/import-storage/local-import-job-storage-strategy.js.map +1 -0
  35. package/src/services/import-storage/s3-import-job-storage-strategy.d.ts +13 -0
  36. package/src/services/import-storage/s3-import-job-storage-strategy.js +109 -0
  37. package/src/services/import-storage/s3-import-job-storage-strategy.js.map +1 -0
  38. package/src/services/product-export.service.d.ts +1 -0
  39. package/src/services/product-export.service.js +24 -3
  40. package/src/services/product-export.service.js.map +1 -1
  41. package/src/services/product-import.service.d.ts +10 -6
  42. package/src/services/product-import.service.js +62 -37
  43. package/src/services/product-import.service.js.map +1 -1
  44. package/src/types.d.ts +21 -1
  45. package/src/ui/components/export-dialog.component.html +1 -1
  46. package/src/ui/components/export-dialog.component.ts +10 -2
  47. package/src/ui/components/product-import.component.html +6 -8
  48. package/src/ui/translations/en.json +1 -1
  49. package/src/ui/translations/sv.json +1 -1
@@ -20,20 +20,19 @@ const constants_1 = require("../constants");
20
20
  const product_importer_1 = require("../providers/import-providers/product-importer");
21
21
  const lodash_1 = require("lodash");
22
22
  let ProductImportService = class ProductImportService {
23
- options;
23
+ importJobStorageStrategy;
24
24
  jobQueueService;
25
25
  productImporter;
26
26
  searchService;
27
- collectionService;
28
27
  productService;
29
28
  eventBus;
29
+ loggerCtx = 'ProductImportService';
30
30
  productImportQueue;
31
- constructor(options, jobQueueService, productImporter, searchService, collectionService, productService, eventBus) {
32
- this.options = options;
31
+ constructor(importJobStorageStrategy, jobQueueService, productImporter, searchService, productService, eventBus) {
32
+ this.importJobStorageStrategy = importJobStorageStrategy;
33
33
  this.jobQueueService = jobQueueService;
34
34
  this.productImporter = productImporter;
35
35
  this.searchService = searchService;
36
- this.collectionService = collectionService;
37
36
  this.productService = productService;
38
37
  this.eventBus = eventBus;
39
38
  }
@@ -41,46 +40,73 @@ let ProductImportService = class ProductImportService {
41
40
  this.productImportQueue = await this.jobQueueService.createQueue({
42
41
  name: 'product-import',
43
42
  process: async (job) => {
44
- // Deserialize the RequestContext from the job data
45
43
  const ctx = core_2.RequestContext.deserialize(job.data.ctx);
46
44
  let jobResult;
47
- return new Promise((resolve, reject) => {
48
- this.productImporter
49
- .parseAndImport(job.data.fileContent, ctx, job.data.updateProductSlug, job.data.mainLanguage, job.data.updatingStrategy)
50
- .subscribe({
51
- next: (result) => {
52
- const processedCount = result.processed;
53
- const importedCount = result.imported;
54
- const percentage = (importedCount / processedCount) * 100;
55
- job.setProgress(percentage);
56
- jobResult = result;
57
- },
58
- complete: async () => {
59
- // Hack for triggering apply-collection-filters job
60
- const firstProduct = await this.productService.findAll(ctx, {
61
- take: 1,
62
- });
63
- this.eventBus.publish(new core_2.ProductEvent(ctx, firstProduct.items[0], 'updated'));
64
- // Reindex the search index
65
- await this.searchService.reindex(ctx);
66
- resolve((0, lodash_1.omit)(jobResult, 'currentProduct'));
67
- },
68
- error: (err) => {
69
- reject(err);
70
- },
45
+ try {
46
+ const fileContent = await this.importJobStorageStrategy.getImportFileContent(ctx, job.data.storageKey);
47
+ return await new Promise((resolve, reject) => {
48
+ this.productImporter
49
+ .parseAndImport(fileContent, ctx, job.data.updateProductSlug, job.data.mainLanguage, job.data.updatingStrategy)
50
+ .subscribe({
51
+ next: (result) => {
52
+ const processedCount = result.processed || 1;
53
+ const importedCount = result.imported || 0;
54
+ const percentage = (importedCount / processedCount) * 100;
55
+ job.setProgress(percentage);
56
+ jobResult = result;
57
+ },
58
+ complete: () => {
59
+ resolve(jobResult ?? { imported: 0, processed: 0, errors: [], currentProduct: '' });
60
+ },
61
+ error: (err) => {
62
+ reject(err);
63
+ },
64
+ });
65
+ }).then(async (result) => {
66
+ await this.runPostImportTasks(ctx, result);
67
+ return (0, lodash_1.omit)(result, 'currentProduct');
71
68
  });
72
- });
69
+ }
70
+ finally {
71
+ await this.cleanupStoredImportFile(ctx, job.data.storageKey);
72
+ }
73
73
  },
74
74
  });
75
75
  }
76
76
  async processFile(ctx, file, updateProductSlug, mainLanguage, updatingStrategy) {
77
- const fileContent = file.buffer.toString('utf-8');
78
- return this.triggerProductImport(ctx, fileContent, updateProductSlug, mainLanguage, updatingStrategy);
77
+ const storageKey = await this.importJobStorageStrategy.storeImportFile(ctx, {
78
+ originalname: file.originalname,
79
+ buffer: file.buffer,
80
+ });
81
+ return this.triggerProductImport(ctx, storageKey, file.originalname, updateProductSlug, mainLanguage, updatingStrategy);
82
+ }
83
+ async cleanupStoredImportFile(ctx, storageKey) {
84
+ try {
85
+ await this.importJobStorageStrategy.deleteImportFile(ctx, storageKey);
86
+ }
87
+ catch (error) {
88
+ core_1.Logger.warn(`Failed to cleanup stored import file "${storageKey}": ${error.message}`, this.loggerCtx);
89
+ }
90
+ }
91
+ async runPostImportTasks(ctx, result) {
92
+ if (result.imported <= 0) {
93
+ return;
94
+ }
95
+ const firstProduct = await this.productService.findAll(ctx, { take: 1 });
96
+ const firstItem = firstProduct.items[0];
97
+ if (firstItem) {
98
+ this.eventBus.publish(new core_2.ProductEvent(ctx, firstItem, 'updated'));
99
+ }
100
+ else {
101
+ core_1.Logger.warn('Skipping ProductEvent publish because no product was found', this.loggerCtx);
102
+ }
103
+ await this.searchService.reindex(ctx);
79
104
  }
80
- triggerProductImport(ctx, fileContent, updateProductSlug, mainLanguage, updatingStrategy) {
105
+ triggerProductImport(ctx, storageKey, fileName, updateProductSlug, mainLanguage, updatingStrategy) {
81
106
  return this.productImportQueue.add({
82
107
  ctx: ctx.serialize(),
83
- fileContent,
108
+ storageKey,
109
+ fileName,
84
110
  updateProductSlug,
85
111
  mainLanguage,
86
112
  updatingStrategy,
@@ -90,11 +116,10 @@ let ProductImportService = class ProductImportService {
90
116
  exports.ProductImportService = ProductImportService;
91
117
  exports.ProductImportService = ProductImportService = __decorate([
92
118
  (0, common_1.Injectable)(),
93
- __param(0, (0, common_1.Inject)(constants_1.PRODUCT_IMPORT_EXPORT_PLUGIN_OPTIONS)),
119
+ __param(0, (0, common_1.Inject)(constants_1.IMPORT_JOB_STORAGE_STRATEGY)),
94
120
  __metadata("design:paramtypes", [Object, core_1.JobQueueService,
95
121
  product_importer_1.ProductImporter,
96
122
  core_1.SearchService,
97
- core_1.CollectionService,
98
123
  core_1.ProductService,
99
124
  core_1.EventBus])
100
125
  ], ProductImportService);
@@ -1 +1 @@
1
- {"version":3,"file":"product-import.service.js","sourceRoot":"","sources":["../../../../../packages/product-import-export-plugin/src/services/product-import.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"product-import.service.js","sourceRoot":"","sources":["../../../../../packages/product-import-export-plugin/src/services/product-import.service.ts"],"names":[],"mappings":"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"}
package/src/types.d.ts CHANGED
@@ -2,6 +2,7 @@ import { ID } from '@vendure/core';
2
2
  import { ParsedProduct, ParsedProductWithVariants } from './providers/import-providers/import-parser';
3
3
  import type { Injector } from '@vendure/core';
4
4
  import { ExportStorageStrategy } from './services/export-storage/export-storage-strategy';
5
+ import { ImportJobStorageStrategy } from './services/import-storage/import-job-storage-strategy';
5
6
  /**
6
7
  * @description
7
8
  * The plugin can be configured using the following options:
@@ -18,11 +19,30 @@ type ImportOptions = {
18
19
  * will be restored during import. If false, deleted entities will remain deleted.
19
20
  */
20
21
  restoreSoftDeleted?: boolean;
22
+ /**
23
+ * @description
24
+ * Preferred configuration: provide an import job storage strategy instance directly.
25
+ */
26
+ storageStrategy?: ImportJobStorageStrategy;
27
+ /**
28
+ * @description
29
+ * Preferred configuration: provide a factory which can use Vendure's DI via the Injector.
30
+ */
31
+ storageStrategyFactory?: (injector: Injector) => ImportJobStorageStrategy | Promise<ImportJobStorageStrategy>;
32
+ /**
33
+ * @description
34
+ * Deprecated. Kept for backward compatibility.
35
+ * Use `storageStrategy` or `storageStrategyFactory` instead.
36
+ */
37
+ importJobStorage?: 'local' | 's3';
21
38
  };
22
39
  export interface PluginInitOptions {
23
40
  importOptions: {
24
41
  visibleOptions?: Array<keyof ImportOptions>;
25
42
  defaultOptions?: ImportOptions;
43
+ storageStrategy?: ImportOptions['storageStrategy'];
44
+ storageStrategyFactory?: ImportOptions['storageStrategyFactory'];
45
+ importJobStorage?: ImportOptions['importJobStorage'];
26
46
  };
27
47
  exportOptions: {
28
48
  defaultFileName?: string;
@@ -54,7 +74,7 @@ export type JsonAsset = {
54
74
  name?: string;
55
75
  };
56
76
  type ExportFields = Array<ProductFields | VariantFields>;
57
- type ProductFields = 'productId' | 'name' | 'slug' | 'description' | 'assets' | 'facets' | 'optionGroups';
77
+ type ProductFields = 'name' | 'slug' | 'description' | 'assets' | 'facets' | 'optionGroups';
58
78
  type VariantFields = 'sku' | 'optionValues' | 'price' | 'taxCategory' | 'stockOnHand' | 'trackInventory' | 'variantAssets' | 'variantFacets' | 'enabled';
59
79
  export type UpdatingStrategy = 'replace' | 'merge';
60
80
  export {};
@@ -26,7 +26,7 @@
26
26
  [value]="field"
27
27
  (change)="toggleExportFieldSelection(field)"
28
28
  [checked]="selectedExportFields.includes(field)"
29
- [disabled]="config.requiredExportFields.includes(field)"
29
+ [disabled]="config.requiredExportFields.includes(field) || isMandatoryExportField(field)"
30
30
  />
31
31
  {{ field }}
32
32
  </div>
@@ -5,7 +5,6 @@ import { SharedModule } from '@vendure/admin-ui/core'
5
5
  import { uniq } from 'lodash'
6
6
 
7
7
  type ProductFields =
8
- | 'productId'
9
8
  | 'name'
10
9
  | 'slug'
11
10
  | 'description'
@@ -51,6 +50,7 @@ export class ExportDialogComponent
51
50
  AfterViewInit,
52
51
  OnInit
53
52
  {
53
+ private mandatoryOptionFields: Array<ProductFields | VariantFields> = ['optionGroups', 'optionValues']
54
54
  @ViewChild('fileNameInput', { static: false }) fileNameElement: ElementRef<HTMLInputElement>
55
55
 
56
56
  resolveWith: (result?: {
@@ -67,7 +67,6 @@ export class ExportDialogComponent
67
67
  exportAssetsAs: 'url' | 'json' = 'url'
68
68
  selectedExportFields: ExportFields = []
69
69
  availableExportFields: ExportFields = [
70
- 'productId',
71
70
  'name',
72
71
  'slug',
73
72
  'description',
@@ -99,6 +98,7 @@ export class ExportDialogComponent
99
98
  this.selectedExportFields = uniq([
100
99
  ...(this.config.defaultExportFields || []),
101
100
  ...(this.config.requiredExportFields || []),
101
+ ...this.mandatoryOptionFields,
102
102
  ])
103
103
  }
104
104
 
@@ -137,6 +137,9 @@ export class ExportDialogComponent
137
137
  }
138
138
 
139
139
  toggleExportFieldSelection(fieldName: ProductFields | VariantFields) {
140
+ if (this.mandatoryOptionFields.includes(fieldName)) {
141
+ return
142
+ }
140
143
  const index = this.selectedExportFields.indexOf(fieldName)
141
144
  if (index > -1) {
142
145
  this.selectedExportFields.splice(index, 1)
@@ -158,8 +161,13 @@ export class ExportDialogComponent
158
161
  ...this.availableExportFields.filter((field) =>
159
162
  this.config.requiredExportFields?.includes(field),
160
163
  ),
164
+ ...this.mandatoryOptionFields,
161
165
  ]
162
166
  this.selectedFields = []
163
167
  }
164
168
  }
169
+
170
+ isMandatoryExportField(field: ProductFields | VariantFields): boolean {
171
+ return this.mandatoryOptionFields.includes(field)
172
+ }
165
173
  }
@@ -14,14 +14,6 @@
14
14
  <button class="button primary" *ngIf="!selectedFile" (click)="fileUpload.click()">
15
15
  {{ 'product-import.card.button-select' | translate }}
16
16
  </button>
17
- <button
18
- class="button primary"
19
- *ngIf="selectedFile"
20
- (click)="uploadFile()"
21
- [disabled]="!selectedMainLanguage"
22
- >
23
- {{ 'product-import.card.button-upload' | translate }}
24
- </button>
25
17
  </div>
26
18
  </vdr-form-field>
27
19
  </div>
@@ -106,6 +98,12 @@
106
98
  </label>
107
99
  </div>
108
100
  </div>
101
+
102
+ <div class="input-row" style="margin-top: 24px; padding-top: 16px; border-top: 1px solid #cdcdcd">
103
+ <button class="button primary" (click)="uploadFile()" [disabled]="!selectedMainLanguage">
104
+ {{ 'product-import.card.button-upload' | translate }}
105
+ </button>
106
+ </div>
109
107
  </div>
110
108
  </vdr-card>
111
109
  </vdr-page-block>
@@ -5,7 +5,7 @@
5
5
  "title": "Import products from CSV",
6
6
  "description": "Choose a CSV file to import products from",
7
7
  "button-select": "Select file",
8
- "button-upload": "Upload file",
8
+ "button-upload": "Start import now",
9
9
  "update-product-slugs": "Update product slugs based on name",
10
10
  "select-main-language": "Select main language: ",
11
11
  "updating-strategy": "Updating strategy for facets and assets: ",
@@ -5,7 +5,7 @@
5
5
  "title": "Importera produkter från CSV",
6
6
  "description": "Välj en CSV-fil att importera produkter från",
7
7
  "button-select": "Välj fil",
8
- "button-upload": "Ladda upp fil",
8
+ "button-upload": "Starta import nu",
9
9
  "update-product-slugs": "Uppdatera produkt-sluggar utifrån namn",
10
10
  "select-main-language": "Välj huvudspråk: ",
11
11
  "updating-strategy": "Uppdateringsstrategi för etiketter och filer: ",