@haus-tech/product-import-export-plugin 3.6.12 → 3.6.13

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 (34) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +65 -8
  3. package/package.json +1 -1
  4. package/src/constants.d.ts +1 -0
  5. package/src/constants.js +2 -1
  6. package/src/constants.js.map +1 -1
  7. package/src/index.d.ts +1 -0
  8. package/src/index.js +1 -0
  9. package/src/index.js.map +1 -1
  10. package/src/product-import-export.plugin.d.ts +11 -1
  11. package/src/product-import-export.plugin.js +32 -2
  12. package/src/product-import-export.plugin.js.map +1 -1
  13. package/src/providers/import-providers/import-parser.d.ts +4 -0
  14. package/src/providers/import-providers/import-parser.js +16 -7
  15. package/src/providers/import-providers/import-parser.js.map +1 -1
  16. package/src/providers/import-providers/product-importer.d.ts +43 -10
  17. package/src/providers/import-providers/product-importer.js +109 -66
  18. package/src/providers/import-providers/product-importer.js.map +1 -1
  19. package/src/services/import-row-groups.d.ts +17 -0
  20. package/src/services/import-row-groups.js +69 -0
  21. package/src/services/import-row-groups.js.map +1 -0
  22. package/src/services/product-import.service.d.ts +1 -3
  23. package/src/services/product-import.service.js +10 -9
  24. package/src/services/product-import.service.js.map +1 -1
  25. package/src/services/relation-lookup-resolver.d.ts +57 -0
  26. package/src/services/relation-lookup-resolver.js +272 -0
  27. package/src/services/relation-lookup-resolver.js.map +1 -0
  28. package/src/strategies/import-row-validation-strategy.d.ts +71 -0
  29. package/src/strategies/import-row-validation-strategy.js +16 -0
  30. package/src/strategies/import-row-validation-strategy.js.map +1 -0
  31. package/src/types.d.ts +8 -0
  32. package/src/services/sku-relation-resolver.d.ts +0 -33
  33. package/src/services/sku-relation-resolver.js +0 -177
  34. package/src/services/sku-relation-resolver.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-row-groups.js","sourceRoot":"","sources":["../../../../../packages/product-import-export-plugin/src/services/import-row-groups.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,6 @@ import { RequestContext } from '@vendure/core';
4
4
  import { UpdatingStrategy } from '../types';
5
5
  import { ProductImporter } from '../providers/import-providers/product-importer';
6
6
  import { ImportJobStorageStrategy } from './import-storage/import-job-storage-strategy';
7
- import { SkuRelationResolver } from './sku-relation-resolver';
8
7
  /** The uploaded file cannot be imported as it is; `errors` says why, one line per problem. */
9
8
  export declare class ImportFileInvalidError extends Error {
10
9
  readonly errors: string[];
@@ -17,10 +16,9 @@ export declare class ProductImportService implements OnModuleInit {
17
16
  private searchService;
18
17
  private productService;
19
18
  private eventBus;
20
- private skuRelationResolver;
21
19
  private readonly loggerCtx;
22
20
  private productImportQueue;
23
- constructor(importJobStorageStrategy: ImportJobStorageStrategy, jobQueueService: JobQueueService, productImporter: ProductImporter, searchService: SearchService, productService: ProductService, eventBus: EventBus, skuRelationResolver: SkuRelationResolver);
21
+ constructor(importJobStorageStrategy: ImportJobStorageStrategy, jobQueueService: JobQueueService, productImporter: ProductImporter, searchService: SearchService, productService: ProductService, eventBus: EventBus);
24
22
  onModuleInit(): Promise<void>;
25
23
  processFile(ctx: RequestContext, file: Express.Multer.File, updateProductSlug: boolean, mainLanguage: LanguageCode, updatingStrategy: UpdatingStrategy): Promise<import("@vendure/core/dist/job-queue/subscribable-job").SubscribableJob<{
26
24
  ctx: SerializedRequestContext;
@@ -19,7 +19,6 @@ const core_2 = require("@vendure/core");
19
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
- const sku_relation_resolver_1 = require("./sku-relation-resolver");
23
22
  const import_progress_1 = require("./import-progress");
24
23
  /** The uploaded file cannot be imported as it is; `errors` says why, one line per problem. */
25
24
  class ImportFileInvalidError extends Error {
@@ -37,17 +36,15 @@ let ProductImportService = class ProductImportService {
37
36
  searchService;
38
37
  productService;
39
38
  eventBus;
40
- skuRelationResolver;
41
39
  loggerCtx = 'ProductImportService';
42
40
  productImportQueue;
43
- constructor(importJobStorageStrategy, jobQueueService, productImporter, searchService, productService, eventBus, skuRelationResolver) {
41
+ constructor(importJobStorageStrategy, jobQueueService, productImporter, searchService, productService, eventBus) {
44
42
  this.importJobStorageStrategy = importJobStorageStrategy;
45
43
  this.jobQueueService = jobQueueService;
46
44
  this.productImporter = productImporter;
47
45
  this.searchService = searchService;
48
46
  this.productService = productService;
49
47
  this.eventBus = eventBus;
50
- this.skuRelationResolver = skuRelationResolver;
51
48
  }
52
49
  async onModuleInit() {
53
50
  this.productImportQueue = await this.jobQueueService.createQueue({
@@ -73,6 +70,11 @@ let ProductImportService = class ProductImportService {
73
70
  },
74
71
  });
75
72
  }).then(async (result) => {
73
+ if (jobResult?.rejected) {
74
+ // The rows were checked again before the first write and nothing was imported.
75
+ const errors = result.errors?.length ? result.errors : ['The import was rejected'];
76
+ throw new ImportFileInvalidError(errors);
77
+ }
76
78
  await this.runPostImportTasks(ctx, result);
77
79
  return (0, lodash_1.omit)(result, 'currentProduct');
78
80
  });
@@ -84,14 +86,14 @@ let ProductImportService = class ProductImportService {
84
86
  });
85
87
  }
86
88
  async processFile(ctx, file, updateProductSlug, mainLanguage, updatingStrategy) {
87
- // Checked before queueing so the uploader sees a wrong header or SKU at once, not as a
88
- // finished job that imported nothing.
89
+ // Checked before queueing so the uploader sees a wrong header, lookup value or row at once, not
90
+ // as a finished job that imported nothing.
89
91
  const csv = file.buffer.toString('utf8');
90
92
  const headerErrors = this.productImporter.validateHeader(csv);
91
93
  if (headerErrors.length > 0) {
92
94
  throw new ImportFileInvalidError(headerErrors);
93
95
  }
94
- const { errors } = await this.skuRelationResolver.resolve(ctx, csv);
96
+ const { errors } = await this.productImporter.checkFile(ctx, csv, mainLanguage, updateProductSlug);
95
97
  if (errors.length > 0) {
96
98
  throw new ImportFileInvalidError(errors);
97
99
  }
@@ -142,7 +144,6 @@ exports.ProductImportService = ProductImportService = __decorate([
142
144
  product_importer_1.ProductImporter,
143
145
  core_1.SearchService,
144
146
  core_1.ProductService,
145
- core_1.EventBus,
146
- sku_relation_resolver_1.SkuRelationResolver])
147
+ core_1.EventBus])
147
148
  ], ProductImportService);
148
149
  //# sourceMappingURL=product-import.service.js.map
@@ -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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"}
@@ -0,0 +1,57 @@
1
+ import { ConfigService, ID, RequestContext, TransactionalConnection } from '@vendure/core';
2
+ /** The fourth header segment that makes a ProductVariant relation column hold SKUs. */
3
+ export declare const SKU_LOOKUP = "sku";
4
+ /** The column a relation custom field's values are matched on, instead of the id. */
5
+ export interface RelationLookup {
6
+ /** Class name of the related entity, e.g. `ProductVariant`. */
7
+ entityName: string;
8
+ /** Property name of the column the values are matched on, e.g. `sku`. */
9
+ column: string;
10
+ }
11
+ export interface RelationLookupResult {
12
+ /** One line per problem, ready to show to the person who uploaded the file. */
13
+ errors: string[];
14
+ /**
15
+ * False when a lookup header is wrong or the file cannot be read, so no row was checked and
16
+ * `fields` may be incomplete. The errors are then about the file, not about rows.
17
+ */
18
+ rowsChecked: boolean;
19
+ /** The id of the single live row behind each value, keyed by `relationLookupKey`. */
20
+ idsByLookup: Map<string, ID>;
21
+ /** The lookup of each `<owner>:<field>` relation column whose values are not ids. */
22
+ fields: Map<string, RelationLookup>;
23
+ }
24
+ /** The key of one looked-up value in `RelationLookupResult.idsByLookup`. */
25
+ export declare function relationLookupKey(lookup: RelationLookup, value: string): string;
26
+ /**
27
+ * Resolves relation custom field columns written as `<owner>:<field>:<entity>:<column>`, where
28
+ * each value names the related row by that column instead of by id (`:sku` on a ProductVariant
29
+ * relation names the variant by SKU). Every value must match exactly one row that is not
30
+ * soft-deleted, in any channel: related rows usually live outside the channel being imported into.
31
+ */
32
+ export declare class RelationLookupResolver {
33
+ private connection;
34
+ private configService;
35
+ constructor(connection: TransactionalConnection, configService: ConfigService);
36
+ resolve(ctx: RequestContext, csv: string): Promise<RelationLookupResult>;
37
+ private splitHeader;
38
+ private checkHeader;
39
+ private findFieldConfig;
40
+ /**
41
+ * A plain text column of the entity, so a CSV cell compares to it without a cast. Relation and
42
+ * embedded columns (custom fields among them) are not lookups.
43
+ */
44
+ private findLookupColumn;
45
+ /**
46
+ * The lookup values each data row references, with the row's line as the importer numbers it:
47
+ * the header is line 1 and blank and comma-only lines are not counted.
48
+ */
49
+ private readValues;
50
+ /** The ids of the live rows behind every value, keyed by `relationLookupKey`. */
51
+ private findLiveRows;
52
+ private findLiveRowsByColumn;
53
+ }
54
+ /** The values in a list relation cell, written `VALUE|VALUE`. */
55
+ export declare function splitLookupList(value: string): string[];
56
+ /** The SKUs in a list relation cell, written `SKU|SKU`. */
57
+ export declare const splitSkuList: typeof splitLookupList;
@@ -0,0 +1,272 @@
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.splitSkuList = exports.RelationLookupResolver = exports.SKU_LOOKUP = void 0;
13
+ exports.relationLookupKey = relationLookupKey;
14
+ exports.splitLookupList = splitLookupList;
15
+ const common_1 = require("@nestjs/common");
16
+ const core_1 = require("@vendure/core");
17
+ const sync_1 = require("csv-parse/sync");
18
+ const typeorm_1 = require("typeorm");
19
+ const import_csv_lines_1 = require("../helpers/import-csv-lines");
20
+ /** The fourth header segment that makes a ProductVariant relation column hold SKUs. */
21
+ exports.SKU_LOOKUP = 'sku';
22
+ /** Values per database query, well below every driver's bind parameter limit. */
23
+ const LOOKUP_QUERY_CHUNK_SIZE = 1000;
24
+ /** Column types a lookup can match a CSV cell against without a cast. */
25
+ const TEXT_COLUMN_TYPES = new Set([
26
+ 'varchar',
27
+ 'character varying',
28
+ 'nvarchar',
29
+ 'text',
30
+ 'char',
31
+ 'character',
32
+ 'nchar',
33
+ 'citext',
34
+ ]);
35
+ /** The key of one looked-up value in `RelationLookupResult.idsByLookup`. */
36
+ function relationLookupKey(lookup, value) {
37
+ return `${lookup.entityName}:${lookup.column}:${value}`;
38
+ }
39
+ /**
40
+ * Resolves relation custom field columns written as `<owner>:<field>:<entity>:<column>`, where
41
+ * each value names the related row by that column instead of by id (`:sku` on a ProductVariant
42
+ * relation names the variant by SKU). Every value must match exactly one row that is not
43
+ * soft-deleted, in any channel: related rows usually live outside the channel being imported into.
44
+ */
45
+ let RelationLookupResolver = class RelationLookupResolver {
46
+ connection;
47
+ configService;
48
+ constructor(connection, configService) {
49
+ this.connection = connection;
50
+ this.configService = configService;
51
+ }
52
+ async resolve(ctx, csv) {
53
+ const idsByLookup = new Map();
54
+ const fields = new Map();
55
+ // The importer reads the same lines and headers, so both agree on which columns hold lookups
56
+ // and on row numbers.
57
+ const lines = (0, import_csv_lines_1.importCsvLines)(csv);
58
+ const headers = (0, import_csv_lines_1.importCsvHeaders)(lines);
59
+ const lookupHeaders = headers.filter((header) => this.splitHeader(header).length === 4);
60
+ if (lookupHeaders.length === 0) {
61
+ return { errors: [], rowsChecked: true, idsByLookup, fields };
62
+ }
63
+ const headerErrors = [
64
+ ...lookupHeaders.flatMap((header) => this.checkHeader(header)),
65
+ ...duplicateFieldErrors(lookupHeaders.map((header) => this.splitHeader(header))),
66
+ ];
67
+ if (headerErrors.length > 0) {
68
+ return { errors: headerErrors, rowsChecked: false, idsByLookup, fields };
69
+ }
70
+ const columns = lookupHeaders.map((header) => {
71
+ const [owner, fieldName, , column] = this.splitHeader(header);
72
+ const config = this.findFieldConfig(header);
73
+ const lookup = { entityName: config.entity.name, column };
74
+ fields.set(`${owner}:${fieldName}`, lookup);
75
+ return {
76
+ index: headers.indexOf(header),
77
+ list: config.list === true,
78
+ lookup,
79
+ entity: config.entity,
80
+ };
81
+ });
82
+ let rows;
83
+ try {
84
+ rows = this.readValues(lines, columns);
85
+ }
86
+ catch (error) {
87
+ return {
88
+ errors: [`Could not read the file: ${error.message}`],
89
+ rowsChecked: false,
90
+ idsByLookup,
91
+ fields,
92
+ };
93
+ }
94
+ const matches = await this.findLiveRows(ctx, rows);
95
+ const errors = [];
96
+ for (const { line, values } of rows) {
97
+ for (const { column, value } of values) {
98
+ const key = relationLookupKey(column.lookup, value);
99
+ const found = matches.get(key) ?? [];
100
+ if (found.length === 1) {
101
+ idsByLookup.set(key, found[0]);
102
+ }
103
+ else {
104
+ errors.push(`Row ${line}: ${lookupError(column.lookup, value, found.length)}`);
105
+ }
106
+ }
107
+ }
108
+ return { errors, rowsChecked: true, idsByLookup, fields };
109
+ }
110
+ splitHeader(header) {
111
+ if (!header.startsWith('product:') && !header.startsWith('variant:')) {
112
+ return [];
113
+ }
114
+ return header.split(':');
115
+ }
116
+ checkHeader(header) {
117
+ const [owner, fieldName, entitySegment, column] = this.splitHeader(header);
118
+ const config = this.findFieldConfig(header);
119
+ if (!config) {
120
+ const entity = owner === 'product' ? 'Product' : 'ProductVariant';
121
+ return [`Column '${header}': ${entity} has no custom field named '${fieldName}'`];
122
+ }
123
+ if (config.type !== 'relation') {
124
+ return [`Column '${header}': a lookup works only on relation custom fields`];
125
+ }
126
+ const { entity } = config;
127
+ const expectedSegment = entity.name.toLowerCase();
128
+ // `:sku` on a ProductVariant relation never read the third segment, so files written with any
129
+ // segment there keep importing.
130
+ const isLegacySku = entity === core_1.ProductVariant && column === exports.SKU_LOOKUP;
131
+ if (!isLegacySku && entitySegment.toLowerCase() !== expectedSegment) {
132
+ return [
133
+ `Column '${header}': the third segment must be '${expectedSegment}', the related entity`,
134
+ ];
135
+ }
136
+ if (!this.findLookupColumn(entity, column)) {
137
+ return [`Invalid lookup column "${column}" on ${entity.name}`];
138
+ }
139
+ return [];
140
+ }
141
+ findFieldConfig(header) {
142
+ const [owner, fieldName] = this.splitHeader(header);
143
+ const configs = owner === 'product'
144
+ ? this.configService.customFields.Product
145
+ : this.configService.customFields.ProductVariant;
146
+ return configs.find((config) => config.name === fieldName);
147
+ }
148
+ /**
149
+ * A plain text column of the entity, so a CSV cell compares to it without a cast. Relation and
150
+ * embedded columns (custom fields among them) are not lookups.
151
+ */
152
+ findLookupColumn(entity, propertyName) {
153
+ // Not findColumnWithPropertyName: it can return a custom field (embedded) column of that name.
154
+ const column = this.connection.rawConnection
155
+ .getMetadata(entity)
156
+ .columns.find((candidate) => candidate.propertyName === propertyName &&
157
+ !candidate.embeddedMetadata &&
158
+ !candidate.relationMetadata);
159
+ if (!column) {
160
+ return undefined;
161
+ }
162
+ const isText = column.type === String || TEXT_COLUMN_TYPES.has(String(column.type));
163
+ return isText ? column : undefined;
164
+ }
165
+ /**
166
+ * The lookup values each data row references, with the row's line as the importer numbers it:
167
+ * the header is line 1 and blank and comma-only lines are not counted.
168
+ */
169
+ readValues(lines, columns) {
170
+ const [, ...records] = (0, sync_1.parse)(lines.join('\n'), {
171
+ bom: true,
172
+ // As lenient as the importer's parser, so a file it imports is never rejected here.
173
+ relax_column_count: true,
174
+ relax_quotes: true,
175
+ });
176
+ return records
177
+ .map((record, index) => ({
178
+ line: index + 2,
179
+ values: columns.flatMap((column) => splitValues(record[column.index], column.list).map((value) => ({ column, value }))),
180
+ }))
181
+ .filter((row) => row.values.length > 0);
182
+ }
183
+ /** The ids of the live rows behind every value, keyed by `relationLookupKey`. */
184
+ async findLiveRows(ctx, rows) {
185
+ // One query (per chunk) for each entity and column, however many columns use it.
186
+ const valuesByLookup = new Map();
187
+ for (const { column, value } of rows.flatMap((row) => row.values)) {
188
+ const groupKey = relationLookupKey(column.lookup, '');
189
+ const group = valuesByLookup.get(groupKey) ?? { column, values: new Set() };
190
+ group.values.add(value);
191
+ valuesByLookup.set(groupKey, group);
192
+ }
193
+ const matches = new Map();
194
+ for (const { column, values } of valuesByLookup.values()) {
195
+ for (const row of await this.findLiveRowsByColumn(ctx, column, [...values])) {
196
+ const key = relationLookupKey(column.lookup, row.value);
197
+ matches.set(key, [...(matches.get(key) ?? []), row.id]);
198
+ }
199
+ }
200
+ return matches;
201
+ }
202
+ async findLiveRowsByColumn(ctx, { entity, lookup }, values) {
203
+ const softDeletes = this.connection.rawConnection.getMetadata(entity).findColumnWithPropertyName('deletedAt') !==
204
+ undefined;
205
+ const repository = this.connection.getRepository(ctx, entity);
206
+ const found = [];
207
+ for (let start = 0; start < values.length; start += LOOKUP_QUERY_CHUNK_SIZE) {
208
+ const chunk = values.slice(start, start + LOOKUP_QUERY_CHUNK_SIZE);
209
+ // The column name was checked against the entity's metadata in checkHeader.
210
+ const where = {
211
+ [lookup.column]: (0, typeorm_1.In)(chunk),
212
+ ...(softDeletes ? { deletedAt: (0, typeorm_1.IsNull)() } : {}),
213
+ };
214
+ const rows = await repository.find({
215
+ select: ['id', lookup.column],
216
+ where,
217
+ });
218
+ found.push(...rows.map((row) => ({
219
+ id: row.id,
220
+ value: String(row[lookup.column]),
221
+ })));
222
+ }
223
+ return found;
224
+ }
225
+ };
226
+ exports.RelationLookupResolver = RelationLookupResolver;
227
+ exports.RelationLookupResolver = RelationLookupResolver = __decorate([
228
+ (0, common_1.Injectable)(),
229
+ __metadata("design:paramtypes", [core_1.TransactionalConnection,
230
+ core_1.ConfigService])
231
+ ], RelationLookupResolver);
232
+ /** A second lookup column for a field that an earlier column already gives. */
233
+ function duplicateFieldErrors(headers) {
234
+ const seen = new Set();
235
+ const errors = [];
236
+ for (const parts of headers) {
237
+ const field = `${parts[0]}:${parts[1]}`;
238
+ if (seen.has(field)) {
239
+ errors.push(`Column '${parts.join(':')}': ${field} is already given by another column`);
240
+ }
241
+ seen.add(field);
242
+ }
243
+ return errors;
244
+ }
245
+ function lookupError(lookup, value, matchCount) {
246
+ const isSku = lookup.entityName === core_1.ProductVariant.name && lookup.column === exports.SKU_LOOKUP;
247
+ if (matchCount === 0) {
248
+ return isSku
249
+ ? `no variant with SKU ${value}`
250
+ : `no ${lookup.entityName} with ${lookup.column} ${value}`;
251
+ }
252
+ return isSku
253
+ ? `SKU ${value} matches ${matchCount} variants`
254
+ : `${lookup.column} ${value} matches ${matchCount} ${lookup.entityName} rows`;
255
+ }
256
+ /** The values in a list relation cell, written `VALUE|VALUE`. */
257
+ function splitLookupList(value) {
258
+ return value
259
+ .split('|')
260
+ .map((item) => item.trim())
261
+ .filter((item) => item !== '');
262
+ }
263
+ /** The SKUs in a list relation cell, written `SKU|SKU`. */
264
+ exports.splitSkuList = splitLookupList;
265
+ function splitValues(value, list) {
266
+ const trimmed = value?.trim() ?? '';
267
+ if (trimmed === '') {
268
+ return [];
269
+ }
270
+ return list ? splitLookupList(trimmed) : [trimmed];
271
+ }
272
+ //# sourceMappingURL=relation-lookup-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation-lookup-resolver.js","sourceRoot":"","sources":["../../../../../packages/product-import-export-plugin/src/services/relation-lookup-resolver.ts"],"names":[],"mappings":"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"}
@@ -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;
@@ -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[];