@haus-tech/product-import-export-plugin 3.6.12 → 3.6.14
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 +17 -0
- package/README.md +110 -10
- package/package.json +1 -1
- package/src/constants.d.ts +1 -0
- package/src/constants.js +2 -1
- package/src/constants.js.map +1 -1
- package/src/dashboard/export-configuration-panel.tsx +1 -0
- package/src/dashboard/utils.ts +1 -0
- package/src/helpers/find-text-column.d.ts +8 -0
- package/src/helpers/find-text-column.js +32 -0
- package/src/helpers/find-text-column.js.map +1 -0
- package/src/index.d.ts +1 -0
- package/src/index.js +1 -0
- package/src/index.js.map +1 -1
- package/src/product-import-export.plugin.d.ts +11 -1
- package/src/product-import-export.plugin.js +35 -3
- package/src/product-import-export.plugin.js.map +1 -1
- package/src/providers/import-providers/import-parser.d.ts +9 -0
- package/src/providers/import-providers/import-parser.js +26 -8
- package/src/providers/import-providers/import-parser.js.map +1 -1
- package/src/providers/import-providers/product-importer.d.ts +58 -10
- package/src/providers/import-providers/product-importer.js +163 -94
- package/src/providers/import-providers/product-importer.js.map +1 -1
- package/src/services/channel-column-resolver.d.ts +24 -0
- package/src/services/channel-column-resolver.js +79 -0
- package/src/services/channel-column-resolver.js.map +1 -0
- package/src/services/export-relation-lookups.d.ts +26 -0
- package/src/services/export-relation-lookups.js +56 -0
- package/src/services/export-relation-lookups.js.map +1 -0
- package/src/services/extended-fast-importer.service.d.ts +16 -0
- package/src/services/extended-fast-importer.service.js +46 -21
- package/src/services/extended-fast-importer.service.js.map +1 -1
- package/src/services/import-row-groups.d.ts +17 -0
- package/src/services/import-row-groups.js +69 -0
- package/src/services/import-row-groups.js.map +1 -0
- package/src/services/product-export.service.d.ts +9 -3
- package/src/services/product-export.service.js +57 -10
- package/src/services/product-export.service.js.map +1 -1
- package/src/services/product-import.service.d.ts +1 -3
- package/src/services/product-import.service.js +10 -9
- package/src/services/product-import.service.js.map +1 -1
- package/src/services/relation-lookup-resolver.d.ts +52 -0
- package/src/services/relation-lookup-resolver.js +245 -0
- package/src/services/relation-lookup-resolver.js.map +1 -0
- package/src/services/self-relation-custom-fields.d.ts +7 -0
- package/src/services/self-relation-custom-fields.js +24 -0
- package/src/services/self-relation-custom-fields.js.map +1 -1
- package/src/strategies/import-row-validation-strategy.d.ts +71 -0
- package/src/strategies/import-row-validation-strategy.js +16 -0
- package/src/strategies/import-row-validation-strategy.js.map +1 -0
- package/src/types.d.ts +21 -1
- package/src/ui/components/export-dialog.component.ts +2 -0
- package/src/ui/components/product-import.component.ts +1 -0
- package/src/services/sku-relation-resolver.d.ts +0 -33
- package/src/services/sku-relation-resolver.js +0 -177
- package/src/services/sku-relation-resolver.js.map +0 -1
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { InjectableStrategy, RequestContext } from '@vendure/core';
|
|
2
|
+
/**
|
|
3
|
+
* @description
|
|
4
|
+
* One product of an import file as the {@link ImportRowValidationStrategy} sees it: the product's
|
|
5
|
+
* first row and every variant row under it, with the line each came from (the header is line 1,
|
|
6
|
+
* blank and comma-only lines are not counted).
|
|
7
|
+
*
|
|
8
|
+
* Custom fields are keyed as the Admin API input takes them: a relation field under its input name
|
|
9
|
+
* (`<name>Id`, or `<name>Ids` for a list) holding id strings, whether the file gave ids or a lookup
|
|
10
|
+
* column (`:sku`, `:code`) that has been resolved. A value that could not be resolved is left out
|
|
11
|
+
* (the lookup error is reported anyway), and so is an empty cell, which leaves the relation as it
|
|
12
|
+
* is. An Asset relation keeps its raw cell under the field name, since assets are only created when
|
|
13
|
+
* the row is written. Other custom fields keep their cell text under the field name.
|
|
14
|
+
* `product.customFields` holds the first translation's custom fields, which include every
|
|
15
|
+
* non-localised field.
|
|
16
|
+
*
|
|
17
|
+
* The groups are copies: changing them changes nothing that is imported.
|
|
18
|
+
*
|
|
19
|
+
* @category Import
|
|
20
|
+
*/
|
|
21
|
+
export interface ImportRowGroup {
|
|
22
|
+
line: number;
|
|
23
|
+
product: {
|
|
24
|
+
customFields: Record<string, unknown>;
|
|
25
|
+
translations: unknown[];
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
};
|
|
28
|
+
variants: Array<{
|
|
29
|
+
line: number;
|
|
30
|
+
variant: {
|
|
31
|
+
sku: string;
|
|
32
|
+
customFields: Record<string, unknown>;
|
|
33
|
+
[key: string]: unknown;
|
|
34
|
+
};
|
|
35
|
+
}>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* @description
|
|
39
|
+
* A problem with one row. Shown to the uploader as `Row <line>: <message>`.
|
|
40
|
+
*
|
|
41
|
+
* @category Import
|
|
42
|
+
*/
|
|
43
|
+
export interface ImportRowError {
|
|
44
|
+
line: number;
|
|
45
|
+
message: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* @description
|
|
49
|
+
* Checks the rows of an import file before anything is written. It runs twice: when the file is
|
|
50
|
+
* uploaded, before it is stored and queued (the upload answers `400` with the errors), and again
|
|
51
|
+
* when the import job starts, since data can change while the job waits (the job fails with the
|
|
52
|
+
* errors and imports nothing). Errors from relation lookups and from this strategy come back in
|
|
53
|
+
* one list.
|
|
54
|
+
*
|
|
55
|
+
* Set it with `ProductImportExportPlugin.init({ importOptions: { rowValidationStrategy } })`.
|
|
56
|
+
* `init(injector)` and `destroy()` are called when the application starts and stops.
|
|
57
|
+
*
|
|
58
|
+
* @category Import
|
|
59
|
+
*/
|
|
60
|
+
export interface ImportRowValidationStrategy extends InjectableStrategy {
|
|
61
|
+
validate(ctx: RequestContext, rows: ImportRowGroup[]): Promise<ImportRowError[]>;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* @description
|
|
65
|
+
* The default {@link ImportRowValidationStrategy}: accepts every row.
|
|
66
|
+
*
|
|
67
|
+
* @category Import
|
|
68
|
+
*/
|
|
69
|
+
export declare class DefaultImportRowValidationStrategy implements ImportRowValidationStrategy {
|
|
70
|
+
validate(): Promise<ImportRowError[]>;
|
|
71
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DefaultImportRowValidationStrategy = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* @description
|
|
6
|
+
* The default {@link ImportRowValidationStrategy}: accepts every row.
|
|
7
|
+
*
|
|
8
|
+
* @category Import
|
|
9
|
+
*/
|
|
10
|
+
class DefaultImportRowValidationStrategy {
|
|
11
|
+
async validate() {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.DefaultImportRowValidationStrategy = DefaultImportRowValidationStrategy;
|
|
16
|
+
//# sourceMappingURL=import-row-validation-strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-row-validation-strategy.js","sourceRoot":"","sources":["../../../../../packages/product-import-export-plugin/src/strategies/import-row-validation-strategy.ts"],"names":[],"mappings":";;;AA8DA;;;;;GAKG;AACH,MAAa,kCAAkC;IAC7C,KAAK,CAAC,QAAQ;QACZ,OAAO,EAAE,CAAA;IACX,CAAC;CACF;AAJD,gFAIC"}
|
package/src/types.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { ParsedProduct, ParsedProductWithVariants } from './providers/import-pro
|
|
|
3
3
|
import type { Injector, Product, ProductVariant, RequestContext } from '@vendure/core';
|
|
4
4
|
import { ExportStorageStrategy } from './services/export-storage/export-storage-strategy';
|
|
5
5
|
import { ImportJobStorageStrategy } from './services/import-storage/import-job-storage-strategy';
|
|
6
|
+
import { ImportRowValidationStrategy } from './strategies/import-row-validation-strategy';
|
|
6
7
|
/**
|
|
7
8
|
* @description
|
|
8
9
|
* The plugin can be configured using the following options:
|
|
@@ -50,6 +51,13 @@ export interface PluginInitOptions {
|
|
|
50
51
|
storageStrategy?: ImportOptions['storageStrategy'];
|
|
51
52
|
storageStrategyFactory?: ImportOptions['storageStrategyFactory'];
|
|
52
53
|
importJobStorage?: ImportOptions['importJobStorage'];
|
|
54
|
+
/**
|
|
55
|
+
* @description
|
|
56
|
+
* Checks the rows of an import file before anything is written: at upload, before the file is
|
|
57
|
+
* stored, and again when the import job starts. Defaults to
|
|
58
|
+
* {@link DefaultImportRowValidationStrategy}, which accepts every row.
|
|
59
|
+
*/
|
|
60
|
+
rowValidationStrategy?: ImportRowValidationStrategy;
|
|
53
61
|
};
|
|
54
62
|
exportOptions: {
|
|
55
63
|
defaultFileName?: string;
|
|
@@ -80,6 +88,18 @@ export interface PluginInitOptions {
|
|
|
80
88
|
* plugin init time.
|
|
81
89
|
*/
|
|
82
90
|
customExportColumns?: CustomExportColumn[];
|
|
91
|
+
/**
|
|
92
|
+
* @description
|
|
93
|
+
* Optional. Writes the chosen relation custom fields by a column of the related row instead
|
|
94
|
+
* of its id, keyed `<owner>:<field>` with the column as value, e.g.
|
|
95
|
+
* `{ 'variant:baseVariant': 'sku', 'product:brand': 'code' }`. The CSV header becomes
|
|
96
|
+
* `<owner>:<field>:<entity>:<column>`, the lookup header the import reads, so the file
|
|
97
|
+
* imports again, also into another database. The column must be a plain text column of the
|
|
98
|
+
* related entity, and the field must not relate to `Asset`; the application does not start
|
|
99
|
+
* otherwise. Soft-deleted related rows and rows without a value in the column are left out
|
|
100
|
+
* of the cell, since the import matches only live rows by a value.
|
|
101
|
+
*/
|
|
102
|
+
relationLookups?: Record<string, string>;
|
|
83
103
|
};
|
|
84
104
|
}
|
|
85
105
|
/**
|
|
@@ -108,7 +128,7 @@ export type JsonAsset = {
|
|
|
108
128
|
name?: string;
|
|
109
129
|
};
|
|
110
130
|
type ExportFields = Array<ProductFields | VariantFields>;
|
|
111
|
-
type ProductFields = 'id' | 'name' | 'slug' | 'description' | 'assets' | 'facets' | 'optionGroups';
|
|
131
|
+
type ProductFields = 'id' | 'name' | 'slug' | 'description' | 'assets' | 'channels' | 'facets' | 'optionGroups';
|
|
112
132
|
type VariantFields = 'sku' | 'optionValues' | 'price' | 'taxCategory' | 'stockOnHand' | 'trackInventory' | 'variantAssets' | 'variantFacets' | 'enabled';
|
|
113
133
|
export type UpdatingStrategy = 'replace' | 'merge';
|
|
114
134
|
export {};
|
|
@@ -9,6 +9,7 @@ type ProductFields =
|
|
|
9
9
|
| 'slug'
|
|
10
10
|
| 'description'
|
|
11
11
|
| 'assets'
|
|
12
|
+
| 'channels'
|
|
12
13
|
| 'facets'
|
|
13
14
|
| 'optionGroups'
|
|
14
15
|
|
|
@@ -71,6 +72,7 @@ export class ExportDialogComponent
|
|
|
71
72
|
'slug',
|
|
72
73
|
'description',
|
|
73
74
|
'assets',
|
|
75
|
+
'channels',
|
|
74
76
|
'facets',
|
|
75
77
|
'optionGroups',
|
|
76
78
|
'sku',
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { ConfigService, ID, RequestContext, TransactionalConnection } from '@vendure/core';
|
|
2
|
-
/** The fourth header segment that makes a relation column hold SKUs instead of ids. */
|
|
3
|
-
export declare const SKU_LOOKUP = "sku";
|
|
4
|
-
export interface SkuRelationResult {
|
|
5
|
-
/** One line per problem, ready to show to the person who uploaded the file. */
|
|
6
|
-
errors: string[];
|
|
7
|
-
/** The id of the single live variant behind each SKU the file references. */
|
|
8
|
-
variantIdsBySku: Map<string, ID>;
|
|
9
|
-
/** `<owner>:<field>` keys of the relation columns whose values are SKUs. */
|
|
10
|
-
fields: Set<string>;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Resolves relation custom field columns written as `<owner>:<field>:<type>:sku`, where each
|
|
14
|
-
* value names the related ProductVariant by SKU. Every SKU must match exactly one variant that is
|
|
15
|
-
* not deleted, in any channel: base variants usually live outside the channel being imported into.
|
|
16
|
-
*/
|
|
17
|
-
export declare class SkuRelationResolver {
|
|
18
|
-
private connection;
|
|
19
|
-
private configService;
|
|
20
|
-
constructor(connection: TransactionalConnection, configService: ConfigService);
|
|
21
|
-
resolve(ctx: RequestContext, csv: string): Promise<SkuRelationResult>;
|
|
22
|
-
private splitHeader;
|
|
23
|
-
private checkHeader;
|
|
24
|
-
private findFieldConfig;
|
|
25
|
-
/**
|
|
26
|
-
* The SKUs each data row references, with the row's line as the importer numbers it: the
|
|
27
|
-
* header is line 1 and blank and comma-only lines are not counted.
|
|
28
|
-
*/
|
|
29
|
-
private readSkus;
|
|
30
|
-
private findLiveVariants;
|
|
31
|
-
}
|
|
32
|
-
/** The SKUs in a list relation cell, written `SKU|SKU`. */
|
|
33
|
-
export declare function splitSkuList(value: string): string[];
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
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;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.SkuRelationResolver = exports.SKU_LOOKUP = void 0;
|
|
13
|
-
exports.splitSkuList = splitSkuList;
|
|
14
|
-
const common_1 = require("@nestjs/common");
|
|
15
|
-
const core_1 = require("@vendure/core");
|
|
16
|
-
const sync_1 = require("csv-parse/sync");
|
|
17
|
-
const typeorm_1 = require("typeorm");
|
|
18
|
-
const import_csv_lines_1 = require("../helpers/import-csv-lines");
|
|
19
|
-
/** The fourth header segment that makes a relation column hold SKUs instead of ids. */
|
|
20
|
-
exports.SKU_LOOKUP = 'sku';
|
|
21
|
-
/** SKUs per database query, well below every driver's bind parameter limit. */
|
|
22
|
-
const SKU_QUERY_CHUNK_SIZE = 1000;
|
|
23
|
-
/**
|
|
24
|
-
* Resolves relation custom field columns written as `<owner>:<field>:<type>:sku`, where each
|
|
25
|
-
* value names the related ProductVariant by SKU. Every SKU must match exactly one variant that is
|
|
26
|
-
* not deleted, in any channel: base variants usually live outside the channel being imported into.
|
|
27
|
-
*/
|
|
28
|
-
let SkuRelationResolver = class SkuRelationResolver {
|
|
29
|
-
connection;
|
|
30
|
-
configService;
|
|
31
|
-
constructor(connection, configService) {
|
|
32
|
-
this.connection = connection;
|
|
33
|
-
this.configService = configService;
|
|
34
|
-
}
|
|
35
|
-
async resolve(ctx, csv) {
|
|
36
|
-
const variantIdsBySku = new Map();
|
|
37
|
-
const fields = new Set();
|
|
38
|
-
// The importer reads the same lines and headers, so both agree on which columns hold SKUs
|
|
39
|
-
// and on row numbers.
|
|
40
|
-
const lines = (0, import_csv_lines_1.importCsvLines)(csv);
|
|
41
|
-
const headers = (0, import_csv_lines_1.importCsvHeaders)(lines);
|
|
42
|
-
const lookupHeaders = headers.filter((header) => this.splitHeader(header).length === 4);
|
|
43
|
-
if (lookupHeaders.length === 0) {
|
|
44
|
-
return { errors: [], variantIdsBySku, fields };
|
|
45
|
-
}
|
|
46
|
-
const headerErrors = lookupHeaders.flatMap((header) => this.checkHeader(header));
|
|
47
|
-
if (headerErrors.length > 0) {
|
|
48
|
-
return { errors: headerErrors, variantIdsBySku, fields };
|
|
49
|
-
}
|
|
50
|
-
const columns = lookupHeaders.map((header) => {
|
|
51
|
-
const [owner, fieldName] = this.splitHeader(header);
|
|
52
|
-
fields.add(`${owner}:${fieldName}`);
|
|
53
|
-
return { index: headers.indexOf(header), list: this.findFieldConfig(header)?.list === true };
|
|
54
|
-
});
|
|
55
|
-
let rows;
|
|
56
|
-
try {
|
|
57
|
-
rows = this.readSkus(lines, columns);
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
60
|
-
return {
|
|
61
|
-
errors: [`Could not read the file: ${error.message}`],
|
|
62
|
-
variantIdsBySku,
|
|
63
|
-
fields,
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
const matches = await this.findLiveVariants(ctx, uniqueSkus(rows));
|
|
67
|
-
const errors = [];
|
|
68
|
-
for (const { line, skus } of rows) {
|
|
69
|
-
for (const sku of skus) {
|
|
70
|
-
const found = matches.get(sku) ?? [];
|
|
71
|
-
if (found.length === 0) {
|
|
72
|
-
errors.push(`Row ${line}: no variant with SKU ${sku}`);
|
|
73
|
-
}
|
|
74
|
-
else if (found.length > 1) {
|
|
75
|
-
errors.push(`Row ${line}: SKU ${sku} matches ${found.length} variants`);
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
variantIdsBySku.set(sku, found[0]);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return { errors, variantIdsBySku, fields };
|
|
83
|
-
}
|
|
84
|
-
splitHeader(header) {
|
|
85
|
-
if (!header.startsWith('product:') && !header.startsWith('variant:')) {
|
|
86
|
-
return [];
|
|
87
|
-
}
|
|
88
|
-
return header.split(':');
|
|
89
|
-
}
|
|
90
|
-
checkHeader(header) {
|
|
91
|
-
const lookup = this.splitHeader(header)[3];
|
|
92
|
-
if (lookup !== exports.SKU_LOOKUP) {
|
|
93
|
-
return [`Column '${header}': only ':${exports.SKU_LOOKUP}' is supported as a lookup`];
|
|
94
|
-
}
|
|
95
|
-
const config = this.findFieldConfig(header);
|
|
96
|
-
if (!config) {
|
|
97
|
-
const [owner, fieldName] = this.splitHeader(header);
|
|
98
|
-
const entity = owner === 'product' ? 'Product' : 'ProductVariant';
|
|
99
|
-
return [`Column '${header}': ${entity} has no custom field named '${fieldName}'`];
|
|
100
|
-
}
|
|
101
|
-
const isVariantRelation = config?.type === 'relation' && config.entity === core_1.ProductVariant;
|
|
102
|
-
if (!isVariantRelation) {
|
|
103
|
-
return [
|
|
104
|
-
`Column '${header}': ':${exports.SKU_LOOKUP}' works only on relation custom fields to ProductVariant`,
|
|
105
|
-
];
|
|
106
|
-
}
|
|
107
|
-
return [];
|
|
108
|
-
}
|
|
109
|
-
findFieldConfig(header) {
|
|
110
|
-
const [owner, fieldName] = this.splitHeader(header);
|
|
111
|
-
const configs = owner === 'product'
|
|
112
|
-
? this.configService.customFields.Product
|
|
113
|
-
: this.configService.customFields.ProductVariant;
|
|
114
|
-
return configs.find((config) => config.name === fieldName);
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* The SKUs each data row references, with the row's line as the importer numbers it: the
|
|
118
|
-
* header is line 1 and blank and comma-only lines are not counted.
|
|
119
|
-
*/
|
|
120
|
-
readSkus(lines, columns) {
|
|
121
|
-
const [, ...records] = (0, sync_1.parse)(lines.join('\n'), {
|
|
122
|
-
bom: true,
|
|
123
|
-
// As lenient as the importer's parser, so a file it imports is never rejected here.
|
|
124
|
-
relax_column_count: true,
|
|
125
|
-
relax_quotes: true,
|
|
126
|
-
});
|
|
127
|
-
return records
|
|
128
|
-
.map((record, index) => ({
|
|
129
|
-
line: index + 2,
|
|
130
|
-
skus: columns.flatMap(({ index: column, list }) => splitSkus(record[column], list)),
|
|
131
|
-
}))
|
|
132
|
-
.filter((row) => row.skus.length > 0);
|
|
133
|
-
}
|
|
134
|
-
async findLiveVariants(ctx, skus) {
|
|
135
|
-
const matches = new Map();
|
|
136
|
-
if (skus.length === 0) {
|
|
137
|
-
return matches;
|
|
138
|
-
}
|
|
139
|
-
const repository = this.connection.getRepository(ctx, core_1.ProductVariant);
|
|
140
|
-
const variants = [];
|
|
141
|
-
for (let start = 0; start < skus.length; start += SKU_QUERY_CHUNK_SIZE) {
|
|
142
|
-
const chunk = skus.slice(start, start + SKU_QUERY_CHUNK_SIZE);
|
|
143
|
-
variants.push(...(await repository.find({
|
|
144
|
-
select: ['id', 'sku'],
|
|
145
|
-
where: { sku: (0, typeorm_1.In)(chunk), deletedAt: (0, typeorm_1.IsNull)() },
|
|
146
|
-
})));
|
|
147
|
-
}
|
|
148
|
-
for (const variant of variants) {
|
|
149
|
-
matches.set(variant.sku, [...(matches.get(variant.sku) ?? []), variant.id]);
|
|
150
|
-
}
|
|
151
|
-
return matches;
|
|
152
|
-
}
|
|
153
|
-
};
|
|
154
|
-
exports.SkuRelationResolver = SkuRelationResolver;
|
|
155
|
-
exports.SkuRelationResolver = SkuRelationResolver = __decorate([
|
|
156
|
-
(0, common_1.Injectable)(),
|
|
157
|
-
__metadata("design:paramtypes", [core_1.TransactionalConnection,
|
|
158
|
-
core_1.ConfigService])
|
|
159
|
-
], SkuRelationResolver);
|
|
160
|
-
/** The SKUs in a list relation cell, written `SKU|SKU`. */
|
|
161
|
-
function splitSkuList(value) {
|
|
162
|
-
return value
|
|
163
|
-
.split('|')
|
|
164
|
-
.map((sku) => sku.trim())
|
|
165
|
-
.filter((sku) => sku !== '');
|
|
166
|
-
}
|
|
167
|
-
function splitSkus(value, list) {
|
|
168
|
-
const trimmed = value?.trim() ?? '';
|
|
169
|
-
if (trimmed === '') {
|
|
170
|
-
return [];
|
|
171
|
-
}
|
|
172
|
-
return list ? splitSkuList(trimmed) : [trimmed];
|
|
173
|
-
}
|
|
174
|
-
function uniqueSkus(rows) {
|
|
175
|
-
return [...new Set(rows.flatMap((row) => row.skus))];
|
|
176
|
-
}
|
|
177
|
-
//# sourceMappingURL=sku-relation-resolver.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sku-relation-resolver.js","sourceRoot":"","sources":["../../../../../packages/product-import-export-plugin/src/services/sku-relation-resolver.ts"],"names":[],"mappings":"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"}
|