@nocobase/plugin-action-import 2.0.0-alpha.5 → 2.0.0-alpha.51

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.
@@ -187,12 +187,13 @@ class XlsxImporter extends import_events.default {
187
187
  getModel() {
188
188
  return this.repository instanceof import_database.RelationRepository ? this.repository.targetModel : this.repository.model;
189
189
  }
190
- async handleRowValuesWithColumns(row, rowValues, options) {
191
- for (let index = 0; index < this.options.columns.length; index++) {
192
- const column = this.options.columns[index];
190
+ async handleRowValuesWithColumns(row, rowValues, options, columns) {
191
+ var _a;
192
+ for (let index = 0; index < columns.length; index++) {
193
+ const column = columns[index];
193
194
  const field = this.options.collection.getField(column.dataIndex[0]);
194
195
  if (!field) {
195
- throw new import_errors.ImportValidationError("Import validation.Field not found", {
196
+ throw new import_errors.ImportValidationError("Import validation. Field not found", {
196
197
  field: column.dataIndex[0]
197
198
  });
198
199
  }
@@ -215,7 +216,15 @@ class XlsxImporter extends import_events.default {
215
216
  ctx.targetCollection = field.targetCollection();
216
217
  ctx.filterKey = column.dataIndex[1];
217
218
  }
218
- rowValues[dataKey] = await interfaceInstance.toValue(this.trimString(str), ctx);
219
+ try {
220
+ rowValues[dataKey] = str == null ? null : await interfaceInstance.toValue(this.trimString(str), ctx);
221
+ } catch (error) {
222
+ throw new import_errors.ImportValidationError("Failed to parse field {{field}} in row {{rowIndex}}: {{message}}", {
223
+ rowIndex: ((_a = options == null ? void 0 : options.context) == null ? void 0 : _a.handingRowIndex) || 1,
224
+ field: dataKey,
225
+ message: error.message
226
+ });
227
+ }
219
228
  }
220
229
  const model = this.getModel();
221
230
  const guard = import_database.UpdateGuard.fromOptions(model, {
@@ -229,10 +238,11 @@ class XlsxImporter extends import_events.default {
229
238
  var _a, _b;
230
239
  let { handingRowIndex = 1 } = options;
231
240
  const { transaction } = runOptions;
241
+ const columns = this.getColumnsByPermission(options == null ? void 0 : options.context);
232
242
  const rows = [];
233
243
  for (const row of chunkRows) {
234
244
  const rowValues = {};
235
- await this.handleRowValuesWithColumns(row, rowValues, runOptions);
245
+ await this.handleRowValuesWithColumns(row, rowValues, runOptions, columns);
236
246
  rows.push({
237
247
  ...this.options.rowDefaultValues || {},
238
248
  ...rowValues
@@ -264,7 +274,7 @@ class XlsxImporter extends import_events.default {
264
274
  });
265
275
  throw new import_errors.ImportError(`Import failed at row ${handingRowIndex}`, {
266
276
  rowIndex: handingRowIndex,
267
- rowData: rows[handingRowIndex],
277
+ rowData: rows[handingRowIndex - (this.options.explain ? 2 : 1)],
268
278
  cause: error
269
279
  });
270
280
  }
@@ -288,11 +298,6 @@ class XlsxImporter extends import_events.default {
288
298
  for (let i = 0; i < instances.length; i++) {
289
299
  const instance = instances[i];
290
300
  const value = values[i];
291
- await this.loggerService.measureExecutedTime(
292
- async () => (0, import_database.updateAssociations)(instance, value, { transaction }),
293
- `Row ${i + 1}: updateAssociations completed in {time}ms`,
294
- "debug"
295
- );
296
301
  if (insertOptions.hooks !== false) {
297
302
  await this.loggerService.measureExecutedTime(
298
303
  async () => {
@@ -308,6 +313,11 @@ class XlsxImporter extends import_events.default {
308
313
  "debug"
309
314
  );
310
315
  }
316
+ await this.loggerService.measureExecutedTime(
317
+ async () => (0, import_database.updateAssociations)(instance, value, { transaction }),
318
+ `Row ${i + 1}: updateAssociations completed in {time}ms`,
319
+ "debug"
320
+ );
311
321
  if ((context == null ? void 0 : context.skipWorkflow) !== true) {
312
322
  await this.loggerService.measureExecutedTime(
313
323
  async () => {
@@ -378,7 +388,7 @@ class XlsxImporter extends import_events.default {
378
388
  headers: expectedHeaders.join(", ")
379
389
  });
380
390
  }
381
- data = this.alignWithHeaders({ data, expectedHeaders, headers });
391
+ data = this.alignWithHeaders({ data, expectedHeaders, headerRowIndex });
382
392
  const rows = data.slice(headerRowIndex + 1);
383
393
  if (rows.length === 0) {
384
394
  throw new import_errors.ImportValidationError("No data to import");
@@ -386,8 +396,14 @@ class XlsxImporter extends import_events.default {
386
396
  return [headers, ...rows];
387
397
  }
388
398
  alignWithHeaders(params) {
389
- const { expectedHeaders, headers, data } = params;
390
- const keepCols = headers.map((x, i) => expectedHeaders.includes(x) ? i : -1).filter((i) => i > -1);
399
+ const { data, expectedHeaders, headerRowIndex } = params;
400
+ const headerRow = data[headerRowIndex];
401
+ const keepCols = expectedHeaders.map((header) => headerRow.indexOf(header));
402
+ if (keepCols.some((index) => index < 0)) {
403
+ throw new import_errors.ImportValidationError("Headers not found. Expected headers: {{headers}}", {
404
+ headers: expectedHeaders.join(", ")
405
+ });
406
+ }
391
407
  return data.map((row) => keepCols.map((i) => row[i]));
392
408
  }
393
409
  findAndValidateHeaders(options) {
@@ -401,6 +417,7 @@ class XlsxImporter extends import_events.default {
401
417
  return { headerRowIndex: rowIndex, headers: orderedHeaders };
402
418
  }
403
419
  }
420
+ return { headerRowIndex: -1, headers: [] };
404
421
  }
405
422
  }
406
423
  // Annotate the CommonJS export names for ESM import in node:
package/package.json CHANGED
@@ -2,12 +2,15 @@
2
2
  "name": "@nocobase/plugin-action-import",
3
3
  "displayName": "Action: Import records",
4
4
  "displayName.zh-CN": "操作:导入记录",
5
+ "displayName.ru-RU": "Действие: Импорт записей",
5
6
  "description": "Import records using excel templates. You can configure which fields to import and templates will be generated automatically.",
7
+ "description.ru-RU": "Импорт записей с помощью шаблонов Excel: можно настроить, какие поля импортировать, шаблоны будут генерироваться автоматически.",
6
8
  "description.zh-CN": "使用 Excel 模板导入数据,可以配置导入哪些字段,自动生成模板。",
7
- "version": "2.0.0-alpha.5",
9
+ "version": "2.0.0-alpha.51",
8
10
  "license": "AGPL-3.0",
9
11
  "main": "./dist/server/index.js",
10
12
  "homepage": "https://docs.nocobase.com/handbook/action-import",
13
+ "homepage.ru-RU": "https://docs.nocobase.ru/handbook/action-import",
11
14
  "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-import",
12
15
  "devDependencies": {
13
16
  "@ant-design/icons": "5.x",
@@ -36,7 +39,7 @@
36
39
  "@nocobase/test": "2.x",
37
40
  "@nocobase/utils": "2.x"
38
41
  },
39
- "gitHead": "943e035bbec27f9ecfe8ce8857955945f20976f3",
42
+ "gitHead": "a1e34dd97f370d54f3d80a6b83ab7ddb9c72dc18",
40
43
  "keywords": [
41
44
  "Actions"
42
45
  ]