@nocobase/server 2.1.0-alpha.12 → 2.1.0-alpha.14

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.
@@ -50,7 +50,7 @@ const availableActions = {
50
50
  view: {
51
51
  displayName: '{{t("View")}}',
52
52
  type: "old-data",
53
- aliases: ["get", "list"],
53
+ aliases: ["get", "list", "query"],
54
54
  allowConfigureFields: true
55
55
  },
56
56
  update: {
@@ -47,6 +47,7 @@ var import_lodash = __toESM(require("lodash"));
47
47
  var import_utils = require("@nocobase/utils");
48
48
  var import_events = require("events");
49
49
  var import_application = __toESM(require("../application"));
50
+ var import_worker_mode = require("../worker-mode");
50
51
  var import_main_only_adapter = require("./main-only-adapter");
51
52
  var import_handler = require("../errors/handler");
52
53
  var import_condition_registry = require("./condition-registry");
@@ -288,6 +289,10 @@ const _AppSupervisor = class _AppSupervisor extends import_events.EventEmitter {
288
289
  return this.discoveryAdapter.getAppStatus(appName, defaultStatus);
289
290
  }
290
291
  async setAppStatus(appName, status, options = {}) {
292
+ if ((0, import_worker_mode.isTransient)()) {
293
+ this.logger.debug("App running as worker, status will not be set", { appName, status });
294
+ return;
295
+ }
291
296
  this.logger.debug("Setting app status", { appName, status });
292
297
  return this.discoveryAdapter.setAppStatus(appName, status, options);
293
298
  }
@@ -329,7 +334,7 @@ const _AppSupervisor = class _AppSupervisor extends import_events.EventEmitter {
329
334
  };
330
335
  }
331
336
  const app = new import_application.default(options);
332
- if (hook ?? app.serving()) {
337
+ if (hook ?? !(0, import_worker_mode.isTransient)()) {
333
338
  app.on("afterStart", async () => {
334
339
  await this.sendSyncMessage(mainApp, {
335
340
  type: "app:started",
@@ -356,6 +361,9 @@ const _AppSupervisor = class _AppSupervisor extends import_events.EventEmitter {
356
361
  this.registerCommandHandler(app);
357
362
  app.on("afterStart", async (app2) => {
358
363
  var _a, _b;
364
+ if ((0, import_worker_mode.isTransient)()) {
365
+ return;
366
+ }
359
367
  await app2.syncMessageManager.subscribe(
360
368
  "app_supervisor:sync",
361
369
  async (message) => {
@@ -390,6 +398,9 @@ const _AppSupervisor = class _AppSupervisor extends import_events.EventEmitter {
390
398
  }
391
399
  });
392
400
  app.on("afterDestroy", async (app2) => {
401
+ if ((0, import_worker_mode.isTransient)()) {
402
+ return;
403
+ }
393
404
  await this.unregisterEnvironment();
394
405
  });
395
406
  return app;
@@ -586,7 +597,7 @@ const _AppSupervisor = class _AppSupervisor extends import_events.EventEmitter {
586
597
  return super.on(eventName, listener);
587
598
  }
588
599
  bindAppEvents(app) {
589
- if (!app.serving()) {
600
+ if ((0, import_worker_mode.isTransient)()) {
590
601
  return;
591
602
  }
592
603
  app.on("afterDestroy", async () => {
@@ -270,8 +270,7 @@ export declare class Application<StateT = DefaultState, ContextT = DefaultContex
270
270
  protected _aesEncryptor: AesEncryptor;
271
271
  get aesEncryptor(): AesEncryptor;
272
272
  /**
273
- * Check if the application is serving as a specific worker.
274
- * @experimental
273
+ * @deprecated use {@link serving} from './worker-mode' instead.
275
274
  */
276
275
  serving(key?: string): boolean;
277
276
  /**
@@ -87,6 +87,7 @@ var import_redis_connection_manager = require("./redis-connection-manager");
87
87
  var import_service_container = require("./service-container");
88
88
  var import_snowflake_id_field = require("./snowflake-id-field");
89
89
  var import_worker_id_allocator = require("./worker-id-allocator");
90
+ var import_worker_mode = require("./worker-mode");
90
91
  const _Application = class _Application extends import_koa.default {
91
92
  constructor(options) {
92
93
  super();
@@ -282,32 +283,10 @@ const _Application = class _Application extends import_koa.default {
282
283
  return this._aesEncryptor;
283
284
  }
284
285
  /**
285
- * Check if the application is serving as a specific worker.
286
- * @experimental
286
+ * @deprecated use {@link serving} from './worker-mode' instead.
287
287
  */
288
288
  serving(key) {
289
- const { WORKER_MODE = "" } = process.env;
290
- if (!WORKER_MODE) {
291
- return true;
292
- }
293
- if (WORKER_MODE === "-") {
294
- return false;
295
- }
296
- const topics = WORKER_MODE.trim().split(",");
297
- if (key) {
298
- if (WORKER_MODE === "*") {
299
- return true;
300
- }
301
- if (topics.includes(key)) {
302
- return true;
303
- }
304
- return false;
305
- } else {
306
- if (topics.includes("!")) {
307
- return true;
308
- }
309
- return false;
310
- }
289
+ return (0, import_worker_mode.serving)(key);
311
290
  }
312
291
  /**
313
292
  * @internal
@@ -19,6 +19,7 @@ import { IPCSocketClient } from './ipc-socket-client';
19
19
  import { IPCSocketServer } from './ipc-socket-server';
20
20
  import { WSServer } from './ws-server';
21
21
  import { Duplex } from 'node:stream';
22
+ export { getHost, getHostname } from './utils';
22
23
  export interface IncomingRequest {
23
24
  url: string;
24
25
  headers: any;
@@ -40,7 +41,7 @@ interface RunOptions {
40
41
  mainAppOptions: ApplicationOptions;
41
42
  }
42
43
  export interface AppSelectorMiddlewareContext {
43
- req: IncomingRequest;
44
+ req: IncomingMessage | IncomingRequest;
44
45
  resolvedAppName: string | null;
45
46
  }
46
47
  export declare class Gateway extends EventEmitter {
@@ -86,7 +87,7 @@ export declare class Gateway extends EventEmitter {
86
87
  private renderV2IndexHtml;
87
88
  requestHandler(req: IncomingMessage, res: ServerResponse): Promise<void>;
88
89
  getAppSelectorMiddlewares(): Toposort<AppSelectorMiddleware>;
89
- getRequestHandleAppName(req: IncomingRequest): Promise<string>;
90
+ getRequestHandleAppName(req: IncomingMessage | IncomingRequest): Promise<string>;
90
91
  getCallback(): any;
91
92
  watch(): Promise<void>;
92
93
  run(options: RunOptions): Promise<void>;
@@ -106,4 +107,3 @@ export declare class Gateway extends EventEmitter {
106
107
  static registerWsHandler(wsServer: (req: IncomingMessage, socket: Duplex, head: Buffer, app: Application) => boolean | void): void;
107
108
  static unregisterWsHandler(wsServer: (req: IncomingMessage, socket: Duplex, head: Buffer, app: Application) => boolean | void): void;
108
109
  }
109
- export {};
@@ -39,7 +39,9 @@ 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 gateway_exports = {};
41
41
  __export(gateway_exports, {
42
- Gateway: () => Gateway
42
+ Gateway: () => Gateway,
43
+ getHost: () => import_utils4.getHost,
44
+ getHostname: () => import_utils4.getHostname
43
45
  });
44
46
  module.exports = __toCommonJS(gateway_exports);
45
47
  var import_logger = require("@nocobase/logger");
@@ -67,6 +69,7 @@ var import_utils3 = require("./utils");
67
69
  var import_ws_server = require("./ws-server");
68
70
  var import_node_worker_threads = require("node:worker_threads");
69
71
  var import_node_process = __toESM(require("node:process"));
72
+ var import_utils4 = require("./utils");
70
73
  const compress = (0, import_node_util.promisify)((0, import_compression.default)());
71
74
  function normalizeBasePath(path = "") {
72
75
  const normalized = path.replace(/\/+/g, "/").replace(/\/$/, "");
@@ -164,12 +167,12 @@ const _Gateway = class _Gateway extends import_events.EventEmitter {
164
167
  const appName = (_a = import_qs.default.parse(parsedUrl.query)) == null ? void 0 : _a.__appName;
165
168
  const apiBasePath = normalizeBasePath(import_node_process.default.env.API_BASE_PATH || "/api");
166
169
  const appPathPrefix = `${apiBasePath}/__app/`;
167
- if (appName) {
168
- ctx.resolvedAppName = appName;
169
- }
170
170
  if (req.headers["x-app"]) {
171
171
  ctx.resolvedAppName = req.headers["x-app"];
172
172
  }
173
+ if (appName) {
174
+ ctx.resolvedAppName = appName;
175
+ }
173
176
  if ((_b = parsedUrl.pathname) == null ? void 0 : _b.startsWith(appPathPrefix)) {
174
177
  const restPath = parsedUrl.pathname.slice(appPathPrefix.length);
175
178
  const [pathAppName, ...segments] = restPath.split("/");
@@ -655,5 +658,7 @@ __publicField(_Gateway, "wsServers", []);
655
658
  let Gateway = _Gateway;
656
659
  // Annotate the CommonJS export names for ESM import in node:
657
660
  0 && (module.exports = {
658
- Gateway
661
+ Gateway,
662
+ getHost,
663
+ getHostname
659
664
  });
@@ -6,7 +6,12 @@
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
+ /// <reference types="node" />
10
+ import { IncomingMessage } from 'http';
11
+ import { IncomingRequest } from '.';
9
12
  export declare function resolvePublicPath(appPublicPath?: string): string;
10
13
  export declare function resolveV2PublicPath(appPublicPath?: string): string;
11
14
  export declare function rewriteV2AssetPublicPath(html: string, assetPublicPath: string): string;
12
15
  export declare function injectRuntimeScript(html: string, runtimeScript: string): string;
16
+ export declare function getHost(req: IncomingMessage | IncomingRequest): any;
17
+ export declare function getHostname(req: IncomingMessage | IncomingRequest): any;
@@ -27,6 +27,8 @@ var __copyProps = (to, from, except, desc) => {
27
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
28
  var utils_exports = {};
29
29
  __export(utils_exports, {
30
+ getHost: () => getHost,
31
+ getHostname: () => getHostname,
30
32
  injectRuntimeScript: () => injectRuntimeScript,
31
33
  resolvePublicPath: () => resolvePublicPath,
32
34
  resolveV2PublicPath: () => resolveV2PublicPath,
@@ -75,8 +77,37 @@ ${moduleScriptMatch[0]}`);
75
77
  ${html}`;
76
78
  }
77
79
  __name(injectRuntimeScript, "injectRuntimeScript");
80
+ function splitCommaSeparatedValues(value, limit) {
81
+ return value.split(",", limit).map((v) => v.trim());
82
+ }
83
+ __name(splitCommaSeparatedValues, "splitCommaSeparatedValues");
84
+ function getHost(req) {
85
+ let host = req.headers["x-forwarded-host"];
86
+ if (!host) {
87
+ host = req.headers[":authority"] || req.headers["host"];
88
+ }
89
+ if (!host) return "";
90
+ host = splitCommaSeparatedValues(host, 1)[0];
91
+ if (host.includes("@")) {
92
+ try {
93
+ host = new URL(`http://${host}`).host;
94
+ } catch (e) {
95
+ return "";
96
+ }
97
+ }
98
+ return host;
99
+ }
100
+ __name(getHost, "getHost");
101
+ function getHostname(req) {
102
+ const host = getHost(req);
103
+ if (!host) return "";
104
+ return host.split(":", 1)[0];
105
+ }
106
+ __name(getHostname, "getHostname");
78
107
  // Annotate the CommonJS export names for ESM import in node:
79
108
  0 && (module.exports = {
109
+ getHost,
110
+ getHostname,
80
111
  injectRuntimeScript,
81
112
  resolvePublicPath,
82
113
  resolveV2PublicPath,
package/lib/index.d.ts CHANGED
@@ -20,6 +20,7 @@ export * from './plugin-manager';
20
20
  export * from './pub-sub-manager';
21
21
  export * from './event-queue';
22
22
  export * from './worker-id-allocator';
23
+ export * from './worker-mode';
23
24
  export * from './redis-connection-manager';
24
25
  export * from './main-data-source';
25
26
  export declare const OFFICIAL_PLUGIN_PREFIX = "@nocobase/plugin-";
package/lib/index.js CHANGED
@@ -63,6 +63,7 @@ __reExport(src_exports, require("./plugin-manager"), module.exports);
63
63
  __reExport(src_exports, require("./pub-sub-manager"), module.exports);
64
64
  __reExport(src_exports, require("./event-queue"), module.exports);
65
65
  __reExport(src_exports, require("./worker-id-allocator"), module.exports);
66
+ __reExport(src_exports, require("./worker-mode"), module.exports);
66
67
  __reExport(src_exports, require("./redis-connection-manager"), module.exports);
67
68
  __reExport(src_exports, require("./main-data-source"), module.exports);
68
69
  var import_findPackageNames = require("./plugin-manager/findPackageNames");
@@ -92,6 +93,7 @@ const OFFICIAL_PLUGIN_PREFIX = "@nocobase/plugin-";
92
93
  ...require("./pub-sub-manager"),
93
94
  ...require("./event-queue"),
94
95
  ...require("./worker-id-allocator"),
96
+ ...require("./worker-mode"),
95
97
  ...require("./redis-connection-manager"),
96
98
  ...require("./main-data-source")
97
99
  });
@@ -76,6 +76,7 @@ const deps = {
76
76
  lodash: "4.x",
77
77
  "china-division": "2.x",
78
78
  cronstrue: "2.x",
79
- "@nocobase/license-kit": "0.3.x"
79
+ "@nocobase/license-kit": "0.3.x",
80
+ joi: "17.x"
80
81
  };
81
82
  var deps_default = deps;
package/lib/plugin.js CHANGED
@@ -234,6 +234,7 @@ const _Plugin = class _Plugin {
234
234
  "**/ai-employees/*/index.ts",
235
235
  "**/ai-employees/*.js",
236
236
  "**/ai-employees/*/index.js",
237
+ "**/ai-employees/*/prompt.md",
237
238
  "!**/ai-employees/**/*.d.ts"
238
239
  ]
239
240
  },
@@ -29,6 +29,7 @@ export declare class HandlerManager {
29
29
  set(channel: string, callback: any, options: PubSubManagerSubscribeOptions): (wrappedMessage: any) => Promise<void>;
30
30
  get(channel: string, callback: any): any;
31
31
  delete(channel: string, callback: any): any;
32
+ cancelPendingDebounce(): void;
32
33
  reset(): void;
33
34
  each(callback: any): Promise<void>;
34
35
  }
@@ -129,7 +129,18 @@ const _HandlerManager = class _HandlerManager {
129
129
  headlerMap.delete(callback);
130
130
  return headler;
131
131
  }
132
+ cancelPendingDebounce() {
133
+ if (this.uniqueMessageHandlers) {
134
+ for (const handler of this.uniqueMessageHandlers.values()) {
135
+ if (typeof (handler == null ? void 0 : handler.cancel) === "function") {
136
+ handler.cancel();
137
+ }
138
+ }
139
+ this.uniqueMessageHandlers.clear();
140
+ }
141
+ }
132
142
  reset() {
143
+ this.cancelPendingDebounce();
133
144
  this.handlers = /* @__PURE__ */ new Map();
134
145
  this.uniqueMessageHandlers = /* @__PURE__ */ new Map();
135
146
  }
@@ -77,6 +77,7 @@ const _PubSubManager = class _PubSubManager {
77
77
  });
78
78
  }
79
79
  async close() {
80
+ this.handlerManager.cancelPendingDebounce();
80
81
  if (!this.adapter) {
81
82
  return;
82
83
  }
@@ -40,7 +40,14 @@ const _SyncMessageManager = class _SyncMessageManager {
40
40
  if (!plugin.name) {
41
41
  return;
42
42
  }
43
- await this.subscribe(plugin.name, plugin.handleSyncMessage.bind(plugin));
43
+ if (typeof plugin.handleSyncMessage === "function") {
44
+ await this.subscribe(plugin.name, async (...args) => {
45
+ if (app.stopped || app.db.closed()) {
46
+ return;
47
+ }
48
+ return plugin.handleSyncMessage(...args);
49
+ });
50
+ }
44
51
  });
45
52
  }
46
53
  versionManager;
@@ -0,0 +1,19 @@
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
+ * Check if the application is running in transient mode (WORKER_MODE === '-'),
11
+ * which means it is a short-lived subprocess spawned to execute a command and then exit.
12
+ * @experimental
13
+ */
14
+ export declare function isTransient(): boolean;
15
+ /**
16
+ * Check if the application is serving as a specific worker.
17
+ * @experimental
18
+ */
19
+ export declare function serving(key?: string): boolean;
@@ -0,0 +1,67 @@
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 __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
15
+ var __export = (target, all) => {
16
+ for (var name in all)
17
+ __defProp(target, name, { get: all[name], enumerable: true });
18
+ };
19
+ var __copyProps = (to, from, except, desc) => {
20
+ if (from && typeof from === "object" || typeof from === "function") {
21
+ for (let key of __getOwnPropNames(from))
22
+ if (!__hasOwnProp.call(to, key) && key !== except)
23
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
24
+ }
25
+ return to;
26
+ };
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+ var worker_mode_exports = {};
29
+ __export(worker_mode_exports, {
30
+ isTransient: () => isTransient,
31
+ serving: () => serving
32
+ });
33
+ module.exports = __toCommonJS(worker_mode_exports);
34
+ function isTransient() {
35
+ return process.env.WORKER_MODE === "-";
36
+ }
37
+ __name(isTransient, "isTransient");
38
+ function serving(key) {
39
+ const { WORKER_MODE = "" } = process.env;
40
+ if (!WORKER_MODE) {
41
+ return true;
42
+ }
43
+ if (WORKER_MODE === "-") {
44
+ return false;
45
+ }
46
+ const topics = WORKER_MODE.trim().split(",");
47
+ if (key) {
48
+ if (WORKER_MODE === "*") {
49
+ return true;
50
+ }
51
+ if (topics.includes(key)) {
52
+ return true;
53
+ }
54
+ return false;
55
+ } else {
56
+ if (topics.includes("!")) {
57
+ return true;
58
+ }
59
+ return false;
60
+ }
61
+ }
62
+ __name(serving, "serving");
63
+ // Annotate the CommonJS export names for ESM import in node:
64
+ 0 && (module.exports = {
65
+ isTransient,
66
+ serving
67
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/server",
3
- "version": "2.1.0-alpha.12",
3
+ "version": "2.1.0-alpha.14",
4
4
  "main": "lib/index.js",
5
5
  "types": "./lib/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -10,21 +10,21 @@
10
10
  "@koa/cors": "^5.0.0",
11
11
  "@koa/multer": "^3.1.0",
12
12
  "@koa/router": "^13.1.0",
13
- "@nocobase/acl": "2.1.0-alpha.12",
14
- "@nocobase/actions": "2.1.0-alpha.12",
15
- "@nocobase/ai": "2.1.0-alpha.12",
16
- "@nocobase/auth": "2.1.0-alpha.12",
17
- "@nocobase/cache": "2.1.0-alpha.12",
18
- "@nocobase/data-source-manager": "2.1.0-alpha.12",
19
- "@nocobase/database": "2.1.0-alpha.12",
20
- "@nocobase/evaluators": "2.1.0-alpha.12",
21
- "@nocobase/lock-manager": "2.1.0-alpha.12",
22
- "@nocobase/logger": "2.1.0-alpha.12",
23
- "@nocobase/resourcer": "2.1.0-alpha.12",
24
- "@nocobase/sdk": "2.1.0-alpha.12",
25
- "@nocobase/snowflake-id": "2.1.0-alpha.12",
26
- "@nocobase/telemetry": "2.1.0-alpha.12",
27
- "@nocobase/utils": "2.1.0-alpha.12",
13
+ "@nocobase/acl": "2.1.0-alpha.14",
14
+ "@nocobase/actions": "2.1.0-alpha.14",
15
+ "@nocobase/ai": "2.1.0-alpha.14",
16
+ "@nocobase/auth": "2.1.0-alpha.14",
17
+ "@nocobase/cache": "2.1.0-alpha.14",
18
+ "@nocobase/data-source-manager": "2.1.0-alpha.14",
19
+ "@nocobase/database": "2.1.0-alpha.14",
20
+ "@nocobase/evaluators": "2.1.0-alpha.14",
21
+ "@nocobase/lock-manager": "2.1.0-alpha.14",
22
+ "@nocobase/logger": "2.1.0-alpha.14",
23
+ "@nocobase/resourcer": "2.1.0-alpha.14",
24
+ "@nocobase/sdk": "2.1.0-alpha.14",
25
+ "@nocobase/snowflake-id": "2.1.0-alpha.14",
26
+ "@nocobase/telemetry": "2.1.0-alpha.14",
27
+ "@nocobase/utils": "2.1.0-alpha.14",
28
28
  "@types/decompress": "4.2.7",
29
29
  "@types/ini": "^1.3.31",
30
30
  "@types/koa-send": "^4.1.3",
@@ -61,5 +61,5 @@
61
61
  "@types/serve-handler": "^6.1.1",
62
62
  "@types/ws": "^8.5.5"
63
63
  },
64
- "gitHead": "f12c4a75470590b1670ce54510b96ef94c2cd7a2"
64
+ "gitHead": "d8735b541de0ff9557bba704de49c799b4962672"
65
65
  }