@nocobase/plugin-action-import 1.0.0-alpha.9 → 1.0.1-alpha.2
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/dist/client/ImportActionInitializer.d.ts +1 -6
- package/dist/client/index.js +6 -6
- package/dist/client/useImportAction.d.ts +1 -0
- package/dist/externalVersion.js +9 -6
- package/dist/locale/en-US.json +3 -3
- package/dist/locale/es-ES.json +2 -2
- package/dist/locale/ko_KR.json +3 -3
- package/dist/locale/pt-BR.json +2 -2
- package/dist/locale/zh-CN.json +3 -3
- package/dist/node_modules/xlsx/bin/xlsx.njs +8 -0
- package/dist/node_modules/xlsx/bower.json +1 -1
- package/dist/node_modules/xlsx/dist/cpexcel.d.ts +39 -0
- package/dist/node_modules/xlsx/dist/xlsx.core.min.js +16 -17
- package/dist/node_modules/xlsx/dist/xlsx.extendscript.js +11207 -15096
- package/dist/node_modules/xlsx/dist/xlsx.full.min.js +23 -23
- package/dist/node_modules/xlsx/dist/xlsx.mini.min.js +9 -8
- package/dist/node_modules/xlsx/dist/xlsx.zahl.js +4 -0
- package/dist/node_modules/xlsx/dist/zahl.d.ts +4 -0
- package/dist/node_modules/xlsx/package.json +1 -1
- package/dist/node_modules/xlsx/types/index.d.ts +220 -40
- package/dist/node_modules/xlsx/xlsx.js +5 -4
- package/dist/node_modules/xlsx/xlsxworker.js +1 -2
- package/dist/server/actions/{downloadXlsxTemplate.js → download-xlsx-template.js} +13 -17
- package/dist/server/actions/import-xlsx.js +89 -0
- package/dist/server/actions/index.d.ts +2 -2
- package/dist/server/actions/index.js +4 -4
- package/dist/server/index.d.ts +1 -2
- package/dist/server/index.js +0 -6
- package/dist/server/services/template-creator.d.ts +24 -0
- package/dist/server/services/template-creator.js +70 -0
- package/dist/server/services/xlsx-importer.d.ts +37 -0
- package/dist/server/services/xlsx-importer.js +185 -0
- package/package.json +3 -3
- package/dist/node_modules/node-xlsx/lib/helpers.js +0 -142
- package/dist/node_modules/node-xlsx/lib/index.js +0 -6
- package/dist/node_modules/node-xlsx/lib/workbook.js +0 -16
- package/dist/node_modules/node-xlsx/package.json +0 -1
- package/dist/node_modules/xlsx/dist/jszip.js +0 -9000
- package/dist/node_modules/xlsx/dist/xlsx.js +0 -22693
- package/dist/node_modules/xlsx/dist/xlsx.min.js +0 -15
- package/dist/node_modules/xlsx/jszip.js +0 -9000
- package/dist/node_modules/xlsx/xlsx.mini.js +0 -10709
- package/dist/server/actions/importXlsx.js +0 -194
- /package/dist/server/actions/{downloadXlsxTemplate.d.ts → download-xlsx-template.d.ts} +0 -0
- /package/dist/server/actions/{importXlsx.d.ts → import-xlsx.d.ts} +0 -0
|
@@ -2,14 +2,13 @@
|
|
|
2
2
|
importScripts('dist/shim.min.js');
|
|
3
3
|
/* uncomment the next line for encoding support */
|
|
4
4
|
importScripts('dist/cpexcel.js');
|
|
5
|
-
importScripts('jszip.js');
|
|
6
5
|
importScripts('xlsx.js');
|
|
7
6
|
postMessage({t:"ready"});
|
|
8
7
|
|
|
9
8
|
onmessage = function (evt) {
|
|
10
9
|
var v;
|
|
11
10
|
try {
|
|
12
|
-
v = XLSX.read(evt.data.d, {type: evt.data.b});
|
|
11
|
+
v = XLSX.read(evt.data.d, {type: evt.data.b, codepage: evt.data.c});
|
|
13
12
|
postMessage({t:"xlsx", d:JSON.stringify(v)});
|
|
14
13
|
} catch(e) { postMessage({t:"e",d:e.stack||e}); }
|
|
15
14
|
};
|
|
@@ -34,33 +34,29 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
34
34
|
mod
|
|
35
35
|
));
|
|
36
36
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
|
-
var
|
|
38
|
-
__export(
|
|
37
|
+
var download_xlsx_template_exports = {};
|
|
38
|
+
__export(download_xlsx_template_exports, {
|
|
39
39
|
downloadXlsxTemplate: () => downloadXlsxTemplate
|
|
40
40
|
});
|
|
41
|
-
module.exports = __toCommonJS(
|
|
42
|
-
var
|
|
41
|
+
module.exports = __toCommonJS(download_xlsx_template_exports);
|
|
42
|
+
var import_template_creator = require("../services/template-creator");
|
|
43
|
+
var import_xlsx = __toESM(require("xlsx"));
|
|
43
44
|
async function downloadXlsxTemplate(ctx, next) {
|
|
44
45
|
let { columns } = ctx.request.body;
|
|
45
46
|
const { explain, title } = ctx.request.body;
|
|
46
47
|
if (typeof columns === "string") {
|
|
47
48
|
columns = JSON.parse(columns);
|
|
48
49
|
}
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
data,
|
|
58
|
-
options: {}
|
|
59
|
-
}
|
|
60
|
-
]);
|
|
50
|
+
const templateCreator = new import_template_creator.TemplateCreator({
|
|
51
|
+
explain,
|
|
52
|
+
title,
|
|
53
|
+
columns
|
|
54
|
+
});
|
|
55
|
+
const workbook = await templateCreator.run();
|
|
56
|
+
const buffer = import_xlsx.default.write(workbook, { type: "buffer", bookType: "xlsx" });
|
|
57
|
+
ctx.body = buffer;
|
|
61
58
|
ctx.set({
|
|
62
59
|
"Content-Type": "application/octet-stream",
|
|
63
|
-
// to avoid "invalid character" error in header (RFC)
|
|
64
60
|
"Content-Disposition": `attachment; filename=${encodeURIComponent(title)}.xlsx`
|
|
65
61
|
});
|
|
66
62
|
await next();
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __create = Object.create;
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
13
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
15
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __export = (target, all) => {
|
|
17
|
+
for (var name in all)
|
|
18
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
19
|
+
};
|
|
20
|
+
var __copyProps = (to, from, except, desc) => {
|
|
21
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
22
|
+
for (let key of __getOwnPropNames(from))
|
|
23
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
24
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
25
|
+
}
|
|
26
|
+
return to;
|
|
27
|
+
};
|
|
28
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
29
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
30
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
31
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
32
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
33
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
34
|
+
mod
|
|
35
|
+
));
|
|
36
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
|
+
var import_xlsx_exports = {};
|
|
38
|
+
__export(import_xlsx_exports, {
|
|
39
|
+
importXlsx: () => importXlsx
|
|
40
|
+
});
|
|
41
|
+
module.exports = __toCommonJS(import_xlsx_exports);
|
|
42
|
+
var import_xlsx = __toESM(require("xlsx"));
|
|
43
|
+
var import_xlsx_importer = require("../services/xlsx-importer");
|
|
44
|
+
var import_async_mutex = require("async-mutex");
|
|
45
|
+
const mutex = new import_async_mutex.Mutex();
|
|
46
|
+
const IMPORT_LIMIT_COUNT = 2e3;
|
|
47
|
+
async function importXlsxAction(ctx, next) {
|
|
48
|
+
let columns = ctx.request.body.columns;
|
|
49
|
+
if (typeof columns === "string") {
|
|
50
|
+
columns = JSON.parse(columns);
|
|
51
|
+
}
|
|
52
|
+
let readLimit = IMPORT_LIMIT_COUNT;
|
|
53
|
+
readLimit += 1;
|
|
54
|
+
if (ctx.request.body.explain) {
|
|
55
|
+
readLimit += 1;
|
|
56
|
+
}
|
|
57
|
+
const workbook = import_xlsx.default.read(ctx.file.buffer, {
|
|
58
|
+
type: "buffer",
|
|
59
|
+
sheetRows: readLimit
|
|
60
|
+
});
|
|
61
|
+
const repository = ctx.getCurrentRepository();
|
|
62
|
+
const dataSource = ctx.dataSource;
|
|
63
|
+
const collection = repository.collection;
|
|
64
|
+
const importer = new import_xlsx_importer.XlsxImporter({
|
|
65
|
+
collectionManager: dataSource.collectionManager,
|
|
66
|
+
collection,
|
|
67
|
+
columns,
|
|
68
|
+
workbook
|
|
69
|
+
});
|
|
70
|
+
const importedCount = await importer.run();
|
|
71
|
+
ctx.bodyMeta = { successCount: importedCount };
|
|
72
|
+
ctx.body = ctx.bodyMeta;
|
|
73
|
+
}
|
|
74
|
+
async function importXlsx(ctx, next) {
|
|
75
|
+
if (mutex.isLocked()) {
|
|
76
|
+
throw new Error(`another import action is running, please try again later.`);
|
|
77
|
+
}
|
|
78
|
+
const release = await mutex.acquire();
|
|
79
|
+
try {
|
|
80
|
+
await importXlsxAction(ctx, next);
|
|
81
|
+
} finally {
|
|
82
|
+
release();
|
|
83
|
+
}
|
|
84
|
+
await next();
|
|
85
|
+
}
|
|
86
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
87
|
+
0 && (module.exports = {
|
|
88
|
+
importXlsx
|
|
89
|
+
});
|
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
-
export * from './
|
|
10
|
-
export * from './
|
|
9
|
+
export * from './download-xlsx-template';
|
|
10
|
+
export * from './import-xlsx';
|
|
@@ -23,10 +23,10 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
|
|
|
23
23
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
24
24
|
var actions_exports = {};
|
|
25
25
|
module.exports = __toCommonJS(actions_exports);
|
|
26
|
-
__reExport(actions_exports, require("./
|
|
27
|
-
__reExport(actions_exports, require("./
|
|
26
|
+
__reExport(actions_exports, require("./download-xlsx-template"), module.exports);
|
|
27
|
+
__reExport(actions_exports, require("./import-xlsx"), module.exports);
|
|
28
28
|
// Annotate the CommonJS export names for ESM import in node:
|
|
29
29
|
0 && (module.exports = {
|
|
30
|
-
...require("./
|
|
31
|
-
...require("./
|
|
30
|
+
...require("./download-xlsx-template"),
|
|
31
|
+
...require("./import-xlsx")
|
|
32
32
|
});
|
package/dist/server/index.d.ts
CHANGED
|
@@ -6,10 +6,9 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
9
|
+
import { Plugin } from '@nocobase/server';
|
|
10
10
|
export declare class PluginActionImportServer extends Plugin {
|
|
11
11
|
beforeLoad(): void;
|
|
12
12
|
load(): Promise<void>;
|
|
13
|
-
install(options: InstallOptions): Promise<void>;
|
|
14
13
|
}
|
|
15
14
|
export default PluginActionImportServer;
|
package/dist/server/index.js
CHANGED
|
@@ -42,10 +42,6 @@ class PluginActionImportServer extends import_server.Plugin {
|
|
|
42
42
|
}
|
|
43
43
|
async load() {
|
|
44
44
|
this.app.dataSourceManager.afterAddDataSource((dataSource) => {
|
|
45
|
-
var _a;
|
|
46
|
-
if (!((_a = dataSource.collectionManager) == null ? void 0 : _a.db)) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
45
|
dataSource.resourceManager.use(import_middleware.importMiddleware);
|
|
50
46
|
dataSource.resourceManager.registerActionHandler("downloadXlsxTemplate", import_actions.downloadXlsxTemplate);
|
|
51
47
|
dataSource.resourceManager.registerActionHandler("importXlsx", import_actions.importXlsx);
|
|
@@ -58,8 +54,6 @@ class PluginActionImportServer extends import_server.Plugin {
|
|
|
58
54
|
dataSource.acl.allow("*", "downloadXlsxTemplate", "loggedIn");
|
|
59
55
|
});
|
|
60
56
|
}
|
|
61
|
-
async install(options) {
|
|
62
|
-
}
|
|
63
57
|
}
|
|
64
58
|
var server_default = PluginActionImportServer;
|
|
65
59
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
import { ICollection } from '@nocobase/data-source-manager';
|
|
10
|
+
import { ImportColumn } from './xlsx-importer';
|
|
11
|
+
import { WorkBook } from 'xlsx';
|
|
12
|
+
type TemplateCreatorOptions = {
|
|
13
|
+
collection?: ICollection;
|
|
14
|
+
title?: string;
|
|
15
|
+
explain?: string;
|
|
16
|
+
columns: Array<ImportColumn>;
|
|
17
|
+
};
|
|
18
|
+
export declare class TemplateCreator {
|
|
19
|
+
private options;
|
|
20
|
+
constructor(options: TemplateCreatorOptions);
|
|
21
|
+
run(): Promise<WorkBook>;
|
|
22
|
+
renderHeaders(): string[];
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __create = Object.create;
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
13
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
15
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __export = (target, all) => {
|
|
17
|
+
for (var name in all)
|
|
18
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
19
|
+
};
|
|
20
|
+
var __copyProps = (to, from, except, desc) => {
|
|
21
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
22
|
+
for (let key of __getOwnPropNames(from))
|
|
23
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
24
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
25
|
+
}
|
|
26
|
+
return to;
|
|
27
|
+
};
|
|
28
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
29
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
30
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
31
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
32
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
33
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
34
|
+
mod
|
|
35
|
+
));
|
|
36
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
|
+
var template_creator_exports = {};
|
|
38
|
+
__export(template_creator_exports, {
|
|
39
|
+
TemplateCreator: () => TemplateCreator
|
|
40
|
+
});
|
|
41
|
+
module.exports = __toCommonJS(template_creator_exports);
|
|
42
|
+
var import_xlsx = __toESM(require("xlsx"));
|
|
43
|
+
class TemplateCreator {
|
|
44
|
+
constructor(options) {
|
|
45
|
+
this.options = options;
|
|
46
|
+
}
|
|
47
|
+
async run() {
|
|
48
|
+
var _a;
|
|
49
|
+
const workbook = import_xlsx.default.utils.book_new();
|
|
50
|
+
const worksheet = import_xlsx.default.utils.sheet_new();
|
|
51
|
+
const data = [this.renderHeaders()];
|
|
52
|
+
if (this.options.explain && ((_a = this.options.explain) == null ? void 0 : _a.trim()) !== "") {
|
|
53
|
+
data.unshift([this.options.explain]);
|
|
54
|
+
}
|
|
55
|
+
import_xlsx.default.utils.sheet_add_aoa(worksheet, data, {
|
|
56
|
+
origin: "A1"
|
|
57
|
+
});
|
|
58
|
+
import_xlsx.default.utils.book_append_sheet(workbook, worksheet, "Sheet 1");
|
|
59
|
+
return workbook;
|
|
60
|
+
}
|
|
61
|
+
renderHeaders() {
|
|
62
|
+
return this.options.columns.map((col) => {
|
|
63
|
+
return col.defaultTitle;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
68
|
+
0 && (module.exports = {
|
|
69
|
+
TemplateCreator
|
|
70
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
import XLSX, { WorkBook } from 'xlsx';
|
|
10
|
+
import { ICollection, ICollectionManager } from '@nocobase/data-source-manager';
|
|
11
|
+
import { Transaction } from 'sequelize';
|
|
12
|
+
export type ImportColumn = {
|
|
13
|
+
dataIndex: Array<string>;
|
|
14
|
+
defaultTitle: string;
|
|
15
|
+
};
|
|
16
|
+
type ImporterOptions = {
|
|
17
|
+
collectionManager: ICollectionManager;
|
|
18
|
+
collection: ICollection;
|
|
19
|
+
columns: Array<ImportColumn>;
|
|
20
|
+
workbook: WorkBook;
|
|
21
|
+
chunkSize?: number;
|
|
22
|
+
explain?: string;
|
|
23
|
+
};
|
|
24
|
+
type RunOptions = {
|
|
25
|
+
transaction?: Transaction;
|
|
26
|
+
};
|
|
27
|
+
export declare class XlsxImporter {
|
|
28
|
+
private options;
|
|
29
|
+
constructor(options: ImporterOptions);
|
|
30
|
+
run(options?: RunOptions): Promise<number>;
|
|
31
|
+
resetSeq(options?: RunOptions): Promise<void>;
|
|
32
|
+
performImport(options?: RunOptions): Promise<number>;
|
|
33
|
+
trimString(str: string): string;
|
|
34
|
+
getData(): unknown[];
|
|
35
|
+
firstSheet(): XLSX.WorkSheet;
|
|
36
|
+
}
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __create = Object.create;
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
13
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
15
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __export = (target, all) => {
|
|
17
|
+
for (var name in all)
|
|
18
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
19
|
+
};
|
|
20
|
+
var __copyProps = (to, from, except, desc) => {
|
|
21
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
22
|
+
for (let key of __getOwnPropNames(from))
|
|
23
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
24
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
25
|
+
}
|
|
26
|
+
return to;
|
|
27
|
+
};
|
|
28
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
29
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
30
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
31
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
32
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
33
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
34
|
+
mod
|
|
35
|
+
));
|
|
36
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
|
+
var xlsx_importer_exports = {};
|
|
38
|
+
__export(xlsx_importer_exports, {
|
|
39
|
+
XlsxImporter: () => XlsxImporter
|
|
40
|
+
});
|
|
41
|
+
module.exports = __toCommonJS(xlsx_importer_exports);
|
|
42
|
+
var import_xlsx = __toESM(require("xlsx"));
|
|
43
|
+
var import_lodash = __toESM(require("lodash"));
|
|
44
|
+
class XlsxImporter {
|
|
45
|
+
constructor(options) {
|
|
46
|
+
this.options = options;
|
|
47
|
+
if (options.columns.length == 0) {
|
|
48
|
+
throw new Error(`columns is empty`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async run(options = {}) {
|
|
52
|
+
let transaction = options.transaction;
|
|
53
|
+
if (!transaction && this.options.collectionManager.db) {
|
|
54
|
+
transaction = options.transaction = await this.options.collectionManager.db.sequelize.transaction();
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const imported = await this.performImport(options);
|
|
58
|
+
if (this.options.collectionManager.db) {
|
|
59
|
+
await this.resetSeq(options);
|
|
60
|
+
}
|
|
61
|
+
transaction && await transaction.commit();
|
|
62
|
+
return imported;
|
|
63
|
+
} catch (error) {
|
|
64
|
+
transaction && await transaction.rollback();
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async resetSeq(options) {
|
|
69
|
+
const { transaction } = options;
|
|
70
|
+
const db = this.options.collectionManager.db;
|
|
71
|
+
const collection = this.options.collection;
|
|
72
|
+
const autoIncrementAttribute = collection.model.autoIncrementAttribute;
|
|
73
|
+
if (!autoIncrementAttribute) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
let tableInfo = collection.getTableNameWithSchema();
|
|
77
|
+
if (typeof tableInfo === "string") {
|
|
78
|
+
tableInfo = {
|
|
79
|
+
tableName: tableInfo
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const autoIncrInfo = await db.queryInterface.getAutoIncrementInfo({
|
|
83
|
+
tableInfo,
|
|
84
|
+
fieldName: autoIncrementAttribute,
|
|
85
|
+
transaction
|
|
86
|
+
});
|
|
87
|
+
const maxVal = await collection.model.max(autoIncrementAttribute, { transaction });
|
|
88
|
+
const queryInterface = db.queryInterface;
|
|
89
|
+
await queryInterface.setAutoIncrementVal({
|
|
90
|
+
tableInfo,
|
|
91
|
+
columnName: collection.model.rawAttributes[autoIncrementAttribute].field,
|
|
92
|
+
currentVal: maxVal,
|
|
93
|
+
seqName: autoIncrInfo.seqName,
|
|
94
|
+
transaction
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
async performImport(options) {
|
|
98
|
+
const transaction = options == null ? void 0 : options.transaction;
|
|
99
|
+
const rows = this.getData();
|
|
100
|
+
const chunks = import_lodash.default.chunk(rows, this.options.chunkSize || 200);
|
|
101
|
+
let handingRowIndex = 1;
|
|
102
|
+
if (this.options.explain) {
|
|
103
|
+
handingRowIndex += 1;
|
|
104
|
+
}
|
|
105
|
+
let imported = 0;
|
|
106
|
+
for (const chunkRows of chunks) {
|
|
107
|
+
for (const row of chunkRows) {
|
|
108
|
+
const rowValues = {};
|
|
109
|
+
handingRowIndex += 1;
|
|
110
|
+
try {
|
|
111
|
+
for (let index = 0; index < this.options.columns.length; index++) {
|
|
112
|
+
const column = this.options.columns[index];
|
|
113
|
+
const field = this.options.collection.getField(column.dataIndex[0]);
|
|
114
|
+
if (!field) {
|
|
115
|
+
throw new Error(`Field not found: ${column.dataIndex[0]}`);
|
|
116
|
+
}
|
|
117
|
+
const str = row[index];
|
|
118
|
+
const dataKey = column.dataIndex[0];
|
|
119
|
+
const fieldOptions = field.options;
|
|
120
|
+
const interfaceName = fieldOptions.interface;
|
|
121
|
+
const InterfaceClass = this.options.collectionManager.getFieldInterface(interfaceName);
|
|
122
|
+
if (!InterfaceClass) {
|
|
123
|
+
rowValues[dataKey] = str;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const interfaceInstance = new InterfaceClass(field.options);
|
|
127
|
+
const ctx = {
|
|
128
|
+
transaction,
|
|
129
|
+
field
|
|
130
|
+
};
|
|
131
|
+
if (column.dataIndex.length > 1) {
|
|
132
|
+
ctx.targetCollection = field.targetCollection();
|
|
133
|
+
ctx.filterKey = column.dataIndex[1];
|
|
134
|
+
}
|
|
135
|
+
rowValues[dataKey] = await interfaceInstance.toValue(this.trimString(str), ctx);
|
|
136
|
+
}
|
|
137
|
+
await this.options.collection.repository.create({
|
|
138
|
+
values: rowValues,
|
|
139
|
+
transaction
|
|
140
|
+
});
|
|
141
|
+
imported += 1;
|
|
142
|
+
await new Promise((resolve) => setTimeout(resolve, 5));
|
|
143
|
+
} catch (error) {
|
|
144
|
+
console.log(error);
|
|
145
|
+
throw new Error(
|
|
146
|
+
`failed to import row ${handingRowIndex}, rowData: ${JSON.stringify(rowValues)} message: ${error.message}`,
|
|
147
|
+
{ cause: error }
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
152
|
+
}
|
|
153
|
+
return imported;
|
|
154
|
+
}
|
|
155
|
+
trimString(str) {
|
|
156
|
+
if (typeof str === "string") {
|
|
157
|
+
return str.trim();
|
|
158
|
+
}
|
|
159
|
+
return str;
|
|
160
|
+
}
|
|
161
|
+
getData() {
|
|
162
|
+
const firstSheet = this.firstSheet();
|
|
163
|
+
const rows = import_xlsx.default.utils.sheet_to_json(firstSheet, { header: 1, defval: null, raw: false });
|
|
164
|
+
if (this.options.explain) {
|
|
165
|
+
rows.shift();
|
|
166
|
+
}
|
|
167
|
+
const headers = rows[0];
|
|
168
|
+
const columns = this.options.columns;
|
|
169
|
+
for (let i = 0; i < columns.length; i++) {
|
|
170
|
+
const column = columns[i];
|
|
171
|
+
if (column.defaultTitle !== headers[i]) {
|
|
172
|
+
throw new Error(`Invalid header: ${column.defaultTitle} !== ${headers[i]}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
rows.shift();
|
|
176
|
+
return rows;
|
|
177
|
+
}
|
|
178
|
+
firstSheet() {
|
|
179
|
+
return this.options.workbook.Sheets[this.options.workbook.SheetNames[0]];
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
183
|
+
0 && (module.exports = {
|
|
184
|
+
XlsxImporter
|
|
185
|
+
});
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"displayName.zh-CN": "操作:导入记录",
|
|
5
5
|
"description": "Import records using excel templates. You can configure which fields to import and templates will be generated automatically.",
|
|
6
6
|
"description.zh-CN": "使用 Excel 模板导入数据,可以配置导入哪些字段,自动生成模板。",
|
|
7
|
-
"version": "1.0.
|
|
7
|
+
"version": "1.0.1-alpha.2",
|
|
8
8
|
"license": "AGPL-3.0",
|
|
9
9
|
"main": "./dist/server/index.js",
|
|
10
10
|
"homepage": "https://docs.nocobase.com/handbook/action-import",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"react": "^18.2.0",
|
|
25
25
|
"react-dom": "^18.2.0",
|
|
26
26
|
"react-i18next": "^11.15.1",
|
|
27
|
-
"xlsx": "
|
|
27
|
+
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"@nocobase/actions": "1.x",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@nocobase/test": "1.x",
|
|
35
35
|
"@nocobase/utils": "1.x"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "fc5a8e3c812516f787cb22d3d198f058f45b1963",
|
|
38
38
|
"keywords": [
|
|
39
39
|
"Actions"
|
|
40
40
|
]
|