/**
 * This file is part of the NocoBase (R) project.
 * Copyright (c) 2020-2024 NocoBase Co., Ltd.
 * Authors: NocoBase Team.
 *
 * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
 * For more information, please refer to: https://www.nocobase.com/agreement.
 */

var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var plugin_exports = {};
__export(plugin_exports, {
  PluginFlowEngineServer: () => PluginFlowEngineServer,
  default: () => plugin_default
});
module.exports = __toCommonJS(plugin_exports);
var import_utils = require("@nocobase/utils");
var import_flow_surfaces = require("./flow-surfaces");
var import_server = __toESM(require("./server"));
var import_resolve = require("./variables/resolve");
class PluginFlowEngineServer extends import_server.default {
  async afterAdd() {
  }
  async beforeLoad() {
    await super.beforeLoad();
  }
  getDatabaseByDataSourceKey(dataSourceKey = "main") {
    const dataSource = this.app.dataSourceManager.get(dataSourceKey);
    const cm = dataSource.collectionManager;
    if (!cm.db) {
      throw new Error("no db");
    }
    return cm.db;
  }
  async runSQLByDataSourceKey(dataSourceKey, sql, options = {}) {
    var _a;
    const key = dataSourceKey || "main";
    const dataSource = this.app.dataSourceManager.get(key);
    if (!dataSource) {
      throw new Error(`data source "${key}" does not exist`);
    }
    const cm = dataSource.collectionManager;
    if (typeof ((_a = cm.db) == null ? void 0 : _a.runSQL) !== "function") {
      throw new Error(`data source "${key}" does not support SQL`);
    }
    return await cm.db.runSQL(sql, options);
  }
  async load() {
    await super.load();
    (0, import_flow_surfaces.registerFlowSurfacesResource)(this);
    this.app.auditManager.registerAction("flowSql:save");
    this.app.auditManager.registerAction("flowModels:save");
    this.app.auditManager.registerAction("flowModels:duplicate");
    this.app.acl.allow("flowSql", "runById", "loggedIn");
    this.app.acl.allow("flowSql", "getBind", "loggedIn");
    this.app.acl.allow("variables", "resolve", "loggedIn");
    this.app.acl.allow("fieldAssignments", "apply", "loggedIn");
    this.app.resourceManager.define({
      name: "variables",
      actions: {
        // 解析 JSON 模板中的 ctx 变量
        resolve: async (ctx, next) => {
          var _a, _b;
          const raw = ((_b = (_a = ctx.action) == null ? void 0 : _a.params) == null ? void 0 : _b.values) ?? {};
          const values = typeof (raw == null ? void 0 : raw.values) !== "undefined" ? raw.values : raw;
          if (Array.isArray(values == null ? void 0 : values.batch)) {
            const batchItems = values.batch;
            const results = await (0, import_resolve.resolveVariablesBatch)(ctx, batchItems);
            ctx.body = { results };
            await next();
            return;
          }
          if (typeof (values == null ? void 0 : values.template) === "undefined") {
            ctx.throw(400, {
              code: "INVALID_PAYLOAD",
              message: "values.template is required when batch is not provided"
            });
          }
          const template = values.template;
          const contextParams = (values == null ? void 0 : values.contextParams) || {};
          ctx.body = await (0, import_resolve.resolveVariablesTemplate)(ctx, template, contextParams);
          await next();
        }
      }
    });
    this.app.acl.registerSnippet({
      name: "ui.flowSql",
      actions: ["flowSql:*"]
    });
    this.app.resourceManager.registerActionHandlers({
      "flowSql:runById": async (ctx, next) => {
        const { uid, type, filter, bind, liquidContext, dataSourceKey = "main" } = ctx.action.params.values;
        const r = this.db.getRepository("flowSql");
        const record = await r.findOne({
          filter: { uid }
        });
        const result = await (0, import_utils.transformSQL)(record.sql);
        const sql = await (0, import_utils.parseLiquidContext)(result.sql, liquidContext);
        ctx.body = await this.runSQLByDataSourceKey(record.dataSourceKey || dataSourceKey, sql, {
          type,
          filter,
          bind
        });
        await next();
      },
      "flowSql:getBind": async (ctx, next) => {
        const { uid } = ctx.action.params;
        const r = this.db.getRepository("flowSql");
        const record = await r.findOne({
          filter: { uid }
        });
        const { bind, liquidContext } = await (0, import_utils.transformSQL)(record.sql);
        ctx.body = {
          bind,
          liquidContext
        };
        await next();
      },
      "flowSql:save": async (ctx, next) => {
        const { uid, sql, dataSourceKey } = ctx.action.params.values;
        const r = this.db.getRepository("flowSql");
        await r.updateOrCreate({
          filterKeys: ["uid"],
          values: { uid, sql, dataSourceKey }
        });
        ctx.body = "ok";
        await next();
      },
      "flowSql:run": async (ctx, next) => {
        const { sql, type, filter, bind, dataSourceKey } = ctx.action.params.values;
        ctx.body = await this.runSQLByDataSourceKey(dataSourceKey, sql, { type, filter, bind });
        await next();
      }
    });
  }
  async install() {
  }
  async afterEnable() {
  }
  async afterDisable() {
  }
  async remove() {
  }
}
var plugin_default = PluginFlowEngineServer;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  PluginFlowEngineServer
});
