@nocobase/server 2.1.0-beta.9 → 2.1.0
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/lib/acl/available-action.js +1 -1
- package/lib/aes-encryptor.js +3 -2
- package/lib/app-supervisor/app-options-factory.d.ts +1 -0
- package/lib/app-supervisor/index.d.ts +13 -5
- package/lib/app-supervisor/index.js +48 -13
- package/lib/app-supervisor/main-only-adapter.d.ts +3 -0
- package/lib/app-supervisor/main-only-adapter.js +7 -0
- package/lib/app-supervisor/types.d.ts +18 -3
- package/lib/application.d.ts +1 -2
- package/lib/application.js +3 -24
- package/lib/audit-manager/index.d.ts +2 -0
- package/lib/audit-manager/index.js +5 -2
- package/lib/commands/ai.js +1 -6
- package/lib/commands/create-migration.js +1 -1
- package/lib/commands/install.js +0 -4
- package/lib/commands/pm.js +7 -0
- package/lib/commands/start.js +2 -5
- package/lib/commands/upgrade.js +0 -4
- package/lib/{ai/create-docs-index.d.ts → constants.d.ts} +1 -5
- package/lib/constants.js +36 -0
- package/lib/event-queue.js +1 -1
- package/lib/gateway/index.d.ts +15 -3
- package/lib/gateway/index.js +180 -20
- package/lib/gateway/static-file-security.d.ts +10 -0
- package/lib/gateway/static-file-security.js +69 -0
- package/lib/gateway/utils.d.ts +19 -0
- package/lib/gateway/utils.js +128 -0
- package/lib/helpers/application-version.js +1 -0
- package/lib/index.d.ts +3 -1
- package/lib/index.js +5 -4
- package/lib/locale/locale.d.ts +24 -0
- package/lib/locale/locale.js +29 -5
- package/lib/main-data-source.js +12 -5
- package/lib/plugin-manager/constants.js +1 -1
- package/lib/plugin-manager/deps.js +3 -2
- package/lib/plugin-manager/findPackageNames.d.ts +5 -5
- package/lib/plugin-manager/findPackageNames.js +35 -58
- package/lib/plugin-manager/options/collection.js +1 -0
- package/lib/plugin-manager/options/resource.d.ts +12 -1
- package/lib/plugin-manager/options/resource.js +210 -65
- package/lib/plugin-manager/plugin-manager.d.ts +7 -2
- package/lib/plugin-manager/plugin-manager.js +59 -81
- package/lib/plugin-manager/utils.d.ts +9 -1
- package/lib/plugin-manager/utils.js +67 -9
- package/lib/plugin.js +33 -2
- package/lib/pub-sub-manager/handler-manager.d.ts +1 -0
- package/lib/pub-sub-manager/handler-manager.js +11 -0
- package/lib/pub-sub-manager/pub-sub-manager.js +2 -1
- package/lib/swagger/app.d.ts +102 -0
- package/lib/swagger/app.js +124 -0
- package/lib/swagger/base.d.ts +244 -0
- package/lib/swagger/base.js +292 -0
- package/lib/swagger/collections.d.ts +996 -0
- package/lib/swagger/collections.js +1264 -0
- package/lib/swagger/index.d.ts +1774 -0
- package/lib/swagger/index.js +70 -0
- package/lib/swagger/pm.d.ts +462 -0
- package/lib/swagger/pm.js +422 -0
- package/lib/sync-message-manager.js +8 -1
- package/lib/worker-mode.d.ts +19 -0
- package/lib/worker-mode.js +67 -0
- package/package.json +18 -18
- package/lib/ai/create-docs-index.js +0 -892
- package/lib/swagger/index.json +0 -1569
|
@@ -39,59 +39,193 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
39
39
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
40
40
|
var resource_exports = {};
|
|
41
41
|
__export(resource_exports, {
|
|
42
|
+
PackageUrls: () => PackageUrls,
|
|
42
43
|
default: () => resource_default
|
|
43
44
|
});
|
|
44
45
|
module.exports = __toCommonJS(resource_exports);
|
|
45
46
|
var import_utils = require("@nocobase/utils");
|
|
47
|
+
var import_crypto = __toESM(require("crypto"));
|
|
46
48
|
var import_fs = __toESM(require("fs"));
|
|
47
49
|
var import_fs_extra = __toESM(require("fs-extra"));
|
|
48
50
|
var import_path = __toESM(require("path"));
|
|
49
|
-
var
|
|
51
|
+
var import_plugin_manager = __toESM(require("../plugin-manager"));
|
|
52
|
+
var import_utils2 = require("../utils");
|
|
50
53
|
var import_package = __toESM(require("../../../package.json"));
|
|
54
|
+
const PLUGIN_CLIENT_ENTRY_FILES = {
|
|
55
|
+
client: "dist/client/index.js",
|
|
56
|
+
"client-v2": "dist/client-v2/index.js"
|
|
57
|
+
};
|
|
58
|
+
const PLUGIN_CLIENT_MARKER_FILES = {
|
|
59
|
+
client: "client.js",
|
|
60
|
+
"client-v2": "client-v2.js"
|
|
61
|
+
};
|
|
62
|
+
function getAppDevPluginUrls() {
|
|
63
|
+
if (process.env.NOCOBASE_APP_DEV !== "true" || !process.env.NOCOBASE_APP_DEV_PLUGIN_URLS) {
|
|
64
|
+
return {};
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
return JSON.parse(process.env.NOCOBASE_APP_DEV_PLUGIN_URLS);
|
|
68
|
+
} catch (error) {
|
|
69
|
+
return {};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
__name(getAppDevPluginUrls, "getAppDevPluginUrls");
|
|
73
|
+
function getAppDevPluginDependencies(packageJson2, lane) {
|
|
74
|
+
const appDevPluginUrls = getAppDevPluginUrls();
|
|
75
|
+
const deps = {
|
|
76
|
+
...packageJson2.dependencies,
|
|
77
|
+
...packageJson2.peerDependencies,
|
|
78
|
+
...packageJson2.devDependencies
|
|
79
|
+
};
|
|
80
|
+
return Object.keys(deps).filter(
|
|
81
|
+
(packageName) => {
|
|
82
|
+
var _a;
|
|
83
|
+
return ((_a = appDevPluginUrls[packageName]) == null ? void 0 : _a[lane]) || packageName.startsWith("@nocobase/plugin-") || packageName.startsWith("@nocobase/preset-");
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
__name(getAppDevPluginDependencies, "getAppDevPluginDependencies");
|
|
51
88
|
const _PackageUrls = class _PackageUrls {
|
|
52
|
-
static
|
|
53
|
-
|
|
54
|
-
|
|
89
|
+
static clear() {
|
|
90
|
+
this.items = {};
|
|
91
|
+
}
|
|
92
|
+
static getCacheKey(packageName, lane) {
|
|
93
|
+
return `${lane}:${packageName}`;
|
|
94
|
+
}
|
|
95
|
+
static async get(packageName, lane = "client") {
|
|
96
|
+
const appDevUrl = this.getAppDevUrl(packageName, lane);
|
|
97
|
+
if (appDevUrl) {
|
|
98
|
+
return appDevUrl;
|
|
99
|
+
}
|
|
100
|
+
const cacheKey = this.getCacheKey(packageName, lane);
|
|
101
|
+
const cached = this.items[cacheKey];
|
|
102
|
+
if (cached) {
|
|
103
|
+
return cached;
|
|
55
104
|
}
|
|
56
|
-
|
|
105
|
+
const nextUrl = await this.fetch(packageName, lane);
|
|
106
|
+
if (nextUrl == null ? void 0 : nextUrl.includes("?hash=")) {
|
|
107
|
+
this.items[cacheKey] = nextUrl;
|
|
108
|
+
} else {
|
|
109
|
+
delete this.items[cacheKey];
|
|
110
|
+
}
|
|
111
|
+
return nextUrl;
|
|
112
|
+
}
|
|
113
|
+
static getAppDevUrl(packageName, lane) {
|
|
114
|
+
var _a;
|
|
115
|
+
return (_a = getAppDevPluginUrls()[packageName]) == null ? void 0 : _a[lane];
|
|
57
116
|
}
|
|
58
|
-
static async
|
|
59
|
-
|
|
117
|
+
static async hasClientEntry(packageName, lane) {
|
|
118
|
+
if (this.getAppDevUrl(packageName, lane)) {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
60
121
|
const pkgPath = import_path.default.resolve(process.env.NODE_MODULES_PATH, packageName);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
122
|
+
if (!await import_fs_extra.default.exists(pkgPath)) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
return await import_fs_extra.default.exists(import_path.default.resolve(pkgPath, PLUGIN_CLIENT_MARKER_FILES[lane]));
|
|
126
|
+
}
|
|
127
|
+
static async fetch(packageName, lane = "client") {
|
|
128
|
+
const pluginClientEntryFile = PLUGIN_CLIENT_ENTRY_FILES[lane];
|
|
129
|
+
const pkgPath = import_path.default.resolve(process.env.NODE_MODULES_PATH, packageName);
|
|
130
|
+
const pkgExists = await import_fs_extra.default.exists(pkgPath);
|
|
131
|
+
if (!pkgExists) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
let t = "";
|
|
135
|
+
const dist = import_path.default.resolve(pkgPath, pluginClientEntryFile);
|
|
136
|
+
const distExists = await import_fs_extra.default.exists(dist);
|
|
137
|
+
if (distExists) {
|
|
138
|
+
const fsState = await import_fs_extra.default.stat(dist);
|
|
139
|
+
const appKey = process.env.APP_KEY || "";
|
|
140
|
+
let version = "";
|
|
141
|
+
try {
|
|
142
|
+
const pkgJson = await import_fs_extra.default.readJson(import_path.default.resolve(pkgPath, "package.json"));
|
|
143
|
+
if (pkgJson && typeof pkgJson.version === "string") {
|
|
144
|
+
version = pkgJson.version;
|
|
76
145
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const url = `${cdnBaseUrl}${"/static/plugins/"}${packageName}/${PLUGIN_CLIENT_ENTRY_FILE}${t}`;
|
|
84
|
-
return url;
|
|
146
|
+
} catch (error) {
|
|
147
|
+
}
|
|
148
|
+
const appVersion = import_package.default.version;
|
|
149
|
+
const salt = process.env.PLUGIN_URL_HASH_SALT || "";
|
|
150
|
+
const hash = import_crypto.default.createHash("sha256").update(fsState.mtime.getTime() + appKey + version + appVersion + salt).digest("hex").slice(0, 8);
|
|
151
|
+
t = `?hash=${hash}`;
|
|
85
152
|
}
|
|
153
|
+
const cdnBaseUrl = process.env.CDN_BASE_URL.replace(/\/+$/, "");
|
|
154
|
+
const url = `${cdnBaseUrl}${"/static/plugins/"}${packageName}/${pluginClientEntryFile}${t}`;
|
|
155
|
+
return url;
|
|
86
156
|
}
|
|
87
157
|
};
|
|
88
158
|
__name(_PackageUrls, "PackageUrls");
|
|
89
159
|
__publicField(_PackageUrls, "items", {});
|
|
90
160
|
let PackageUrls = _PackageUrls;
|
|
161
|
+
async function listEnabledPlugins(ctx, lane = "client") {
|
|
162
|
+
const pm = ctx.db.getRepository("applicationPlugins");
|
|
163
|
+
const items = await pm.find({
|
|
164
|
+
filter: {
|
|
165
|
+
enabled: true
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
const arr = [];
|
|
169
|
+
for (const item of items) {
|
|
170
|
+
if (lane === "client-v2" && !await PackageUrls.hasClientEntry(item.packageName, lane)) {
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
const url = await PackageUrls.get(item.packageName, lane);
|
|
174
|
+
const { name, packageName, options } = item.toJSON();
|
|
175
|
+
if (url) {
|
|
176
|
+
const entry = {
|
|
177
|
+
name,
|
|
178
|
+
packageName,
|
|
179
|
+
options,
|
|
180
|
+
url
|
|
181
|
+
};
|
|
182
|
+
if (PackageUrls.getAppDevUrl(packageName, lane)) {
|
|
183
|
+
const packageJson2 = await import_plugin_manager.default.getPackageJson(packageName);
|
|
184
|
+
entry.devMode = "esm";
|
|
185
|
+
entry.appDevDependencies = getAppDevPluginDependencies(packageJson2, lane);
|
|
186
|
+
}
|
|
187
|
+
if (lane === "client" && await PackageUrls.hasClientEntry(packageName, "client-v2")) {
|
|
188
|
+
const clientV2Url = await PackageUrls.get(packageName, "client-v2");
|
|
189
|
+
if (clientV2Url) {
|
|
190
|
+
entry.clientV2Url = clientV2Url;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
arr.push(entry);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return arr;
|
|
197
|
+
}
|
|
198
|
+
__name(listEnabledPlugins, "listEnabledPlugins");
|
|
199
|
+
function normalizePmPluginKeys(filterByTk) {
|
|
200
|
+
if (typeof filterByTk === "string") {
|
|
201
|
+
return filterByTk.split(",").map((k) => k.trim()).filter(Boolean);
|
|
202
|
+
}
|
|
203
|
+
if (!Array.isArray(filterByTk) || filterByTk.some((item) => typeof item !== "string")) {
|
|
204
|
+
return [];
|
|
205
|
+
}
|
|
206
|
+
return filterByTk.flatMap(
|
|
207
|
+
(item) => item.split(",").map((k) => k.trim()).filter(Boolean)
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
__name(normalizePmPluginKeys, "normalizePmPluginKeys");
|
|
211
|
+
function coerceAwaitResponse(value) {
|
|
212
|
+
if (value === true || value === 1) {
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
if (typeof value === "string") {
|
|
216
|
+
const v = value.trim().toLowerCase();
|
|
217
|
+
return v === "true" || v === "1" || v === "yes";
|
|
218
|
+
}
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
__name(coerceAwaitResponse, "coerceAwaitResponse");
|
|
91
222
|
var resource_default = {
|
|
92
223
|
name: "pm",
|
|
93
224
|
actions: {
|
|
94
225
|
async add(ctx, next) {
|
|
226
|
+
if (process.env.DISABLE_PM_ADD === "true") {
|
|
227
|
+
ctx.throw(403, "The current environment does not allow adding plugins online");
|
|
228
|
+
}
|
|
95
229
|
const app = ctx.app;
|
|
96
230
|
const { values = {} } = ctx.action.params;
|
|
97
231
|
if (values == null ? void 0 : values.packageName) {
|
|
@@ -107,12 +241,12 @@ var resource_default = {
|
|
|
107
241
|
}
|
|
108
242
|
app.runAsCLI(["pm", "add", values.packageName, ...args], { from: "user" });
|
|
109
243
|
} else if (ctx.file) {
|
|
110
|
-
const tmpDir =
|
|
244
|
+
const tmpDir = (0, import_utils.storagePathJoin)("tmp");
|
|
111
245
|
try {
|
|
112
246
|
await import_fs.default.promises.mkdir(tmpDir, { recursive: true });
|
|
113
247
|
} catch (error) {
|
|
114
248
|
}
|
|
115
|
-
const tempFile = import_path.default.join(
|
|
249
|
+
const tempFile = import_path.default.join(tmpDir, (0, import_utils.uid)() + import_path.default.extname(ctx.file.originalname));
|
|
116
250
|
await import_fs.default.promises.writeFile(tempFile, ctx.file.buffer, "binary");
|
|
117
251
|
app.runAsCLI(["pm", "add", tempFile], { from: "user" });
|
|
118
252
|
} else if (values.compressedFileUrl) {
|
|
@@ -122,6 +256,9 @@ var resource_default = {
|
|
|
122
256
|
await next();
|
|
123
257
|
},
|
|
124
258
|
async update(ctx, next) {
|
|
259
|
+
if (process.env.DISABLE_PM_ADD === "true") {
|
|
260
|
+
ctx.throw(403, "The current environment does not allow adding plugins online");
|
|
261
|
+
}
|
|
125
262
|
const app = ctx.app;
|
|
126
263
|
const values = ctx.action.params.values || {};
|
|
127
264
|
const args = [];
|
|
@@ -136,12 +273,12 @@ var resource_default = {
|
|
|
136
273
|
}
|
|
137
274
|
if (ctx.file) {
|
|
138
275
|
values.packageName = ctx.request.body.packageName;
|
|
139
|
-
const tmpDir =
|
|
276
|
+
const tmpDir = (0, import_utils.storagePathJoin)("tmp");
|
|
140
277
|
try {
|
|
141
278
|
await import_fs.default.promises.mkdir(tmpDir, { recursive: true });
|
|
142
279
|
} catch (error) {
|
|
143
280
|
}
|
|
144
|
-
const tempFile = import_path.default.join(
|
|
281
|
+
const tempFile = import_path.default.join(tmpDir, (0, import_utils.uid)() + import_path.default.extname(ctx.file.originalname));
|
|
145
282
|
await import_fs.default.promises.writeFile(tempFile, ctx.file.buffer, "binary");
|
|
146
283
|
values.compressedFileUrl = tempFile;
|
|
147
284
|
}
|
|
@@ -159,23 +296,40 @@ var resource_default = {
|
|
|
159
296
|
await next();
|
|
160
297
|
},
|
|
161
298
|
async enable(ctx, next) {
|
|
162
|
-
const { filterByTk } = ctx.action.params;
|
|
299
|
+
const { filterByTk, awaitResponse: awaitResponseRaw } = ctx.action.params;
|
|
163
300
|
const app = ctx.app;
|
|
164
|
-
|
|
301
|
+
const keys = normalizePmPluginKeys(filterByTk);
|
|
302
|
+
if (!keys.length) {
|
|
165
303
|
ctx.throw(400, "plugin name invalid");
|
|
166
304
|
}
|
|
167
|
-
const
|
|
168
|
-
|
|
305
|
+
const awaitResponse = coerceAwaitResponse(awaitResponseRaw);
|
|
306
|
+
const argv = ["pm", "enable", ...keys];
|
|
307
|
+
if (awaitResponse) {
|
|
308
|
+
await app.runAsCLI(argv, { from: "user", throwError: true });
|
|
309
|
+
} else {
|
|
310
|
+
void app.runAsCLI(argv, { from: "user" }).catch((err) => {
|
|
311
|
+
app.log.error(err);
|
|
312
|
+
});
|
|
313
|
+
}
|
|
169
314
|
ctx.body = filterByTk;
|
|
170
315
|
await next();
|
|
171
316
|
},
|
|
172
317
|
async disable(ctx, next) {
|
|
173
|
-
const { filterByTk } = ctx.action.params;
|
|
174
|
-
|
|
318
|
+
const { filterByTk, awaitResponse: awaitResponseRaw } = ctx.action.params;
|
|
319
|
+
const app = ctx.app;
|
|
320
|
+
const keys = normalizePmPluginKeys(filterByTk);
|
|
321
|
+
if (!keys.length) {
|
|
175
322
|
ctx.throw(400, "plugin name invalid");
|
|
176
323
|
}
|
|
177
|
-
const
|
|
178
|
-
|
|
324
|
+
const awaitResponse = coerceAwaitResponse(awaitResponseRaw);
|
|
325
|
+
const argv = ["pm", "disable", ...keys];
|
|
326
|
+
if (awaitResponse) {
|
|
327
|
+
await app.runAsCLI(argv, { from: "user", throwError: true });
|
|
328
|
+
} else {
|
|
329
|
+
void app.runAsCLI(argv, { from: "user" }).catch((err) => {
|
|
330
|
+
app.log.error(err);
|
|
331
|
+
});
|
|
332
|
+
}
|
|
179
333
|
ctx.body = filterByTk;
|
|
180
334
|
await next();
|
|
181
335
|
},
|
|
@@ -190,6 +344,11 @@ var resource_default = {
|
|
|
190
344
|
await next();
|
|
191
345
|
},
|
|
192
346
|
async list(ctx, next) {
|
|
347
|
+
const { mode } = ctx.action.params;
|
|
348
|
+
if (mode === "summary") {
|
|
349
|
+
ctx.body = await (0, import_utils2.pmListSummary)(ctx.app);
|
|
350
|
+
return next();
|
|
351
|
+
}
|
|
193
352
|
const locale = ctx.getCurrentLocale();
|
|
194
353
|
const pm = ctx.app.pm;
|
|
195
354
|
const plugin = pm.get("nocobase");
|
|
@@ -197,29 +356,11 @@ var resource_default = {
|
|
|
197
356
|
await next();
|
|
198
357
|
},
|
|
199
358
|
async listEnabled(ctx, next) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
const arr = [];
|
|
208
|
-
for (const item of items) {
|
|
209
|
-
const url = await PackageUrls.get(item.packageName);
|
|
210
|
-
const { name, packageName, options } = item.toJSON();
|
|
211
|
-
if (url) {
|
|
212
|
-
arr.push({
|
|
213
|
-
name,
|
|
214
|
-
packageName,
|
|
215
|
-
options,
|
|
216
|
-
url
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
return arr;
|
|
221
|
-
}, "toArr");
|
|
222
|
-
ctx.body = await toArr();
|
|
359
|
+
ctx.body = await listEnabledPlugins(ctx, "client");
|
|
360
|
+
await next();
|
|
361
|
+
},
|
|
362
|
+
async listEnabledV2(ctx, next) {
|
|
363
|
+
ctx.body = await listEnabledPlugins(ctx, "client-v2");
|
|
223
364
|
await next();
|
|
224
365
|
},
|
|
225
366
|
async get(ctx, next) {
|
|
@@ -235,3 +376,7 @@ var resource_default = {
|
|
|
235
376
|
}
|
|
236
377
|
}
|
|
237
378
|
};
|
|
379
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
380
|
+
0 && (module.exports = {
|
|
381
|
+
PackageUrls
|
|
382
|
+
});
|
|
@@ -13,7 +13,6 @@ import Application from '../application';
|
|
|
13
13
|
import { Plugin } from '../plugin';
|
|
14
14
|
import { PluginManagerRepository } from './plugin-manager-repository';
|
|
15
15
|
import { PluginData } from './types';
|
|
16
|
-
import { checkAndGetCompatible } from './utils';
|
|
17
16
|
export declare const sleep: (timeout?: number) => Promise<unknown>;
|
|
18
17
|
export interface PluginManagerOptions {
|
|
19
18
|
app: Application;
|
|
@@ -29,7 +28,12 @@ export declare class AddPresetError extends Error {
|
|
|
29
28
|
}
|
|
30
29
|
export declare class PluginManager {
|
|
31
30
|
options: PluginManagerOptions;
|
|
32
|
-
static
|
|
31
|
+
private static compatibleCache;
|
|
32
|
+
private static compatiblePending;
|
|
33
|
+
static checkAndGetCompatible(packageName: string): Promise<{
|
|
34
|
+
isCompatible: boolean;
|
|
35
|
+
depsCompatible: import("./utils").DepCompatible[];
|
|
36
|
+
}>;
|
|
33
37
|
/**
|
|
34
38
|
* @internal
|
|
35
39
|
*/
|
|
@@ -95,6 +99,7 @@ export declare class PluginManager {
|
|
|
95
99
|
create(pluginName: string, options?: {
|
|
96
100
|
forceRecreate?: boolean;
|
|
97
101
|
}): Promise<void>;
|
|
102
|
+
addOrThrow(plugin?: string | typeof Plugin, options?: any, insert?: boolean, isUpgrade?: boolean): Promise<void>;
|
|
98
103
|
add(plugin?: string | typeof Plugin, options?: any, insert?: boolean, isUpgrade?: boolean): Promise<void>;
|
|
99
104
|
/**
|
|
100
105
|
* @internal
|
|
@@ -57,6 +57,7 @@ var import_middleware = require("./middleware");
|
|
|
57
57
|
var import_collection = __toESM(require("./options/collection"));
|
|
58
58
|
var import_resource = __toESM(require("./options/resource"));
|
|
59
59
|
var import_plugin_manager_repository = require("./plugin-manager-repository");
|
|
60
|
+
var import_plugin_package = require("../../../utils/plugin-package");
|
|
60
61
|
var import_utils2 = require("./utils");
|
|
61
62
|
const _PluginLoadError = class _PluginLoadError extends Error {
|
|
62
63
|
constructor(pluginName) {
|
|
@@ -90,6 +91,7 @@ const _PluginManager = class _PluginManager {
|
|
|
90
91
|
this._repository.setPluginManager(this);
|
|
91
92
|
this.app.resourcer.define(import_resource.default);
|
|
92
93
|
this.app.acl.allow("pm", "listEnabled", "public");
|
|
94
|
+
this.app.acl.allow("pm", "listEnabledV2", "public");
|
|
93
95
|
this.app.acl.registerSnippet({
|
|
94
96
|
name: "pm",
|
|
95
97
|
actions: ["pm:*"]
|
|
@@ -100,6 +102,23 @@ const _PluginManager = class _PluginManager {
|
|
|
100
102
|
});
|
|
101
103
|
this.app.resourceManager.use(import_middleware.uploadMiddleware, { tag: "upload", after: "acl" });
|
|
102
104
|
}
|
|
105
|
+
static async checkAndGetCompatible(packageName) {
|
|
106
|
+
if (this.compatibleCache.has(packageName)) {
|
|
107
|
+
return this.compatibleCache.get(packageName);
|
|
108
|
+
}
|
|
109
|
+
const pending = this.compatiblePending.get(packageName);
|
|
110
|
+
if (pending) {
|
|
111
|
+
return pending;
|
|
112
|
+
}
|
|
113
|
+
const task = (0, import_utils2.checkAndGetCompatible)(packageName).then((compatible) => {
|
|
114
|
+
this.compatibleCache.set(packageName, compatible);
|
|
115
|
+
return compatible;
|
|
116
|
+
}).finally(() => {
|
|
117
|
+
this.compatiblePending.delete(packageName);
|
|
118
|
+
});
|
|
119
|
+
this.compatiblePending.set(packageName, task);
|
|
120
|
+
return task;
|
|
121
|
+
}
|
|
103
122
|
/**
|
|
104
123
|
* @internal
|
|
105
124
|
*/
|
|
@@ -137,7 +156,11 @@ const _PluginManager = class _PluginManager {
|
|
|
137
156
|
*/
|
|
138
157
|
static async getPackageJson(nameOrPkg) {
|
|
139
158
|
const { packageName } = await this.parseName(nameOrPkg);
|
|
140
|
-
const
|
|
159
|
+
const nodeModulesPath = String(process.env.NODE_MODULES_PATH ?? "").trim();
|
|
160
|
+
if (!nodeModulesPath) {
|
|
161
|
+
throw new Error("NODE_MODULES_PATH is not configured");
|
|
162
|
+
}
|
|
163
|
+
const packageFile = (0, import_path.resolve)(nodeModulesPath, packageName, "package.json");
|
|
141
164
|
if (!await import_fs_extra.default.exists(packageFile)) {
|
|
142
165
|
throw new Error(`Cannot find plugin '${nameOrPkg}'`);
|
|
143
166
|
}
|
|
@@ -158,9 +181,7 @@ const _PluginManager = class _PluginManager {
|
|
|
158
181
|
* @internal
|
|
159
182
|
*/
|
|
160
183
|
static getPluginPkgPrefix() {
|
|
161
|
-
return (
|
|
162
|
-
","
|
|
163
|
-
);
|
|
184
|
+
return (0, import_plugin_package.getPluginPackagePrefixes)();
|
|
164
185
|
}
|
|
165
186
|
/**
|
|
166
187
|
* @internal
|
|
@@ -215,32 +236,10 @@ const _PluginManager = class _PluginManager {
|
|
|
215
236
|
if (this.parsedNames[nameOrPkg]) {
|
|
216
237
|
return this.parsedNames[nameOrPkg];
|
|
217
238
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
};
|
|
223
|
-
return this.parsedNames[nameOrPkg];
|
|
224
|
-
}
|
|
225
|
-
if (nameOrPkg.startsWith("@nocobase/preset-")) {
|
|
226
|
-
this.parsedNames[nameOrPkg] = {
|
|
227
|
-
packageName: nameOrPkg,
|
|
228
|
-
name: nameOrPkg.replace("@nocobase/preset-", "")
|
|
229
|
-
};
|
|
230
|
-
return this.parsedNames[nameOrPkg];
|
|
231
|
-
}
|
|
232
|
-
const exists = /* @__PURE__ */ __name(async (name, isPreset = false) => {
|
|
233
|
-
return import_fs_extra.default.exists(
|
|
234
|
-
(0, import_path.resolve)(process.env.NODE_MODULES_PATH, `@nocobase/${isPreset ? "preset" : "plugin"}-${name}`, "package.json")
|
|
235
|
-
);
|
|
236
|
-
}, "exists");
|
|
237
|
-
if (await exists(nameOrPkg)) {
|
|
238
|
-
this.parsedNames[nameOrPkg] = { name: nameOrPkg, packageName: `@nocobase/plugin-${nameOrPkg}` };
|
|
239
|
-
} else if (await exists(nameOrPkg, true)) {
|
|
240
|
-
this.parsedNames[nameOrPkg] = { name: nameOrPkg, packageName: `@nocobase/preset-${nameOrPkg}` };
|
|
241
|
-
} else {
|
|
242
|
-
this.parsedNames[nameOrPkg] = { name: nameOrPkg, packageName: nameOrPkg };
|
|
243
|
-
}
|
|
239
|
+
this.parsedNames[nameOrPkg] = await (0, import_plugin_package.parsePluginName)(nameOrPkg, {
|
|
240
|
+
nodeModulesPath: process.env.NODE_MODULES_PATH,
|
|
241
|
+
pluginPackagePrefixes: this.getPluginPkgPrefix()
|
|
242
|
+
});
|
|
244
243
|
return this.parsedNames[nameOrPkg];
|
|
245
244
|
}
|
|
246
245
|
addPreset(plugin, options = {}) {
|
|
@@ -279,69 +278,46 @@ const _PluginManager = class _PluginManager {
|
|
|
279
278
|
}
|
|
280
279
|
/* istanbul ignore next -- @preserve */
|
|
281
280
|
async create(pluginName, options) {
|
|
282
|
-
const createPlugin = /* @__PURE__ */ __name(async (
|
|
283
|
-
const pluginDir = (0, import_path.resolve)(process.cwd(), "packages/plugins",
|
|
281
|
+
const createPlugin = /* @__PURE__ */ __name(async (name) => {
|
|
282
|
+
const pluginDir = (0, import_path.resolve)(process.cwd(), "packages/plugins", name);
|
|
284
283
|
if (options == null ? void 0 : options.forceRecreate) {
|
|
285
284
|
await import_fs_extra.default.rm(pluginDir, { recursive: true, force: true });
|
|
286
285
|
}
|
|
287
|
-
const { PluginGenerator } = require("@nocobase/cli/src/plugin-generator");
|
|
286
|
+
const { PluginGenerator } = require("@nocobase/cli-v1/src/plugin-generator");
|
|
288
287
|
const generator = new PluginGenerator({
|
|
289
288
|
cwd: process.cwd(),
|
|
290
289
|
args: {},
|
|
291
290
|
context: {
|
|
292
|
-
name
|
|
291
|
+
name
|
|
293
292
|
}
|
|
294
293
|
});
|
|
295
294
|
await generator.run();
|
|
296
295
|
}, "createPlugin");
|
|
297
296
|
await createPlugin(pluginName);
|
|
298
297
|
this.app.log.info("attempt to add the plugin to the app");
|
|
299
|
-
const { name, packageName } = await _PluginManager.parseName(pluginName);
|
|
300
|
-
const json = await _PluginManager.getPackageJson(packageName);
|
|
301
|
-
this.app.log.info(`add plugin [${packageName}]`, {
|
|
302
|
-
name,
|
|
303
|
-
packageName,
|
|
304
|
-
version: json.version
|
|
305
|
-
});
|
|
306
|
-
await (0, import_helper.tsxRerunning)();
|
|
307
298
|
}
|
|
308
|
-
async
|
|
299
|
+
async addOrThrow(plugin, options = {}, insert = false, isUpgrade = false) {
|
|
309
300
|
if (!isUpgrade && this.has(plugin)) {
|
|
310
301
|
const name = typeof plugin === "string" ? plugin : plugin.name;
|
|
311
|
-
|
|
312
|
-
return;
|
|
302
|
+
throw new Error(`plugin [${name}] already added`);
|
|
313
303
|
}
|
|
314
304
|
if (!options.name && typeof plugin === "string") {
|
|
315
305
|
options.name = plugin;
|
|
316
306
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
options["packageName"] = packageName;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
if (options.packageName) {
|
|
325
|
-
const packageJson = await _PluginManager.getPackageJson(options.packageName);
|
|
326
|
-
options["packageJson"] = packageJson;
|
|
327
|
-
options["version"] = packageJson.version;
|
|
307
|
+
if (typeof plugin === "string" && options.name && !options.packageName) {
|
|
308
|
+
const packageName = await _PluginManager.getPackageName(options.name);
|
|
309
|
+
if (packageName) {
|
|
310
|
+
options["packageName"] = packageName;
|
|
328
311
|
}
|
|
329
|
-
} catch (error) {
|
|
330
|
-
this.app.log.error(error);
|
|
331
|
-
console.error(error);
|
|
332
312
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
P = await _PluginManager.resolvePlugin(options.packageName || plugin, isUpgrade, !!options.packageName);
|
|
342
|
-
} catch (error) {
|
|
343
|
-
this.app.log.warn("plugin not found", error);
|
|
344
|
-
return;
|
|
313
|
+
if (options.packageName) {
|
|
314
|
+
const packageJson = await _PluginManager.getPackageJson(options.packageName);
|
|
315
|
+
options["packageJson"] = packageJson;
|
|
316
|
+
options["version"] = packageJson.version;
|
|
317
|
+
}
|
|
318
|
+
const P = await _PluginManager.resolvePlugin(options.packageName || plugin, isUpgrade, !!options.packageName);
|
|
319
|
+
if (!P) {
|
|
320
|
+
throw new Error(`plugin [${(options == null ? void 0 : options.name) || "unknown"}] load error`);
|
|
345
321
|
}
|
|
346
322
|
const instance = new P((0, import_helper.createAppProxy)(this.app), options);
|
|
347
323
|
this.pluginInstances.set(P, instance);
|
|
@@ -352,12 +328,13 @@ const _PluginManager = class _PluginManager {
|
|
|
352
328
|
this.pluginAliases.set(options.packageName, instance);
|
|
353
329
|
}
|
|
354
330
|
await instance.afterAdd();
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
331
|
+
}
|
|
332
|
+
async add(plugin, options = {}, insert = false, isUpgrade = false) {
|
|
333
|
+
try {
|
|
334
|
+
await this.addOrThrow(plugin, options, insert, isUpgrade);
|
|
335
|
+
} catch (error) {
|
|
336
|
+
this.app.log.error(error);
|
|
337
|
+
}
|
|
361
338
|
}
|
|
362
339
|
/**
|
|
363
340
|
* @internal
|
|
@@ -528,7 +505,7 @@ const _PluginManager = class _PluginManager {
|
|
|
528
505
|
added[pluginName] = true;
|
|
529
506
|
continue;
|
|
530
507
|
}
|
|
531
|
-
await this.
|
|
508
|
+
await this.addOrThrow(pluginName);
|
|
532
509
|
}
|
|
533
510
|
for (const name of pluginNames) {
|
|
534
511
|
const { name: pluginName } = await _PluginManager.parseName(name);
|
|
@@ -771,7 +748,7 @@ const _PluginManager = class _PluginManager {
|
|
|
771
748
|
if (process.env.VITEST) {
|
|
772
749
|
return;
|
|
773
750
|
}
|
|
774
|
-
const file = (0,
|
|
751
|
+
const file = (0, import_utils.storagePathJoin)(".upgrading");
|
|
775
752
|
this.app.log.debug("pending upgrade");
|
|
776
753
|
await import_fs_extra.default.writeFile(file, "upgrading");
|
|
777
754
|
}, "writeFile");
|
|
@@ -856,7 +833,7 @@ const _PluginManager = class _PluginManager {
|
|
|
856
833
|
});
|
|
857
834
|
return;
|
|
858
835
|
}
|
|
859
|
-
const file = (0,
|
|
836
|
+
const file = (0, import_utils.storagePathJoin)("app-upgrading");
|
|
860
837
|
await import_fs_extra.default.writeFile(file, "", "utf-8");
|
|
861
838
|
await (0, import_helper.tsxRerunning)();
|
|
862
839
|
await (0, import_execa.default)("yarn", ["nocobase", "pm2-restart"], {
|
|
@@ -1121,7 +1098,8 @@ const _PluginManager = class _PluginManager {
|
|
|
1121
1098
|
}
|
|
1122
1099
|
};
|
|
1123
1100
|
__name(_PluginManager, "PluginManager");
|
|
1124
|
-
__publicField(_PluginManager, "
|
|
1101
|
+
__publicField(_PluginManager, "compatibleCache", /* @__PURE__ */ new Map());
|
|
1102
|
+
__publicField(_PluginManager, "compatiblePending", /* @__PURE__ */ new Map());
|
|
1125
1103
|
__publicField(_PluginManager, "parsedNames", {});
|
|
1126
1104
|
let PluginManager = _PluginManager;
|
|
1127
1105
|
var plugin_manager_default = PluginManager;
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { AxiosRequestConfig } from 'axios';
|
|
10
10
|
import { PluginManagerRepository } from './plugin-manager-repository';
|
|
11
11
|
import { PluginData } from './types';
|
|
12
|
+
import Application from '../application';
|
|
12
13
|
/**
|
|
13
14
|
* get temp dir
|
|
14
15
|
*
|
|
@@ -16,7 +17,8 @@ import { PluginData } from './types';
|
|
|
16
17
|
* getTempDir() => '/tmp/nocobase'
|
|
17
18
|
*/
|
|
18
19
|
export declare function getTempDir(): Promise<string>;
|
|
19
|
-
export declare function
|
|
20
|
+
export declare function assertSafePluginPackageName(packageName: string): void;
|
|
21
|
+
export declare function resolveSafeChildPath(baseDir: string, child: string): string;
|
|
20
22
|
export declare function getLocalPluginPackagesPathArr(): string[];
|
|
21
23
|
export declare function getStoragePluginDir(packageName: string): string;
|
|
22
24
|
export declare function getLocalPluginDir(packageDirBasename: string): string;
|
|
@@ -112,4 +114,10 @@ export declare function checkAndGetCompatible(packageName: string): Promise<{
|
|
|
112
114
|
depsCompatible: DepCompatible[];
|
|
113
115
|
}>;
|
|
114
116
|
export declare function getPluginBasePath(packageName: string): Promise<string>;
|
|
117
|
+
export declare function pmListSummary(app: Application): Promise<{
|
|
118
|
+
displayName: any;
|
|
119
|
+
packageName: any;
|
|
120
|
+
enabled: boolean;
|
|
121
|
+
description: any;
|
|
122
|
+
}[]>;
|
|
115
123
|
export {};
|