@nocobase/server 2.1.0-beta.15 → 2.1.0-beta.16

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.
@@ -39,59 +39,128 @@ 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 import_crypto = __toESM(require("crypto"));
51
+ var import_utils2 = require("../utils");
50
52
  var import_package = __toESM(require("../../../package.json"));
53
+ const PLUGIN_CLIENT_ENTRY_FILES = {
54
+ client: "dist/client/index.js",
55
+ "client-v2": "dist/client-v2/index.js"
56
+ };
57
+ const PLUGIN_CLIENT_MARKER_FILES = {
58
+ client: "client.js",
59
+ "client-v2": "client-v2.js"
60
+ };
51
61
  const _PackageUrls = class _PackageUrls {
52
- static async get(packageName) {
53
- if (!this.items[packageName]) {
54
- this.items[packageName] = await this.fetch(packageName);
62
+ static clear() {
63
+ this.items = {};
64
+ }
65
+ static getCacheKey(packageName, lane) {
66
+ return `${lane}:${packageName}`;
67
+ }
68
+ static async get(packageName, lane = "client") {
69
+ const cacheKey = this.getCacheKey(packageName, lane);
70
+ if (!this.items[cacheKey]) {
71
+ this.items[cacheKey] = await this.fetch(packageName, lane);
55
72
  }
56
- return this.items[packageName];
73
+ return this.items[cacheKey];
57
74
  }
58
- static async fetch(packageName) {
59
- const PLUGIN_CLIENT_ENTRY_FILE = "dist/client/index.js";
75
+ static async hasClientEntry(packageName, lane) {
60
76
  const pkgPath = import_path.default.resolve(process.env.NODE_MODULES_PATH, packageName);
61
- const r = await import_fs_extra.default.exists(pkgPath);
62
- if (r) {
63
- let t = "";
64
- const dist = import_path.default.resolve(pkgPath, PLUGIN_CLIENT_ENTRY_FILE);
65
- const distExists = await import_fs_extra.default.exists(dist);
66
- if (distExists) {
67
- const fsState = await import_fs_extra.default.stat(distExists ? dist : pkgPath);
68
- const appKey = process.env.APP_KEY || "";
69
- let version = "";
70
- try {
71
- const pkgJson = await import_fs_extra.default.readJson(import_path.default.resolve(pkgPath, "package.json"));
72
- if (pkgJson && typeof pkgJson.version === "string") {
73
- version = pkgJson.version;
74
- }
75
- } catch (error) {
77
+ if (!await import_fs_extra.default.exists(pkgPath)) {
78
+ return false;
79
+ }
80
+ return await import_fs_extra.default.exists(import_path.default.resolve(pkgPath, PLUGIN_CLIENT_MARKER_FILES[lane]));
81
+ }
82
+ static async fetch(packageName, lane = "client") {
83
+ const pluginClientEntryFile = PLUGIN_CLIENT_ENTRY_FILES[lane];
84
+ const pkgPath = import_path.default.resolve(process.env.NODE_MODULES_PATH, packageName);
85
+ const pkgExists = await import_fs_extra.default.exists(pkgPath);
86
+ if (!pkgExists) {
87
+ return;
88
+ }
89
+ let t = "";
90
+ const dist = import_path.default.resolve(pkgPath, pluginClientEntryFile);
91
+ const distExists = await import_fs_extra.default.exists(dist);
92
+ if (distExists) {
93
+ const fsState = await import_fs_extra.default.stat(dist);
94
+ const appKey = process.env.APP_KEY || "";
95
+ let version = "";
96
+ try {
97
+ const pkgJson = await import_fs_extra.default.readJson(import_path.default.resolve(pkgPath, "package.json"));
98
+ if (pkgJson && typeof pkgJson.version === "string") {
99
+ version = pkgJson.version;
76
100
  }
77
- const appVersion = import_package.default.version;
78
- const salt = process.env.PLUGIN_URL_HASH_SALT || "";
79
- const hash = import_crypto.default.createHash("sha256").update(fsState.mtime.getTime() + appKey + version + appVersion + salt).digest("hex").slice(0, 8);
80
- t = `?hash=${hash}`;
81
- }
82
- const cdnBaseUrl = process.env.CDN_BASE_URL.replace(/\/+$/, "");
83
- const url = `${cdnBaseUrl}${"/static/plugins/"}${packageName}/${PLUGIN_CLIENT_ENTRY_FILE}${t}`;
84
- return url;
101
+ } catch (error) {
102
+ }
103
+ const appVersion = import_package.default.version;
104
+ const salt = process.env.PLUGIN_URL_HASH_SALT || "";
105
+ const hash = import_crypto.default.createHash("sha256").update(fsState.mtime.getTime() + appKey + version + appVersion + salt).digest("hex").slice(0, 8);
106
+ t = `?hash=${hash}`;
85
107
  }
108
+ const cdnBaseUrl = process.env.CDN_BASE_URL.replace(/\/+$/, "");
109
+ const url = `${cdnBaseUrl}${"/static/plugins/"}${packageName}/${pluginClientEntryFile}${t}`;
110
+ return url;
86
111
  }
87
112
  };
88
113
  __name(_PackageUrls, "PackageUrls");
89
114
  __publicField(_PackageUrls, "items", {});
90
115
  let PackageUrls = _PackageUrls;
116
+ async function listEnabledPlugins(ctx, lane = "client") {
117
+ const pm = ctx.db.getRepository("applicationPlugins");
118
+ const items = await pm.find({
119
+ filter: {
120
+ enabled: true
121
+ }
122
+ });
123
+ const arr = [];
124
+ for (const item of items) {
125
+ if (lane === "client-v2" && !await PackageUrls.hasClientEntry(item.packageName, lane)) {
126
+ continue;
127
+ }
128
+ const url = await PackageUrls.get(item.packageName, lane);
129
+ const { name, packageName, options } = item.toJSON();
130
+ if (url) {
131
+ arr.push({
132
+ name,
133
+ packageName,
134
+ options,
135
+ url
136
+ });
137
+ }
138
+ }
139
+ return arr;
140
+ }
141
+ __name(listEnabledPlugins, "listEnabledPlugins");
142
+ function normalizePmPluginKeys(filterByTk) {
143
+ return filterByTk.split(",").map((k) => k.trim()).filter(Boolean);
144
+ }
145
+ __name(normalizePmPluginKeys, "normalizePmPluginKeys");
146
+ function coerceAwaitResponse(value) {
147
+ if (value === true || value === 1) {
148
+ return true;
149
+ }
150
+ if (typeof value === "string") {
151
+ const v = value.trim().toLowerCase();
152
+ return v === "true" || v === "1" || v === "yes";
153
+ }
154
+ return false;
155
+ }
156
+ __name(coerceAwaitResponse, "coerceAwaitResponse");
91
157
  var resource_default = {
92
158
  name: "pm",
93
159
  actions: {
94
160
  async add(ctx, next) {
161
+ if (process.env.DISABLE_PM_ADD === "true") {
162
+ ctx.throw(403, "The current environment does not allow adding plugins online");
163
+ }
95
164
  const app = ctx.app;
96
165
  const { values = {} } = ctx.action.params;
97
166
  if (values == null ? void 0 : values.packageName) {
@@ -107,12 +176,12 @@ var resource_default = {
107
176
  }
108
177
  app.runAsCLI(["pm", "add", values.packageName, ...args], { from: "user" });
109
178
  } else if (ctx.file) {
110
- const tmpDir = import_path.default.resolve(process.cwd(), "storage", "tmp");
179
+ const tmpDir = (0, import_utils.storagePathJoin)("tmp");
111
180
  try {
112
181
  await import_fs.default.promises.mkdir(tmpDir, { recursive: true });
113
182
  } catch (error) {
114
183
  }
115
- const tempFile = import_path.default.join(process.cwd(), "storage/tmp", (0, import_utils.uid)() + import_path.default.extname(ctx.file.originalname));
184
+ const tempFile = import_path.default.join(tmpDir, (0, import_utils.uid)() + import_path.default.extname(ctx.file.originalname));
116
185
  await import_fs.default.promises.writeFile(tempFile, ctx.file.buffer, "binary");
117
186
  app.runAsCLI(["pm", "add", tempFile], { from: "user" });
118
187
  } else if (values.compressedFileUrl) {
@@ -122,6 +191,9 @@ var resource_default = {
122
191
  await next();
123
192
  },
124
193
  async update(ctx, next) {
194
+ if (process.env.DISABLE_PM_ADD === "true") {
195
+ ctx.throw(403, "The current environment does not allow adding plugins online");
196
+ }
125
197
  const app = ctx.app;
126
198
  const values = ctx.action.params.values || {};
127
199
  const args = [];
@@ -136,12 +208,12 @@ var resource_default = {
136
208
  }
137
209
  if (ctx.file) {
138
210
  values.packageName = ctx.request.body.packageName;
139
- const tmpDir = import_path.default.resolve(process.cwd(), "storage", "tmp");
211
+ const tmpDir = (0, import_utils.storagePathJoin)("tmp");
140
212
  try {
141
213
  await import_fs.default.promises.mkdir(tmpDir, { recursive: true });
142
214
  } catch (error) {
143
215
  }
144
- const tempFile = import_path.default.join(process.cwd(), "storage/tmp", (0, import_utils.uid)() + import_path.default.extname(ctx.file.originalname));
216
+ const tempFile = import_path.default.join(tmpDir, (0, import_utils.uid)() + import_path.default.extname(ctx.file.originalname));
145
217
  await import_fs.default.promises.writeFile(tempFile, ctx.file.buffer, "binary");
146
218
  values.compressedFileUrl = tempFile;
147
219
  }
@@ -159,23 +231,46 @@ var resource_default = {
159
231
  await next();
160
232
  },
161
233
  async enable(ctx, next) {
162
- const { filterByTk } = ctx.action.params;
234
+ const { filterByTk, awaitResponse: awaitResponseRaw } = ctx.action.params;
163
235
  const app = ctx.app;
164
- if (!filterByTk) {
236
+ if (filterByTk == null || filterByTk === "" || typeof filterByTk !== "string") {
165
237
  ctx.throw(400, "plugin name invalid");
166
238
  }
167
- const keys = Array.isArray(filterByTk) ? filterByTk : [filterByTk];
168
- app.runAsCLI(["pm", "enable", ...keys], { from: "user" });
239
+ const keys = normalizePmPluginKeys(filterByTk);
240
+ if (!keys.length) {
241
+ ctx.throw(400, "plugin name invalid");
242
+ }
243
+ const awaitResponse = coerceAwaitResponse(awaitResponseRaw);
244
+ const argv = ["pm", "enable", ...keys];
245
+ if (awaitResponse) {
246
+ await app.runAsCLI(argv, { from: "user", throwError: true });
247
+ } else {
248
+ void app.runAsCLI(argv, { from: "user" }).catch((err) => {
249
+ app.log.error(err);
250
+ });
251
+ }
169
252
  ctx.body = filterByTk;
170
253
  await next();
171
254
  },
172
255
  async disable(ctx, next) {
173
- const { filterByTk } = ctx.action.params;
174
- if (!filterByTk) {
256
+ const { filterByTk, awaitResponse: awaitResponseRaw } = ctx.action.params;
257
+ const app = ctx.app;
258
+ if (filterByTk == null || filterByTk === "" || typeof filterByTk !== "string") {
175
259
  ctx.throw(400, "plugin name invalid");
176
260
  }
177
- const app = ctx.app;
178
- app.runAsCLI(["pm", "disable", filterByTk], { from: "user" });
261
+ const keys = normalizePmPluginKeys(filterByTk);
262
+ if (!keys.length) {
263
+ ctx.throw(400, "plugin name invalid");
264
+ }
265
+ const awaitResponse = coerceAwaitResponse(awaitResponseRaw);
266
+ const argv = ["pm", "disable", ...keys];
267
+ if (awaitResponse) {
268
+ await app.runAsCLI(argv, { from: "user", throwError: true });
269
+ } else {
270
+ void app.runAsCLI(argv, { from: "user" }).catch((err) => {
271
+ app.log.error(err);
272
+ });
273
+ }
179
274
  ctx.body = filterByTk;
180
275
  await next();
181
276
  },
@@ -190,6 +285,11 @@ var resource_default = {
190
285
  await next();
191
286
  },
192
287
  async list(ctx, next) {
288
+ const { mode } = ctx.action.params;
289
+ if (mode === "summary") {
290
+ ctx.body = await (0, import_utils2.pmListSummary)(ctx.app);
291
+ return next();
292
+ }
193
293
  const locale = ctx.getCurrentLocale();
194
294
  const pm = ctx.app.pm;
195
295
  const plugin = pm.get("nocobase");
@@ -197,29 +297,11 @@ var resource_default = {
197
297
  await next();
198
298
  },
199
299
  async listEnabled(ctx, next) {
200
- const toArr = /* @__PURE__ */ __name(async () => {
201
- const pm = ctx.db.getRepository("applicationPlugins");
202
- const items = await pm.find({
203
- filter: {
204
- enabled: true
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();
300
+ ctx.body = await listEnabledPlugins(ctx, "client");
301
+ await next();
302
+ },
303
+ async listEnabledV2(ctx, next) {
304
+ ctx.body = await listEnabledPlugins(ctx, "client-v2");
223
305
  await next();
224
306
  },
225
307
  async get(ctx, next) {
@@ -235,3 +317,7 @@ var resource_default = {
235
317
  }
236
318
  }
237
319
  };
320
+ // Annotate the CommonJS export names for ESM import in node:
321
+ 0 && (module.exports = {
322
+ PackageUrls
323
+ });
@@ -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 checkAndGetCompatible: typeof checkAndGetCompatible;
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
  */
@@ -90,6 +90,7 @@ const _PluginManager = class _PluginManager {
90
90
  this._repository.setPluginManager(this);
91
91
  this.app.resourcer.define(import_resource.default);
92
92
  this.app.acl.allow("pm", "listEnabled", "public");
93
+ this.app.acl.allow("pm", "listEnabledV2", "public");
93
94
  this.app.acl.registerSnippet({
94
95
  name: "pm",
95
96
  actions: ["pm:*"]
@@ -100,6 +101,23 @@ const _PluginManager = class _PluginManager {
100
101
  });
101
102
  this.app.resourceManager.use(import_middleware.uploadMiddleware, { tag: "upload", after: "acl" });
102
103
  }
104
+ static async checkAndGetCompatible(packageName) {
105
+ if (this.compatibleCache.has(packageName)) {
106
+ return this.compatibleCache.get(packageName);
107
+ }
108
+ const pending = this.compatiblePending.get(packageName);
109
+ if (pending) {
110
+ return pending;
111
+ }
112
+ const task = (0, import_utils2.checkAndGetCompatible)(packageName).then((compatible) => {
113
+ this.compatibleCache.set(packageName, compatible);
114
+ return compatible;
115
+ }).finally(() => {
116
+ this.compatiblePending.delete(packageName);
117
+ });
118
+ this.compatiblePending.set(packageName, task);
119
+ return task;
120
+ }
103
121
  /**
104
122
  * @internal
105
123
  */
@@ -757,7 +775,7 @@ const _PluginManager = class _PluginManager {
757
775
  if (process.env.VITEST) {
758
776
  return;
759
777
  }
760
- const file = (0, import_path.resolve)(process.cwd(), "storage/.upgrading");
778
+ const file = (0, import_utils.storagePathJoin)(".upgrading");
761
779
  this.app.log.debug("pending upgrade");
762
780
  await import_fs_extra.default.writeFile(file, "upgrading");
763
781
  }, "writeFile");
@@ -842,7 +860,7 @@ const _PluginManager = class _PluginManager {
842
860
  });
843
861
  return;
844
862
  }
845
- const file = (0, import_path.resolve)(process.cwd(), "storage/app-upgrading");
863
+ const file = (0, import_utils.storagePathJoin)("app-upgrading");
846
864
  await import_fs_extra.default.writeFile(file, "", "utf-8");
847
865
  await (0, import_helper.tsxRerunning)();
848
866
  await (0, import_execa.default)("yarn", ["nocobase", "pm2-restart"], {
@@ -1107,7 +1125,8 @@ const _PluginManager = class _PluginManager {
1107
1125
  }
1108
1126
  };
1109
1127
  __name(_PluginManager, "PluginManager");
1110
- __publicField(_PluginManager, "checkAndGetCompatible", import_utils2.checkAndGetCompatible);
1128
+ __publicField(_PluginManager, "compatibleCache", /* @__PURE__ */ new Map());
1129
+ __publicField(_PluginManager, "compatiblePending", /* @__PURE__ */ new Map());
1111
1130
  __publicField(_PluginManager, "parsedNames", {});
1112
1131
  let PluginManager = _PluginManager;
1113
1132
  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,6 @@ import { PluginData } from './types';
16
17
  * getTempDir() => '/tmp/nocobase'
17
18
  */
18
19
  export declare function getTempDir(): Promise<string>;
19
- export declare function getPluginStoragePath(): string;
20
20
  export declare function getLocalPluginPackagesPathArr(): string[];
21
21
  export declare function getStoragePluginDir(packageName: string): string;
22
22
  export declare function getLocalPluginDir(packageDirBasename: string): string;
@@ -112,4 +112,10 @@ export declare function checkAndGetCompatible(packageName: string): Promise<{
112
112
  depsCompatible: DepCompatible[];
113
113
  }>;
114
114
  export declare function getPluginBasePath(packageName: string): Promise<string>;
115
+ export declare function pmListSummary(app: Application): Promise<{
116
+ displayName: any;
117
+ packageName: any;
118
+ enabled: boolean;
119
+ description: any;
120
+ }[]>;
115
121
  export {};
@@ -59,12 +59,12 @@ __export(utils_exports, {
59
59
  getPackagesFromFiles: () => getPackagesFromFiles,
60
60
  getPluginBasePath: () => getPluginBasePath,
61
61
  getPluginInfoByNpm: () => getPluginInfoByNpm,
62
- getPluginStoragePath: () => getPluginStoragePath,
63
62
  getServerPackages: () => getServerPackages,
64
63
  getStoragePluginDir: () => getStoragePluginDir,
65
64
  getTempDir: () => getTempDir,
66
65
  isNotBuiltinModule: () => isNotBuiltinModule,
67
66
  isValidPackageName: () => isValidPackageName,
67
+ pmListSummary: () => pmListSummary,
68
68
  readJSONFileContent: () => readJSONFileContent,
69
69
  removePluginPackage: () => removePluginPackage,
70
70
  removeRequireCache: () => removeRequireCache,
@@ -88,17 +88,14 @@ var import_semver = __toESM(require("semver"));
88
88
  var import_clientStaticUtils = require("./clientStaticUtils");
89
89
  var import_constants = require("./constants");
90
90
  var import_deps = __toESM(require("./deps"));
91
+ var import_findPackageNames = require("./findPackageNames");
92
+ var import_plugin_manager = __toESM(require("./plugin-manager"));
91
93
  /* istanbul ignore next -- @preserve */
92
94
  async function getTempDir() {
93
95
  const temporaryDirectory = await import_fs_extra.default.realpath(import_os.default.tmpdir());
94
96
  return import_path.default.join(temporaryDirectory, import_constants.APP_NAME);
95
97
  }
96
98
  __name(getTempDir, "getTempDir");
97
- function getPluginStoragePath() {
98
- const pluginStoragePath = process.env.PLUGIN_STORAGE_PATH || import_constants.DEFAULT_PLUGIN_STORAGE_PATH;
99
- return import_path.default.isAbsolute(pluginStoragePath) ? pluginStoragePath : import_path.default.join(process.cwd(), pluginStoragePath);
100
- }
101
- __name(getPluginStoragePath, "getPluginStoragePath");
102
99
  function getLocalPluginPackagesPathArr() {
103
100
  const pluginPackagesPathArr = process.env.PLUGIN_PATH || import_constants.DEFAULT_PLUGIN_PATH;
104
101
  return pluginPackagesPathArr.split(",").map((pluginPackagesPath) => {
@@ -108,7 +105,7 @@ function getLocalPluginPackagesPathArr() {
108
105
  }
109
106
  __name(getLocalPluginPackagesPathArr, "getLocalPluginPackagesPathArr");
110
107
  function getStoragePluginDir(packageName) {
111
- const pluginStoragePath = getPluginStoragePath();
108
+ const pluginStoragePath = (0, import_utils.resolvePluginStoragePath)();
112
109
  return import_path.default.join(pluginStoragePath, packageName);
113
110
  }
114
111
  __name(getStoragePluginDir, "getStoragePluginDir");
@@ -525,6 +522,33 @@ async function getPluginBasePath(packageName) {
525
522
  return import_path.default.dirname(import_path.default.dirname(file));
526
523
  }
527
524
  __name(getPluginBasePath, "getPluginBasePath");
525
+ async function pmListSummary(app) {
526
+ const plugins1 = await (0, import_findPackageNames.findBuiltInPlugins)();
527
+ const plugins2 = await (0, import_findPackageNames.findLocalPlugins)();
528
+ let enabledPlugins = [];
529
+ try {
530
+ enabledPlugins = (await app.pm.repository.find({
531
+ filter: {
532
+ enabled: true
533
+ }
534
+ })).map((item) => item.packageName);
535
+ } catch (error) {
536
+ }
537
+ const items = await Promise.all(
538
+ [...plugins1, ...plugins2].map(async (name) => {
539
+ const item = await import_plugin_manager.default.parseName(name);
540
+ const json = await import_plugin_manager.default.getPackageJson(item.packageName);
541
+ return {
542
+ displayName: json.displayName || name,
543
+ packageName: item.packageName,
544
+ enabled: enabledPlugins.includes(item.packageName),
545
+ description: json.description
546
+ };
547
+ })
548
+ );
549
+ return items;
550
+ }
551
+ __name(pmListSummary, "pmListSummary");
528
552
  // Annotate the CommonJS export names for ESM import in node:
529
553
  0 && (module.exports = {
530
554
  checkAndGetCompatible,
@@ -549,12 +573,12 @@ __name(getPluginBasePath, "getPluginBasePath");
549
573
  getPackagesFromFiles,
550
574
  getPluginBasePath,
551
575
  getPluginInfoByNpm,
552
- getPluginStoragePath,
553
576
  getServerPackages,
554
577
  getStoragePluginDir,
555
578
  getTempDir,
556
579
  isNotBuiltinModule,
557
580
  isValidPackageName,
581
+ pmListSummary,
558
582
  readJSONFileContent,
559
583
  removePluginPackage,
560
584
  removeRequireCache,
package/lib/plugin.js CHANGED
@@ -206,6 +206,7 @@ const _Plugin = class _Plugin {
206
206
  return;
207
207
  }
208
208
  const toolsLoader = new import_ai.ToolsLoader(this.ai, {
209
+ pluginName: this.getName(),
209
210
  scan: {
210
211
  basePath,
211
212
  pattern: ["**/tools/**/*.ts", "**/tools/**/*.js", "!**/tools/**/*.d.ts", "**/tools/**/*/description.md"]
@@ -213,6 +214,37 @@ const _Plugin = class _Plugin {
213
214
  log: this.log
214
215
  });
215
216
  await toolsLoader.load();
217
+ const mcpLoader = new import_ai.MCPLoader(this.ai, {
218
+ pluginName: this.getName(),
219
+ scan: {
220
+ basePath,
221
+ pattern: ["mcp/*.ts", "mcp/*.js", "!mcp/*.d.ts"]
222
+ },
223
+ log: this.log
224
+ });
225
+ await mcpLoader.load();
226
+ const skillsLoader = new import_ai.SkillsLoader(this.ai, {
227
+ pluginName: this.getName(),
228
+ scan: { basePath, pattern: ["**/skills/**/SKILLS.md"] },
229
+ log: this.log
230
+ });
231
+ await skillsLoader.load();
232
+ const employeeLoader = new import_ai.AIEmployeeLoader(this.ai, {
233
+ pluginName: this.getName(),
234
+ scan: {
235
+ basePath,
236
+ pattern: [
237
+ "**/ai-employees/*.ts",
238
+ "**/ai-employees/*/index.ts",
239
+ "**/ai-employees/*.js",
240
+ "**/ai-employees/*/index.js",
241
+ "**/ai-employees/*/prompt.md",
242
+ "!**/ai-employees/**/*.d.ts"
243
+ ]
244
+ },
245
+ log: this.log
246
+ });
247
+ await employeeLoader.load();
216
248
  }
217
249
  /**
218
250
  * @deprecated
@@ -265,7 +297,7 @@ const _Plugin = class _Plugin {
265
297
  ...await (0, import_utils2.checkAndGetCompatible)(packageName),
266
298
  lastUpdated: (await import_fs.default.promises.stat(file)).ctime,
267
299
  file,
268
- updatable: file.startsWith(process.env.PLUGIN_STORAGE_PATH)
300
+ updatable: file.startsWith((0, import_utils.resolvePluginStoragePath)())
269
301
  };
270
302
  }
271
303
  return results;
@@ -0,0 +1,102 @@
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
+ declare const _default: {
10
+ readonly '/app:getLang': {
11
+ readonly get: {
12
+ readonly tags: readonly ["app"];
13
+ readonly summary: "Get the current application language";
14
+ readonly description: "Return the current locale used by the server.";
15
+ readonly parameters: readonly [];
16
+ readonly responses: {
17
+ readonly 200: {
18
+ readonly description: "OK";
19
+ readonly content: {
20
+ readonly 'application/json': {
21
+ readonly schema: {
22
+ readonly type: "string";
23
+ };
24
+ };
25
+ };
26
+ };
27
+ };
28
+ };
29
+ };
30
+ readonly '/app:getInfo': {
31
+ readonly get: {
32
+ readonly tags: readonly ["app"];
33
+ readonly summary: "Get application metadata";
34
+ readonly description: "Return basic application information, including version and environment-related metadata.";
35
+ readonly parameters: readonly [];
36
+ readonly responses: {
37
+ readonly 200: {
38
+ readonly description: "OK";
39
+ readonly content: {
40
+ readonly 'application/json': {
41
+ readonly schema: {
42
+ readonly type: "object";
43
+ readonly additionalProperties: true;
44
+ };
45
+ };
46
+ };
47
+ };
48
+ };
49
+ };
50
+ };
51
+ readonly '/app:getPlugins': {
52
+ readonly get: {
53
+ readonly tags: readonly ["app"];
54
+ readonly summary: "List loaded plugins";
55
+ readonly description: "Return plugin metadata for the current application runtime.";
56
+ readonly parameters: readonly [];
57
+ readonly responses: {
58
+ readonly 200: {
59
+ readonly description: "OK";
60
+ readonly content: {
61
+ readonly 'application/json': {
62
+ readonly schema: {
63
+ readonly type: "array";
64
+ readonly items: {
65
+ readonly type: "object";
66
+ readonly additionalProperties: true;
67
+ };
68
+ };
69
+ };
70
+ };
71
+ };
72
+ };
73
+ };
74
+ };
75
+ readonly '/app:restart': {
76
+ readonly post: {
77
+ readonly tags: readonly ["app"];
78
+ readonly summary: "Restart the application";
79
+ readonly description: "Trigger an application restart asynchronously.";
80
+ readonly parameters: readonly [];
81
+ readonly responses: {
82
+ readonly 200: {
83
+ readonly description: "OK";
84
+ };
85
+ };
86
+ };
87
+ };
88
+ readonly '/app:clearCache': {
89
+ readonly post: {
90
+ readonly tags: readonly ["app"];
91
+ readonly summary: "Clear application cache";
92
+ readonly description: "Clear server-side caches used by the current application instance.";
93
+ readonly parameters: readonly [];
94
+ readonly responses: {
95
+ readonly 200: {
96
+ readonly description: "OK";
97
+ };
98
+ };
99
+ };
100
+ };
101
+ };
102
+ export default _default;