@haus-tech/product-import-export-plugin 3.0.29-0 → 3.0.29

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.
@@ -1,15 +1,4 @@
1
- import {
2
- Button,
3
- DashboardRouteDefinition,
4
- Page,
5
- PageTitle,
6
- PageLayout,
7
- PageBlock,
8
- Switch,
9
- Label,
10
- RadioGroup,
11
- RadioGroupItem,
12
- } from '@vendure/dashboard'
1
+ import { Button, Switch, Label, RadioGroup, RadioGroupItem } from '@vendure/dashboard'
13
2
  import { UploadIcon } from 'lucide-react'
14
3
  import { useState, useRef, useEffect } from 'react'
15
4
  import { toast } from 'sonner'
@@ -24,7 +13,7 @@ import {
24
13
  } from './utils'
25
14
 
26
15
  // Import page component
27
- function ProductImportPage() {
16
+ export function ProductImportBlock() {
28
17
  const fileInputRef = useRef<HTMLInputElement>(null)
29
18
  const [selectedFile, setSelectedFile] = useState<File | null>(null)
30
19
  const [validateFile, setValidateFile] = useState<File | null>(null)
@@ -502,133 +491,100 @@ function ProductImportPage() {
502
491
  }
503
492
 
504
493
  return (
505
- <Page pageId="product-import">
506
- <PageTitle>Import Products</PageTitle>
507
- <PageLayout>
508
- <PageBlock column="main" blockId="main-form" title="Import products from CSV">
509
- <div className="space-y-6">
510
- <div>
511
- <Label htmlFor="file-upload">Choose a CSV file to import products from</Label>
512
- <div className="flex items-center gap-2 mt-2">
513
- <input
514
- ref={fileInputRef}
515
- type="file"
516
- id="file-upload"
517
- accept=".csv"
518
- onChange={onFileSelected}
519
- className="hidden"
520
- />
521
- {selectedFile ? (
522
- <>
523
- <Button
524
- type="button"
525
- variant="outline"
526
- onClick={() => fileInputRef.current?.click()}
527
- >
528
- <UploadIcon className="mr-2 h-4 w-4" />
529
- {selectedFile.name}
530
- </Button>
531
- <Button type="button" onClick={uploadFile} disabled={!selectedMainLanguage}>
532
- Upload file
533
- </Button>
534
- </>
535
- ) : (
536
- <Button
537
- type="button"
538
- variant="default"
539
- onClick={() => fileInputRef.current?.click()}
540
- >
541
- <UploadIcon className="mr-2 h-4 w-4" />
542
- Select file
543
- </Button>
544
- )}
545
- </div>
494
+ <div className="space-y-6">
495
+ <div>
496
+ <Label htmlFor="file-upload">Upload CSV file</Label>
497
+ <div className="flex items-center gap-2 mt-2">
498
+ <input
499
+ ref={fileInputRef}
500
+ type="file"
501
+ id="file-upload"
502
+ accept=".csv"
503
+ onChange={onFileSelected}
504
+ className="hidden"
505
+ />
506
+ {selectedFile ? (
507
+ <>
508
+ <Button type="button" variant="outline" onClick={() => fileInputRef.current?.click()}>
509
+ <UploadIcon className="mr-2 h-4 w-4" />
510
+ {selectedFile.name}
511
+ </Button>
512
+ <Button type="button" onClick={uploadFile} disabled={!selectedMainLanguage}>
513
+ Upload file
514
+ </Button>
515
+ </>
516
+ ) : (
517
+ <Button type="button" variant="default" onClick={() => fileInputRef.current?.click()}>
518
+ <UploadIcon className="mr-2 h-4 w-4" />
519
+ Select file
520
+ </Button>
521
+ )}
522
+ </div>
523
+ </div>
524
+
525
+ {selectedFile && (
526
+ <div className="space-y-4 pt-4 border-t">
527
+ {config?.visibleOptions?.includes('updateProductSlug') && (
528
+ <div className="flex items-center space-x-2">
529
+ <Switch
530
+ id="update-slug"
531
+ checked={updateProductSlug}
532
+ onCheckedChange={setUpdateProductSlug}
533
+ />
534
+ <Label htmlFor="update-slug">Update product slugs based on name</Label>
546
535
  </div>
547
-
548
- {selectedFile && (
549
- <div className="space-y-4 pt-4 border-t">
550
- {config?.visibleOptions?.includes('updateProductSlug') && (
551
- <div className="flex items-center space-x-2">
552
- <Switch
553
- id="update-slug"
554
- checked={updateProductSlug}
555
- onCheckedChange={setUpdateProductSlug}
556
- />
557
- <Label htmlFor="update-slug">Update product slugs based on name</Label>
536
+ )}
537
+
538
+ <div>
539
+ <Label>Select main language:</Label>
540
+ <RadioGroup
541
+ value={selectedMainLanguage || ''}
542
+ onValueChange={(val) => onMainLanguageChange(val as LanguageCode)}
543
+ >
544
+ <div className="flex flex-col gap-2 mt-2">
545
+ {availableLanguages.map((lang) => (
546
+ <div key={lang} className="flex items-center space-x-2">
547
+ <RadioGroupItem value={lang} id={`lang-${lang}`} />
548
+ <Label htmlFor={`lang-${lang}`} className="font-normal">
549
+ {lang}
550
+ </Label>
558
551
  </div>
559
- )}
560
-
561
- <div>
562
- <Label>Select main language:</Label>
563
- <div className="flex flex-col gap-2 mt-2">
564
- {availableLanguages.map((lang) => (
565
- <div key={lang} className="flex items-center space-x-2">
566
- <input
567
- type="radio"
568
- id={`lang-${lang}`}
569
- name="selectedMainLanguage"
570
- value={lang}
571
- checked={selectedMainLanguage === lang}
572
- onChange={() => onMainLanguageChange(lang)}
573
- />
574
- <Label htmlFor={`lang-${lang}`} className="font-normal">
575
- {lang}
576
- </Label>
577
- </div>
578
- ))}
579
- </div>
580
- <p className="text-sm text-muted-foreground mt-2 italic">
581
- The main language is used as a fallback when translations are missing. It is
582
- recommended to select the language that is used the most in your system.
583
- </p>
584
- </div>
585
-
586
- <div>
587
- <Label>Updating strategy for facets and assets:</Label>
588
- <RadioGroup
589
- value={updatingStrategy}
590
- onValueChange={(val) => setUpdatingStrategy(val as UpdatingStrategy)}
591
- >
592
- <div className="flex items-center space-x-2">
593
- <RadioGroupItem value="merge" id="merge" />
594
- <Label htmlFor="merge" className="font-normal">
595
- Merge
596
- </Label>
597
- </div>
598
- <div className="flex items-center space-x-2">
599
- <RadioGroupItem value="replace" id="replace" />
600
- <Label htmlFor="replace" className="font-normal">
601
- Overwrite
602
- </Label>
603
- </div>
604
- </RadioGroup>
605
- {updatingStrategy === 'replace' && (
606
- <p className="text-sm text-red-600 mt-2">
607
- Warning: This will remove existing facets and assets from products and
608
- variants.
609
- </p>
610
- )}
611
- </div>
552
+ ))}
553
+ </div>
554
+ </RadioGroup>
555
+ <p className="text-sm text-muted-foreground mt-2 italic">
556
+ The main language is used as a fallback when translations are missing. It is
557
+ recommended to select the language that is used the most in your system.
558
+ </p>
559
+ </div>
560
+
561
+ <div>
562
+ <Label>Strategy for facets and assets:</Label>
563
+ <RadioGroup
564
+ value={updatingStrategy}
565
+ onValueChange={(val) => setUpdatingStrategy(val as UpdatingStrategy)}
566
+ >
567
+ <div className="flex items-center space-x-2 mt-2">
568
+ <RadioGroupItem value="merge" id="merge" />
569
+ <Label htmlFor="merge" className="font-normal">
570
+ Merge
571
+ </Label>
572
+ </div>
573
+ <div className="flex items-center space-x-2">
574
+ <RadioGroupItem value="replace" id="replace" />
575
+ <Label htmlFor="replace" className="font-normal">
576
+ Overwrite
577
+ </Label>
612
578
  </div>
579
+ </RadioGroup>
580
+ {updatingStrategy === 'replace' && (
581
+ <p className="text-sm text-red-600 mt-2">
582
+ Warning: This will remove existing facets and assets from products and variants.
583
+ </p>
613
584
  )}
614
585
  </div>
615
- </PageBlock>
616
- </PageLayout>
617
- </Page>
586
+ </div>
587
+ )}
588
+ </div>
618
589
  )
619
590
  }
620
-
621
- // Import route definition
622
- export const productImportRoute: DashboardRouteDefinition = {
623
- navMenuItem: {
624
- sectionId: 'catalog',
625
- id: 'product-importer',
626
- url: '/product-importer',
627
- title: 'Import Products',
628
- },
629
- path: '/product-importer',
630
- loader: () => ({
631
- breadcrumb: 'Import Products',
632
- }),
633
- component: () => <ProductImportPage />,
634
- }
@@ -1,6 +1,59 @@
1
- import { defineDashboardExtension } from '@vendure/dashboard'
2
- import { productImportRoute } from './import'
3
- import { ExportProductsBulkAction } from './export'
1
+ import {
2
+ defineDashboardExtension,
3
+ DashboardRouteDefinition,
4
+ PageTitle,
5
+ Page,
6
+ PageLayout,
7
+ PageBlock,
8
+ } from '@vendure/dashboard'
9
+ import { ExportProductsBulkAction } from './bulk-export'
10
+ import { ProductImportBlock } from './import'
11
+ import { ProductExportBlock } from './export'
12
+ import { ExportedList } from './exported-list'
13
+
14
+ export const productImportRoute: DashboardRouteDefinition = {
15
+ navMenuItem: {
16
+ sectionId: 'catalog',
17
+ id: 'product-importer',
18
+ url: '/product-importer',
19
+ title: 'Import/export products',
20
+ },
21
+ path: '/product-importer',
22
+ loader: () => ({
23
+ breadcrumb: 'Import/export products',
24
+ }),
25
+ component: () => (
26
+ <Page pageId="product-import">
27
+ <PageTitle>Import/export products</PageTitle>
28
+ <PageLayout>
29
+ <PageBlock
30
+ column="main"
31
+ blockId="main-form-import"
32
+ title="Import products"
33
+ description="Import products from a CSV file"
34
+ >
35
+ <ProductImportBlock />
36
+ </PageBlock>
37
+ <PageBlock
38
+ column="main"
39
+ blockId="main-form-export"
40
+ title="Export products"
41
+ description="Exports all products to a CSV file. The export is added to the job queue and will be processed in the background. When the file is ready, you will receive an email and the exported file will be available to download from the list below."
42
+ >
43
+ <ProductExportBlock />
44
+ </PageBlock>
45
+ <PageBlock
46
+ column="main"
47
+ blockId="main-form-exported-list"
48
+ title="Exported files"
49
+ description="Files available for download"
50
+ >
51
+ <ExportedList />
52
+ </PageBlock>
53
+ </PageLayout>
54
+ </Page>
55
+ ),
56
+ }
4
57
 
5
58
  defineDashboardExtension({
6
59
  routes: [productImportRoute],
@@ -0,0 +1,16 @@
1
+ import { RequestContext, VendureEvent } from '@vendure/core';
2
+ export interface ProductExportResult {
3
+ filePath: string;
4
+ fileName: string;
5
+ productCount: number;
6
+ toEmail: string;
7
+ }
8
+ /**
9
+ * @description
10
+ * This event is fired whenever a Product export job completes successfully.
11
+ */
12
+ export declare class ProductExportedEvent extends VendureEvent {
13
+ ctx: RequestContext;
14
+ input: ProductExportResult;
15
+ constructor(ctx: RequestContext, input: ProductExportResult);
16
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProductExportedEvent = void 0;
4
+ const core_1 = require("@vendure/core");
5
+ /**
6
+ * @description
7
+ * This event is fired whenever a Product export job completes successfully.
8
+ */
9
+ class ProductExportedEvent extends core_1.VendureEvent {
10
+ ctx;
11
+ input;
12
+ constructor(ctx, input) {
13
+ super();
14
+ this.ctx = ctx;
15
+ this.input = input;
16
+ }
17
+ }
18
+ exports.ProductExportedEvent = ProductExportedEvent;
19
+ //# sourceMappingURL=product-exported.event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-exported.event.js","sourceRoot":"","sources":["../../../../../packages/product-import-export-plugin/src/events/product-exported.event.ts"],"names":[],"mappings":";;;AAAA,wCAA4D;AAS5D;;;GAGG;AACH,MAAa,oBAAqB,SAAQ,mBAAY;IAE3C;IACA;IAFT,YACS,GAAmB,EACnB,KAA0B;QAEjC,KAAK,EAAE,CAAA;QAHA,QAAG,GAAH,GAAG,CAAgB;QACnB,UAAK,GAAL,KAAK,CAAqB;IAGnC,CAAC;CACF;AAPD,oDAOC"}
@@ -0,0 +1,2 @@
1
+ import { ProductExportedEvent } from '../events/product-exported.event';
2
+ export declare const productExportedHandler: import("@vendure/email-plugin").EmailEventHandler<"product-export-complete", ProductExportedEvent>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.productExportedHandler = void 0;
4
+ const email_plugin_1 = require("@vendure/email-plugin");
5
+ const product_exported_event_1 = require("../events/product-exported.event");
6
+ exports.productExportedHandler = new email_plugin_1.EmailEventListener('product-export-complete')
7
+ .on(product_exported_event_1.ProductExportedEvent)
8
+ .setRecipient((event) => event.input.toEmail)
9
+ .setFrom('{{ fromAddress }}')
10
+ .setSubject((event) => `Product export complete - ${event.input.fileName}`)
11
+ .setTemplateVars((event) => ({
12
+ fileName: event.input.fileName,
13
+ productCount: event.input.productCount,
14
+ }));
15
+ //# sourceMappingURL=product-exported.handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-exported.handler.js","sourceRoot":"","sources":["../../../../../packages/product-import-export-plugin/src/handlers/product-exported.handler.ts"],"names":[],"mappings":";;;AAAA,wDAA0D;AAC1D,6EAAuE;AAE1D,QAAA,sBAAsB,GAAG,IAAI,iCAAkB,CAAC,yBAAyB,CAAC;KACpF,EAAE,CAAC,6CAAoB,CAAC;KACxB,YAAY,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;KAC5C,OAAO,CAAC,mBAAmB,CAAC;KAC5B,UAAU,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,6BAA6B,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;KAC1E,eAAe,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC3B,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ;IAC9B,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,YAAY;CACvC,CAAC,CAAC,CAAA"}
@@ -57,6 +57,7 @@ const asset_importer_1 = require("./providers/import-providers/asset-importer");
57
57
  const product_import_service_1 = require("./services/product-import.service");
58
58
  const extended_fast_importer_service_1 = require("./services/extended-fast-importer.service");
59
59
  const product_export_service_1 = require("./services/product-export.service");
60
+ const product_export_queue_service_1 = require("./services/product-export-queue.service");
60
61
  let ProductImportExportPlugin = class ProductImportExportPlugin {
61
62
  static { ProductImportExportPlugin_1 = this; }
62
63
  static options;
@@ -142,6 +143,7 @@ exports.ProductImportExportPlugin = ProductImportExportPlugin = ProductImportExp
142
143
  import_parser_1.ImportParser,
143
144
  asset_importer_1.ExtendedAssetImporter,
144
145
  product_export_service_1.ProductExportService,
146
+ product_export_queue_service_1.ProductExportQueueService,
145
147
  ],
146
148
  controllers: [
147
149
  product_import_controller_1.ProductImportController,
@@ -1 +1 @@
1
- {"version":3,"file":"product-import-export.plugin.js","sourceRoot":"","sources":["../../../../packages/product-import-export-plugin/src/product-import-export.plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"product-import-export.plugin.js","sourceRoot":"","sources":["../../../../packages/product-import-export-plugin/src/product-import-export.plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { OnModuleInit } from '@nestjs/common';
2
+ import { RequestContext, JobQueueService, SerializedRequestContext, ID, EventBus } from '@vendure/core';
3
+ import { PluginInitOptions } from '../types';
4
+ import { ProductExportService } from './product-export.service';
5
+ export declare class ProductExportQueueService implements OnModuleInit {
6
+ private options;
7
+ private jobQueueService;
8
+ private productExportService;
9
+ private eventBus;
10
+ private productExportQueue;
11
+ constructor(options: PluginInitOptions, jobQueueService: JobQueueService, productExportService: ProductExportService, eventBus: EventBus);
12
+ onModuleInit(): Promise<void>;
13
+ triggerExport(ctx: RequestContext, fileName: string, customFields: string, exportAssetsAs: 'url' | 'json', selectedExportFields: string, allProducts?: boolean): Promise<import("@vendure/core/dist/job-queue/subscribable-job").SubscribableJob<{
14
+ ctx: SerializedRequestContext;
15
+ fileName: string;
16
+ customFields: string;
17
+ exportAssetsAs: "url" | "json";
18
+ selectedExportFields: string;
19
+ allProducts: boolean;
20
+ selectedProductIds?: ID[];
21
+ }>>;
22
+ triggerExportWithSelection(ctx: RequestContext, fileName: string, customFields: string, exportAssetsAs: 'url' | 'json', selectedExportFields: string, selectedProductIds: ID[]): Promise<import("@vendure/core/dist/job-queue/subscribable-job").SubscribableJob<{
23
+ ctx: SerializedRequestContext;
24
+ fileName: string;
25
+ customFields: string;
26
+ exportAssetsAs: "url" | "json";
27
+ selectedExportFields: string;
28
+ allProducts: boolean;
29
+ selectedProductIds?: ID[];
30
+ }>>;
31
+ }
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ var __metadata = (this && this.__metadata) || function (k, v) {
42
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
+ };
44
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
45
+ return function (target, key) { decorator(target, key, paramIndex); }
46
+ };
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.ProductExportQueueService = void 0;
49
+ const common_1 = require("@nestjs/common");
50
+ const core_1 = require("@vendure/core");
51
+ const constants_1 = require("../constants");
52
+ const product_export_service_1 = require("./product-export.service");
53
+ const product_exported_event_1 = require("../events/product-exported.event");
54
+ const path = __importStar(require("path"));
55
+ let ProductExportQueueService = class ProductExportQueueService {
56
+ options;
57
+ jobQueueService;
58
+ productExportService;
59
+ eventBus;
60
+ productExportQueue;
61
+ constructor(options, jobQueueService, productExportService, eventBus) {
62
+ this.options = options;
63
+ this.jobQueueService = jobQueueService;
64
+ this.productExportService = productExportService;
65
+ this.eventBus = eventBus;
66
+ }
67
+ async onModuleInit() {
68
+ this.productExportQueue = await this.jobQueueService.createQueue({
69
+ name: 'product-export',
70
+ process: async (job) => {
71
+ try {
72
+ const ctx = core_1.RequestContext.deserialize(job.data.ctx);
73
+ let productIds = [];
74
+ if (job.data.allProducts) {
75
+ productIds = await this.productExportService.getAllProductIds(ctx);
76
+ }
77
+ else if (job.data.selectedProductIds) {
78
+ productIds = job.data.selectedProductIds;
79
+ }
80
+ else {
81
+ throw new Error('No products to export');
82
+ }
83
+ const filePath = await this.productExportService.createExportFile(ctx, productIds, job.data.fileName, job.data.customFields, job.data.exportAssetsAs, job.data.selectedExportFields);
84
+ const result = {
85
+ filePath,
86
+ fileName: path.basename(filePath),
87
+ productCount: productIds.length,
88
+ };
89
+ const userEmail = ctx.session?.user?.identifier || '';
90
+ const eventResult = {
91
+ ...result,
92
+ toEmail: userEmail,
93
+ };
94
+ // Publish event for email notification
95
+ this.eventBus.publish(new product_exported_event_1.ProductExportedEvent(ctx, eventResult));
96
+ return result;
97
+ }
98
+ catch (err) {
99
+ console.error('Product export job failed:', err);
100
+ throw err;
101
+ }
102
+ },
103
+ });
104
+ }
105
+ async triggerExport(ctx, fileName, customFields, exportAssetsAs, selectedExportFields, allProducts = true) {
106
+ return this.productExportQueue.add({
107
+ ctx: ctx.serialize(),
108
+ fileName,
109
+ customFields,
110
+ exportAssetsAs,
111
+ selectedExportFields,
112
+ allProducts,
113
+ });
114
+ }
115
+ async triggerExportWithSelection(ctx, fileName, customFields, exportAssetsAs, selectedExportFields, selectedProductIds) {
116
+ return this.productExportQueue.add({
117
+ ctx: ctx.serialize(),
118
+ fileName,
119
+ customFields,
120
+ exportAssetsAs,
121
+ selectedExportFields,
122
+ allProducts: false,
123
+ selectedProductIds,
124
+ });
125
+ }
126
+ };
127
+ exports.ProductExportQueueService = ProductExportQueueService;
128
+ exports.ProductExportQueueService = ProductExportQueueService = __decorate([
129
+ (0, common_1.Injectable)(),
130
+ __param(0, (0, common_1.Inject)(constants_1.PRODUCT_IMPORT_EXPORT_PLUGIN_OPTIONS)),
131
+ __metadata("design:paramtypes", [Object, core_1.JobQueueService,
132
+ product_export_service_1.ProductExportService,
133
+ core_1.EventBus])
134
+ ], ProductExportQueueService);
135
+ //# sourceMappingURL=product-export-queue.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-export-queue.service.js","sourceRoot":"","sources":["../../../../../packages/product-import-export-plugin/src/services/product-export-queue.service.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,7 @@ export declare class ProductExportService {
16
16
  private getStockOnHand;
17
17
  private mapTranslations;
18
18
  private mapFacetTranslations;
19
+ getAllProductIds(ctx: RequestContext): Promise<ID[]>;
19
20
  getCustomFields(ctx: RequestContext, productIds: string[]): Promise<{
20
21
  name: string;
21
22
  type: string;